I have highlighted (red) my problem in the image; I want to animate that blue indicator triangle.
The triangle is moving, but it is not properly moving. I don't know what I am missing.
Timer Image with what I have achieved so far:
This is my code so far.
val center = Offset(size.width / 2f, size.height / 2f)
val beta = (250f * value 145f) * (PI / 180f).toFloat()
val r = size.width / 2f
val a = cos(beta) * r
val b = sin(beta) * r
drawPoints(
listOf(Offset(center.x a, center.y b)),
pointMode = PointMode.Points,
color = Color.Gray,
strokeWidth = (strokeWidth * 2.2f).toPx(),
cap = StrokeCap.Round
)
drawPoints(
listOf(Offset(center.x a, center.y b)),
pointMode = PointMode.Points,
color = Color.White,
strokeWidth = (strokeWidth * 2f).toPx(),
cap = StrokeCap.Round
)
drawPoints(
listOf(Offset(center.x a, center.y b)),
pointMode = PointMode.Points,
color = PrimaryBlueColor,
strokeWidth = (strokeWidth * 1f).toPx(),
cap = StrokeCap.Round
)
drawImage(
image = vector,
topLeft = Offset(center.x a, center.y b)
)
CodePudding user response:
Rotation in Compose is very simple. Insider Canvas or actually DrawScope call
rotate(value) {
// Anything you draw here is rotate by angle in degrees
}
As
val centerX = center.x
val centerY = center.y
val triangleWidthPx = triangleWidth.toPx()
val triangleHeightPx = triangleHeight.toPx()
val diff = offsetX.toPx()
val strokeWidthPx = strokeWidth.toPx()
val triangleStartX = centerX radiusPx - diff
if (trianglePath.isEmpty) {
trianglePath.apply {
moveTo(triangleStartX, centerY - triangleHeightPx / 2)
lineTo(triangleStartX triangleWidthPx, centerY)
lineTo(triangleStartX, centerY triangleHeightPx / 2)
lineTo(triangleStartX, centerY - triangleHeightPx / 2)
}
}
rotate(value) {
drawPath(trianglePath, Color(0xff243f8d))
}
Full Sample
Demonstration
Code
@Composable
private fun CanvasRotationSample() {
var value by remember {
mutableStateOf(0f)
}
val diameter = 160.dp
Spacer(modifier = Modifier.height(50.dp))
Slider(value = value, onValueChange = { value = it }, valueRange = 0f..360f)
Spacer(modifier = Modifier.height(50.dp))
val trianglePath = remember {
Path()
}
val triangleWidth = 24.dp
val triangleHeight = 24.dp
val offsetX = 2.dp
Box(
Modifier
.fillMaxWidth()
.aspectRatio(1f),
contentAlignment = Alignment.Center
) {
Canvas(
modifier = Modifier.matchParentSize()
) {
val radius = diameter.toPx() / 2
val centerX = center.x
val centerY = center.y
val triangleWidthPx = triangleWidth.toPx()
val triangleHeightPx = triangleHeight.toPx()
val diff = offsetX.toPx()
val triangleStartX = centerX radius - diff
if (trianglePath.isEmpty) {
trianglePath.apply {
moveTo(triangleStartX, centerY - triangleHeightPx / 2)
lineTo(triangleStartX triangleWidthPx, centerY)
lineTo(triangleStartX, centerY triangleHeightPx / 2)
lineTo(triangleStartX, centerY - triangleHeightPx / 2)
}
}
rotate(value) {
drawPath(trianglePath, Color(0xff243f8d))
}
}
Box(
modifier = Modifier
.shadow(4.dp, CircleShape)
.background(Color(0xfff9f9fa))
.size(diameter)
.padding(24.dp)
) {
Box(
modifier = Modifier
.shadow(1.dp, CircleShape)
.background(Color.White)
.matchParentSize()
.drawBehind {
drawArc(
color = Color(0xff6175ad),
useCenter = true,
startAngle = -60f,
sweepAngle = 120f
)
}
)
}
}
}