CoreAnimation 变换

CoreAnimation 变换


    CoreAnimation 目录html

    博客园MakeDown支持不佳,若有须要请进GitHubgit

    本片博客主要内容:github

  • 仿射变换 - CGAffineTransform
  • 3D变换 - CATransform3D

仿射变换 - CGAffineTransform

     CGAffineTransform 是用于二维空间的旋转,缩放和平移的属性.首先展现一个简单的样例,将图片顺时针旋转45°⬇️.ide

图片一
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformRotate(transform, M_PI_4);
self.imageView.layer.affineTransform = transform;

    向右平移200⬇️.测试

图片二
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformTranslate(transform, 200, 0);
self.imageView.layer.affineTransform = transform;

    先进行旋转后进行向右平移⬇️.3d

图片三
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformRotate(transform, M_PI_4);
transform = CGAffineTransformTranslate(transform, 200, 0);
self.imageView.layer.affineTransform = transform;

注意:
图片二与图片三同是向右平移200,可是经过观察两图的对比不难发现,图片三的平移距离明显比图片二的距离小,与此同时图片三相对图片二向下也有必定的平移,这是由于transform的上一次设置会对下一次设置的效果产生影响.code

    混合变换方法 CGAffineTransformConcat ⬇️.orm

图片四
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformRotate(transform, M_PI_4);
CGAffineTransform transformTwo = CGAffineTransformMakeTranslation(-200, 0);
transform = CGAffineTransformConcat(transform, transformTwo);
self.imageView.layer.affineTransform = transform;

3D变换 - CATransform3D

     CATransform3D 支持图层在三维空间内的操做,x轴旋转⬇️.htm

图片五
CATransform3D transform3d = CATransform3DIdentity;
transform3d = CATransform3DRotate(transform3d, M_PI_4, 1, 0, 0);
self.imageView.layer.transform = transform3d;

    y轴旋转⬇️.对象

图片六
CATransform3D transform3d = CATransform3DIdentity;
transform3d = CATransform3DRotate(transform3d, M_PI_4, 0, 1, 0);
self.imageView.layer.transform = transform3d;

    z轴旋转⬇️.

图片七
CATransform3D transform3d = CATransform3DIdentity;
transform3d = CATransform3DRotate(transform3d, M_PI_4, 0, 0, 1);
self.imageView.layer.transform = transform3d;

    以上三张样图只能让咱们发现与原有图片有所不一样,可是不能明显的区别出差异在哪里,此时咱们能够设置m34来实现透视投影的效果.

    透视投影 - x轴旋转⬇️.

图片八
CATransform3D transform3d = CATransform3DIdentity;
transform3d.m34 = - 1.0 / 500.0;
transform3d = CATransform3DRotate(transform3d, M_PI_4, 1, 0, 0);
self.imageView.layer.transform = transform3d;

    透视投影 - y轴旋转⬇️.

图片九
CATransform3D transform3d = CATransform3DIdentity;
transform3d.m34 = - 1.0 / 500.0;
transform3d = CATransform3DRotate(transform3d, M_PI_4, 0, 1, 0);
self.imageView.layer.transform = transform3d;

    透视投影 - z轴旋转⬇️.

图片十
CATransform3D transform3d = CATransform3DIdentity;
transform3d.m34 = - 1.0 / 500.0;
transform3d = CATransform3DRotate(transform3d, M_PI_4, 0, 0, 1);
self.imageView.layer.transform = transform3d;

    灭点 : 当在透视角度绘图的时候,远离相机视角的物体将会变小变远,当远离到一个极限距离,它们就缩成了一个点,所以全部的物体最后都汇聚消失在同一个点.在现实中,这个点一般是视图的中心,因而为了在应用中建立拟真效果的透视,这个点应该聚在屏幕中点,或者至少是包含全部3D对象的视图中点.

图片十一

    了解灭点后便会遇到一个问题,一般状态下手机屏幕所显示的内容存在着不少图层,那么咱们要一一设置他们的灭点吗?显然这种方法是不可行的觉得它十分不方便.封装?或许是一个错的方法,可是那样会带来一个严重的后果就是不灵活,那么应该怎样去作?sublayerTransform是最完美的选择,它也是CATransform3D类型,但和对一个图层的变换不一样,它影响到全部的子图层.这意味着你能够一次性对包含这些图层的容器作变换,因而全部的子图层都自动继承了这个变换方法.

    作一个简单的测试.

图片十二
CATransform3D perspective = CATransform3DIdentity;
perspective.m34 = - 1.0 / 500;
self.view.layer.sublayerTransform = perspective;
CATransform3D transform = CATransform3DIdentity;
CATransform3D twoTransform = CATransform3DIdentity;
transform = CATransform3DRotate(transform, M_PI_4, 0, 1, 0);
twoTransform = CATransform3DRotate(twoTransform, -M_PI_4, 0, 1, 0);
self.imageView.layer.transform = transform;
self.imageTwoView.layer.transform = twoTransform;

     背面 : 设置图层翻转180°.

图片十三
CATransform3D perspective = CATransform3DIdentity;
perspective.m34 = - 1.0 / 500;
self.view.layer.sublayerTransform = perspective;
CATransform3D transform = CATransform3DIdentity;
CATransform3D twoTransform = CATransform3DIdentity;
transform = CATransform3DRotate(transform, M_PI_4, 0, 1, 0);
twoTransform = CATransform3DRotate(twoTransform, -M_PI, 0, 1, 0);
self.imageView.layer.transform = transform;
self.imageTwoView.layer.transform = twoTransform;

    背面的绘制是很浪费cpu以及gpu的,所以咱们更多的时候是须要禁止绘制图层背面的.

图片十四
CATransform3D perspective = CATransform3DIdentity;
perspective.m34 = - 1.0 / 500;
self.view.layer.sublayerTransform = perspective;
CATransform3D transform = CATransform3DIdentity;
CATransform3D twoTransform = CATransform3DIdentity;
transform = CATransform3DRotate(transform, M_PI_4, 0, 1, 0);
twoTransform = CATransform3DRotate(twoTransform, -M_PI, 0, 1, 0);
self.imageView.layer.transform = transform;
self.imageTwoView.layer.transform = twoTransform;
self.imageTwoView.layer.doubleSided = NO;// 不绘制背面

    最后来讨论一下,子图的相对父图层的逆变换是否会恢复原状.z轴?

图片十五
CATransform3D perspective = CATransform3DIdentity;
perspective.m34 = - 1.0 / 500;
self.view.layer.sublayerTransform = perspective;
CATransform3D outer = CATransform3DIdentity;
CATransform3D inter = CATransform3DIdentity;
outer = CATransform3DRotate(outer, M_PI_4, 0, 0, 1);
inter = CATransform3DRotate(inter, -M_PI_4, 0, 0, 1);
self.outer.layer.transform = outer;
self.inter.layer.transform = inter;

    z轴状态下是能够恢复原状的.y轴?

图片十六
CATransform3D perspective = CATransform3DIdentity;
perspective.m34 = - 1.0 / 500;
self.view.layer.sublayerTransform = perspective;
CATransform3D outer = CATransform3DIdentity;
CATransform3D inter = CATransform3DIdentity;
outer = CATransform3DRotate(outer, M_PI_4, 0, 1, 0);
inter = CATransform3DRotate(inter, -M_PI_4, 0, 1, 0);
self.outer.layer.transform = outer;
self.inter.layer.transform = inter;

y轴并非,这是因为尽管Core Animation图层存在于3D空间以内,但它们并不都存在同一个3D空间.每一个图层的3D场景实际上是扁平化的,当你从正面观察一个图层,看到的实际上由子图层建立的想象出来的3D场景,但当你倾斜这个图层,你会发现实际上这个3D场景仅仅是被绘制在图层的表面.

相关文章
相关标签/搜索