Reputation: 6855
I have a simple Composable Canvas that draws a shape multiple times in different positions, and I wish to apply rotation to each iteration of the shape as per a particular algorithm. However, I am unable to fully control the positioning of the shapes in the canvas since the rotate
transformation seems to apply a translation
trasformation of its own. Here's what I have
@Preview
@Composable
fun CanvasCollosum() {
val painter = rememberVectorPainter(image = ImageVector.vectorResource(id = R.drawable.tick))
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center){
Canvas(modifier = Modifier.height(200.dp).aspectRatio(1f)) {
with(painter) {
repeat(12) {
(it * 30f).let { angle ->
translate(
top = 0f, // Some translation is still applied by 'rotate'
left = 0f
) {
rotate(angle) {
draw(
Size(100f, 100f),
colorFilter = ColorFilter.tint(Color.White)
)
}
}
}
}
}
}
}
}
Hence, for some reason, the positionings of all of the shapes here (12 in total) assume the shape of a circle, which is not at all what I expected. I can assume it is something related to the 'pivot' of the rotation. However, it is set, by default, as the center of the Canvas, which seems fairly appropriate. The shape is being rendered far away from the pivot which seems to be causing the translation effect to occur as a side effect, so the question is -- How do I render all my shapes with a fixed rotation, and position them with specific (x, y) cords, given that I have an algorithm to position them relative to the center of the Canvas?
For reference, here's some outputs, displaying a single shape, with the only varying property being the rotation angle
0f Degrees
90f Degrees
180f Degrees
270f Degrees
360f is the same as 0f
This does not seem like something that should be happening here, but it is.
The Square is the Box
Composable and the little white thing is the shape in concern.
Upvotes: 2
Views: 2128
Reputation: 2376
It is not applying translation, but is rotating around a pivot, which is set to the center of the Box
.
rotate
has a parameter named pivot
that will solve your problem:
@Composable
fun Rotation() {
val painter = rememberVectorPainter(image = Icons.Default.ThumbUp)
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Canvas(
modifier = Modifier
.height(200.dp)
.background(color = Color.Red)
.aspectRatio(1f)
) {
with(painter) {
repeat(4) {
rotate(
degrees = (it * 90f),
pivot = Offset(
painter.intrinsicSize.width * 2,
painter.intrinsicSize.height * 2
)
) {
draw(
Size(100f, 100f),
colorFilter = ColorFilter.tint(Color.White)
)
}
}
}
}
}
}
The code above produces this result:
In order to change the point, around which the rotation is done, simple change the coordinates in pivot
parameter.
Upvotes: 2