zoukankan      html  css  js  c++  java
  • CoreAnimation 变换

    CoreAnimation 变换


        CoreAnimation 目录

        博客园MakeDown支持不佳,如有需要请进GitHub

        本片博客主要内容:

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

    仿射变换 - CGAffineTransform

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

    图片一
    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;
    

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

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

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

        混合变换方法 CGAffineTransformConcat ⬇️.

    图片四
    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轴旋转⬇️.

    图片五
    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场景仅仅是被绘制在图层的表面.

  • 相关阅读:
    JUC锁框架_AbstractQueuedSynchronizer详细分析
    npm的镜像替换成淘宝
    MHA+keepalived集群环境搭建
    Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
    链表中倒数第k个结点
    调整数组顺序使奇数位于偶数前面
    数值的整数次方
    二进制中1的个数
    矩形覆盖
    OS之进程管理---多线程模型和线程库(POSIX PTread)
  • 原文地址:https://www.cnblogs.com/xubaoaichiyu/p/6589507.html
Copyright © 2011-2022 走看看