zoukankan      html  css  js  c++  java
  • CATransformLayer

    CATransformLayer与CALayer有着细微的差别,但这些差别会影响到3D变换的动画效果.

    动画都有坐标系,如下所示(注意,这个不是iOS中的坐标系,请勿对号入座):

    iOS中layer的锚点就在坐标系的正中间.

    layer的position可以理解为View的center.

    实现带有3d景深效果动画:

    复制代码
    //
    //  RootViewController.m
    //  CATransformLayer
    //
    //  Copyright (c) 2014年 Y.X. All rights reserved.
    //
    
    #import "RootViewController.h"
    #import "YXGCD.h"
    
    @interface RootViewController ()
    @property (nonatomic, strong) GCDTimer  *timer;
    @end
    
    @implementation RootViewController
    
    #define V_CENTER_X           self.view.center.x
    #define V_CENTER_Y           self.view.center.y
    #define CG_COLOR(R, G, B, A) [UIColor colorWithRed:(R) green:(G) blue:(B) alpha:(A)].CGColor
    #define DEGREE(d)            ((d) * M_PI / 180.0f)
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        // 普通的一个layer
        CALayer *plane        = [CALayer layer];
        plane.anchorPoint = CGPointMake(0.5, 0.5);                         // 锚点
        plane.frame       = (CGRect){CGPointZero, CGSizeMake(100, 100)};   // 尺寸
        plane.position    = CGPointMake(V_CENTER_X, V_CENTER_Y);           // 位置
        plane.opacity         = 0.6;                                       // 背景透明度
        plane.backgroundColor = CG_COLOR(1, 0, 0, 1);                      // 背景色
        plane.borderWidth     = 3;                                         // 边框宽度
        plane.borderColor     = CG_COLOR(1, 1, 1, 0.5);                    // 边框颜色(设置了透明度)
        plane.cornerRadius    = 10;                                        // 圆角值
        
        // 创建容器layer
        CALayer *container = [CALayer layer];
        container.frame    = self.view.bounds;
        [self.view.layer addSublayer:container];
        [container addSublayer:plane];
        
        
        // 启动定时器
        _timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]];
        [_timer event:^{
            static float degree = 0.f;
            
            // 起始值
            CATransform3D fromValue = CATransform3DIdentity;
            fromValue.m34           = 1.0/ -500;
            fromValue               = CATransform3DRotate(fromValue, degree, 0, 1, 0);
            
            // 结束值
            CATransform3D toValue   = CATransform3DIdentity;
            toValue.m34             = 1.0/ -500;
            toValue                 = CATransform3DRotate(toValue, degree += 45.f, 0, 1, 0);
            
            // 添加3d动画
            CABasicAnimation *transform3D = [CABasicAnimation animationWithKeyPath:@"transform"];
            transform3D.duration  = 1.f;
            transform3D.fromValue = [NSValue valueWithCATransform3D:fromValue];
            transform3D.toValue   = [NSValue valueWithCATransform3D:toValue];
            plane.transform = toValue;
            [plane addAnimation:transform3D forKey:@"transform3D"];
            
        } timeInterval:NSEC_PER_SEC];
        [_timer start];
    }
    
    @end
    复制代码

    下图中的m34值代表着景深效果,非常关键,其值越接近0,景深效果就越发强烈

    如果写成这样子:

    那么显示就会变成:

    毫无3d感可言.

    将景深效果添加到容器上面去我们就能得到如下的效果:

    复制代码
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        // 普通的一个layer
        CALayer *plane1        = [CALayer layer];
        plane1.anchorPoint = CGPointMake(0.5, 0.5);                         // 锚点
        plane1.frame       = (CGRect){CGPointZero, CGSizeMake(100, 100)};   // 尺寸
        plane1.position    = CGPointMake(60, V_CENTER_Y);                   // 位置
        plane1.opacity         = 0.6;                                       // 背景透明度
        plane1.backgroundColor = CG_COLOR(1, 0, 0, 1);                      // 背景色
        plane1.borderWidth     = 3;                                         // 边框宽度
        plane1.borderColor     = CG_COLOR(1, 1, 1, 0.5);                    // 边框颜色(设置了透明度)
        plane1.cornerRadius    = 10;                                        // 圆角值
    
        
        // 普通的一个layer
        CALayer *plane2        = [CALayer layer];
        plane2.anchorPoint = CGPointMake(0.5, 0.5);                         // 锚点
        plane2.frame       = (CGRect){CGPointZero, CGSizeMake(100, 100)};   // 尺寸
        plane2.position    = CGPointMake(60 + 110, V_CENTER_Y);             // 位置
        plane2.opacity         = 0.6;                                       // 背景透明度
        plane2.backgroundColor = CG_COLOR(0, 1, 0, 1);                      // 背景色
        plane2.borderWidth     = 3;                                         // 边框宽度
        plane2.borderColor     = CG_COLOR(1, 1, 1, 0.5);                    // 边框颜色(设置了透明度)
        plane2.cornerRadius    = 10;                                        // 圆角值
        
        // 创建容器layer
        CALayer *container = [CALayer layer];
        container.frame    = self.view.bounds;
        [self.view.layer addSublayer:container];
        
        CATransform3D plane_3D = CATransform3DIdentity;
        plane_3D.m34           = 1.0/ -500;
        plane_3D               = CATransform3DRotate(plane_3D, DEGREE(30), 0, 1, 0);
        container.transform    = plane_3D;
        
        [container addSublayer:plane1];
        [container addSublayer:plane2];
    }
    复制代码

    注意,下图红框中的值是非常关键的哦:

    到这里还没讲CATransformLayer呢,先看个例子:

    效果如下:

    复制代码
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        // 普通的一个layer
        CALayer *plane1        = [CALayer layer];
        plane1.anchorPoint = CGPointMake(0.5, 0.5);                         // 锚点
        plane1.frame       = (CGRect){CGPointZero, CGSizeMake(100, 100)};   // 尺寸
        plane1.position    = CGPointMake(200, V_CENTER_Y);                  // 位置
        plane1.opacity         = 0.6;                                       // 背景透明度
        plane1.backgroundColor = CG_COLOR(1, 0, 0, 1);                      // 背景色
        plane1.borderWidth     = 3;                                         // 边框宽度
        plane1.borderColor     = CG_COLOR(1, 1, 1, 0.5);                    // 边框颜色(设置了透明度)
        plane1.cornerRadius    = 10;                                        // 圆角值
        
        // Z轴平移
        CATransform3D plane1_3D = CATransform3DIdentity;
        plane1_3D               = CATransform3DTranslate(plane1_3D, 0, 0, -10);
        plane1.transform        = plane1_3D;
        
        // 普通的一个layer
        CALayer *plane2        = [CALayer layer];
        plane2.anchorPoint = CGPointMake(0.5, 0.5);                         // 锚点
        plane2.frame       = (CGRect){CGPointZero, CGSizeMake(100, 100)};   // 尺寸
        plane2.position    = CGPointMake(200, V_CENTER_Y);                  // 位置
        plane2.opacity         = 0.6;                                       // 背景透明度
        plane2.backgroundColor = CG_COLOR(0, 1, 0, 1);                      // 背景色
        plane2.borderWidth     = 3;                                         // 边框宽度
        plane2.borderColor     = CG_COLOR(1, 1, 1, 0.5);                    // 边框颜色(设置了透明度)
        plane2.cornerRadius    = 10;                                        // 圆角值
        
        // Z轴平移
        CATransform3D plane2_3D = CATransform3DIdentity;
        plane2_3D               = CATransform3DTranslate(plane2_3D, 0, 0, -30);
        plane2.transform        = plane2_3D;
        
        // 创建容器layer
        CALayer *container = [CALayer layer];
        container.frame    = self.view.bounds;
        [self.view.layer addSublayer:container];
        
        // 以Y轴为坐标系,旋转45度
        CATransform3D t = CATransform3DIdentity;
        t.m34 = 1.0/-500;
        t = CATransform3DRotate(t, DEGREE(45), 0, 1, 0);
        container.transform = t;
        
        [container addSublayer:plane1];
        [container addSublayer:plane2];
    }
    复制代码

    如果把上图的CALayer替换成下图的CATransformLayer

    则会产生如下的效果:

    看到上面的图,你应该就明白了CATransformLayer当做容器是为了给里面的Layer提供景深效果用的.

    再来做成动画看看效果吧:

    复制代码
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        // 普通的一个layer
        CALayer *plane1        = [CALayer layer];
        plane1.anchorPoint = CGPointMake(0.5, 0.5);                         // 锚点
        plane1.frame       = (CGRect){CGPointZero, CGSizeMake(100, 100)};   // 尺寸
        plane1.position    = CGPointMake(200, V_CENTER_Y);                  // 位置
        plane1.opacity         = 0.6;                                       // 背景透明度
        plane1.backgroundColor = CG_COLOR(1, 0, 0, 1);                      // 背景色
        plane1.borderWidth     = 3;                                         // 边框宽度
        plane1.borderColor     = CG_COLOR(1, 1, 1, 0.5);                    // 边框颜色(设置了透明度)
        plane1.cornerRadius    = 10;                                        // 圆角值
        
        // Z轴平移
        CATransform3D plane1_3D = CATransform3DIdentity;
        plane1_3D               = CATransform3DTranslate(plane1_3D, 0, 0, -10);
        plane1.transform        = plane1_3D;
        
        // 普通的一个layer
        CALayer *plane2        = [CALayer layer];
        plane2.anchorPoint = CGPointMake(0.5, 0.5);                         // 锚点
        plane2.frame       = (CGRect){CGPointZero, CGSizeMake(100, 100)};   // 尺寸
        plane2.position    = CGPointMake(200, V_CENTER_Y);                  // 位置
        plane2.opacity         = 0.6;                                       // 背景透明度
        plane2.backgroundColor = CG_COLOR(0, 1, 0, 1);                      // 背景色
        plane2.borderWidth     = 3;                                         // 边框宽度
        plane2.borderColor     = CG_COLOR(1, 1, 1, 0.5);                    // 边框颜色(设置了透明度)
        plane2.cornerRadius    = 10;                                        // 圆角值
        
        // Z轴平移
        CATransform3D plane2_3D = CATransform3DIdentity;
        plane2_3D               = CATransform3DTranslate(plane2_3D, 0, 0, -30);
        plane2.transform        = plane2_3D;
        
        // 创建容器layer
        CATransformLayer *container = [CATransformLayer layer];
        container.frame    = self.view.bounds;
        [self.view.layer addSublayer:container];
        [container addSublayer:plane1];
        [container addSublayer:plane2];
        
        // 启动定时器
        _timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]];
        [_timer event:^{
            static float degree = 0.f;
            
            // 起始值
            CATransform3D fromValue = CATransform3DIdentity;
            fromValue.m34           = 1.0/ -500;
            fromValue               = CATransform3DRotate(fromValue, degree, 0, 1, 0);
            
            // 结束值
            CATransform3D toValue   = CATransform3DIdentity;
            toValue.m34             = 1.0/ -500;
            toValue                 = CATransform3DRotate(toValue, degree += 45.f, 0, 1, 0);
            
            // 添加3d动画
            CABasicAnimation *transform3D = [CABasicAnimation animationWithKeyPath:@"transform"];
            transform3D.duration  = 1.f;
            transform3D.fromValue = [NSValue valueWithCATransform3D:fromValue];
            transform3D.toValue   = [NSValue valueWithCATransform3D:toValue];
            container.transform = toValue;
            [container addAnimation:transform3D forKey:@"transform3D"];
            
        } timeInterval:NSEC_PER_SEC];
        [_timer start];
    }
    复制代码

    转自:http://www.cnblogs.com/YouXianMing/p/3777778.html yaoxianming博客

  • 相关阅读:
    HTML: vertical algin Big/small div in same row (bootstrap)
    unix时间转换
    chrome工具分析
    DNF 包管理器
    安装nodejs
    location属性解释
    angular深入理解途径
    ui-router与ngRoute
    angular $location服务获取url
    Python文件操作
  • 原文地址:https://www.cnblogs.com/LyChen/p/5109441.html
Copyright © 2011-2022 走看看