CATransform3D是一个结构体
struct CATransform3D{
CGFloat m11(x缩放), m12(y切变), m13(旋转), m14();
CGFloat m21(x切变), m22(y缩放), m23, m24;
CGFloat m31(旋转), m32, m33, m34(透视效果,要有旋转角度才能看出效果);
CGFloat m41(x平移), m42(y平移), m43(z平移), m44;
};
github上有个demo可以直接更改m11~m44的值,直观的看到效果
红色的点就是锚点(anchorPoint)的位置:默认为(0.5,0.5)。在对图像进行变换时,都是围绕这个点来进行缩放,偏移等。
- CATransform3DIdentity
CATransform3DIdentity是单位矩阵,该矩阵没有缩放、旋转、歪斜、透视。把该矩阵应用到图层上面,会把图层几何属性修改为默认值。
可以用CATransform3DIsIdentity方法判断是否为单位矩阵。
bool CATransform3DIsIdentity ( CATransform3D t );
平移变换(Translation)
//返回一个平移变换的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 );
// 左边是初始状态,右边是经过下列代码处理后的结果
CATransform3D transform3D = CATransform3DMakeTranslation(100, 100, 10);
self.translateCatImgView.layer.transform = transform3D;
- tx:X轴偏移位置,往下为正数。
ty:Y轴偏移位置,往右为正数。
tz:Z轴偏移位置,往外为正数。对于tz来说,值越大,那么图层就越往外(接近屏幕),值越小,图层越往里(屏幕里)
缩放变换(Scale)
//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 );
CATransform3D transform3D = CATransform3DMakeScale(0.5, 0.5, 0);
self.scaleCatImgView.layer.transform = transform3D;
旋转变换(Rotation)
/*angle参数是旋转的角度,为弧度制 0-2π
x,y,z决定了旋转围绕的中轴,取值为-1——1之间*/
CATransform3D CATransform3DMakeRotation ( CGFloat angle, CGFloat x, CGFloat y, CGFloat z );
CATransform3D CATransform3DRotate ( CATransform3D t, CGFloat angle, CGFloat x, CGFloat y, CGFloat z );
CATransform3D xRotation = CATransform3DMakeRotation(45*M_PI/180.0, 1.0, 0, 0);
CATransform3D yRotation = CATransform3DIdentity;
CGFloat zDistance = 1000;
yRotation.m34 = - 1.0 / zDistance;// (-1.0 / zDistance),zDistance越小,透视效果越明显 必须先设置m34再设置旋转角度
yRotation = CATransform3DRotate(yRotation,-30*M_PI/180.0, 0.0, 1.0, 0);
CATransform3D xYRotation = CATransform3DConcat(xRotation, yRotation);//合并xRotation, yRotation
self.rotationCatImgView.layer.transform = xYRotation;
旋转的单位采用弧度(radians) [0-2π],而不是角度(degress)。以下两个函数,你可以在弧度和角度之间切换。
CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};
CGFloat RadiansToDegrees(CGFloat radians) {return radians * 180 / M_PI;};
- 按我的理解说下X,Y,Z 取值大于0的旋转效果,小于0即反过来
X:视图的上边沿往屏幕里靠拢旋转
Y:视图的右边沿往屏幕里靠拢旋转
Z:视图平面顺时针旋转
合并两个CATransform3D(CATransform3DConcat)
CATransform3D CATransform3DConcat ( CATransform3D a, CATransform3D b );
CATransform3DInvert效果反转(反效果,比如原来扩大,就变成缩小)
CATransform3D CATransform3DInvert ( CATransform3D t );
CATransform3D与CGAffineTransform的转换
//将一个CGAffinrTransform转化为CATransform3D
CATransform3D CATransform3DMakeAffineTransform (CGAffineTransform m);
//判断一个CATransform3D是否可以转换为CAAffineTransform
bool CATransform3DIsAffine (CATransform3D t);
//将CATransform3D转换为CGAffineTransform
CGAffineTransform CATransform3DGetAffineTransform (CATransform3D t);
-
CGAffineTransform(仿射变换)是作用于UIViews的2D操作,而CATransform3D是作用于CALayers的更复杂的3D操作,
struct CGAffineTransform {
CGFloat a, b, c, d;
CGFloat tx, ty;
};
CGAffineTransform CGAffineTransformMake(CGFloat a, CGFloat b,CGFloat c, CGFloat d, CGFloat tx, CGFloat ty)/*各个参数的定义可以理解成 sx,sy:缩放因子 shx,shy:斜切因子 tx,ty:移动因子 CGAffineTransformMake (sx,shx,shy,sy,tx,ty) */
到这斜切的概念还没搞清楚,具体看iOS动画和特效(七)仿射变换-CGAffineTransform,里面有详解,CGAffineTransform其他方法与CATransform3D基本类似
通过键值路径修改变换
核心动画扩展了键-值编码协议,允许通过关键路径获取和设置一个图层的CATransform3D矩阵的值。表4描述了图层的transform和sublayerTransform属性的相应关键路径。
[myLayer setValue:[NSNumber numberWithInt:0] forKeyPath:@"transform.rotation.x"];
结合上述基础做个动画
写了个Demo模仿荷包App的启动动画
里面用了三种方法实现 1.改变frame 2.改变transform3.用动画库JHChainableAnimations
还涉及到frame,position,anchorPoint的关系,这篇文章容易理解些
参考文章
CATransform3D 特效详解
CoreAnimation编程指南(三)几何变换
iOS开发CoreAnimation解读之六——CATransform3D变换的应用
iOS动画和特效(七)仿射变换-CGAffineTransform