熟练使用CATransform3D能实现我们所需求的较复杂的动画效果,以下将系统介绍CATransform3D的一些属性以及使用。
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;
CATransform3D是一个4* 4的结构体,二维的放射矩阵是一个3*3的矩阵
点击进入头文件中
CA_EXTERN const CATransform3D CATransform3DIdentity;
//一个无任何变换的默认矩阵常量,可用于使变换后的Layer恢复初始状态
CA_EXTERN bool CATransform3DIsIdentity (CATransform3D t);
//判断是否为默认矩阵
CA_EXTERN bool CATransform3DEqualToTransform (CATransform3D a,
CATransform3D b);
//判断两个矩阵是否相同
CA_EXTERN CATransform3D CATransform3DMakeTranslation (CGFloat tx,
CGFloat ty, CGFloat tz);
//生成一个依照参数平移转换后的矩阵
CA_EXTERN CATransform3D CATransform3DMakeScale (CGFloat sx, CGFloat sy,
CGFloat sz);
//生成一个依照参数缩放后的
CA_EXTERN CATransform3D CATransform3DMakeRotation (CGFloat angle, CGFloat x, CGFloat y, CGFloat z);//生成一个依照参数旋转后的矩(旋转的时候注意锚点)
CA_EXTERN CATransform3D CATransform3DTranslate (CATransform3D t, CGFloat tx,
CGFloat ty, CGFloat tz);
//变换指定的矩阵(t就是将要变换的矩阵,下同)
CA_EXTERN CATransform3D CATransform3DScale (CATransform3D t, CGFloat sx,
CGFloat sy, CGFloat sz);
//变换指定的矩阵
CA_EXTERN CATransform3D CATransform3DRotate (CATransform3D t, CGFloat angle,
CGFloat x, CGFloat y, CGFloat z);
//变换指定的矩阵
//需要注意的是x/y/z三个参数均为指定旋转轴,可选值0和1,0代表此轴不做旋转,1代表作旋转。
例如想对x、y轴做45度旋转,则angle = M____PI____4,x = 1,y = 1,z = 0。
另外,旋转角度为弧度制哦,不是角度制
CA_EXTERN CATransform3D CATransform3DConcat (CATransform3D a, CATransform3D b);
//计算两个矩阵的乘积
CA_EXTERN CATransform3D CATransform3DInvert (CATransform3D t);
//反转矩阵
CA_EXTERN CATransform3D CATransform3DMakeAffineTransform (CGAffineTransform m);
//通过2D得到一个3D矩阵
CA_EXTERN bool CATransform3DIsAffine (CATransform3D t);
//判断3D矩阵是否可以用2D矩阵表示
CA_EXTERN CGAffineTransform CATransform3DGetAffineTransform (CATransform3D t);
//从3D矩阵中获取2D矩阵
以上为CATransform3D中头文件属性解释。
举个旋转的例子:
CALayer * layer = [CALayer layer];
layer.backgroundColor = [UIColor greenColor].CGColor;
layer.frame =CGRectMake(100, 100, 100, 100);
[self.view.layer addSublayer:layer];
CATransform3D transA = CATransform3DIdentity;
transA.m34 = -1.0/500; //此属性为透视效果,近大远小,稍后放个例子容易理解
transA = CATransform3DRotate(transA, M_PI/3, 1, 0, 0); //x:1是围绕X轴旋转
layer.transform = transA;
关于m34解释
CATransform3D是一个4* 4机构体,改变他的m34这个属性,改变透视,看起来更加立体,m34= -1/D,D越小效果越明显,m34为负值表示远离屏幕,正值相反。下边的图就是加m34和不加的区别。
使用动画完成CATransform3D的转变
CATransform3D transB = CATransform3DMakeScale(10, 10, 10);
CABasicAnimation * animaiton =[CABasicAnimation animationWithKeyPath:@"transform"];
animaiton.duration = 2;
animaiton.repeatCount = 1;
animaiton.autoreverses =YES;
animaiton.toValue = [NSValue valueWithCATransform3D:transB];
[layer addAnimation:animaiton forKey:nil];
效果如下:
补充说明
- CATransform3D是做3D坐标变换, 经常适用于CALayer
CGAffineTransform是做2D坐标变换, 经常适用于UIView。 - 我们不仅可以通过直接修改结构体中的数值改变动画,也可以同过KVC形式进行赋值。
[self.view.layer setValue:[NSNumber numberWithFloat:60*M_PI/180] forKeyPath:@"transform.rotation.y"];
- CATransformLayer是继承CALayer的,头文件中没有属性,但是我们在做动画的时候,可以将其当成一个容器使用,意思是可以创建几个不同的layer,放在CATransformLayer中组成不同的形状。
下边是从网上找的例子
//create cube layer
CATransformLayer *cube = [CATransformLayer layer];
//add cube face 1
CATransform3D ct = CATransform3DMakeTranslation(0, 0, 50);
[cube addSublayer:[self faceWithTransform:ct]];
//add cube face 2
ct = CATransform3DMakeTranslation(50, 0, 0);
ct = CATransform3DRotate(ct, M_PI_2, 0, 1, 0);
[cube addSublayer:[self faceWithTransform:ct]];
//add cube face 3
ct = CATransform3DMakeTranslation(0, -50, 0);
ct = CATransform3DRotate(ct, M_PI_2, 1, 0, 0);
[cube addSublayer:[self faceWithTransform:ct]];
//add cube face 4
ct = CATransform3DMakeTranslation(0, 50, 0);
ct = CATransform3DRotate(ct, -M_PI_2, 1, 0, 0);
[cube addSublayer:[self faceWithTransform:ct]];
//add cube face 5
ct = CATransform3DMakeTranslation(-50, 0, 0);
ct = CATransform3DRotate(ct, -M_PI_2, 0, 1, 0);
[cube addSublayer:[self faceWithTransform:ct]];
//add cube face 6
ct = CATransform3DMakeTranslation(0, 0, -50);
ct = CATransform3DRotate(ct, M_PI, 0, 1, 0);
[cube addSublayer:[self faceWithTransform:ct]];
//center the cube layer within the container
CGSize containerSize = self.view.bounds.size;
cube.position = CGPointMake(containerSize.width / 2.0, containerSize.height / 2.0);
cube.transform = CATransform3DMakeRotation(30, 1, 1, 0);
[self.view.layer addSublayer:cube];
}
- (CALayer *)faceWithTransform:(CATransform3D)transform
{
//create cube face layer
CALayer *face = [CALayer layer];
face.bounds = CGRectMake(0, 0, 100, 100);
//apply a random color
CGFloat red = (rand() / (double)INT_MAX);
CGFloat green = (rand() / (double)INT_MAX);
CGFloat blue = (rand() / (double)INT_MAX);
face.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0].CGColor;
face.transform = transform;
return face;
}
形成的形状如下
也可以加动画让其旋转。