CoreAnimation 可用在 Mac OS X和iOS平臺
CoreAnimation 的動畫執行過程都是在後臺操做的,不會阻塞主線程。
CoreAnimation 是直接做用在CALayer 上的,並非UIView。 用一張圖來簡要介紹一下核心動畫成員之間的關係。
關於Animation 的架構php
CoreAnimation 基礎框架
CALayer 圖層(動畫都是基於圖層產生的) CALayer 不能夠與用戶交互,只能顯示內容 CALayer 發生改變,子圖層 不會跟隨發生改變 UIView 是一個視圖,能夠添加響應事件,能夠與用戶交互 UIView —>rootLayer 發生改變,子圖層也會發生改變 例如:UIButton ,不止有一個視圖,改變的只是其中一個視圖的rootLayer —>仍然會顯示未被裁切的邊框 爲什麼要封裝成這麼多的類? 體現了面向對象的特性,就是每一個對象都控制着不一樣的特性,每一個類控制動畫一方面。
核心動畫的一切都是假象,並不會真是改變layer的值
UIView 真實改變屬性纔能有動畫 使用場景: UIView 用在須要交互的地方 核心動畫用在不須要交互的地方。
基礎框架
CALayer 圖層(動畫都是基於圖層產生的)
自帶動畫效果(當屬性值改變的時候)—> 隱式動畫
UIView 是一個視圖,能夠添加響應事件,能夠與用戶交互,他的rootLayer沒有動畫效果
CALayer 不能夠與用戶交互,只能顯示內容
bounds 邊境範圍
position 中心點
zPosition z軸中心點
anchorPoint 錨點 ✮✮✮✮✮ 默認錨點 是與中心點重合 錨點的值與位置 最小值是(0,0),最大值是(1,1) 默認錨點的值是(0.5,0.5)= 中心點 (0,0) = 圖層的左上角 (0,1) = 圖層的左下角 (1,0) = 圖層的右上角 (1,1) = 圖層的右下角 錨點值 = 錨點在視圖上的位置.x.y/視圖的寬高 當視圖改變的時候,是以錨點爲基準改變的 anchorPointZ Z軸錨點 transform 轉換形態 frame NO. Animatable 座標 hidden 隱藏 doubleSided 圖層背面是否顯示 geometryFlipped 翻轉 顛倒 masksToBounds 裁切邊境 contents 內容 opaque 不透明度 allowsEdgeAntialiasing 是否使用 變形後的抗鋸齒 backgroundColor 背景顏色 borderWidth 邊框寬 borderColor 邊框顏色 opacity 不透明度 shadowColor 陰影顏色 shadowOpacity 陰影不透明度 rasterizationScale 防止Retina屏幕像素化 shadowOffset 陰影偏移量 shadowRadius 陰影的半徑
CAKeyframeAnimation 簡介 關鍵幀動畫,是CAPropertyAnimation的子類 與 CABasicAniamtion 的區別是CABasicAniamtion是從fromValue 到toValue 兩個值的變化,而 CAKeyframeAnimation 可使用 NSArray 來保存這些數值。 屬性說明: values:NSArray 對象,裏面的元素就是「關鍵幀」,動畫會在指定的時間內,依次顯示 values 數組中的每個關鍵幀。 path:能夠設置CGPathRef、CGMutablePathRef,讓圖層按照軌跡移動,path只對CALayer的 anchorPoint 和 point 起做用。若是設置了path, 那麼values將被忽略。 keyTimes:關鍵幀指定對應的時間點,取值範圍從0~1,keyTimes中的每個時間值對應values中的每一幀,若是沒有設置,時間是平分的。 CABasicAniamtion 可看作 只有兩個關鍵幀的CAKeyframeAnimation
CAAnimationGroup 是 CAAnimation 的子類,能夠保存一組動畫對象,將 CAAnimationGroup 對象加入層以後,族中全部的動畫對象能夠同時併發運行。 屬性說明: animations:保存一組動畫對象的NSArray。 默認狀況下,一組動畫對象是同時運行的,也能夠經過設置動畫對象的 beginTimer 屬性來更改動畫的開始時間。
CATransition 爲層提供移出屏幕和移入屏幕的動畫效果。 UINavigationController就是經過CATransition實現了將控制器推入屏幕的動畫效果 動畫屬性: type:動畫過渡類型 subtype:動畫過渡方向 startProgress:動畫起點 endProgress:動畫終點 CAAnimation (基類)全部動畫的父類,不能直接使用 CAPropertyAnimation (屬性動畫)也是基類,不可直接使用—>經過屬性值的改變產生動畫效果 CABasicAnimation (基礎動畫)只能是兩個點之間的變化 CASpringAnimation CAKeyFrameAnimation (關鍵幀動畫)能夠添加多個點的變化 或者路徑 CAAnimationGRoup(動畫組)能夠同時添加多種動畫,達到預期效果 CATransition(轉場動畫 )給視圖切換的時候 添加動畫效果
#import "ViewController.h" #define Angle(a) (a)*M_PI/180 #define sAngle 6 //每秒旋轉多少度:sAngle*N秒*M_PI/180 @interface ViewController (){ CALayer *layer; } @property (nonatomic,strong)CALayer *pointLayer; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //初始化CAlayer layer = [CALayer layer]; layer.frame = CGRectMake(100, 100, 100, 100); //設置圖層拐角 layer.cornerRadius = 100/2; layer.backgroundColor =[UIColor brownColor].CGColor; //添加到父圖層 [self.view.layer addSublayer:layer]; NSLog(@"%@",self.pointLayer); _pointLayer.anchorPoint =CGPointMake(0, 0.5); //放置一張圖片 /* 圖層上 要的是顏色(CGColorRef) 圖片(CGImageRef)的 數據,而非UI */ _pointLayer.contents =(id)[UIImage imageNamed:@"shizhen.png"].CGImage; self.pointLayer.anchorPoint = CGPointMake(0.5, 0.9); [self star]; [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(star) userInfo:nil repeats:YES]; } -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ //得到點擊觸摸的點 layer.position =[[touches anyObject] locationInView:self.view]; CGFloat width =CGRectGetWidth(layer.bounds)!=100?100:50; //經過得到的點 改變尺寸 layer.bounds =CGRectMake(0, 0, width, width); //改變顏色 CGColorRef color = [UIColor brownColor].CGColor != layer.backgroundColor ? [UIColor brownColor].CGColor: [UIColor colorWithRed:0.863 green:0.634 blue:0.490 alpha:1.000].CGColor; layer.backgroundColor = color; //改變半徑 layer.cornerRadius =width!=100?0:width/2; //改變透明度 layer.opacity = 0.3; //設置錨點,最大值是1,最小值是0 _pointLayer.transform = CATransform3DMakeRotation(/*弧度*/Angle(60),0 , 0, 1); } -(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ layer.opacity = 1.0; //還原 _pointLayer.transform = CATransform3DIdentity; } //利用懶加載 建立一個layer -(CALayer *)pointLayer{ if (_pointLayer) { return _pointLayer; } _pointLayer = [CALayer layer]; _pointLayer.bounds =CGRectMake(0, 0, 18, 220); //設置中心點 _pointLayer.position =self.view.center; _pointLayer.backgroundColor = [UIColor colorWithRed:1.000 green:0.392 blue:0.929 alpha:1.000].CGColor; [self.view.layer addSublayer:_pointLayer]; return _pointLayer; } -(void)star{ //NSCalendar 日曆;能夠得到年月日 時分秒,都是NSCalendar上的組件 // NSDateComponents //得到當前日曆 NSCalendar *calender =[NSCalendar currentCalendar]; NSDateComponents *componest =[calender components: NSCalendarUnitHour| NSCalendarUnitMinute| NSCalendarUnitSecond fromDate:[NSDate date]]; float s = componest.second * sAngle; _pointLayer.transform = CATransform3DMakeRotation(/*弧度*/Angle(s),0 , 0, 1); }
CABasicAnimation *ani3 = [CABasicAnimation animation]; ani3.keyPath = @"opacity"; ani3.fromValue = @1; ani3.toValue = @0; ani3.duration = 1; ani3.repeatCount = MAXFLOAT; ani3.removedOnCompletion = NO; ani3.fillMode = kCAFillModeBackwards; CAKeyframeAnimation
CAKeyframeAnimation* ani = [CAKeyframeAnimation animation]; ani.keyPath = @"position"; UIBezierPath *path =[UIBezierPath bezierPathWithArcCenter:_img.center radius:100 startAngle:0 endAngle:M_PI*2 clockwise:YES]; ani.path = path.CGPath; ani.repeatCount = MAXFLOAT; ani.duration = 2; ani.removedOnCompletion = NO; ani.fillMode = kCAFillModeBoth;
#define angle2Radion(angle) (angle / 180.0 * M_PI) CAKeyframeAnimation*ani2 = [CAKeyframeAnimation animation]; ani2.keyPath = @"transform.rotation"; ani2.values = @[@(angle2Radion(-5)),@(angle2Radion(5)),@(angle2Radion(-5))]; ani2.duration = 0.15; ani2.repeatCount = MAXFLOAT; CAAnimationGroup /*注意:每一次group循環內的動畫仍舊是由每一個動畫各自的屬性控制, 有一點須要注意就是duration這個屬性,爲了保證動畫的連貫性, group的duration屬性最好設置成與動畫數組內時間最長的動畫一致。*/ //group CAAnimationGroup *group = [CAAnimationGroup animation]; //位移 CAKeyframeAnimation* ani = [CAKeyframeAnimation animation]; ani.keyPath = @"position"; UIBezierPath *path =[UIBezierPath bezierPathWithArcCenter:_img.center radius:100 startAngle:0 endAngle:M_PI*2 clockwise:YES]; ani.path = path.CGPath; ani.repeatCount = MAXFLOAT; ani.duration = 2; ani.removedOnCompletion = NO; ani.fillMode = kCAFillModeBoth; //抖動 CAKeyframeAnimation*ani2 = [CAKeyframeAnimation animation]; ani2.keyPath = @"transform.rotation"; ani2.values = @[@(angle2Radion(-5)),@(angle2Radion(5)),@(angle2Radion(-5))]; ani2.duration = 0.15; ani2.repeatCount = MAXFLOAT; //透明度 CABasicAnimation *ani3 = [CABasicAnimation animation]; ani3.keyPath = @"opacity"; ani3.fromValue = @1; ani3.toValue = @0; ani3.duration = 1; ani3.repeatCount = MAXFLOAT; ani3.removedOnCompletion = NO; ani3.fillMode = kCAFillModeBackwards; //將動畫添加進group group.animations = @[ani,ani2,ani3]; group.duration = 2; group.repeatCount = MAXFLOAT; group.removedOnCompletion = NO; group.fillMode = kCAFillModeBackwards; [_img.layer addAnimation:group forKey:nil]; CATransition // 界面切換的代碼 static int i = 2; NSString *imageName = [NSString stringWithFormat:@"%d",i]; _imageView.image = [UIImage imageNamed:imageName]; i++; if (i > 3) { i = 1; } // 只要切換界面 均可以使用轉場動畫 // 誰切換界面 就添加到誰上 // 轉場動畫代碼必須和界面切換的代碼放在一塊兒 // 轉場動畫 CATransition *anim = [CATransition animation]; // 指定轉場類型 anim.type = @"pageCurl"; // 設置轉場的方向 anim.subtype = kCATransitionFromLeft; // 設置動畫的進度 anim.startProgress = 0; anim.endProgress = 1; anim.duration = 0.5; [_imageView.layer addAnimation:anim forKey:nil];
粒子發送器圖層html
CAEmitterLayer:發送器 birthRate:每秒發送粒子數量 emitterMode :發送的樣式 kCAEmitterLayerPoints:點 kCAEmitterLayerOutline:線 kCAEmitterLayerSurface:面 kCAEmitterLayerVolume:團 kCAEmitterLayerRectangle 矩形 kCAEmitterLayerCuboid 立方體 kCAEmitterLayerCircle 曲線 kCAEmitterLayerSphere 圓形 renderMode渲染樣式 kCAEmitterLayerOldestFirst 最後的出生的粒子 在第一個 kCAEmitterLayerOldestLast 最後的出生的粒子 在最後面 kCAEmitterLayerBackToFront 把後面的 放到上面 kCAEmitterLayerAdditive 疊加 kCAEmitterLayerOldestFirst 最後的出生的粒子 在第一個 kCAEmitterLayerOldestLast 最後的出生的粒子 在最後面 kCAEmitterLayerBackToFront 把後面的 放到上面 kCAEmitterLayerAdditive 疊加 emitterCells:在粒子發送器上面 添加粒子 CAEmitterCell:粒子 contents:粒子的內容 lifetime:存活時間 lifetimeRange:存活時間範圍 birthRate:每秒粒子生成的數量 emissionLatitude:散發的緯度(方向) 緯度表示 上下 emissionLongitude:散發的經度(方向) 經度表示左右 velocity :發送的速度(速度越快,越遠) velocityRange:發送的速度範圍 xAcceleration:X軸加速度 yAcceleration:y軸加速度 zAcceleration:z軸加速度 emissionRange:散發的範圍 弧度 name:能夠經過名字 找到粒子 - (void)viewDidLoad { [super viewDidLoad]; //初始化粒子發送器 //self.emitterLayer.frame = CGRectMake(0, 300, 100,400); // 設置粒子發送器 每秒鐘發送的數量 self.emitterLayer.birthRate = 1; //設置粒子的中心點 //self.emitterLayer.position = CGPointMake(0, 0); // 設置粒子發送器的樣式 self.emitterLayer.renderMode = kCAEmitterLayerBackToFront; //設置粒子的中心店 self.emitterLayer.emitterPosition =self.view.center; //初始化粒子 CAEmitterCell *cell = [CAEmitterCell emitterCell]; cell.contents = (id)[UIImage imageNamed:@"H3"].CGImage; //粒子的出生量 cell.birthRate = 10; //粒子的存活時間,默認是0,單位是秒 cell.lifetime = 10; cell.lifetimeRange =11; //粒子發送的速度,默認是0 cell.velocity = 100; cell.velocityRange= 10; //設置粒子發送的 方向 cell.emissionLongitude = 30*M_PI/180; cell.emissionLatitude = M_PI/180; //設置粒子散發的範圍 弧度 cell.emissionRange = 180*M_PI/180; //設置粒子的加速度 cell.yAcceleration = -100; // 把粒子的cell 放到粒子發送器上 self.emitterLayer.emitterCells = @[cell]; } -(CAEmitterLayer *)emitterLayer{ if (_emitterLayer) { return _emitterLayer; } _emitterLayer =[CAEmitterLayer layer]; [self.view.layer addSublayer:_emitterLayer]; return _emitterLayer; }
CAGradientLayer colors:漸變顏色的數組 必須是CGColor類型 locations: 顏色漸變的百分比 數組 startPoint: 顏色漸變的起始點 endPoint:顏色漸變的終點 顏色會根據設置的起始點和終點去變化 self.view.backgroundColor =[UIColor whiteColor]; UIImageView *imageView =[[UIImageView alloc]initWithFrame:self.view.frame]; imageView.contentMode =UIViewContentModeScaleAspectFit; imageView.image =[UIImage imageNamed:@"H4"]; [self.view addSubview:imageView]; //初始化漸變 圖層 CAGradientLayer *layer =[CAGradientLayer layer]; layer.frame =self.view.frame; //設置漸變的顏色數組 layer.colors =@[(id)[UIColor redColor].CGColor, (id)[UIColor orangeColor].CGColor, (id)[UIColor yellowColor].CGColor, (id)[UIColor greenColor].CGColor, (id)[UIColor cyanColor].CGColor, (id)[UIColor blueColor].CGColor, (id)[UIColor purpleColor].CGColor]; //設置透明度 layer.opacity =0.2; //設置起始點 layer.startPoint = CGPointMake(0, 0); //設置 layer.locations =@[@0.1,@0.2,@0.3]; [self.view.layer addSublayer:layer];
![3][http://down.treney.com/img/CAAnimation/ca3.png]git
在使用複製圖層的時候,必須重寫layerClass,把原有的CALayer 修改爲 CAReplicatorLayer //建立重寫後 能夠複製的圖層 CanReplicatorLayer *view= [[CanReplicatorLayer alloc]initWithFrame: CGRectMake(0, 100, 300, 300)]; [self.view addSubview:view]; self.view.backgroundColor =[UIColor whiteColor]; UIImageView *imageView =[[UIImageView alloc]initWithFrame: CGRectMake(0, 100, 300, 300)]; imageView.contentMode =UIViewContentModeScaleAspectFit; imageView.image =[UIImage imageNamed:@"H4"]; [view addSubview:imageView]; //複製圖層 CAReplicatorLayer *layer = (CAReplicatorLayer *)view.layer; //instance 複製以後,有原來的圖層 有新的圖層,這是如今實例化出來的layer的數量 layer.instanceCount = 2;//複製出來一份 //改變複製圖層的樣式 CATransform3D tansFrom = CATransform3DMakeTranslation(0, 80, 0); layer.instanceTransform = CATransform3DRotate(tansFrom,180*M_PI/180, 1, 0, 0); //設置複製圖層 顏色偏移量 layer.instanceRedOffset =-0.2; layer.instanceBlueOffset = -0.3; layer.instanceGreenOffset =-0.4;
做者:【鵬威の博客】 treney
本文連接:http://blog.treney.com/index.php/archives/CoreAnimation.html?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io 來源博客:http://blog.treney.com/