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

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

/*@interface CAEmitterLayer : CALayer
 --粒子的数组 把设置好的粒子放入数组设置到layer上
 @property(nullable, copy) NSArray *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;
        });
    });
}

你可能感兴趣的:(iOS开发:使用CAEmitterLayer实现动画效果)