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より小さい場合、プラスチックの平らなシートの裏側が露出します。半透明なので裏側が見えますが、裏側から見ているので鏡像になっています。角度が円周率に達すると、シートはy軸上で完全に180度反転します。逆さまになっていて、後ろから画像が見えるので後ろ向きです。

于 2012-09-26T01:38:46.387 に答える