CoreAnimation-粒子动画

1,224 阅读2分钟

一、首先我们来看一下粒子动画常用的类和API

发射源:CAEmitterLayer

初始化

CAEmitterLayer *colorBallLayer = [CAEmitterLayer layer];

常用属性

emitterSize:粒子发射器的大小

emitterShape:粒子发射器的形状

kCAEmitterLayerPoint:点

kCAEmitterLayerLine:线

kCAEmitterLayerRectangle:矩形

kCAEmitterLayerCuboid:3D立方体

kCAEmitterLayerCircle:圆

kCAEmitterLayerSphere:3D球

emitterMode:发射模式

kCAEmitterLayerPoints:从顶点发射

kCAEmitterLayerOutline:从轮廓发射

kCAEmitterLayerSurface:从表面发射

kCAEmitterLayerVolume:3D图形内部发射

emitterPosition:发射器的中心点

粒子:CAEmitterCell

初始化

CAEmitterCell * colorBallCell = [CAEmitterCell emitterCell]

常用属性:

birthRate:粒子产生率,越大粒子越多

lifetime:粒子的生命周期,也就是你希望能活多长时间

velocity:粒子速度

velocityRange:粒子速度平均量

yAcceleration:Y方向上的加速分量,如果你希望向Y轴发射,则设置这个值>0

xAcceleration:X方向上的加速分量

zAcceleration:Z方向上的加速分量

scale:缩放比例

scaleRange:缩放比例范围

scaleSpeed:在生命周期内的缩放速度

contents:粒子的内容,可以通过这个属性设置寄宿图片

color:粒子的颜色

redRange:粒子红色值的范围

greenRange:粒子绿色值的范围

blueRange:粒子蓝色值的范围

alphaRange:粒子透明度的范围

通过emitterCells属性给CAEmitterLayer设置CAEmitterCell,是一个数组

colorBallLayer.emitterCells = @[colorBallCell];

二、通过粒子动画实现微信发送生日快乐落下蛋糕的动画

创建CAEmitterLayer

CAEmitterLayer *birthLayer = [CAEmitterLayer layer];

[self.view.layer addSublayer:birthLayer];

设置emitterSize,设置为整屏宽

birthLayer.emitterSize = CGSizeMake(**self**.view.frame.size.width, 0);

设置emitterShape,很明显发射源为上面的一条线形

birthLayer.emitterShape = kCAEmitterLayerLine;

设置emitterMode,从轮廓发射

birthLayer.emitterMode = kCAEmitterLayerOutline;

设置emitterPosition

birthLayer.emitterPosition = CGPointMake(self.view.frame.size.width / 2, -20);

创建CAEmitterCell,并设置属性

CAEmitterCell *cell = [CAEmitterCell emitterCell];

cell.birthRate = 2.0;

cell.lifetime = 10.f;

cell.velocity = 20.f;

cell.velocityRange = 30.f;

cell.yAcceleration = 50.f;

cell.scale = 0.3;

cell.emissionRange = 10;

cell.contents = (**id**)[UIImage imageNamed:@"dangao"].CGImage;

添加cell

birthLayer.emitterCells = @[cell];

三、通过粒子动画实现下面的点赞动效

菥菥菥-2021-10-10-15.14.gif

重写UIButton的initWithFrame方法,添加粒子

- (void)setupExplosion

{

    CAEmitterLayer *explosionLayer = [CAEmitterLayer layer];

    [self.layer addSublayer:explosionLayer];

    self.explosionLayer = explosionLayer;

    explosionLayer.emitterSize = CGSizeMake(self.bounds.size.width + 40, self.bounds.size.height + 40);

    explosionLayer.emitterShape = kCAEmitterLayerCircle;

    explosionLayer.emitterMode = kCAEmitterLayerOutline;

    explosionLayer.renderMode = kCAEmitterLayerOldestFirst;

    CAEmitterCell *explosionCell = [CAEmitterCell emitterCell];

    explosionCell.name = @"explosionCell";;

    explosionCell.alphaSpeed = -1.f;

    explosionCell.alphaRange = 0.1;

    //生命周期

    explosionCell.lifetime = 1;

    //生命周期range

    explosionCell.lifetimeRange = 0.1;

    //粒子速度

    explosionCell.velocity = 40.f;

    //粒子速度范围

    explosionCell.velocityRange = 10.f;

    //缩放比例

    explosionCell.scale = 0.08;

    //缩放比例range

    explosionCell.scaleRange = 0.02;

    //粒子图片

    explosionCell.contents = (id)[[UIImage imageNamed:@"spark_red"] CGImage];

    explosionLayer.emitterCells = @[explosionCell];

}

重写setSelected方法,添加缩放动画并设置粒子效果

- (void)setSelected:(**BOOL**)selected

{

    [super setSelected:selected];

    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];

    if (selected) {

        animation.values = @[@1.5,@2.0,@0.8,@1.0];

        animation.duration = 0.5;

        animation.calculationMode = kCAAnimationCubic;

        [self.layer addAnimation:animation forKey:nil];

        [self performSelector: @selector(startAnimation) withObject:nil afterDelay:0.25];

    } else {

        [self stopAnimation];

    }
}

- (void)startAnimation

{

    // 用KVC设置颗粒个数

    [self.explosionLayer setValue:@1000 forKeyPath:@"emitterCells.explosionCell.birthRate"];

    

    // 开始动画

    self.explosionLayer.beginTime = CACurrentMediaTime();

    

    // 延迟停止动画

    [self performSelector: @selector(stopAnimation) withObject:nil afterDelay:0.15];

}


- (void)stopAnimation

{

    // 用KVC设置颗粒个数

    [self.explosionLayer setValue:@0 forKeyPath:@"emitterCells.explosionCell.birthRate"];

    //移除动画

    [self.explosionLayer removeAllAnimations];

}