前言
最近正学到OpenGL ES如何实现粒子效果,使用苹果官方封装的CoreAnimation也能实现粒子效果,所以这篇文章实现一下抖音点赞,微信红包雨等一些常见的粒子效果。
什么是粒子效果?
-
粒子系统表示三维计算机图形学中模拟一些特定的模糊现象的技术,而这些现象用其它传统的渲染技术难以实现的真实感的游戏图形。经常使用粒子系统模拟的现象有火、爆炸、烟、水流、火花、落叶、云、雾、雪、尘、流星尾迹或者象发光轨迹这样的抽象视觉效果等等。
-
通常粒子系统在三维空间中的位置与运动是由发射器控制的。发射器主要由一组粒子行为参数以及在三维空间中的位置所表示。粒子行为参数可以包括粒子生成速度(即单位时间粒子生成的数目)、粒子初始速度向量(例如什么时候向什么方向运动)、粒子寿命(经过多长时间粒子湮灭)、粒子颜色、在粒子生命周期中的变化以及其它参数等等。使用大概值而不是绝对值的模糊参数占据全部或者绝大部分是很正常的,一些参数定义了中心值以及允许的变化。
-
典型的粒子系统更新循环可以划分为两个不同的阶段:参数更新/模拟阶段以及渲染阶段。每个循环执行每一帧动画。
在iOS 12后苹果推出了Metal框架,以下是CoreAnimation的从渲染到显示的示例图
![]()
![]()
了解CoreAnimation特殊图层

实现红包雨效果
CordeAnimation配置粒子,主要需要发射器和要发射的粒子。
以下代码就能实现简单的红包雨效果,这处只提供代码,由于比较简单,所以会详细的介绍后面的抖音点赞效果。
//1.设置CAEmitterLayer
CAEmitterLayer *rainLayer = [CAEmitterLayer layer];
//2.在背景图上添加粒子图层
[self.view.layer addSublayer:rainLayer];
self.rainLayer = rainLayer;
//3.发射形状--线性
rainLayer.emitterShape = kCAEmitterLayerLine;
rainLayer.emitterMode = kCAEmitterLayerSurface;
rainLayer.emitterSize = self.view.frame.size;
rainLayer.emitterPosition = CGPointMake(self.view.bounds.size.width * 0.5, -10);
//4.配置Cell
CAEmitterCell *snowCell = [CAEmitterCell emitterCell];
snowCell.contents = (id)[[UIImage imageNamed:@"zongzi2.jpg"] CGImage];
snowCell.birthRate = 1.0;
snowCell.lifetime = 30;
snowCell.speed = 2;
snowCell.velocity = 10.f;
snowCell.velocityRange = 10.f;
snowCell.yAcceleration = 60;
snowCell.scale = 0.05;
snowCell.scaleRange = 0.f;
//5.添加到图层上
rainLayer.emitterCells = @[snowCell];
这里演示一下效果

实现抖音点赞效果
这个点赞效果其实可以分解为两步,第一步是点赞按钮的放大动画,第二步是粒子的波纹扩散效果。看下图中的效果即可理解

1. 创建一个类继承UIButton,重写initWithFrame
-(instancetype)initWithFrame:(CGRect)frame{
if(self = [super initWithFrame:frame]){
[self setupExplosion];
}
return self;}
2. 设置粒子和发射源
设置粒子的相关参数,然后设置发射源,要通过设置值让这个发射源在外圈扩散,相关参数需要了解的话可以看苹果的官方文档的解释
-(void)setupExplosion{
//1.粒子
CAEmitterCell *explosionCell = [CAEmitterCell emitterCell];
explosionCell.name = @"explosionCell";
//透明值变化速度
explosionCell.alphaSpeed = -1.f;
//alphaRange透明值范围
explosionCell.alphaRange = 0.10;
//生命周期
explosionCell.lifetime = 1;
//生命周期range
explosionCell.lifetimeRange = 0.1;
//粒子速度
explosionCell.velocity = 40.f;
//粒子速度范围
explosionCell.velocityRange = 10.f;
//缩放比例
explosionCell.scale = 0.08;
//缩放比例范围
explosionCell.scaleRange = 0.02;
//粒子图片
explosionCell.contents = (id)[[UIImage imageNamed:@"spark_red"] CGImage];
// 2.发射源
CAEmitterLayer *explosionLayer = [CAEmitterLayer layer];
[self.layer addSublayer:explosionLayer];
self.explosionLayer = explosionLayer;
//发射源尺寸大小
self.explosionLayer.emitterSize = CGSizeMake(self.bounds.size.width + 40, self.bounds.size.height +40);
//emitterShape表示粒子从什么形状发射出来,圆形形状
explosionLayer.emitterShape = kCAEmitterLayerCircle;
//emitterMode发射模型,轮廓模式,从形状的边界上发射粒子
explosionLayer.emitterMode = kCAEmitterLayerOutline;
//renderMode:渲染模式
explosionLayer.renderMode = kCAEmitterLayerOldestFirst;
//粒子cell 数组
explosionLayer.emitterCells = @[explosionCell];
}
3.设置发射源的位置
-(void)layoutSubviews{
//发射源位置
self.explosionLayer.position = CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5);
[super layoutSubviews];
}
4.实现缩放效果
/**
* 选中状态 实现缩放
*/
- (void)setSelected:(BOOL)selected{
[super setSelected:selected];
//通过关键帧动画实现缩放
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
//设置动画路径
animation.keyPath = @"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];
}
}
5.开启动画和结束动画方法
/**
* 开始动画
*/
- (void)startAnimation{
//用KVC设置粒子数为1000
[self.explosionLayer setValue:@1000 forKeyPath:@"emitterCells.explosionCell.birthRate"];
//开始动画
self.explosionLayer.beginTime = CACurrentMediaTime();
//延迟停止动画
[self performSelector:@selector(stopAnimation) withObject:nil afterDelay:0.15];
}
/**
* 动画结束
*/
-(void)stopAnimation{
//设置粒子数为0
[self.explosionLayer setValue:@0 forKeyPath:@"emitterCells.explosionCell.birthRate"];
//移除动画
[self.explosionLayer removeAllAnimations];
}
总结
以上就是用苹果官方的CoreAnimation实现的两种粒子效果的实例,封装性很好,对于大部分的简单的粒子效果已经是够用了。当然,还可以使用GLSL语言自定义来实现粒子效果,自由度更高了,不过对于没接触过OpenGL ES的开发者来说太复杂,这里我提供以上两种效果的demo和使用GLSL语言实现的粒子效果的demo,如果有兴趣可以自行下载查看。
CoreAnimation粒子效果Demo
GLSL例子效果Demo
期待
-
文章若有些许帮助,请给个喜欢💛或评论; 若没啥帮助,请给点建议~
-
如果有疑问,请在文章底部评论指出,我会火速解决和修正问题。
网友评论