今天我们来看下CAEmitterLayer(粒子发生器)在开发中的使用
一、CAEmitterLayer 粒子发生器
1、CAEmitterLayer是CALayer的一个子类,和CAEmitterCell一起使用可以创造出多样的动画效果。
2、CAEmitterLayer主要用于实现基于Core Animation的粒子发生器系统。
3、在粒子系统中,CAEmitterLayer负责发射粒子(当然粒子也可以发射粒子),而这些所谓的粒子,就是CAEmitterCell,我们可以将CAEmitterLayer比作是CAEmitterCell的容器,它会按照你的设置来以不同的样式不断产生粒子,也就是CAEmitterCell。
4、CAEmitterLayer决定了粒子从什么样的几何特性上发射出来,这个几何特性包括了位置,形状,大小。另外还有一些渲染相关的特性。另外的一些属性是CAEmitterLayer和CAEmiiterCell都有的,CAEmitterLayer的这些属性会作为CAEmitterCell相同属性的系数。
例如当CAEmitterCell的lifetime(生命周期)为2,其所属CAEmitterLayer的lifetime为3时,在其它参数选择默认值的情况下,这个CAEmitterCell的生命周期就是2*3=6秒,6秒后,CAEmitterCell就会从粒子系统中被移除。
5、CAEmitterCell则决定了粒子自身的一些特征,例如速度,加速度,发射的范围,颜色等等。这些属性大多是以“中间值”配合一个范围值的方式来表示的。
例如velocity和velocityRange。表示CAEmitterCell的初始速度为velocity ± velocityRange。
二、CAEmitterLayer的属性
CAEmitterLayer类提供了一个粒子发射器系统为核心的动画。这些粒子是由CAEmitterCell组成的实例,它相当于一个管理者,来管理 CAEmitterCell的发射的一些细节,比如发射的位置,发射形状等等。
/*
@interface CAEmitterLayer : CALayer
--粒子的数组 把设置好的粒子放入数组设置到layer上
@property(nullable, copy) NSArray*emitterCells;
--粒子产生系数,默认1.0;每个cell的产生率乘以这个粒子产生系数,得出每一秒粒子的创建个数。 即:cell.birthRate 乘以 layer.birthRate =每秒粒子产生个数
@property float birthRate;
--粒子的生命周期系数,默认1.0 即:(cell.lifetime 乘以 layer.lifetime)等于粒子的生命周期
@property float lifetime;
--发射源中心点的位置 默认(0,0)
@property CGPoint emitterPosition;
--z轴上的位置
@property CGFloat emitterZPosition;
--是发射源的大小 并不是layer的大小
@property CGSize emitterSize;
--
@property CGFloat emitterDepth;
--发射源的形状 有圆形 方形 线型等 粒子从什么形状发射出来,它并不是表示粒子自己的形状。
kCAEmitterLayerPoints 点模式,发射器是以点的形势发射粒子。
kCAEmitterLayerOutline 轮廓,即边上 整个边框都是发射点,即边框进行发射
kCAEmitterLayerSurface 区域进行抛洒
kCAEmitterLayerVolume 容积,即3D图形的体积内
@property(copy) NSString *emitterShape;
--发散形式
kCAEmitterLayerPoint 点形状,发射源的形状就是一个点,
kCAEmitterLayerLine 线形状,发射源的形状是一条线,位置在rect的横向的位于垂直方向中间那条
kCAEmitterLayerRectangle 矩形状,发射源是一个矩形,
kCAEmitterLayerCuboid 立体矩形形状,发射源是一个立体矩形,这里要生效的话需要设置z方向的数据,如果不设置就同矩形状
kCAEmitterLayerCircle 圆形形状,发射源是一个圆形,形状为矩形包裹的那个圆,二维的
kCAEmitterLayerSphere 立体圆形,三维的圆形,同样需要设置z方向数据,不设置则通二维一样
@property(copy) NSString *emitterMode;
--描绘模式
kCAEmitterLayerUnordered 粒子是无序出现的,多个发射源将混合
kCAEmitterLayerOldestFirst 声明久的粒子会被渲染在最上层
kCAEmitterLayerOldestLast 年轻的粒子会被渲染在最上层
kCAEmitterLayerBackToFront 粒子的渲染按照Z轴的前后顺序进行
kCAEmitterLayerAdditive 进行粒子混合
@property(copy) NSString *renderMode;
--是否展示在z轴上的效果 把图层进行3d变形如沿y轴旋转90度 会有很明显的立体效果
@property BOOL preservesDepth;
--粒子速度系数, 默认1.0 发射速度 和cell的速度属性一起决定了粒子的速度 猜测粒子的速度是两者的乘积
而且和cell的速度属性不同 这个属性可以为负 (cell.velocity 乘以 layer.velocity)等于粒子的速度
为负的时候发散方向是向反方向的 为正时是向指定方向的
@property float velocity;
--粒子的缩放比例系数, 默认1.0 缩放大小 和速度相同 粒子的scale值是两者相乘 cell.scale 乘以 layer.scale)等于粒子的缩放比例
@property float scale;
-- 自旋转速度系数, 默认1.0 cell.spin 乘以 layer.spin)等于粒子的自旋转速度
@property float spin;
-- 随机数设置种子
@property unsigned int seed;
*/
三、CAEmitterCell部分属性
CAEmitterCell是粒子发射系统里的粒子,用CAEmitterCell来定义你所需要的粒子的样式,图片,颜色,方向,运动,缩放比例和生命周期等等。
/*
@interface CAEmitterCell : NSObject
--粒子的创建
+ (instancetype)emitterCell;
--根据键获得值
+ (nullable id)defaultValueForKey:(NSString *)key
--是否归档键值
- (BOOL)shouldArchiveValueForKey:(NSString *)key;
--粒子的名字,默认nil.
@property(nullable, copy) NSString *name;
--是否允许被绘制出来
@property(getter=isEnabled) BOOL enabled;
--生成速率默认0
@property float birthRate;
--生存周期以秒为单位。两者默认0
@property float lifetime;
--生存周期的绝对值的偏移量的最大值
@property float lifetimeRange;
--z轴方向上的发射角度纬度,纬度角代表了x-z轴平面上与x轴之间的夹角,两者默认0
@property CGFloat emissionLatitude;
--在xy平面上的发射角度经度,经度角代表了x-y轴平面上与x轴之间的夹角
@property CGFloat emissionLongitude;
--周围发射角度,默认0
@property CGFloat emissionRange;
--放射速度两者默认0
@property CGFloat velocity;
--速度偏移量
@property CGFloat velocityRange;
--在三个坐标轴上的速度增量可以做出类似重力风吹的效果默认0
@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;
--内容范围默认(0,0,1,1)
@property CGRect contentsRect;
--内容缩放
@property CGFloat contentsScale;
--渲染'内容'图像时使用的滤波器参数。
@property(copy) NSString *minificationFilter;
@property(copy) NSString *magnificationFilter;
@property float minificationFilterBias;
---粒子发射的粒子
@property(nullable, copy) NSArray *emitterCells;
@property(nullable, copy) NSDictionary *style;
*/
总结,我们可以emitterShape和emitterMode组合多种需要的效果图。
四、相关实例
1、仿造微信掉落表情效果图:
代码:
- (void)snowAnimation
{
CAEmitterLayer *snowEmitter = [CAEmitterLayer layer];
//降落区域的方位
snowEmitter.frame = self.view.bounds;
//添加到父视图Layer上
[self.view.layer addSublayer:snowEmitter];
//指定发射源的位置
snowEmitter.emitterPosition = CGPointMake(self.view.bounds.size.width / 2.0, -10);
//指定发射源的大小
snowEmitter.emitterSize = CGSizeMake(self.view.bounds.size.width, 0.0);
//指定发射源的形状和模式 层级
snowEmitter.emitterShape = kCAEmitterLayerLine;
snowEmitter.emitterMode = kCAEmitterLayerOutline;
snowEmitter.renderMode = kCAEmitterLayerOldestFirst;
//创建CAEmitterCell
CAEmitterCell *snowflake = [CAEmitterCell emitterCell];
//每秒多少个
snowflake.birthRate = 10.0;
//存活时间
snowflake.lifetime = 50.0;
//初速度,因为动画属于落体效果,所以我们只需要设置它在y方向上的加速度就行了。
snowflake.velocity = 10;
//初速度范围
snowflake.velocityRange = 5;
//y轴方向的加速度
snowflake.yAcceleration = 30;
//以锥形分布开的发射角度。角度用弧度制。粒子均匀分布在这个锥形范围内。
snowflake.emissionRange = 5;
//设置降落的图片
snowflake.contents = (id) [[UIImage imageNamed:@"love"] CGImage];
//图片缩放比例
snowflake.scale = 0.5;
//开始动画
snowEmitter.emitterCells = [NSArray arrayWithObject:snowflake];
}
2、烟花效果图
代码:
- (void)fireWorkAnimation{
_emitterLayer = [CAEmitterLayer layer];
//发射源
_emitterLayer.emitterPosition = CGPointMake(self.view.frame.size.width / 2.0, self.view.frame.size.height - 50);
//发射源尺寸大小
_emitterLayer.emitterSize = CGSizeMake(50, 0);
//发射源模式
_emitterLayer.emitterMode = kCAEmitterLayerOutline;
//发射源形状
_emitterLayer.emitterShape = kCAEmitterLayerLine;
//渲染模式
_emitterLayer.renderMode = kCAEmitterLayerAdditive;
//发射方向
_emitterLayer.velocity = 1;
//产生粒子数量
_emitterLayer.seed = (arc4random() % 100 ) + 1;
CAEmitterCell *cell = [CAEmitterCell emitterCell];
//产生的速lv
cell.birthRate = 1.0;
//发射角度
cell.emissionRange = 0.11 * M_PI;
//速度
cell.velocity = 300;
//范围
cell.velocityRange = 150;
//y 加速度
cell.yAcceleration = 75;
//存活时间
cell.lifetime = 2.04;
//cell 内容
cell.contents = (__bridge id _Nullable)([UIImage imageNamed:@"FFRing"].CGImage);
//缩放比例
cell.scale = 0.2;
//粒子颜色
cell.color = [[UIColor colorWithRed:0.6 green:0.6 blue:0.6 alpha:1.0] CGColor];
// 一个粒子的颜色green 能改变的范围
cell.greenRange = 1.0;
// 一个粒子的颜色red 能改变的范围
cell.redRange = 1.0;
// 一个粒子的颜色blue 能改变的范围
cell.blueRange = 1.0;
// 子旋转角度范围
cell.spinRange = M_PI;
// 爆炸
CAEmitterCell *burst = [CAEmitterCell emitterCell];
// 粒子产生系数
burst.birthRate = 1.0;
// 速度
burst.velocity = 0;
// 缩放比例
burst.scale = 2.5;
// shifting粒子red在生命周期内的改变速度
burst.redSpeed = -1.5;
// shifting粒子blue在生命周期内的改变速度
burst.blueSpeed = +1.5;
// shifting粒子green在生命周期内的改变速度
burst.greenSpeed = +1.0;
//生命周期
burst.lifetime = 0.35;
// 火花 and finally, the sparks
CAEmitterCell *spark = [CAEmitterCell emitterCell];
//粒子产生系数,默认为1.0
spark.birthRate = 400;
//速度
spark.velocity = 125;
// 360 deg//周围发射角度
spark.emissionRange = 2 * M_PI;
// gravity//y方向上的加速度分量
spark.yAcceleration = 75;
//粒子生命周期
spark.lifetime = 3;
//是个CGImageRef的对象,既粒子要展现的图片
spark.contents = (id)
[[UIImage imageNamed:@"FFTspark"] CGImage];
//缩放比例速度
spark.scaleSpeed = -0.2;
//粒子green在生命周期内的改变速度
spark.greenSpeed = -0.1;
//粒子red在生命周期内的改变速度
spark.redSpeed = 0.4;
//粒子blue在生命周期内的改变速度
spark.blueSpeed = -0.1;
//粒子透明度在生命周期内的改变速度
spark.alphaSpeed = -0.25;
//子旋转角度
spark.spin = 2* M_PI;
//子旋转角度范围
spark.spinRange = 2* M_PI;
self.emitterLayer.emitterCells = [NSArray arrayWithObject:cell];
cell.emitterCells = [NSArray arrayWithObjects:burst, nil];
burst.emitterCells = [NSArray arrayWithObject:spark];
[self.view.layer addSublayer:self.emitterLayer];
}
demo: Github