CATransform3D
本章介绍图层的几何组成部分,及他们之间的相互关,同时介绍如何变换矩阵可以产生复杂的视觉效果。
1.1 图层的坐标系
图层的坐标系在不同平台上面具有差异性。在iOS系统中,默认的坐标系统原点在图层的中心左上角地方,原点向右和向下为正值。在Mac OS X系统中,默认的坐标系原点在图层的中心左下角地方,原点向右和向上为正值。坐标系的所有值都是浮点类型。你在任何平台上面创建的图层都采用该平台默认的坐标系。
每个图层定义并维护自己的坐标系,它里面的全部内容都由此相关的坐标系指定位置。该准则同时适应于图层自己的内容和它的任何子图层。因为任何图层定义了它自己的坐标系,CALayer类提供相应的方法用于从一个图层坐标系的点、矩形、大小值转化为另一个图层坐标系相应的值。
一些基于图层的属性使用单元坐标空间测量它们的值。单元坐标空间指定图层边界的相对值,而不是绝对值。单元坐标空间给定的x和y的值总是在0.0到1.0之间。指定一个沿X轴的值为0.0的点,得到的是图层左边缘的一个点,而指定一个1.0的点,则是图层右边缘的一个点。(对 Y轴而言,如果是在iOS系统,则0.0对应于顶部的点,而1.0则是底部的点,而在Mac OS X系统,得到的刚好相反,就如之前提到的坐标系不同一样)。而点(0.5,0.5)则刚好是图层的中心点。
1.2 指定图层的几何
虽然图层和图层树与视图和视图的结构在很多方面具有相似性,但是图层的几何却不同,它更加简单通俗。图层的所有几何属性,包括图层的矩阵变换,都可以隐式和显式动画。
下图显示可以在上下文中指定图层几何的属性:
图 1 CALayer的几何属性
图层的position属性是一个CGPoint的值,它指定图层相当于它父图层的位置,该值基于父图层的坐标系。
图层的bounds属性是一个CGRect的值,指定图层的大小(bounds.size)和图层的原点(bounds.origin)。当你重写图层的重画方法的时候,bounds的原点可以作为图形上下文的原点。
图层拥有一个隐式的frame,它是position,bounds,anchorPoint和transform属性的一部分。设置新的frame将会相应的改变图层的position和bounds属性,但是frame本身并没有被保存。但是设置新的frame时候,bounds的原点不受干扰,bounds的大小变为frame的大小,即bounds.size=frame.size。图层的位置被设置为相对于锚点(anchor point)的适合位置。当你设置frame的值的时候,它的计算方式和position、bounds、和anchorPoint的属性相关。
图层的anchorPoint属性是一个CGPoint值,它指定了一个基于图层bounds的符合位置坐标系的位置。锚点(anchor point)指定了bounds相对于position的值,同时也作为变换时候的支点。锚点使用单元空间坐标系表示,(0.0,0.0)点接近图层的原点,而(1.0,1.0)是原点的对角点。改变图层的父图层的变换属性(如果存在的话)将会影响到anchorPoint的方向,具体变化取决于父图层坐标系的Y轴。
当你设置图层的frame属性的时候,position会根据锚点(anchorPoint)相应的改变,而当你设置图层的position属性的时候,bounds会根据锚点(anchorPoint)做相应的改变。
iOS 注意:以下示例描述基于Mac OS X的图层,它的坐标系原点基于左下角。在iOS上面,图层的坐标系原点位于左上角,原点向下和向右为正值。这变化用具体数值显示,而不是概念描述。
下图描述了基于锚点的三个示例值:
图 2 三个锚点值
anchorPoint默认值是(0.5,0.5),位于图层边界的中心点(如上图显示),B点把anchorPoint设置为(0.0,0.5)。最后C点(1.0,0.0)把图层的position设置为图层frame的右下角。该图适用于Mac OS X的图层。在iOS系统里面,图层使用不同的坐标系,相应的(0.0,0.0)位于左上角,而(1.0,1.0)位于右下角。
图层的frame、bounds、position和anchorPoint关系如下图所示:
图 3 图层原点 :基于(0.5,0.5)
在该示例中,anchorPoint默认值为(0.5,0.5),位于图层的中心点。图层的position值为(100.0,100.0),bounds为(0.0,0.0,120,80.0)。通过计算得到图层的frame为(40.0,60.0,120.0,80.0)。
如果你新创建一个图层,则只有设置图层的frame为(40.0,60.0,120.0,80.0),相应的position属性值将会自动设置为(100.0,100.0),而bounds会自动设置为(0.0,0.0,120.0,80.0)。
下图显示一个图层具有相同的frame(如上图),但是在该图中它的anchorPoint属性值被设置为(0.0,0.0),位于图层的左下角位置。
图 4 图层原点 :基于 (0.0,0.0)
图层的frame值同样为(40.0,60.0,120.0,80.0),bounds的值不变,但是图层的position值已经改变为(40.0,60.0)。
图层的几何外形和Cocoa视图另外一个不同地方是,你可以设置图层的一个边角的半径来把图层显示为圆角。图层的cornerRadius属性指定了重绘图层内容,剪切子图层,绘制图层的边界和阴影的时候时候圆角的半径。
图层的zPosition属性值指定了该图层位于Z轴上面位置,zPosition用于设置图层相对于图层的同级图层的可视位置。
1.3 图层的几何变换
图层一旦创建,你就可以通过矩阵变换来改变一个图层的几何形状。CATransform3D的数据结构定义一个同质的三维变换(4×4 CGFloat值的矩阵),用于图层的旋转,缩放,偏移,歪斜和应用的透视。
图层的两个属性指定了变换矩阵:transform和sublayerTransform属性。图层的transform属性指定的矩阵结合图层的anchorPoint属性作用于图层和图层的子图层上面。图 3显示在使用anchorPoint默认值(0.5,0.5)的时候旋转和缩放变换如何影响一个图层。而图 4显示了同样的矩阵变换在anchorPoint为(0.0,0.0)的时候如何改变一个图层。图层的sublayerTransform属性指定的矩阵只会影响图层的子图层,而不会对图层本身产生影响。
你可以通过以下的任何一个方法改变CATransform3D的数据结构:
- 使用CATransform3D函数
- 直接修改数据结构的成员
- 使用键-值编码改变键路径
CATransform3DIdentity是单位矩阵,该矩阵没有缩放、旋转、歪斜、透视。把该矩阵应用到图层上面,会把图层几何属性修改为默认值。
1.3.1 变换函数
使用变换函数可以在核心动画里面在操作矩阵。你可以使用这些函数(如下表)去创建一个矩阵一般后面用于改变图层或者它的子图层的transform和sublayerTransform属性。变换函数或者直接操或者返回一个CATransform3D的数据结构。这可以让你能够构建简单或复杂的转换,以便重复使用。
表 1 CATransform3D 变换函数 :偏移、旋转和缩放
Function |
Use |
|
Returns a transform that translates by ‘(tx, ty, tz)’. t’ = [1 0 0 0; 0 1 0 0; 0 0 1 0; tx ty tz 1]. |
|
Translate ‘t’ by ‘(tx, ty, tz)’ and return the result: * t’ = translate(tx, ty, tz) * t. |
|
Returns a transform that scales by `(sx, sy, sz)’: * t’ = [sx 0 0 0; 0 sy 0 0; 0 0 sz 0; 0 0 0 1]. |
|
Scale ‘t’ by ‘(sx, sy, sz)’ and return the result: * t’ = scale(sx, sy, sz) * t. |
|
Returns a transform that rotates by ‘angle’ radians about the vector ‘(x, y, z)’. If the vector has length zero the identity transform is returned. |
|
Rotate ‘t’ by ‘angle’ radians about the vector ‘(x, y, z)’ and return the result. t’ = rotation(angle, x, y, z) * t. |
旋转的单位采用弧度(radians),而不是角度(degress)。以下两个函数,你可以在弧度和角度之间切换。
1
2
|
CGFloat DegreesToRadians( CGFloat degrees) { return degrees * M_PI / 180 ;}; CGFloat RadiansToDegrees( CGFloat radians) { return radians * 180 / M_PI;}; |
核心动画 提供了用于转换矩阵的变换函数CATransform3DInvert。一般是用反转点内转化对象提供反向转换。当你需要恢复一个已经被变换了的矩阵的时候,反转将会非常有帮助。反转矩阵乘以逆矩阵值,结果是原始值。
变换函数同时允许你把CATransform3D矩阵转化为CGAffineTransform(仿射)矩阵,前提是CATransform3D矩阵采用如下表示方法。
表 2 CATransform3D 与 CGAffineTransform 转换
Function |
Use |
|
Returns a |
|
Returns |
|
Returns the affine transform represented by the passed |
变换函数同时提供了可以比较一个变换矩阵是否是单位矩阵,或者两个矩阵是否相等。
表 3 CATransform3D 相等测试
Function |
Use |
|
Returns |
|
Returns |
1.3.2 修改变换的数据结构
你可以修改CATransform3D的数据结构的元素为任何其他你想要的数据值。代码1包含了CATransform3D数据结构的定义,结构的成员都在其相应的矩阵位置。
代码 1 CATransform3D structure
1
2
3
4
5
6
7
8
9
|
struct CATransform3D { CGFloat m11, m12, m13, m14; CGFloat m21, m22, m23, m24; CGFloat m31, m32, m33, m34; CGFloat m41, m42, m43, m44; }; typedef struct CATransform3D CATransform3D; |
代码2中的示例说明了如何配置一个CATransform3D一个角度变换。
代码 2 直接修改CATransform3D数据结构
1
2
3
4
|
CATransform3D aTransform = CATransform3DIdentity; // the value of zDistance affects the sharpness of the transform. zDistance = 850 ; aTransform.m34 = 1 .0 / -zDistance; |
1.3.3 通过键值路径修改变换
核心动画扩展了键-值编码协议,允许通过关键路径获取和设置一个图层的CATransform3D矩阵的值。表4描述了图层的transform和sublayerTransform属性的相应关键路径。
表 4 CATransform3D key paths
Field Key Path |
Description |
rotation.x |
The rotation, in radians, in the x axis. |
rotation.y |
The rotation, in radians, in the y axis. |
rotation.z |
The rotation, in radians, in the z axis. |
rotation |
The rotation, in radians, in the z axis. This is identical to setting the rotation.z field. |
scale.x |
Scale factor for the x axis. |
scale.y |
Scale factor for the y axis. |
scale.z |
Scale factor for the z axis. |
scale |
Average of all three scale factors. |
translation.x |
Translate in the x axis. |
translation.y |
Translate in the y axis. |
translation.z |
Translate in the z axis. |
translation |
Translate in the x and y axis. Value is an NSSize or CGSize. |
你不可以通过Objective-C 2.0的属性来设置结构域的值,比如下面的代码将会无法正常运行:
1
|
myLayer.transform.rotation.x =0 ; |
替换的办法是,你必须通过setValue:forKeyPath:或者valueForKeyPath:方法,具体如下:
1
|
[myLayer setValue :[ NSNumber numberWithInt :0 ] forKeyPath : @ "transform.rotation.x" ]; |
CATransform3D的更多相关文章
- CATransform3D方法汇总
CATransform3D三维变换 struct CATransform3D { CGFloat m11, m12, m13, m14; CGFloat m21, m22, m23, m24; CGF ...
- iOS - CALayer相关(CATransform3D)
一.图层的几何 图层的几何简单通俗,图层的所有几何属性(包括矩阵变换),都可以有隐式和显式动画. 图层几何的属性: 1.position是CGPoint值,她指定图层相对于她图层的位置,该值基于父图层 ...
- TableView使用CATransform3D特效动画
效果一: 在代理方法中实现: - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell fo ...
- CGAffineTransform与CATransform3D
CGAffineTransform 1.CG的前缀告诉我们,CGAffineTransform类型属于Core Graphics框架,Core Graphics实际上是一个严格意义上的2D绘图API, ...
- 【转】 CATransform3D 矩阵变换之立方体旋转实现细节
原文网址:http://blog.csdn.net/ch_soft/article/details/7351896 第一部分.前几天做动画,使用到了CATransform3D ,由于没有学过计算机图形 ...
- 在图层上使用CATransform3D制做三维动画-b
在UIView上,我们可以使用CGAffineTransform来对视图进行:平移(translation),旋转(Rotation),缩 放(scale),倾斜(Invert)操作,但这些操作是没有 ...
- CATransform3D 讲解
最近看到一个3D动画效果,决定认真就研究一下.从网上看到很多介绍,下面详细的讲解一下CATransform3D CATransform3D结构成员的意义. structCATransform3D { ...
- CATransform3D中m34字段的取值含义
转载自:http://zhidao.baidu.com/link?url=OlVQoGOKIBmaXKgQisOLtzliTLPvreOOsRmny3yebA1Wb6-B3KtuKlRXmv0tO3y ...
- CATransform3D参数的意义
经常忘记CATransform3D各参数的意思,记下来好好理解下 struct CATransform3D { CGFloat m11(x缩放),m12(y切变),m13(旋转),m14(); C ...
随机推荐
- 2666 Accept Ratio(打表AC)
2666 Accept Ratio 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 某陈痴迷 ...
- WPF在XAML中Binding使用StringFormat属性
1. 绑定Currency, 如果没有字符的话, =后面需要先加入{}. 不加的话会出问题. 1 <TextBlock Text="{Binding Amount, StringFor ...
- PHP5.5 + IIS + Win7的配置
PHP运行环境主要分windows环境和linux环境,本文主要简单介绍下我自己的配置,其他就不一一说明了. windows环境 方式一:.Apache的安装配置:2.MySQL的安装配置,可安装ph ...
- vim常用命令汇总
vim常用命令汇总: http://www.cnblogs.com/softwaretesting/archive/2011/07/12/2104435.html 定位 本行第一个字符 ctrl+$ ...
- Photoshop Cc高级设计师培训视频教程(共109节课程)
Photoshop Cc高级设计师培训视频教程(共109节课程) 专业培训Photoshop技能,其他网站收费内容,这里收集了,免费分享给你们哦~ 以下为部分截图: 下载地址: http://fu83 ...
- 简单工厂模式 Simple Factory
简单工厂模式的作用就是定义一个用于创建对象的接口 在简单工厂模式中,一个工厂类处于对产品类实例化调用的中心位置上,它决定那一个产品类应当被实例化. 先来看看它的组成: 1) 工厂类角色 ...
- LINUX下C语言编程基础
实验二 Linux下C语言编程基础 一.实验目的 1. 熟悉Linux系统下的开发环境 2. 熟悉vi的基本操作 3. 熟悉gcc编译器的基本原理 4. 熟练使用gcc编译器的常用选项 5 .熟练使用 ...
- 20145222黄亚奇《Java程序设计》实验一实验报告
实验一 Java开发环境的熟悉(Linux+Eclipse) 实验内容及步骤 使用JDK编译.运行简单的Java程序 在NetBeans IDEA中输入如下代码: package ljp; publi ...
- JavaScript实现MVVM之我就是想监测一个普通对象的变化
http://hcysun.me/2016/04/28/JavaScript%E5%AE%9E%E7%8E%B0MVVM%E4%B9%8B%E6%88%91%E5%B0%B1%E6%98%AF%E6% ...
- 成都普华永道税务开发的offer
首先这是一个.net税务开发的offer,我是做开发的. 有没有人在成都普华永道的,最近收到普华永道的offer,如果有的话请联系我.想知道里面的情况.最想知道里面的加班情况,薪资还是有点诱惑的.毕竟 ...