CAEmitterLayer 粒子动画

最近有点时间,研究了一下CAEmitterLayer粒子动画效果,分享出来,以备自己以后使用,先看一下基本的效果吧:

CAEmitterLayer.gif

首先,说一下CALayer 经常使用到的一些类

CALayer.png

然后说一下管理CALayer内容的几个函数

addSublayer: 添加子图层
removeFromSuperlayer将自己从父图层中移除
insertSublayer:atIndex:在自己子图层数组中的第idx位置添加图层
insertSublayer:above: 将图层layer添加在子图层的上面
insertSublayer:below: 将图层layer添加在子图层的下面
replaceSublayer:with: 将图层layer替换另一个layer

CALayer的动画操作

addAnimation:forKey: 增加某一属性的动画
animationForKey:获取某一属性的动画
removeAllAnimations移除所有动画
removeAnimationForKey:移除某一属性的动画
animationKeys获取所有的属性动画

CALayer就介绍到这里,想要了解更多的,请点我

今天主要介绍一下CAEmitterLayer
CAEmitterLayerCALayer的一个子类,CAEmitterLayer是用于实现基于Core Animation的粒子发生器系统,可以用来做一些酷炫的效果,比如我的demo里面的都是用CAEmitterLayer做的一些效果。

说道CAEmitterLayer,我们不得不提到的就是CAEmitterCell , 刚才我们说CAEmitterLayer是粒子发生器系统,那么CAEmitterCell就是我们具体发射的粒子了;粒子动画原理其实挺简单的,就是我们需要了解他的一些属性,做出一些效果来,比如红包雨这个动画,代码如下:

- (void)createRedPacketSuperView:(UIView *)superView {
    //设置EmitterLayer
    CAEmitterLayer *redPacketLayer = [CAEmitterLayer layer];
    [superView.layer addSublayer:redPacketLayer];
    self.emitterlayer = redPacketLayer;
    redPacketLayer.emitterShape = kCAEmitterLayerLine;// 发射源的形状
    redPacketLayer.emitterMode = kCAEmitterLayerSurface;//发射模式
    redPacketLayer.emitterSize = superView.frame.size;//发射源的size 决定了发射源的大小
    redPacketLayer.emitterPosition = CGPointMake(superView.frame.size.width * 0.5, superView.frame.origin.y);//发射源的位置
    redPacketLayer.birthRate = 0.0f; // 每秒产生的粒子数量的系数
    //配置EmitterCell
    CAEmitterCell *emitterCell = [CAEmitterCell emitterCell];
    NSString *path = [[NSBundle mainBundle] pathForResource:@"Emitter.bundle/red_packet.png" ofType:nil];
    NSData *data = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:path]];
    emitterCell.contents = (id)[[UIImage imageWithData:data] CGImage];// 粒子的内容 是CGImageRef类型
    emitterCell.birthRate = 10.0f;// 每秒产生的粒子数量
    emitterCell.lifetime = 20.0f;// 粒子的生命周期
    emitterCell.velocity = 8.f;  // 粒子的速度
    emitterCell.yAcceleration = 1000.f; // 粒子再y方向的加速的
    emitterCell.scale = 0.8f;  // 粒子的缩放比例
    
    redPacketLayer.emitterCells = @[emitterCell];
}

代码很简单,看CAEmitterLayerCAEmitterCell你会发现,这里面有好多相似的属性,你可能会迷糊,但是API说明的很清楚,CAEmitterLayer的这些属性会作为CAEmitterCell相同属性的系数,举个例子,如果CAEmitterCellbirthRate = 20(每秒产生的粒子数量),其所属的CAEmitterLayerbirthRate = 2,那么在其他参数默认的情况下,这个CAEmitterCell总的每秒产生的粒子数量是20 * 2 = 40 。也就是每秒会产生20个这样的粒子。

然后我们分别来说明一下他们的属性作用吧:
1、CAEmitterLayer

@property(nullable, copy) NSArray<CAEmitterCell *> *emitterCells; //存放例子
@property float birthRate; // 每秒产生的粒子数量的系数,默认为1/s
@property float lifetime;//粒子的生命周期系数,默认为1s
@property CGPoint emitterPosition;// 发射器在xy平面的中心位置
@property CGFloat emitterZPosition;//   发射器在Z平面的位置
@property CGSize emitterSize;// 发射器的尺寸大小
@property CGFloat emitterDepth;// 发射器的深度,在某些模式下会产生立体效果
@property(copy) CAEmitterLayerEmitterShape emitterShape;// 发射器的形状
@property(copy) CAEmitterLayerEmitterMode emitterMode;//  发射器的发射模式
@property(copy) CAEmitterLayerRenderMode renderMode;//   发射器渲染模式
@property BOOL preservesDepth; //是否开启三维空间效果
@property float velocity;//粒子的运动速度系数,默认为1
@property float scale;//粒子的缩放比例系数,默认为1
@property float spin;//粒子的旋转位置,默认为1
@property unsigned int seed;// 随机数发生器

这就是CAEmitterLayer的一些属性
其中emitterShape包括这几种


CA_EXTERN CAEmitterLayerEmitterShape const kCAEmitterLayerPoint
    API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//点的形状,粒子从一个点发出
CA_EXTERN CAEmitterLayerEmitterShape const kCAEmitterLayerLine
    API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//线的形状,粒子从一条线发出
CA_EXTERN CAEmitterLayerEmitterShape const kCAEmitterLayerRectangle
    API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//矩形形状,粒子从一个矩形中发出
CA_EXTERN CAEmitterLayerEmitterShape const kCAEmitterLayerCuboid
    API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//立方体形状,这里要生效的话需要设置z方向的数据,如果不设置就同矩形状
CA_EXTERN CAEmitterLayerEmitterShape const kCAEmitterLayerCircle
    API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//圆形,粒子会在圆形范围发射
CA_EXTERN CAEmitterLayerEmitterShape const kCAEmitterLayerSphere
    API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//立体圆形(3D),三维的圆形,同样需要设置z方向数据,不设置则通二维一样

emitterMode有这几种

CA_EXTERN CAEmitterLayerEmitterMode const kCAEmitterLayerPoints
    API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));////从发射器中发出
CA_EXTERN CAEmitterLayerEmitterMode const kCAEmitterLayerOutline
    API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));///从发射器边缘发出
CA_EXTERN CAEmitterLayerEmitterMode const kCAEmitterLayerSurface
    API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//从发射器表面发出
CA_EXTERN CAEmitterLayerEmitterMode const kCAEmitterLayerVolume
    API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//相对于3D形状的“球体内”或“立方体内”发射,从发射器中点发出

renderMode有这几种模式

CA_EXTERN CAEmitterLayerRenderMode const kCAEmitterLayerUnordered
    API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//粒子是无序出现的,多个发射源将混合
CA_EXTERN CAEmitterLayerRenderMode const kCAEmitterLayerOldestFirst
    API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//声明久的粒子会被渲染在最上层
CA_EXTERN CAEmitterLayerRenderMode const kCAEmitterLayerOldestLast
    API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//刚开始的粒子会被渲染在最上层
CA_EXTERN CAEmitterLayerRenderMode const kCAEmitterLayerBackToFront
    API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//粒子的渲染按照Z轴的前后顺序进行
CA_EXTERN CAEmitterLayerRenderMode const kCAEmitterLayerAdditive
    API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0));//这种模式会进行粒子混合

好了,这基本上就是CAEmitterLayer的所有属性了,然后我们说一下CAEmitterCell的属性、方法。

2、CAEmitterCell


+ (instancetype)emitterCell;//类方法创建发射粒子
+ (nullable id)defaultValueForKey:(NSString *)key;//获取某一属性的值
- (BOOL)shouldArchiveValueForKey:(NSString *)key;//返回指定的属性值是否可以归档。基本上不用
@property(nullable, copy) NSString *name;//设置发射粒子的名称
@property(getter=isEnabled) BOOL enabled;//是否允许发射粒子渲染
@property float birthRate;//发射粒子的产生率,默认0
@property float lifetime;//发射粒子的生命周期,以秒为单位。默认0
@property float lifetimeRange;//发射粒子的生命周期范围,以秒为单位。默认0
@property CGFloat emissionLatitude;//发射粒子的指定纬度,纬度角代表了在x-z轴平面坐标系中与x轴之间的夹角,也就是粒子在Z轴方向的发射角度,默认0
@property CGFloat emissionLongitude;//发射粒子的指定经度,经度角代表了在x-y轴平面坐标系中与x轴之间的夹角,也就是粒子在xy平面的发射角度,默认0:
@property CGFloat emissionRange;//发射粒子角度范围,默认0,以锥形分布开的发射角度。角度用弧度制。粒子均匀分布在这个锥形范围内;
@property CGFloat velocity;//发射粒子的速度 ,默认0
@property CGFloat velocityRange;//发射粒子的速度范围 ,默认0
@property CGFloat xAcceleration;//发射粒子x方向的加速度,默认0
@property CGFloat yAcceleration;//发射粒子y方向的加速度,默0
@property CGFloat zAcceleration;//发射粒子z方向的加速度,默认0
@property CGFloat scale;//发射粒子的缩放系数,默认1
@property CGFloat scaleRange;//发射粒子的缩放系数范围,默认0
@property CGFloat scaleSpeed;//发射粒子的缩放速度,默认0
@property CGFloat spin;//发射粒子的平均旋转速度,默认是0
@property CGFloat spinRange;//发射粒子的平均旋转速度范围,默认是0
@property(nullable) CGColorRef color;//发射粒子的颜色,默认白色
@property float redRange;//发射粒子红色的范围,默认0
@property float greenRange;//发射粒子绿色的范围,默认0
@property float blueRange;//发射粒子蓝色的范围,默认0
@property float alphaRange;//发射粒子透明度的范围,默认0
@property float redSpeed;//发射粒子红色的变化速度,默认0
@property float greenSpeed;//发射粒子绿色的变化速度,默认0
@property float blueSpeed;//发射粒子蓝色的变化速度,默认0
@property float alphaSpeed;//发射粒子透明度的变化速度,默认0
@property(nullable, strong) id contents;//发射的渲染粒子的内容,可以设置为一个CGImage的对象
@property CGRect contentsRect;//发射的渲染粒子内容的渲染范围
@property CGFloat contentsScale;//内容的缩放系数

//下面三个是拉伸过滤,没使用过,具体的话可以看看这篇文章:https://www.jianshu.com/p/ae216733eacc
@property(copy) NSString *minificationFilter;
@property(copy) NSString *magnificationFilter;
@property float minificationFilterBias;

@property(nullable, copy) NSArray<CAEmitterCell *> *emitterCells;// 粒子里面的包含的粒子
@property(nullable, copy) NSDictionary *style; //不知道干什么用的

基本上就是这些,更多的效果,需要我们自己去探索,了解了他们的一些参数就可以做出一些效果来了,最后再奉上自己的demo

希望大家能提出宝贵的意见,可以给我留言,也可以发邮件到我的邮箱:namezyqyx@163.com
谢谢大家,如果你有更好的想法或文章请告知,不胜感激。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,829评论 1 331
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,603评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,846评论 0 226
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,600评论 0 191
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,780评论 3 272
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,695评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,136评论 2 293
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,862评论 0 182
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,453评论 0 229
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,942评论 2 233
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,347评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,790评论 2 236
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,293评论 3 221
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,839评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,448评论 0 181
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,564评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,623评论 2 249

推荐阅读更多精彩内容

  • 1 CALayer IOS SDK详解之CALayer(一) http://doc.okbase.net/Hell...
    Kevin_Junbaozi阅读 4,968评论 3 23
  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌。在这里你可以看...
    F麦子阅读 4,982评论 5 13
  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥ios动画全貌。在这里你可以看...
    每天刷两次牙阅读 8,311评论 6 30
  • 想必以前QQ空间的点赞效果大家都知道吧,点赞之后按钮周围会有一圈爆裂的小圆点;还有微信的红包雨表情动画等,以及烟花...
    NotFunGuy阅读 8,921评论 5 52
  • 雨将下未下 空气沉闷炽热 水泥地面上涌动的热流 将双脚紧紧包裹 浓稠的的温度捂住我 喘不过气来 钢筋水泥的城市 柏...
    麦八月阅读 204评论 0 0