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

CoreAnimation 变换的更多相关文章

  1. 二、CoreAnimation之寄宿图详解

    在之前的图层树中我们知道,可以使用CALayer对象创建一些有背景颜色的图层,其实使用CALayer,不仅可以利用其展示背景颜色,还可以展示图片.而这些展示内容,其实就是CALayer的寄宿图.这一节 ...

  2. 一、CoreAnimation之图层树详解

    CoreAnimation :在字面意思为“核心动画”,但是如果您认为它仅仅是一个动画框架,那可能就要错过一些经典功能了.动画,只是CoreAnimation功能的一小部分,毕竟人家的源头是一个叫做L ...

  3. CoreAnimation笔记

    核心动画继承结构 CoreAnimation Core Animation是直接作用在CALayer上的(并非UIView上)非常强大的跨Mac OS X和iOS平台的动画处理API,Core Ani ...

  4. iOS开发CoreAnimation解读之三——几种常用Layer的使用解析

    iOS开发CoreAnimation解读之三——几种常用Layer的使用解析 一.CAEmitterLayer 二.CAGradientLayer 三.CAReplicatorLayer 四.CASh ...

  5. iOS开发CoreAnimation解读之二——对CALayer的分析

    iOS开发CoreAnimation解读之二——对CALayer的分析 一.UIView中的CALayer属性 1.Layer专门负责view的视图渲染 2.自定义view默认layer属性的类 二. ...

  6. CoreAnimation 开篇

    CoreAnimation 开篇 CoreAnimation系列博客是我对学习CoreAnimation的知识整理,博客排列顺序以及知识讲解存在欠缺望见谅. 博客的编写是在工作之余,尽量保证CoreA ...

  7. ios之CoreAnimation

    CoreAnimation的好处: 1.高性能,简单的编程模块 2.像View一样,使用层级结构来构建负责的界面 3.轻量级数据结构,能使上百个动画同时执行 4.抽象的动画接口,允许动画在一个独立的线 ...

  8. iOS动画——CoreAnimation

    CoreAnimation在我之前的UIKit动画里面简单的提了一句CoreAnimation动画,其实大家别看它类库名种有个animation,实际上animation在这个库中只占有很小的地位. ...

  9. BZOJ 1692: [Usaco2007 Dec]队列变换 [后缀数组 贪心]

    1692: [Usaco2007 Dec]队列变换 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1383  Solved: 582[Submit][St ...

随机推荐

  1. HDU5058

    So easy Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  2. [转载] 编程每一天(Write Code Every Day)

    转载自:http://kb.cnblogs.com/page/536779/ 英文原文:Write Code Every Day 去年秋天,我的个人项目似乎走到了尽头:我一直没能取得必要的进展,在不牺 ...

  3. ADO.NET 数据库操作类

    操作数据类 避免代码重用.造对象太多.不能分工开发 利用面向对象的方法,把数据访问的方式优化一下,利用封装类   一般封装成三个类: 1.数据连接类 提供数据连接对象 需要引用命名空间: using ...

  4. ArcGIS制图表达Representation-制图表达原理

    ArcGIS制图表达技术-制图表达原理 by 李远祥 在讲述原理之前,需要对上一章内容进行一些必要的补充说明.既然制图表达有很多优势,是不是什么情况下都可以使用制图表达技术呢?如果有以下的一些特殊的要 ...

  5. JAVA构造函数的继承

    1.子类中无参构造函数,可直接继承父类中无参构造函数,前提是所有变量均为public 如下:父类Student中有空构造函数Student(),子类Pupil中有空构造函数Pupil(),后者会继承前 ...

  6. SOCKET是什么

    一.问题的引入--socket的引入是为了解决不同计算机间进程间通信的问题 1.socket与进程的关系 1).socket与进程间的关系:socket   用来让一个进程和其他的进程互通信息(IPC ...

  7. redisson实现分布式锁原理

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  8. 【前端】:HTML

    前言: 最近开始学前端了,这篇博客主要介绍html的一些主要标签,写完这篇博客,我会用刚学的html做一个简单的登陆界面~~ 一.HTML介绍 HTML(Hyper Text Mark-up Lang ...

  9. html5表单和伪类

    type = "email"; 自带验证格式type = "url"; 网址 http//:type = "tel";移动端会变成数字键盘t ...

  10. FZU 2167 大王叫我来巡山呐

    Problem 2167 大王叫我来巡山呐 Accept: 931    Submit: 1405Time Limit: 1000 mSec    Memory Limit : 32768 KB Pr ...