iOS开发:使用CAEmitterLayer实现动画效果

CAEmitterLayer是CALayer的一个子类,和CAEmitterCell一起使用可以创造出多样的动画效果。
CAEmitterLayer的属性:

/*@interface CAEmitterLayer : CALayer
 --粒子的数组 把设置好的粒子放入数组设置到layer上
 @property(nullable, copy) NSArray<CAEmitterCell *> *emitterCells;
 --layer生产率 与cell的birthRate相乘就是粒子的生产率
 @property float birthRate;
 --layer存在时间 同上
 @property float lifetime;
 --发射源中心点的位置
 @property CGPoint emitterPosition;
 --z轴上的位置
 @property CGFloat emitterZPosition;
 --是发射源的大小 并不是layer的大小
 @property CGSize emitterSize;
 --不清楚是什么效果
 @property CGFloat emitterDepth;
 --发射源的形状 有圆形 方形 线型等
 @property(copy) NSString *emitterShape;
 --发散形式 “layerPoints”是指发射粒子的位置在发射源的关键点上
 如方形发射源的四个角点 圆形发射源的中心点
 “OutLine”就是指例子发射的位置位于发射源的边框
 “surface”即是表面 “volume”暂时不清楚
 @property(copy) NSString *emitterMode;
 --描绘模式 “unordered”不规律的 增加了立体感
 “oldestFirst”先生成的在上 “oldestLast”反之 
“backToFront”根据z轴上的位置进行描绘 “additive”发射源的多种粒子进行混合
 @property(copy) NSString *renderMode;
 --是否展示在z轴上的效果 把图层进行3d变形如沿y轴旋转90度 会有很明显的立体效果
 @property BOOL preservesDepth;
 --发射速度 和cell的速度属性一起决定了粒子的速度 猜测粒子的速度是两者的乘积 
而且和cell的速度属性不同 这个属性可以为负 
为负的时候发散方向是向反方向的 为正时是向指定方向的
 @property float velocity;
 -- 缩放大小 和速度相同 粒子的scale值是两者相乘 也可以为负 为负时效果不清楚
 @property float scale;
 -- 同上面的两个属性
 @property float spin;
 -- 可能是给图层中需要用到的随机数设置种子
 @property unsigned int seed;*/

CAEmitterCell的部分属性

/*
 --是否允许被绘制出来
 @property(getter=isEnabled) BOOL enabled;
 
 --生成速率
 @property float birthRate;
 
 --生存周期
 @property float lifetime;
 --生存周期的绝对值的偏移量的最大值   。。。
 @property float lifetimeRange;
 
 --z轴方向上的发射角度
 @property CGFloat emissionLatitude;
 --在xy平面上的发射角度 
 @property CGFloat emissionLongitude;
 
 --放射角度的偏移量
 @property CGFloat emissionRange;
 
 --放射速度
 @property CGFloat velocity;
 --速度偏移量
 @property CGFloat velocityRange;
 --在三个坐标轴上的速度增量 可以做出类似重力 风吹的效果
 @property CGFloat xAcceleration;
 @property CGFloat yAcceleration;
 @property CGFloat zAcceleration;
 --缩放数值
 @property CGFloat scale;
 --缩放数值的偏移量
 @property CGFloat scaleRange;
 --缩放速度 不清楚怎么设置 可能和velocity属性有关系
 @property CGFloat scaleSpeed;
 --旋转
 @property CGFloat spin;
 --旋转的偏移量
 @property CGFloat spinRange;
 --设置cell的颜色 content的颜色会影响实际颜色
 @property(nullable) CGColorRef color;
 --设置三原色和透明度的值 偏移值 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的内容 一般是UIImage
 @property(nullable, strong) id contents;
 --内容范围
 @property CGRect contentsRect;
 --内容缩放
 @property CGFloat contentsScale;
 */

CAEmitterLayer和CAEmitterCell有众多属性,所以就有更多的搭配,从而实现多种多样的动画效果。
几个简单的小例子:

1 落雪效果的实现 使用更逼真的图片作为内容效果会好得多

+(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 爆炸效果的实现 可以通过修改一些属性 设置爆炸的效果


-(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];
    //设置了很高的出生率 模拟碎片
    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];
        });
        //发射源只发射了0.01秒 模拟爆炸的瞬间
        [NSThread sleepForTimeInterval:0.01];
        dispatch_async(mainQ, ^{
            self.birthRate = 0;
        });
    });
} 
3 烟花效果的实现 三个方法依次调用 缺少素材 效果一般 还可以优化 

+(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;
        });
    });
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343

推荐阅读更多精彩内容