CATransform3D笔记

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)。在对图像进行变换时,都是围绕这个点来进行缩放,偏移等。

timeline.gif
  • 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 );
F086A392-C96F-4473-B1EB-53EF6B37700D.png
 // 左边是初始状态,右边是经过下列代码处理后的结果
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 );
6162FB6E-35F5-4316-885E-8B78F3C95545.png
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 );
C3F3D5B0-51B9-4A2E-9128-B4008F658BB9.png
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属性的相应关键路径。

CDD718FD-F229-4A60-8DA0-97D8AB387660.png
[myLayer setValue:[NSNumber numberWithInt:0] forKeyPath:@"transform.rotation.x"];

结合上述基础做个动画

hebao.gif

写了个Demo模仿荷包App的启动动画
里面用了三种方法实现 1.改变frame 2.改变transform3.用动画库JHChainableAnimations
还涉及到frame,position,anchorPoint的关系,这篇文章容易理解些

参考文章

CATransform3D 特效详解
CoreAnimation编程指南(三)几何变换
iOS开发CoreAnimation解读之六——CATransform3D变换的应用
iOS动画和特效(七)仿射变换-CGAffineTransform

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念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

推荐阅读更多精彩内容