动画| 魔性形变之CGAffineTransform的使用

时间:2022-06-10
本文章向大家介绍动画| 魔性形变之CGAffineTransform的使用,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

前言

在介绍UIView的2D、3D形变之前需要知道一个概念,那就是锚点,各种变换就会按照这个点来运动。所以想达到特殊的效果,可以通过修改锚点的位置来达到。

锚点的位置:默认为(0.5,0.5)。在对图像进行变换时,都是按照这个点来进行缩放,偏移等空间变换的。 一旦修改锚点的位置为:(0,0),那么图像的形变就会基于这个新锚点产生对应的效果。

CGAffineTransform

UIView的transform属性是一个CGAffineTransform类型,用于在二维空间做旋转,缩放和平移。CGAffineTransform是一个可以和二维空间向量(例如CGPoint)做乘法的3X2的矩阵。称为仿射变换,“仿射”的意思是无论变换矩阵用什么值,图层中平行的两条线在变换之后任然保持平行”。

官方定义:
struct CGAffineTransform {
    CGFloat a, b, c, d;
    CGFloat tx, ty;
};

虽然结构体中只有a,b,c,d,tx,ty 6个参数,但其实还有3个固定的参数[0,0,1]来组成3x3的矩阵。如下图所示:

[图片上传失败...(image-1b6485-1522132215759)]

x' = ax + cy + tx y' = xb + yd + ty

常规应用

恢复原状

    self.myView.transform = CGAffineTransformIdentity;

平移

    self.myView.transform = CGAffineTransformIdentity;
    [UIView animateWithDuration:0.3 animations:^{
       self.myView.transform = CGAffineTransformMakeTranslation(100, 100);
    }];
     或者 ************************************
     在某个transform变换的基础上平移
    CGAffineTransform transform = CGAffineTransformIdentity;
    transform =CGAffineTransformTranslate(transform, 100, 100);
     或者 ************************************
    self.showView.transform = CGAffineTransformMake(1, 0, 0, 1, 100, 100);

放缩

    self.myView.transform = CGAffineTransformIdentity;
    [UIView animateWithDuration:0.3 animations:^{
       self.myView.transform = CGAffineTransformMakeScale(.5, .5);
    }];
    或者 ************************************
    在某个transform变换的基础上放缩
    CGAffineTransform transform = CGAffineTransformIdentity;
    transform =CGAffineTransformScale(transform, .5, .5);
    或者 ************************************
    self.showView.transform = CGAffineTransformMake(.5, 0, 0, .5, 0, 0);

旋转

    self.myView.transform = CGAffineTransformIdentity;
    [UIView animateWithDuration:0.3 animations:^{
       self.myView.transform = CGAffineTransformMakeRotation(M_PI_4);
    }];
    或者 ************************************
    在某个transform变换的基础上旋转
    CGAffineTransform transform = CGAffineTransformIdentity;
    transform = CGAffineTransformRotate(transform, M_PI_4);
    反向旋转
   self.showView.transform = CGAffineTransformInvert(transform);
    或者 ************************************
    self.showView.transform = CGAffineTransformMake(cos(M_PI_4), sin(M_PI_4), -sin(M_PI_4), cos(M_PI_4), 0, 0);

其他有意思的方法

       /* 反向旋转 */
    CG_EXTERN CGAffineTransform CGAffineTransformInvert(CGAffineTransform t)
    CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
    
    /* 合并两个transform :t' = t1 * t2 */
    CG_EXTERN CGAffineTransform CGAffineTransformConcat(CGAffineTransform t1,
                                                        CGAffineTransform t2) CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
    
    /* 判读两个transform是否相等 */
    CG_EXTERN bool CGAffineTransformEqualToTransform(CGAffineTransform t1,
                                                     CGAffineTransform t2) CG_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0);
    
    /* 得到新的中心:
     p' = p * t
     where p = [ x y 1 ]. */
    CG_EXTERN CGPoint CGPointApplyAffineTransform(CGPoint point,
                                                  CGAffineTransform t) CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
    
    /* 得到新的size:
     s' = s * t
     where s = [ width height 0 ]. */
    CG_EXTERN CGSize CGSizeApplyAffineTransform(CGSize size, CGAffineTransform t)
    CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
    
    /* 得到新的rect */
    CG_EXTERN CGRect CGRectApplyAffineTransform(CGRect rect, CGAffineTransform t)
    CG_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0);