关于CAEmitterLayer和CAEmitterCell结合使用

今天我们来看下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、仿造微信掉落表情效果图:

关于CAEmitterLayer和CAEmitterCell结合使用_第1张图片
snow.gif

代码:

- (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、烟花效果图

关于CAEmitterLayer和CAEmitterCell结合使用_第2张图片
yanhua.gif

代码:

- (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

你可能感兴趣的:(关于CAEmitterLayer和CAEmitterCell结合使用)