iOS CAEmitterLayer动画

1. CAEmitterLayer

CAEmitterLayer是一个高性能的粒子引擎,被用来创建复杂的粒子发射动画,而所谓的粒子就是CAEmitterCell。可以把CAEmitterLayer看做CAEmitterCell的容器,CAEmitterCell可以进行个性化定制。

CAEmitterLayer主要属性

// 粒子数组
@property(nullable, copy) NSArray<CAEmitterCell *> *emitterCells;

// 发射源中心点位置,默认是 (0, 0, 0)
@property CGPoint emitterPosition;
@property CGFloat emitterZPosition;

// 发射源大小,宽、高和纵向深度。默认是 (0, 0, 0)
@property CGSize emitterSize;
@property CGFloat emitterDepth;

// 发射源的形状,有
// kCAEmitterLayerPoint(默认),点形状
// kCAEmitterLayerLine,线性形状
// kCAEmitterLayerRectangle,矩形形状
// kCAEmitterLayerCuboid,长方体形状
// kCAEmitterLayerCircle,圆形形状
// kCAEmitterLayerSphere,球体形状
@property(copy) CAEmitterLayerEmitterShape emitterShape;

// 发散形式,有
// kCAEmitterLayerPoints(默认),在点的位置发射粒子
// kCAEmitterLayerOutline,在边框上发射粒子,可以实现爆炸效果
// kCAEmitterLayerSurface,在区域内发射粒子
// kCAEmitterLayerVolume,在3D图形的体积内内发射粒子
@property(copy) CAEmitterLayerEmitterMode emitterMode;

// 绘制模式,有
// kCAEmitterLayerUnordered,无序出现的,多个发射源将混合
// kCAEmitterLayerOldestFirst,出现时间长的粒子会被渲染在最上层
// kCAEmitterLayerOldestLast,出现时间短的粒子会被渲染在最上层
// kCAEmitterLayerBackToFront,粒子的渲染按照Z轴的前后顺序进行
// kCAEmitterLayerAdditive,进行粒子混合
@property(copy) CAEmitterLayerRenderMode renderMode;

// birthRate、lifetime、velocity、scale和spin属性,都要与CAEmitterCell的对应属性相乘
// 每秒钟产生的粒子数量, 默认1。
@property float birthRate;
// 粒子的生命周期, 默认1
@property float lifetime;
// 粒子发射速度, 默认1.0, 为负的时候发散方向是向反方向的 为正时是向指定方向的
@property float velocity;
// 粒子的缩放比例系数, 默认是1
@property float scale;
// 自旋转速度系数, 默认1.0
@property float spin;

emitterShapeemitterMode需要配合使用,我们设置CAEmitterCellvelocity为正数

发射源的形状 说明
kCAEmitterLayerPoint 从点往右发射粒子
kCAEmitterLayerLine emitterMode是kCAEmitterLayerPoints时,从两个端点往右发射粒子,
其他都是往上发射粒子
kCAEmitterLayerRectangle
kCAEmitterLayerCuboid
emitterMode是kCAEmitterLayerOutline时,往四周发射粒子,
emitterMode是kCAEmitterLayerPoints时,从四个端点往右发射粒子,
其他都是往右发射粒子
kCAEmitterLayerCircle
kCAEmitterLayerSphere
emitterMode是kCAEmitterLayerOutline时,往四周发射粒子,
emitterMode是kCAEmitterLayerPoints时,从中心点往右发射粒子,
其他都是往右发射粒子

CAEmitterCellvelocity为负数时,方向与正数时相反。

2. CAEmitterCell

CAEmitterCell实现了粒子效果,定义所需粒子样式。

// 粒子的名字,默认nil,用于构建key paths
@property(nullable, copy) NSString *name;
// 是否允许被绘制
@property(getter=isEnabled) BOOL enabled;

// 每秒钟产生的粒子数量,默认是0
@property float birthRate;

// 粒子的生命周期, 默认是0
@property float lifetime;
// 为粒子的生命周期设定一个范围,[lifetime-lifetimeRange, lifetime+lifetimeRange]
@property float lifetimeRange;

// 粒子平均初始速度
@property CGFloat velocity;
// 为粒子初始速度设定一个范围,类似于lifetime和lifetimeRange的关系
@property CGFloat velocityRange;

// x、y、z轴上的加速度,默认是0
@property CGFloat xAcceleration;
@property CGFloat yAcceleration;
@property CGFloat zAcceleration;

// 粒子的缩放比例系数, 默认是1
@property CGFloat scale;
// 为粒子的缩放比例设定一个范围,类似于lifetime和lifetimeRange的关系
@property CGFloat scaleRange;
// 缩放系数每秒会被修改一次,默认是0,正数变大,负数变小
@property CGFloat scaleSpeed;

// 粒子的旋转系数, 默认是0
@property CGFloat spin;
// 为粒子的旋转系数设定一个范围,类似于lifetime和lifetimeRange的关系
@property CGFloat spinRange;

// cell的颜色,默认白色
@property(nullable) CGColorRef color;

// 三原色和透明度范围设置
@property float redRange;
@property float greenRange;
@property float blueRange;
@property float alphaRange;

// 三原色和透明度的变化速率每秒会被修改一次
@property float redSpeed;
@property float greenSpeed;
@property float blueSpeed;
@property float alphaSpeed;

// 指定纬度,纬度角代表了在x-z轴平面坐标系中与x轴之间的夹角,默认0
@property CGFloat emissionLatitude;
// 指定经度,经度角代表了在x-y轴平面坐标系中与x轴之间的夹角,默认0
// 顺时针方向为正,M_PI_2为90度向下
@property CGFloat emissionLongitude;
// 发射角度范围,角度用弧度制,默认0,以锥形分布开的发射角度。
// 粒子均匀分布在这个锥形范围内
@property CGFloat emissionRange;

// 绘制内容,一般是图片
@property(nullable, strong) id contents;

// 粒子发射的粒子
@property(nullable, copy) NSArray<CAEmitterCell *> *emitterCells;

3. 效果示例

3.1 下雪效果

示例代码

CAEmitterLayer *emitterLayer = [CAEmitterLayer layer];
emitterLayer.contents = (id)[UIImage imageNamed:@"icon_iv_sample"].CGImage;
emitterLayer.frame = self.view.bounds;
emitterLayer.emitterPosition = CGPointMake(self.view.center.x, -10);
emitterLayer.emitterSize = CGSizeMake(self.view.bounds.size.width-100, 10);

emitterLayer.emitterShape = kCAEmitterLayerLine;
emitterLayer.emitterMode = kCAEmitterLayerLine;
emitterLayer.renderMode = kCAEmitterLayerAdditive;

CAEmitterCell *cell = [CAEmitterCell emitterCell];
cell.contents = (id)[UIImage imageNamed:@"snow_white"].CGImage;
cell.birthRate = 50;
cell.lifetime = 20;
cell.lifetimeRange = 2;
cell.scale = 0.3;
cell.scaleRange = 0.2;
cell.yAcceleration = 50;
cell.alphaSpeed = -0.05;
cell.velocity = 75;
cell.emissionRange = 0.5 * M_PI_4;

emitterLayer.emitterCells = @[cell];

效果如下

3.2 爆炸效果

示例代码

 - (void)onExplodeClick:(UIButton *)sender {
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    animation.repeatCount = 1;
    animation.duration = 0.2;
    animation.toValue = @1.2;

    [sender.layer addAnimation:animation forKey:nil];
    
    CAEmitterLayer *emitterLayer = [CAEmitterLayer layer];
    emitterLayer.beginTime = CACurrentMediaTime();
    emitterLayer.frame = self.view.bounds;
    emitterLayer.emitterPosition = sender.center;
    emitterLayer.emitterSize = CGSizeMake(50, 50);

    emitterLayer.emitterShape = kCAEmitterLayerCircle;
    emitterLayer.emitterMode = kCAEmitterLayerOutline;

    CAEmitterCell *cell = [CAEmitterCell emitterCell];
    cell.contents = (id)[UIImage imageNamed:@"launch"].CGImage;
    cell.birthRate = 2000;
    cell.lifetime = 0.3;
    cell.lifetimeRange = 0.05;
    cell.scale = 0.03;
    cell.scaleRange = 0.01;
    cell.velocity = 80;
    cell.velocityRange = 20;

    emitterLayer.emitterCells = @[cell];
    
    [self.view.layer addSublayer:emitterLayer];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        emitterLayer.birthRate = 0;
    });
}

效果如下
iOS CAEmitterLayer动画_第1张图片

参考资料: iOS进阶之CAEmitterLayer
参考资料: 关于CAEmitterLayer和CAEmitterCell结合使用

你可能感兴趣的:(iOS,图像动画,ios,CAEmitterLayer)