iOS開發(fā):使用CAEmitterLayer實現(xiàn)動畫效果

CAEmitterLayer是CALayer的一個子類,和CAEmitterCell一起使用可以創(chuàng)造出多樣的動畫效果。
CAEmitterLayer的屬性:

/*@interface CAEmitterLayer : CALayer
 --粒子的數(shù)組 把設(shè)置好的粒子放入數(shù)組設(shè)置到layer上
 @property(nullable, copy) NSArray<CAEmitterCell *> *emitterCells;
 --layer生產(chǎn)率 與cell的birthRate相乘就是粒子的生產(chǎn)率
 @property float birthRate;
 --layer存在時間 同上
 @property float lifetime;
 --發(fā)射源中心點的位置
 @property CGPoint emitterPosition;
 --z軸上的位置
 @property CGFloat emitterZPosition;
 --是發(fā)射源的大小 并不是layer的大小
 @property CGSize emitterSize;
 --不清楚是什么效果
 @property CGFloat emitterDepth;
 --發(fā)射源的形狀 有圓形 方形 線型等
 @property(copy) NSString *emitterShape;
 --發(fā)散形式 “l(fā)ayerPoints”是指發(fā)射粒子的位置在發(fā)射源的關(guān)鍵點上
 如方形發(fā)射源的四個角點 圓形發(fā)射源的中心點
 “OutLine”就是指例子發(fā)射的位置位于發(fā)射源的邊框
 “surface”即是表面 “volume”暫時不清楚
 @property(copy) NSString *emitterMode;
 --描繪模式 “unordered”不規(guī)律的 增加了立體感
 “oldestFirst”先生成的在上 “oldestLast”反之 
“backToFront”根據(jù)z軸上的位置進(jìn)行描繪 “additive”發(fā)射源的多種粒子進(jìn)行混合
 @property(copy) NSString *renderMode;
 --是否展示在z軸上的效果 把圖層進(jìn)行3d變形如沿y軸旋轉(zhuǎn)90度 會有很明顯的立體效果
 @property BOOL preservesDepth;
 --發(fā)射速度 和cell的速度屬性一起決定了粒子的速度 猜測粒子的速度是兩者的乘積 
而且和cell的速度屬性不同 這個屬性可以為負(fù) 
為負(fù)的時候發(fā)散方向是向反方向的 為正時是向指定方向的
 @property float velocity;
 -- 縮放大小 和速度相同 粒子的scale值是兩者相乘 也可以為負(fù) 為負(fù)時效果不清楚
 @property float scale;
 -- 同上面的兩個屬性
 @property float spin;
 -- 可能是給圖層中需要用到的隨機(jī)數(shù)設(shè)置種子
 @property unsigned int seed;*/

CAEmitterCell的部分屬性

/*
 --是否允許被繪制出來
 @property(getter=isEnabled) BOOL enabled;
 
 --生成速率
 @property float birthRate;
 
 --生存周期
 @property float lifetime;
 --生存周期的絕對值的偏移量的最大值   。。。
 @property float lifetimeRange;
 
 --z軸方向上的發(fā)射角度
 @property CGFloat emissionLatitude;
 --在xy平面上的發(fā)射角度 
 @property CGFloat emissionLongitude;
 
 --放射角度的偏移量
 @property CGFloat emissionRange;
 
 --放射速度
 @property CGFloat velocity;
 --速度偏移量
 @property CGFloat velocityRange;
 --在三個坐標(biāo)軸上的速度增量 可以做出類似重力 風(fēng)吹的效果
 @property CGFloat xAcceleration;
 @property CGFloat yAcceleration;
 @property CGFloat zAcceleration;
 --縮放數(shù)值
 @property CGFloat scale;
 --縮放數(shù)值的偏移量
 @property CGFloat scaleRange;
 --縮放速度 不清楚怎么設(shè)置 可能和velocity屬性有關(guān)系
 @property CGFloat scaleSpeed;
 --旋轉(zhuǎn)
 @property CGFloat spin;
 --旋轉(zhuǎn)的偏移量
 @property CGFloat spinRange;
 --設(shè)置cell的顏色 content的顏色會影響實際顏色
 @property(nullable) CGColorRef color;
 --設(shè)置三原色和透明度的值 偏移值 0-1
 @property float redRange;
 @property float greenRange;
 @property float blueRange;
 @property float alphaRange;
 --變色速率
 @property float redSpeed;
 @property float greenSpeed;
 @property float blueSpeed;
 @property float alphaSpeed;
 --cell的內(nèi)容 一般是UIImage
 @property(nullable, strong) id contents;
 --內(nèi)容范圍
 @property CGRect contentsRect;
 --內(nèi)容縮放
 @property CGFloat contentsScale;
 */

CAEmitterLayer和CAEmitterCell有眾多屬性,所以就有更多的搭配,從而實現(xiàn)多種多樣的動畫效果。
幾個簡單的小例子:

1 落雪效果的實現(xiàn) 使用更逼真的圖片作為內(nèi)容效果會好得多

+(instancetype)layer {
    Emitter_snow *snow = [super layer];
    if (snow) {
        
        [snow creatLayer];
        [snow addCells];
        
    }
    return snow;
}

-(void)creatLayer {

    self.emitterSize = CGSizeMake(400, 200);
    self.emitterPosition = CGPointMake(200, 0);
    self.emitterShape = kCAEmitterLayerLine;
    self.emitterMode = kCAEmitterLayerVolume;
}
-(void)addCells {
    
    CAEmitterCell *cell = [CAEmitterCell emitterCell];
    cell.birthRate = 1.0;
    cell.lifetime = 100;
    cell.name = @"snow";
    cell.velocity = 10.0;
    cell.velocityRange = 2;
    cell.yAcceleration = 2;

    cell.emissionRange = M_PI_2;
    cell.spinRange = M_PI_4;
    cell.contents = (id)[UIImage imageNamed:@"snow"].CGImage;
    cell.color = [UIColor whiteColor].CGColor;
   
    self.emitterCells = @[cell];
}

2 爆炸效果的實現(xiàn) 可以通過修改一些屬性 設(shè)置爆炸的效果


-(void)creatLayer {

    self.emitterSize = CGSizeMake(20, 20);
    self.emitterPosition = CGPointMake(200, 200);
    self.emitterShape = kCAEmitterLayerSphere;
    self.emitterMode = kCAEmitterLayerVolume;
}
-(void)addCells {
    
    __block CAEmitterCell *cell = [CAEmitterCell emitterCell];
    cell.birthRate = 1000.0;
    cell.lifetime = 0.1;
    cell.name = @"exploding";
    cell.velocity = 0;
    cell.velocityRange = 1;
    cell.emissionRange = M_PI*2;
    cell.spinRange = M_PI_4;
    cell.contents = (id)[UIImage imageNamed:@"explode"].CGImage;
    cell.color = [UIColor whiteColor].CGColor;
   
    self.emitterCells = @[cell];
}
//啟動爆炸的方法
-(void)explode {
    
    __block CAEmitterCell *cell = [CAEmitterCell emitterCell];
    //設(shè)置了很高的出生率 模擬碎片
    cell.birthRate = 30000.0;
    cell.lifetime = 100;
    cell.name = @"boom";
    cell.velocity = 500;
    cell.velocityRange = 10;
    // 爆炸是向四面八方的
    cell.emissionRange = M_PI*2;
    cell.spinRange = M_PI;
    cell.contents = (id)[UIImage imageNamed:@"1"].CGImage;
    cell.color = [UIColor redColor].CGColor;
    dispatch_queue_t mainQ = dispatch_get_main_queue();
    dispatch_queue_t globalQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(globalQ, ^{
        [NSThread sleepForTimeInterval:3];
        dispatch_async(mainQ, ^{
          self.emitterCells = @[cell];
        });
        //發(fā)射源只發(fā)射了0.01秒 模擬爆炸的瞬間
        [NSThread sleepForTimeInterval:0.01];
        dispatch_async(mainQ, ^{
            self.birthRate = 0;
        });
    });
} 
3 煙花效果的實現(xiàn) 三個方法依次調(diào)用 缺少素材 效果一般 還可以優(yōu)化 

+(instancetype)layer {
    Emitter_fire *fire = [super layer];
    if (fire) {
        
        [fire creatLayer];
        [fire fireLine];
        [fire fireWork];
    }
    return fire;
}


-(void)creatLayer {

    self.emitterSize = CGSizeMake(2, 2);
    self.emitterPosition = CGPointMake(200, 200);
    self.emitterShape = kCAEmitterLayerPoint;
    self.emitterMode = kCAEmitterLayerVolume;
   
}

-(void)fireLine {
    
    CALayer *line = [CALayer layer];
    line.backgroundColor = [UIColor orangeColor].CGColor;
    line.bounds = CGRectMake(0, 0, 3, 40);
    line.anchorPoint = CGPointMake(0.5, 0);
    line.position = CGPointMake(200, 610);
    
    CAKeyframeAnimation *keyAni = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.y"];
    keyAni.values = @[@(-200),@(-300),@(-350),@(-380),@(-400),@(-410)];
    keyAni.duration = 1;
    [line addAnimation:keyAni forKey:@"ani"];
    [self addSublayer:line];
    
}

-(void)fireWork {
    
    __block CAEmitterCell *cell = [CAEmitterCell emitterCell];
    cell.birthRate = 300.0;
    cell.lifetime = 3;
    cell.scale = 0.3;
    cell.name = @"boom";
    cell.velocity = 50;
    cell.velocityRange = 0;
    cell.emissionLongitude = -M_PI_2;
    cell.emissionRange = M_PI*3/4;
    cell.spinRange = M_PI;
    
    cell.greenRange = 0.5;
    cell.redRange = 0.5;
    cell.blueRange = 0.1;
    cell.greenSpeed = -0.5;
    cell.redSpeed  = 0.35;
    cell.blueSpeed  = -0.15;
    cell.alphaSpeed = -0.2;
   
    cell.contents = (id)[UIImage imageNamed:@"fireWork"].CGImage;
    cell.color = [UIColor redColor].CGColor;
    dispatch_queue_t mainQ = dispatch_get_main_queue();
    dispatch_queue_t globalQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(globalQ, ^{
        [NSThread sleepForTimeInterval:1];
        self.sublayers = nil;
        dispatch_async(mainQ, ^{
          self.emitterCells = @[cell];
        });
        [NSThread sleepForTimeInterval:0.1];
        dispatch_async(mainQ, ^{
            cell.yAcceleration = 60;
            self.emitterCells = @[cell];
        });
        [NSThread sleepForTimeInterval:0.1];
        dispatch_async(mainQ, ^{
            self.birthRate = 0;
        });
    });
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、簡介 iOS動畫主要是指Core Animation框架。官方使用文檔地址為:Core Animation G...
    阿拉斯加的狗閱讀 3,347評論 5 49
  • 大家好,我是前幾天剛剛簽完三方協(xié)議的 Yellow。和很多同學(xué)一樣,我在大四上一直在外面實習(xí),甚至看過上周我那篇租...
    7a3466b7d857閱讀 5,653評論 0 10
  • 周末下午到上海書城逛逛,三樓社會經(jīng)濟(jì)聚集了好多人,大家暢所欲言談,我也參與其中……。不知不覺店門要關(guān)了,一伙人...
    步步嬌閱讀 303評論 0 0
  • 玩錢
    wenjuit閱讀 169評論 1 0
  • 那年不散場的青春 (終究畢業(yè)了,仿佛又是一場夢。然而我的大學(xué)連載還沒有更新完。回想起過去的事,回看著自己寫過的東西...
    阿缽閱讀 506評論 0 2

友情鏈接更多精彩內(nèi)容