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. 第二章:在HTML中使用JavaScript

    1:在使用<script>嵌入JavaScript代码死,记住不要在代码中的任何地方出现"</script>"字符串 例如,浏览器在加载下面所示代码时就会产 ...

  2. redis的删除库应用(linux)

    1.首先从linux进入redis的安装目录下 2.用redis-cli在Shell命令行下启动Redis客户端工具. 3.select 库名 进入到库下 4.flushdb 刷新当前库 redis的 ...

  3. 从你的全世界切过(胡说八道支持向量机SVM小故事)

    背景 据说很久很久以前, 澳门有一家"胡说八道大赌场", 专门提供各种奇奇怪怪的玩法. 其中有一个赌博叫"从你的全世界切过"(连名字也这么奇怪). 玩法是在一张 ...

  4. jQuery.sort对DOM元素进行排序

    实例: 每个tr的第三列显示的都是数字,我们就以这数字列作为排序依据,方法就是利用jquery的sort()方法. 首先,利用jquery选择器获取每个tr元素,获取回来是一个数据: var $trs ...

  5. iOS开发一些小技巧

    1.隐藏多余的tableView的cell分割线 self.tableView.tableFooterView= [[UIViewalloc]init]; 2.取消系统自带的返回字样 [[UIBarB ...

  6. linux gdb基本概念

    GDB是一个功能强大的调试器,它是一个自由软件,能够用在许多UNIX平台上.它同时也是Linux系统中的默认调试器.GDB已被移植到许多其他的计算机平台上,并且能够用于调试嵌入式实时系统.一般来说,G ...

  7. redis-如何在工程中使用redis

    这里,我们介绍下如何使用redis作为缓存服务器使用在我们的工程中. 使用思路 对于java中的使用redis提供了一个jedis的jar包.我们在安装好我们的redis服务器以后,只需要通过redi ...

  8. Visual Studio 与 Matlab实现混合编程

    环境: Win10 vs2010 Matlab2015 里面有很多选做的内容,其中2.3必做 1.Matlab环境设置:   (选做)我没有做这步,因为打mbuild -setup指令不识别,缺少SD ...

  9. java udp socket通信(仅发送)

    实现功能:客户端发送一个字符串(可以为汉字),服务器端接收并显示 服务器端程序: package udpServer; import java.io.*; import java.net.*; /** ...

  10. 设置npm安装模块目录<nodejs>

    nodejs安装模块命令: npm install <input_name> # 本地安装 npm install <input_name> -g # 全局安装 1.npm i ...