详解iOS的Core Animation框架中的CATransform3D图形变换

一、矩阵坐标
CATransform3D定义了一个变化矩阵,通过对矩阵参数的设置,我们可以改变layer的一些属性,这个属性的改变,可以产生动画的效果。
CATransform3D CATransform3DMakeTranslation (CGFloat tx, CGFloat ty, CGFloat tz)
tx:X轴偏移位置,往下为正数。
ty:Y轴偏移位置,往右为正数。
tz:Z轴偏移位置,往外为正数。
例:
如果有2个图层,一个是绿色的,一个是红色的。先加载绿色,后加载红色。
tx,ty的左右偏移先不说了。
如果绿色的tz为-10 ,红色的tz为 0 效果如下。

如果绿色的tz为 0 ,红色的tz为-10 效果如下。

对于tz来说,值越大,那么图层就越往外(接近屏幕),值越小,图层越往里(屏幕里)。
CATransform3D CATransform3DTranslate (CATransform3D t, CGFloat tx, CGFloat ty, CGFloat tz);
t:就是上一个函数。其他的都一样。
就可以理解为:函数的叠加,效果的叠加。
CATransform3D CATransform3DMakeScale (CGFloat sx, CGFloat sy, CGFloat sz);
sx:X轴缩放,代表一个缩放比例,一般都是 0 --- 1 之间的数字。
sy:Y轴缩放。
sz:整体比例变换时,也就是m11(sx)== m22(sy)时,若m33(sz)>1,图形整体缩小,若0<1,图形整体放大,若m33(sz)<0,发生关于原点的对称等比变换。
当sx = 1,sy = 1时。如图:

当sx = 0.5,sy = 0.5时。如图:

CATransform3D CATransform3DScale (CATransform3D t, CGFloat sx, CGFloat sy, CGFloat sz)
t:就是上一个函数。其他的都一样。
就可以理解为:函数的叠加,效果的叠加。
CATransform3D CATransform3DMakeRotation (CGFloat angle, CGFloat x, CGFloat y, CGFloat z);
旋转效果。
angle:旋转的弧度,所以要把角度转换成弧度:角度 * M_PI / 180。
x:向X轴方向旋转。值范围-1 --- 1之间
y:向Y轴方向旋转。值范围-1 --- 1之间
z:向Z轴方向旋转。值范围-1 --- 1之间
例:向X轴旋转60度。

向Y轴旋转60度。

向Z轴旋转60度。

向 X轴,Y轴都旋转60度,就是沿着对角线旋转。


可以通过X,Y,Z轴同时变化,来旋转图像。
CATransform3D CATransform3DRotate (CATransform3D t, CGFloat angle, CGFloat x, CGFloat y, CGFloat z);
t:就是上一个函数。其他的都一样。
就可以理解为:函数的叠加,效果的叠加。
CATransform3D CATransform3DInvert (CATransform3D t);
翻转效果。

CGAffineTransform CATransform3DGetAffineTransform (CATransform3D t);
bool CATransform3DIsAffine (CATransform3D t);
仿射效果。
就是把一个 CATransform3D 对象转换成一个 CGAffineTransform 对象。
也就是把 CATransform3D 矩阵 转换成 CGAffineTransform 矩阵
变换函数同时提供了可以比较一个变换矩阵是否是单位矩阵,或者两个矩阵是否相等。
bool CATransform3DIsIdentity (CATransform3D t);
bool CATransform3DEqualToTransform (CATransform3D a, CATransform3D b);
也可以通过修改数据结构和键值来设置变换效果。
struct CATransform3D
               {

                 CGFloat m11, m12, m13, m14;

                           CGFloat m21, m22, m23, m24;

                           CGFloat m31, m32, m33, m34;

                                  CGFloat m41, m42, m43, m44;
}
可以直接修改 其中的一个值,来达到相同的效果。
或者修改键值
[myLayer setValue:[NSNumber numberWithInt:0] forKeyPath:@"transform.rotation.x"];

二、CATransform3D中的属性和方法
//初始化一个transform3D对象,不做任何变换
const CATransform3D CATransform3DIdentity;
//判断一个transform3D对象是否是初始化的对象
bool CATransform3DIsIdentity (CATransform3D t);
//比较两个transform3D对象是否相同
bool CATransform3DEqualToTransform (CATransform3D a, CATransform3D b);
//将两个 transform3D对象变换属性进行叠加,返回一个新的transform3D对象
CATransform3D CATransform3DConcat (CATransform3D a, CATransform3D b);
1、平移变换
//返回一个平移变换的transform3D对象 tx,ty,tz对应x,y,z轴的平移
CATransform3D CATransform3DMakeTranslation (CGFloat tx, CGFloat ty, CGFloat tz);
//在某个transform3D变换的基础上进行平移变换,t是上一个transform3D,其他参数同上
CATransform3D CATransform3DTranslate (CATransform3D t, CGFloat tx, CGFloat ty, CGFloat tz);
例如:

    UIImageView * imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
    imageView.image = [UIImage imageNamed:@"屏幕快照 2015-12-06 下午3.27.15.png"];
    [self.view addSubview:imageView];
   
    UIImageView * newImageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
    newImageView.image=[UIImage imageNamed:@"屏幕快照 2015-12-06 下午3.27.15.png"];
    [self.view addSubview:newImageView];
    CATransform3D trans = CATransform3DMakeTranslation(10, 200, 0);
    newImageView.layer.transform =trans;
效果如下:

2、缩放变换
//x,y,z分别对应x轴,y轴,z轴的缩放比例
CATransform3D CATransform3DMakeScale (CGFloat sx, CGFloat sy, CGFloat sz);
//在一个transform3D变换的基础上进行缩放变换,其他参数同上
CATransform3D CATransform3DScale (CATransform3D t, CGFloat sx, CGFloat sy, CGFloat sz);
例如:
UIImageView * imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
    imageView.image = [UIImage imageNamed:@"屏幕快照 2015-12-06 下午3.27.15.png"];
    [self.view addSubview:imageView];
   
    UIImageView * newImageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 300, 100, 100)];
    newImageView.image=[UIImage imageNamed:@"屏幕快照 2015-12-06 下午3.27.15.png"];
    [self.view addSubview:newImageView];
    CATransform3D trans = CATransform3DMakeScale(2, 1, 1);
    newImageView.layer.transform =trans;
效果如下:

3、旋转变换
//angle参数是旋转的角度,为弧度制 0-2π
//x,y,z决定了旋转围绕的中轴,取值为-1——1之间,例如(1,0,0),则是绕x轴旋转(0.5,0.5,0),则是绕x轴与y轴中
//间45度为轴旋转,依次进行计算
CATransform3D CATransform3DMakeRotation (CGFloat angle, CGFloat x, CGFloat y, CGFloat z);
//在一个transform3D的基础上进行旋转变换,其他参数如上
CATransform3D CATransform3DRotate (CATransform3D t, CGFloat angle, CGFloat x, CGFloat y, CGFloat z);
例如:
UIImageView * imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
    imageView.image = [UIImage imageNamed:@"屏幕快照 2015-12-06 下午3.27.15.png"];
    [self.view addSubview:imageView];
   
    UIImageView * newImageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 300, 100, 100)];
    newImageView.image=[UIImage imageNamed:@"屏幕快照 2015-12-06 下午3.27.15.png"];
    [self.view addSubview:newImageView];
    CATransform3D trans = CATransform3DMakeRotation(M_PI/2, 0, 0, 1);
    newImageView.layer.transform =trans;
效果如下:

另外,当我们有垂直于z轴的旋转分量时,设置m34的值可以增加透视效果,也可以理解为景深效果,例如:

    UIImageView * imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
    imageView.image = [UIImage imageNamed:@"屏幕快照 2015-12-06 下午3.27.15.png"];
    imageView.layer.transform = CATransform3DMakeRotation(M_PI/4, 0, 1, 0);
    [self.view addSubview:imageView];
   
    UIImageView * newImageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 300, 100, 100)];
    newImageView.image=[UIImage imageNamed:@"屏幕快照 2015-12-06 下午3.27.15.png"];
    [self.view addSubview:newImageView];
    CATransform3D trans = CATransform3DIdentity;
    trans.m34 = -1/100.0;
    trans = CATransform3DRotate(trans, M_PI/4, 0, 1, 0); 
    newImageView.layer.transform =trans;
两个imageView都进行了y轴的旋转变换,第二个有透视效果,第一个没有,运行如下:

4、旋转翻转变换
//将一个旋转的效果进行翻转
CATransform3D CATransform3DInvert (CATransform3D t);
例如:
    UIImageView * imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
    imageView.image = [UIImage imageNamed:@"屏幕快照 2015-12-06 下午3.27.15.png"];
    imageView.layer.transform = CATransform3DMakeRotation(M_PI/4, 0, 0, 1);
    [self.view addSubview:imageView];
   
    UIImageView * newImageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 300, 100, 100)];
    newImageView.image=[UIImage imageNamed:@"屏幕快照 2015-12-06 下午3.27.15.png"];
    [self.view addSubview:newImageView];
    CATransform3D trans = CATransform3DMakeRotation(M_PI/4, 0, 0, 1);
    trans = CATransform3DInvert(trans);
   
    newImageView.layer.transform =trans;
5、CATransform3D与CGAffineTransform的转换
CGAffineTransform是UIKit框架中一个用于变换的矩阵,其作用与CATransform类似,只是其可以直接作用于View,而不用作用于layer,这两个矩阵也可以进行转换,方法如下:
//将一个CGAffinrTransform转化为CATransform3D
CATransform3D CATransform3DMakeAffineTransform (CGAffineTransform m);
//判断一个CATransform3D是否可以转换为CAAffineTransform
bool CATransform3DIsAffine (CATransform3D t);
//将CATransform3D转换为CGAffineTransform
CGAffineTransform CATransform3DGetAffineTransform (CATransform3D t);

(0)

相关推荐

  • IOS 实现3D 浮动效果动画

    涉及到的技术点 CATransform3DRotate 转换坐标系 整体视图的层级结构 tvOSCardView cardImageView cardParallaxView 转换坐标系的代码 CGFloat xFactor = MIN(1, MAX(-1, (touchPoint.x - (self.bounds.size.width / 2)) / (self.bounds.size.width / 2))); CGFloat yFactor = MIN(1, MAX(-1, (touchP

  • Unity3d发布IOS9应用时出现中文乱码的解决方法

    简单的说,解决方法就是批量修改NGUI的label字体,修复ios就删除arial引起的中文乱码 我们来看具体如何操作 static public void yaheifont() { uf = AssetDatabase.LoadAssetAtPath("Assets/yahei.prefab",typeof( UIFont)) as UIFont; UnityEngine.Object[] objs = Selection.GetFiltered (typeof(UnityEngi

  • php、java、android、ios通用的3des方法(推荐)

    php服务器,java服务器,android,ios开发兼容的3des加密解密, php <?php class DES3 { var $key = "my.oschina.net/penngo?#@"; var $iv = "01234567"; function encrypt($input){ $size = mcrypt_get_block_size(MCRYPT_3DES,MCRYPT_MODE_CBC); $input = $this->pk

  • iOS动画之向右拉的抽屉3D效果

    首先我们忽略掉3D效果,先要做的是一个右拉的抽屉效果. 总体思路: 1.创建一个ContainerViewController容器控制器,然后把左侧选择菜单的SideMenuViewController,和右侧负责显示内容的MainViewController 添加到ContainerViewController中. 2.给容器控制器ContainerViewController添加一个手势监听,通过修改偏移量完成抽屉效果. 3.设置anchorPoint,给左侧SideMenuViewCont

  • 一行代码实现IOS 3DES加密解密

    3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称.它相当于是对每个数据块应用三次DES加密算法.由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解:3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法. 3DES又称Triple DES,是DES加密算法的一种模式,它使用3条56位的密钥对数据进行三次加密.数据加密标

  • 详解iOS的Core Animation框架中的CATransform3D图形变换

    一.矩阵坐标 CATransform3D定义了一个变化矩阵,通过对矩阵参数的设置,我们可以改变layer的一些属性,这个属性的改变,可以产生动画的效果. CATransform3D CATransform3DMakeTranslation (CGFloat tx, CGFloat ty, CGFloat tz) tx:X轴偏移位置,往下为正数. ty:Y轴偏移位置,往右为正数. tz:Z轴偏移位置,往外为正数. 例: 如果有2个图层,一个是绿色的,一个是红色的.先加载绿色,后加载红色. tx,t

  • 详解iOS应用的设计模式开发中Mediator中介者模式的使用

    何为中介者模式? 面向对象的设计鼓励把行为分散到不同对象中,这种分散可能导致对象之间的相互关联.在最糟糕的情况下,所有对象都彼此了解并相互操作. 虽然把行为分散到不同对象增强了可复用性,但是增加的相互关联又减少了获得的益处.增加的关联使得对象很难或不能在不依赖其他对象的情况下工作.应用程序的整体行为可能难以进行任何重大修改,因为行为分布于许多对象.于是结果可能是创建越来越多的子类,以支持应用程序中的任何新行为. 中介者模式:用一个对象来封装一系列对象的交互方式.中介者使各对象不需要显式地相互引用

  • 详解在Python的Django框架中创建模板库的方法

    不管是写自定义标签还是过滤器,第一件要做的事是创建模板库(Django能够导入的基本结构). 创建一个模板库分两步走: 第一,决定模板库应该放在哪个Django应用下. 如果你通过 manage.py startapp 创建了一个应用,你可以把它放在那里,或者你可以为模板库单独创建一个应用. 我们更推荐使用后者,因为你的filter可能在后来的工程中有用. 无论你采用何种方式,请确保把你的应用添加到 INSTALLED_APPS 中. 我们稍后会解释这一点. 第二,在适当的Django应用包里创

  • 详解在Java的Struts2框架中配置Action的方法

    在Struts2中Action部分,也就是Controller层采用了低侵入的方式.为什么这么说?这是因为在Struts2中action类并不需要继承任何的基类,或实现任何的接口,更没有与Servlet的API直接耦合.它通常更像一个普通的POJO(通常应该包含一个无参数的execute方法),而且可以在内容定义一系列的方法(无参方法),并可以通过配置的方式,把每一个方法都当作一个独立的action来使用,从而实现代码复用. 例如: package example; public class U

  • 详解在PHP的Yii框架中使用行为Behaviors的方法

    一个绑定了行为的类,表现起来是这样的: // Step 1: 定义一个将绑定行为的类 class MyClass extends yii\base\Component { // 空的 } // Step 2: 定义一个行为类,他将绑定到MyClass上 class MyBehavior extends yii\base\Behavior { // 行为的一个属性 public $property1 = 'This is property in MyBehavior.'; // 行为的一个方法 p

  • 详解 iOS 系统中的视图动画

    动画为用户界面的状态转换提供了流畅的可视化效果, 在 iOS 中大量使用了动画效果, 包括改变视图位置. 大小. 从可视化树中删除视图, 隐藏视图等. 你可以考虑用动画效果给用户提供反馈或者用来实现有趣的特效. 在 iOS 系统中, Core Animation 提供了内置的动画支持, 创建动画不需要任何绘图的代码, 你要做的只是激发指定的动画, 接下来就交给 Core Animation 来渲染, 总之, 复杂的动画只需要几行代码就可以了. 哪些属性可以添加动画效果 根据 iOS 视图编程指南

  • 详解IOS开发中生成推送的pem文件

    详解IOS开发中生成推送的pem文件 具体步骤如下: 首先,需要一个pem的证书,该证书需要与开发时签名用的一致. 具体生成pem证书方法如下: 1. 登录到 iPhone Developer Connection Portal(http://developer.apple.com/iphone/manage/overview/index.action )并点击 App IDs 2. 创建一个不使用通配符的 App ID .通配符 ID 不能用于推送通知服务.例如,  com.itotem.ip

  • 详解IOS中文件路径判断是文件还是文件夹

    详解IOS中文件路径判断是文件还是文件夹 方法1 + (BOOL)isDirectory:(NSString *)filePath { BOOL isDirectory = NO; [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDirectory]; return isDirectory; } 方法2 + (BOOL)isDirectory:(NSString *)filePath { NSNum

  • 详解在.net core中完美解决多租户分库分表的问题

    前几天有人想做一个多租户的平台,每个租户一个库,可以进行水平扩展,应用端根据登录信息,切换到不同的租户库 计划用ef core实现,他们说做不出来,需要动态创建dbContext,不好实现 然而这个使用CRL很轻松就能解决了 以下为演示数据库,有两个库testdb和testdb2,查询结果如下 目标: 根据传入登录信息连不不同的库,查询返回结果,如登录人为01,返回d1.default,登录人为02 返回 d2.default 实际上这个需求就是分库分表的实现,通过设置数据库/表映射关系,根据传

  • 详解ASP.NET Core中配置监听URLs的五种方式

    默认情况下,ASP. NET Core应用会监听一下2个Url: http://localhost:5000 https://localhost:5001 在本篇博文中,我将展示如何使用五种不同的方式改变应用监听的URLs. 在ASP.NET Core项目启动时,有多种配置监听Url的方式,在我之前的一篇博客中,已经展示了在ASP.NET Core 1.0中如何应用不同的方式配置,在ASP.NET Core 3.x中,大部分方式还是一样的. UseUrls() - 在Program.cs配置程序

随机推荐