美文网首页Reports
CATransform3D笔记

CATransform3D笔记

作者: HuangJn | 来源:发表于2016-08-15 13:45 被阅读302次

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

相关文章

网友评论

  • Micro同学:大神求问一个问题。。。以下是对一个立方体的拖拽动作:
    - (void)panOnView: (UIPanGestureRecognizer *)pan {
    NSLog(@"Panned!!!");
    if (self.animationHappening) {
    return;
    }


    CATransform3D transform = CATransform3DIdentity;
    transform.m34 = -1.0/2000;
    CGPoint translation = [pan translationInView:self.mView];
    // CATransform3D transform = MakePerspetiveTransform();
    transform = CATransform3DRotate(transform, kPanScale * translation.x, 0, 1, 0);
    transform = CATransform3DRotate(transform, -kPanScale * translation.y, 1, 0, 0);

    [UIView animateWithDuration:0
    animations:^{
    // self.mainLayer.transform = transform;
    self.mView.layer.sublayerTransform = transform;
    // self.lastScale = pinch.scale;
    } completion:^(BOOL finished) {
    self.animationHappening = NO;
    }];
    }

    但是每次再触发的时候他会复位。。请问如何能够在前一次的情况下再继续呢?谢谢!!!

本文标题:CATransform3D笔记

本文链接:https://www.haomeiwen.com/subject/anrssttx.html