我在CALayer的子类中使用此代码,其实例是根CALayer的子层。
-(void)setSelected:(bool)s {
selected=s;
if (s)
{
CATransform3D rot = CATransform3DMakeRotation(M_PI, 0, 1, 0);
rot.m34=-1.0 / 200;
[self setTransform:rot];
}
else
{
CATransform3D rot = CATransform3DMakeRotation(0, 0, 1, 0);
rot.m34=-1.0 / 200;
[self setTransform:rot];
}
}
当所选属性设置为TRUE时,会发生以下情况:旋转完成直到角度等于M_PI / 2,然后图层消失,因为它是正交的。动画的结尾是错误的:在动画的第一部分(例如在左侧)看起来增长的边缘在左侧而不是右侧结束动画。然而,内容被翻转。
我认为这与两个旋转矩阵之间的插值有关,但我无法准确理解发生了什么。
详细信息:动画看起来就像这样:
翻转的内容是我想要实现的目标。
以下是我得到的动画帧。如你所见,梯形的小边始终在左边;它应该在动画结尾的右侧(右上方框架)。
答案 0 :(得分:6)
变换的数学运算不正确。您应该在旋转变换后应用透视变换,这意味着连接两个变换。更改旋转变换的m34系数不等效。
您应该通过以下方式替换您的代码:
-(void)setSelected:(bool)s {
selected=s;
CATransform3D perpectiveTransform = CATransform3DIdentity;
perpectiveTransform.m34 =-1.0 / 200;
if (s)
{
CATransform3D rot = CATransform3DMakeRotation(M_PI, 0, 1, 0);
[self setTransform:CATransform3DConcat(rot, perpectiveTransform)];
}
else
{
CATransform3D rot = CATransform3DMakeRotation(0, 0, 1, 0);
[self setTransform:CATransform3DConcat(rot, perpectiveTransform)];
}
}
顺便说一下,应用透视变换的一种更方便的方法是使用超层的sublayerTransform
属性,从而将其应用于每个子层(如果需要)。
这会产生类似的结果:
self.superlayer.sublayerTransform = perspectiveTransform; //do this in your setup
....
self.transform = rot;
获得相同的结果。
答案 1 :(得分:0)
想象一下,你的图层是一块半透明的塑料,上面投射着一个图像,因此它会照射到两侧。在pi / 2的旋转时,它是边缘开启的,因此它消失了。当您的旋转大于pi / 2但小于pi时,平板塑料的背面会暴露出来。因为它是半透明的,你可以看到图像的背面,但是因为你从后面看到它,所以它是镜像的。当角度达到pi时,纸张在y轴上翻转整整180度。它是倒置的,你可以看到后面的图像,所以它是向后的。