Compose Canvas 的 'rotate' 转换造成的混淆行为
Confusing behaviour by the 'rotate' transformation of Compose Canvas
我有一个简单的可组合项 Canvas,它在不同位置多次绘制一个形状,我希望根据特定算法对形状的每次迭代应用旋转。但是,我无法完全控制 canvas 中形状的定位,因为 rotate
转换似乎应用了它自己的 translation
转换。这是我的
@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)
)
}
}
}
}
}
}
}
}
因此,由于某种原因,这里所有形状的定位(一共12个)都呈现为圆形,这与我的预期完全不同。我可以假设它与旋转的 'pivot' 有关。但是,它默认设置为 Canvas 的中心,这似乎很合适。形状远离枢轴呈现,这似乎导致平移效果作为副作用发生,所以问题是 - 如何以固定旋转渲染我的所有形状,并使用特定的(x , y) 线,因为我有一个算法可以将它们相对于 Canvas?
的中心定位
作为参考,这里有一些输出,显示单一形状,唯一的变化 属性 是旋转角度
0f 度
90f 度
180f 度
270f 度
360f 与 0f 相同
这似乎不应该发生在这里,但确实如此。
方形是 Box
可组合项,白色的小东西是相关形状。
它没有应用平移,而是围绕一个枢轴旋转,该枢轴设置为 Box
。
rotate
有一个名为 pivot
的参数可以解决您的问题:
@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)
)
}
}
}
}
}
}
上面的代码产生了这个结果:
为了改变完成旋转的点,简单地改变pivot
参数中的坐标。
我有一个简单的可组合项 Canvas,它在不同位置多次绘制一个形状,我希望根据特定算法对形状的每次迭代应用旋转。但是,我无法完全控制 canvas 中形状的定位,因为 rotate
转换似乎应用了它自己的 translation
转换。这是我的
@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)
)
}
}
}
}
}
}
}
}
因此,由于某种原因,这里所有形状的定位(一共12个)都呈现为圆形,这与我的预期完全不同。我可以假设它与旋转的 'pivot' 有关。但是,它默认设置为 Canvas 的中心,这似乎很合适。形状远离枢轴呈现,这似乎导致平移效果作为副作用发生,所以问题是 - 如何以固定旋转渲染我的所有形状,并使用特定的(x , y) 线,因为我有一个算法可以将它们相对于 Canvas?
的中心定位作为参考,这里有一些输出,显示单一形状,唯一的变化 属性 是旋转角度
0f 度
90f 度
180f 度
270f 度
360f 与 0f 相同
这似乎不应该发生在这里,但确实如此。
方形是 Box
可组合项,白色的小东西是相关形状。
它没有应用平移,而是围绕一个枢轴旋转,该枢轴设置为 Box
。
rotate
有一个名为 pivot
的参数可以解决您的问题:
@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)
)
}
}
}
}
}
}
上面的代码产生了这个结果:
为了改变完成旋转的点,简单地改变pivot
参数中的坐标。