CATransformLayer與CALayer有着細微的差異,但這些差異會影響到3D變換的動畫效果.ide
動畫都有座標系,以下所示(注意,這個不是iOS中的座標系,請勿對號入座):動畫
iOS中layer的錨點就在座標系的正中間.atom
layer的position能夠理解爲View的center.spa
實現帶有3d景深效果動畫: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,景深效果就愈加強烈code
若是寫成這樣子:orm
那麼顯示就會變成:blog
毫無3d感可言.ci
將景深效果添加到容器上面去咱們就能獲得以下的效果:animation
- (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]; }