Canoe

iOS核心动画实践四(变换)

2017.06.20

仿射变换

CGAffineTransformMakeRotation(CGFloat angle)
CGAffineTransformMakeScale(CGFloat sx, CGFloat sy)
CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty)

可以改变视图的位置和缩放以及旋转。
混合变换可以在一个变换的基础上继续进行下一个变换,依赖顺序执行。

CGAffineTransformRotate(CGAffineTransform t, CGFloat angle)
CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy)
CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty)

如果要混合两个已经存在的变换,可以使用

CGAffineTransformConcat(CGAffineTransform t1, CGAffineTransform t2);

3D变换

CATransform3D是一个可以在3维空间内做变换的4*4的矩阵。

CATransform3DMakeRotation(CGFloat angle, CGFloat x, CGFloat y, CGFloat z)
CATransform3DMakeScale(CGFloat sx, CGFloat sy, CGFloat sz) 
CATransform3DMakeTranslation(Gloat tx, CGFloat ty, CGFloat tz)

但是当我们按照上述方式设置layer的3d变换:

    CATransform3D transform = CATransform3DMakeRotation(M_PI_4, 0, 1, 0);
    testView.layer.transform = transform;

结果却是:

看起来图层是变窄了,但是并没有旋转,其实是因为我们在一个斜向的角度看它,而不是透视。

透视投影

为了让图层看起来像有空间感,我们需要引入投影变换,来对出了旋转之外的变换做一些修改。
CATransform3D的透视效果通过一个矩阵中一个很简单的元素来控制:m34用来按比例缩放X和Y的值来计算到底要离视角多远。
m34的值默认是0。可以设置m34为-1.0/d来应用透视效果。d代表了想象中视角相机和屏幕的距离。

    CATransform3D transform = CATransform3DIdentity;
    //apply perspective
    transform.m34 = - 1.0 / 500.0;
    //rotate by 45 degrees along the Y axis
    transform = CATransform3DRotate(transform, M_PI_4, 0, 1, 0);
    testView.layer.transform = transform;


当修改d的值为300后


通过查看View的frame我们可以看到是以layer所占最大面积来算的。
那么我们就可以实现淘宝的购买切换的效果

sublayerTransform
这个属性是在一个视图内,多个子视图都要做3D变换,需要设置不同的m34值很麻烦。和对一个图层的变换不同,它影响到所有的子图层。这意味着你可以一次性对包含这些图层的容器做变换,于是所有的子图层都自动继承了这个变换方法。

背面

在旋转的时候,当我们设置旋转180度的时候,那么图层会完全旋转到背面,背面当我们需要显示镜像效果的时候会很简单,但是如果正常的时候我们并不需要它,那么CPU绘制他们就会造成资源浪费。
CALayer有一个属性叫做doubleSided来控制背面是否要被绘制,默认为YES,可以设置为NO。

当我们要实现一个立方体的时候,可以使用3Dtransform来实现,但是要实现光亮和阴影就需要使用GLKit库了,具体使用可以看iOS核心动画高级技巧这本书。

这一部分我们可以实现视图的旋转和3D的旋转,以及利用图形的旋转实现一个立方体。

Comments
Write a Comment