2

I use this code inside a subclass of CALayer which instances are sublayers of the root 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];
    }
}

When the selected property to set to TRUE, here is what happens: the rotation is done until the angle is equal to M_PI/2, then the layer disappears because it is orthogonal. The end of the animation is wrong: the edge that appeared to grow in the first part of the animation (for example on the left side), ends the animation on the left side instead of the right side. However the content is flipped.

I think this has something to do with the interpolation between the two rotation matrices but I can't understand exactly what is happening.

Details: The animation looks like it is doing this:

  1. increment rotation around Y axis by +Pi/2
  2. content flipping
  3. increment rotation around Y axis by -Pi/2, as if it bounced of the (yz)plane

The flipped content is what I am trying to achieve.

Here are the frames of the animation I get. As you can see, the small side of the trapezoid is always of the left; it should be on the right on at the end of the animation (top right frame). A layer rotating around the Y-axis

4

3 回答 3

7

如果有人只想水平翻转图像或视图的方向

yourView.layer.transform = CATransform3DMakeScale(-1, 1, 1);

或者

yourView.layer.affineTransform =  CGAffineTransformMakeScale(-1, 1);
于 2015-09-10T09:10:36.320 回答
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;

以获得相同的外观结果。

于 2012-09-26T14:30:46.983 回答
0

想象一下,您的图层是一块平坦的半透明塑料,上面投射有图像,因此它的两面都发光。在 pi/2 旋转时,它是边缘打开的,因此它消失了。当您的旋转大于 pi/2 但小于 pi 时,塑料平板的背面就会暴露出来。因为它是半透明的,所以你可以看到图像的背面,但是因为你是从背面看到的,所以它是镜像的。当角度达到 pi 时,纸张在 y 轴上翻转了 180 度。它是倒置的,你可以从后面看到图像,所以它是倒着的。

于 2012-09-26T01:38:46.387 回答