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

原文链接
本文直接copy的原文,用来记录。

CATransform3D一般用于操作view的layer的,是Core Animation的结构体,可以用来做比较复杂的3D操作,这里我们就带大家来详解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 效果如下。

[图片上传失败...(image-d4fb12-1521887022756)]

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

[图片上传失败...(image-c17273-1521887022758)]

对于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时。如图:

[图片上传失败...(image-b7c248-1521887022758)]

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

[图片上传失败...(image-3c7c3-1521887022758)]

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度。

[图片上传失败...(image-80f111-1521887022758)]

向Y轴旋转60度。

[图片上传失败...(image-cc9673-1521887022758)]

向Z轴旋转60度。

[图片上传失败...(image-4b3d7-1521887022758)]

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

[图片上传失败...(image-18287a-1521887022758)]

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

[图片上传失败...(image-7c8dce-1521887022758)]

[图片上传失败...(image-8961e0-1521887022758)]

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;` 效果如下:

[图片上传失败...(image-c3995c-1521887022758)]

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;` 效果如下:

[图片上传失败...(image-1875ab-1521887022758)]

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;` 效果如下:

[图片上传失败...(image-fe28db-1521887022757)]

另外,当我们有垂直于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轴的旋转变换,第二个有透视效果,第一个没有,运行如下:

[图片上传失败...(image-fd460b-1521887022757)]

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);

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容