原文链接
本文直接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);