为什么 2π 旋转动画不适用于 CALayer.transform?
Why 2π rotation animation doesn't work for CALayer.transform?
为什么 transform
直接使用 CATransform3D
不起作用
let rotationAnimation1 = CABasicAnimation(keyPath: #keyPath(CALayer.transform))
rotationAnimation1.toValue = CATransform3DMakeRotation(.pi * 2, 0, 0, 1)
rotationAnimation1.duration = 1
但是对 transform.rotation
使用 CGFloat
有效吗?
let rotationAnimation2 = CABasicAnimation(keyPath: "transform.rotation")
rotationAnimation2.toValue = CGFloat.pi * 2
rotationAnimation2.duration = 1
这是要玩的 Playground。
当你安装一个完整的CATransform3D
作为动画的toValue时,系统唯一要做的就是动画开始状态和结束状态的区别。一个变换和一个旋转 2π 的变换是相同的。因此,没有变化。
当您为 transform.rotation
制作动画时,您会向动画引擎提供有关您正在做什么以及您的意图的信息。它可以告诉您要绕 Z 轴顺时针旋转对象。
编辑:
当您创建 CAAnimation 时,核心动画会采用您在动画中设置的更改并确定如何应用它们。如果您只是提交一个更改后的 CATransform3D,Core Animation 必须比较开始和结束变换,并弄清楚如何生成从开始到结束状态的实际动画。例如,如果您旋转小于 1/2π,它将以最短的旋转让您到达那里。如果您的变换旋转 -3/2π(向另一个方向旋转 270 度),您的意图就会丢失,它仍然会旋转 +45°。如果您改为提交对 transform.rotation 的更改,您会为 Core Animation 提供更多信息。
需要注意的是 transform
属性 的动画 不是 通过分量矩阵插值完成的,而是通过分解两个开始来完成的并结束转换为原始组件(旋转、平移等),然后从插值组件重新创建转换。
让我们考虑恒等和 2π 旋转变换之间的 2 秒动画并问问自己 "What transform will be there after 1 second of animation has elapsed?"。这两个矩阵本质上都是 0
弧度旋转。 0
和0
之间的50%插值仍然是0
,因此1秒后的最终矩阵也有0
弧度旋转。
当你直接插入 transform.rotation
时,Core Animation 已经有了可用的原始组件——你实际上只是将旋转传递给它,不需要进行分解。 0
和 2π
之间的 50% 插值是 π
,因此 1 秒后的最终矩阵是预期的 π
弧度旋转。
为什么 transform
直接使用 CATransform3D
不起作用
let rotationAnimation1 = CABasicAnimation(keyPath: #keyPath(CALayer.transform))
rotationAnimation1.toValue = CATransform3DMakeRotation(.pi * 2, 0, 0, 1)
rotationAnimation1.duration = 1
但是对 transform.rotation
使用 CGFloat
有效吗?
let rotationAnimation2 = CABasicAnimation(keyPath: "transform.rotation")
rotationAnimation2.toValue = CGFloat.pi * 2
rotationAnimation2.duration = 1
这是要玩的 Playground。
当你安装一个完整的CATransform3D
作为动画的toValue时,系统唯一要做的就是动画开始状态和结束状态的区别。一个变换和一个旋转 2π 的变换是相同的。因此,没有变化。
当您为 transform.rotation
制作动画时,您会向动画引擎提供有关您正在做什么以及您的意图的信息。它可以告诉您要绕 Z 轴顺时针旋转对象。
编辑:
当您创建 CAAnimation 时,核心动画会采用您在动画中设置的更改并确定如何应用它们。如果您只是提交一个更改后的 CATransform3D,Core Animation 必须比较开始和结束变换,并弄清楚如何生成从开始到结束状态的实际动画。例如,如果您旋转小于 1/2π,它将以最短的旋转让您到达那里。如果您的变换旋转 -3/2π(向另一个方向旋转 270 度),您的意图就会丢失,它仍然会旋转 +45°。如果您改为提交对 transform.rotation 的更改,您会为 Core Animation 提供更多信息。
需要注意的是 transform
属性 的动画 不是 通过分量矩阵插值完成的,而是通过分解两个开始来完成的并结束转换为原始组件(旋转、平移等),然后从插值组件重新创建转换。
让我们考虑恒等和 2π 旋转变换之间的 2 秒动画并问问自己 "What transform will be there after 1 second of animation has elapsed?"。这两个矩阵本质上都是 0
弧度旋转。 0
和0
之间的50%插值仍然是0
,因此1秒后的最终矩阵也有0
弧度旋转。
当你直接插入 transform.rotation
时,Core Animation 已经有了可用的原始组件——你实际上只是将旋转传递给它,不需要进行分解。 0
和 2π
之间的 50% 插值是 π
,因此 1 秒后的最终矩阵是预期的 π
弧度旋转。