zoukankan      html  css  js  c++  java
  • 用CATransform3D实现3D效果和制作简单3D动画

    我们先来看下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结构体, 另外它还有一个弟弟CGAffineTransform是 3 * 3结构体

    他们的区别看名字就很明显,

    CATransform3D是做3D坐标变换, 经常适用于CALayer

    CGAffineTransform是做2D坐标变换, 经常适用于UIView

    CATransform3D这个结构体中, 我们使用最多的是m34 后面我们再来说这个, 先知道就好了

    我们继续看下CATransform3D头文件中的其他内容

    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);
    //变换指定的矩阵 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矩阵

    我们先看一个简单的例子, 实现一个矩形向内翻转

    上代码:

    #import "ViewController.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        
        [super viewDidLoad];
        
        //创建CALayer
        CALayer * staticLayerA       = [CALayer layer];
        staticLayerA.bounds          = CGRectMake(0, 0, 100, 100);
        staticLayerA.position        = self.view.center;
        staticLayerA.backgroundColor = [UIColor redColor].CGColor;
        
        //添加到主界面
        [self.view.layer addSublayer:staticLayerA];
        
        //创建CATransform3D默认变换矩阵
        CATransform3D transA = CATransform3DIdentity;
        
        //调整m34, 向里偏500个单位
        transA.m34           = - 1.0 / 500;
        
        //设置沿x轴偏转60度
        transA               = CATransform3DRotate(transA, M_PI / 3, 1, 0, 0);
        
        //设置Layer3D偏转
        staticLayerA.transform = transA;
    }

    代码里M34 = - 1.0 / 500 的意思就是图层距离屏幕向里500的单位。如果向外则是M34 = 1.0 / 500。这个距离至一般掌握至500~1000这个范围会取得不错的效果。

    这里需要注意的是M34的赋值一定要写在矩阵变换前面

    可以再用BasicAnimation来实现3D动画, 用关键字: Transform

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];
        animation.duration     = 2;
        animation.repeatCount  = 100;
        animation.autoreverses = YES;
        animation.toValue      = [NSValue valueWithCATransform3D:transA];
        
        [staticLayerA addAnimation:animation forKey:nil];

    大家可以试试看效果

  • 相关阅读:
    NPOI Word 多级标题结构设置
    ^M的问题解决
    sed命令详解
    Python time datetime string 相互转换
    Linux环境下调试python代码----pdb模块
    k8s更新证书记录
    sealos + NFS 部署 kubesphere 3.0
    使用wireshark排除一例网络问题
    Prometheus监控Oracle数据库
    记录一次清理挖矿病毒
  • 原文地址:https://www.cnblogs.com/zhouxihi/p/6277868.html
Copyright © 2011-2022 走看看