iOS实现粒子发射动画效果图
代码已上传 GitHub:https://github.com/Silence-GitHub/CoreAnimationDemo
动画效果用 CAEmitterLayer 实现。CAEmitterLayer 显示粒子发射动画,具体的粒子由 CAEmitterCell 封装。代码示例是展示 CAEmitterLayer 如何使用。为了方便,直接在控制器(UIViewController)中设置 CAEmitterLayer。如果在项目中使用,有时在自定义视图(UIView)中加入 CAEmitterLayer 比较合理,例如自定义点赞按钮,可以精简控制器的代码。
下雨动画效果
这里的雨匀速下落,雨的密度逐渐变化。
给控制器添加类型为 CAEmitterLayer 的属性 rainLayer,在 viewDidLoad 方法中对此属性进行初始化
private var rainLayer: CAEmitterLayer!
private func setupRainLayer() {
// 粒子发射图层
rainLayer = CAEmitterLayer()
// 发射器形状为线形,默认发射方向向上
rainLayer.emitterShape = kCAEmitterLayerLine
// 从发射器的轮廓发射粒子
rainLayer.emitterMode = kCAEmitterLayerOutline
// 优先渲染旧的粒子
rainLayer.renderMode = kCAEmitterLayerOldestFirst
// 发射位置
// 对于线形发射器,线的两端点分别为
// (emitterPosition.x - emitterSize.width/2, emitterPosition.y, emitterZPosition)和
// (emitterPosition.x + emitterSize.width/2, emitterPosition.y, emitterZPosition)
rainLayer.emitterPosition = CGPoint(x: view.bounds.midX, y: 0)
// 发射器大小
rainLayer.emitterSize = CGSize(width: view.bounds.width, height: 0)
// 粒子生成速率的倍数,一开始不发射,设置为零
rainLayer.birthRate = 0
// 发射的粒子
let cell = CAEmitterCell()
// 粒子显示的内容,设置CGImage,显示图片
cell.contents = #imageLiteral(resourceName: "Heart_red").cgImage
// 粒子缩放倍数
cell.scale = 0.1
// 粒子寿命,单位是秒
cell.lifetime = 5
// 粒子生成速率,单位是个/秒,实际显示效果要乘以CAEmitterLayer的birthRate
cell.birthRate = 1000
// 粒子速度
cell.velocity = 500
// 粒子发射角度,正值表示顺时针方向
cell.emissionLongitude = CGFloat.pi
// 图层要发射1种粒子
rainLayer.emitterCells = [cell]
// 添加粒子发射图层
view.layer.addSublayer(rainLayer)
}
点击按钮开始或停止动画。用 CABasicAnimation 使粒子生成速率的倍数渐变,达到雨逐渐变大或变小的效果
@IBAction func rainButtonClicked(_ sender: UIButton) {
// 连续调用此方法会影响雨变大或变小的连贯性,所以禁止连续点击按钮
sender.isUserInteractionEnabled = false
// 粒子生成速率渐变动画
let birthRateAnimation = CABasicAnimation(keyPath: "birthRate")
birthRateAnimation.duration = 3
if rainLayer.birthRate == 0 {
// 雨变大
birthRateAnimation.fromValue = 0
birthRateAnimation.toValue = 1
rainLayer.birthRate = 1
} else {
// 雨变小
birthRateAnimation.fromValue = 1
birthRateAnimation.toValue = 0
rainLayer.birthRate = 0
}
// 加入动画
rainLayer.add(birthRateAnimation, forKey: "birthRate")
// 动画时长过后恢复按钮可点击状态
DispatchQueue.main.asyncAfter(deadline: .now() + birthRateAnimation.duration) { [weak self] in
guard self != nil else { return }
sender.isUserInteractionEnabled = true
}
}
发射一圈粒子动画效果
给控制器添加类型为 CAEmitterLayer 的属性 centerHeartLayer,在 viewDidLoad 方法中对此属性进行初始化
private var centerHeartLayer: CAEmitterLayer!
private func setupCenterHeartLayer() {
centerHeartLayer = CAEmitterLayer()
// 发射器形状为圆形,默认向四周发射粒子
centerHeartLayer.emitterShape = kCAEmitterLayerCircle
centerHeartLayer.emitterMode = kCAEmitterLayerOutline
centerHeartLayer.renderMode = kCAEmitterLayerOldestFirst
// 发射器位置
// 对于圆形发射器
// 圆心位于(emitterPosition.x, emitterPosition.y, emitterZPosition)
// 半径为emitterSize.width
centerHeartLayer.emitterPosition = CGPoint(x: view.bounds.midX, y: view.bounds.midY)
centerHeartLayer.emitterSize = centerHeartButton.frame.size
centerHeartLayer.birthRate = 0
let cell = CAEmitterCell()
cell.contents = #imageLiteral(resourceName: "Heart_red").cgImage
cell.lifetime = 1
cell.birthRate = 2000
cell.scale = 0.05
// 粒子缩放倍数每秒减小0.02,粒子逐渐缩小
cell.scaleSpeed = -0.02
// 粒子透明度每秒减小1,粒子逐渐变透明
cell.alphaSpeed = -1
cell.velocity = 30
centerHeartLayer.emitterCells = [cell]
view.layer.addSublayer(centerHeartLayer)
}
点击按钮开始动画
@IBAction func centerHeartButtonClicked(_ sender: UIButton) {
sender.isUserInteractionEnabled = false
// 设置动画开始时间,否则会有太多粒子
centerHeartLayer.beginTime = CACurrentMediaTime()
// 开始生成粒子
centerHeartLayer.birthRate = 1
// 一段时间后停止生成粒子
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
guard let strongSelf = self else { return }
strongSelf.centerHeartLayer.birthRate = 0
}
DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in
guard self != nil else { return }
sender.isUserInteractionEnabled = true
}
}
向上发射一个粒子动画效果
给控制器添加类型为 CAEmitterLayer 的属性 leftHeartLayer,在 viewDidLoad 方法中对此属性进行初始化
private var leftHeartLayer: CAEmitterLayer!
private func setupLeftHeartLayer() {
leftHeartLayer = CAEmitterLayer()
// 点状发射器,默认发射方向向右
// 这句可以省略,点状是默认值
leftHeartLayer.emitterShape = kCAEmitterLayerPoint
// 从发射器中的一点发射粒子
// 这句可以省略,是默认值
leftHeartLayer.emitterMode = kCAEmitterLayerVolume
leftHeartLayer.renderMode = kCAEmitterLayerOldestFirst
// 发射器位置
// 对于点状发射器,发射点在(emitterPosition.x, emitterPosition.y, emitterZPosition)
leftHeartLayer.emitterPosition = CGPoint(x: view.bounds.midX * 0.5, y: view.bounds.midY)
leftHeartLayer.birthRate = 0
let cell = CAEmitterCell()
cell.contents = #imageLiteral(resourceName: "Heart_red").cgImage
cell.scale = 0.5
cell.lifetime = 1
// 1秒发射1个粒子
cell.birthRate = 1
cell.alphaSpeed = -1
cell.velocity = 50
cell.emissionLongitude = -CGFloat.pi / 2
leftHeartLayer.emitterCells = [cell]
view.layer.addSublayer(leftHeartLayer)
}
点击按钮开始动画
@IBAction func leftHeartButtonClicked(_ sender: UIButton) {
sender.isUserInteractionEnabled = false
// 从上1秒开始动画,使按钮点击后立即发射粒子
leftHeartLayer.beginTime = CACurrentMediaTime() - 1
leftHeartLayer.birthRate = 1
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
guard let strongSelf = self else { return }
strongSelf.leftHeartLayer.birthRate = 0
}
DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in
guard self != nil else { return }
sender.isUserInteractionEnabled = true
}
}
向上发射几个粒子动画效果
给控制器添加类型为 CAEmitterLayer 的属性 rightHeartLayer,在 viewDidLoad 方法中对此属性进行初始化
private var rightHeartLayer: CAEmitterLayer!
private func setupRightHeartLayer() {
rightHeartLayer = CAEmitterLayer()
rightHeartLayer.renderMode = kCAEmitterLayerOldestFirst
rightHeartLayer.emitterPosition = CGPoint(x: view.bounds.midX * 1.5, y: view.bounds.midY)
rightHeartLayer.birthRate = 0
let cell = CAEmitterCell()
cell.contents = #imageLiteral(resourceName: "Heart_red").cgImage
cell.scale = 0.5
cell.lifetime = 1
cell.birthRate = 5
cell.alphaSpeed = -1
cell.velocity = 50
cell.emissionLongitude = -CGFloat.pi / 2
// 粒子发射角度的变化范围
cell.emissionRange = CGFloat.pi / 4
rightHeartLayer.emitterCells = [cell]
view.layer.addSublayer(rightHeartLayer)
}
点击按钮开始动画
@IBAction func rightHeartButtonClicked(_ sender: UIButton) {
sender.isUserInteractionEnabled = false
// 1秒发射5个粒子,0.2秒发射1个粒子,从上0.2秒开始动画,使按钮点击后立即发射粒子
rightHeartLayer.beginTime = CACurrentMediaTime() - 0.2
rightHeartLayer.birthRate = 1
DispatchQueue.main.asyncAfter(deadline: .now() + 0.8) { [weak self] in
guard let strongSelf = self else { return }
strongSelf.rightHeartLayer.birthRate = 0
}
DispatchQueue.main.asyncAfter(deadline: .now() + 1.6) { [weak self] in
guard self != nil else { return }
sender.isUserInteractionEnabled = true
}
}
抛物线粒子动画效果
实现抛物线动画需要给粒子加上重力加速度。此外,这里还加入粒子旋转效果,同时发射两种粒子。
给控制器添加类型为 CAEmitterLayer 的属性 gravityLayer,在 viewDidLoad 方法中对此属性进行初始化
private var gravityLayer: CAEmitterLayer!
private func setupGravityLayer() {
gravityLayer = CAEmitterLayer()
gravityLayer.renderMode = kCAEmitterLayerOldestFirst
gravityLayer.emitterPosition = CGPoint(x: 0, y: view.bounds.maxY)
gravityLayer.birthRate = 0
let cell = CAEmitterCell()
cell.contents = #imageLiteral(resourceName: "Heart_red").cgImage
cell.scale = 0.5
cell.lifetime = 10
cell.alphaSpeed = -0.1
cell.birthRate = 10
cell.velocity = 100
// y轴方法的加速度,模拟重力加速度
cell.yAcceleration = 20
cell.emissionLongitude = -CGFloat.pi / 4
cell.emissionRange = CGFloat.pi / 4
// 粒子旋转角速度,单位是弧度/秒,正值表示顺时针旋转
// 这句可以省略,默认值是零
cell.spin = 0
// 粒子旋转角速度变化范围
cell.spinRange = CGFloat.pi * 2
let cell2 = CAEmitterCell()
cell2.contents = #imageLiteral(resourceName: "Heart_blue").cgImage
cell2.scale = 0.3
cell2.lifetime = 20
cell2.alphaSpeed = -0.05
cell2.birthRate = 5
cell2.velocity = 135
cell2.yAcceleration = 20
cell2.emissionLongitude = -CGFloat.pi / 4
cell2.emissionRange = CGFloat.pi / 4
cell2.spin = 0
cell2.spinRange = CGFloat.pi * 2
// 图层要发射2种粒子
gravityLayer.emitterCells = [cell, cell2]
view.layer.addSublayer(gravityLayer)
}
点击开始或停止动画
@IBAction func gravityButtonClicked(_ sender: UIButton) {
if gravityLayer.birthRate == 0 {
gravityLayer.beginTime = CACurrentMediaTime()
gravityLayer.birthRate = 1
} else {
gravityLayer.birthRate = 0
}
}
以上是动画的实现方法,代码已上传 GitHub:https://github.com/Silence-GitHub/CoreAnimationDemo
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# iOS
# CAEmitterLayer
# 粒子发射
# iOS实现自定义起始时间选择器视图
# iOS中 UIActionSheet字体的修改
# IOS 获取网络图片大小实例详解
# IOS中UIWebView、WKWebView之JS交互
# IOS打开照相机与本地相册选择图片实例详解
# 图层
# 对此
# 重力加速度
# 这句
# 变大
# 默认值
# 自定义
# 上传
# 几个
# 是个
# 会有
# 太多
# 两种
# 分别为
# 如何使用
# 时长
# 大家多多
# 为零
# 显示效果
# 顺时针
相关文章:
韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南
小视频制作网站有哪些,有什么看国内小视频的网站,求推荐?
如何高效配置IIS服务器搭建网站?
合肥做个网站多少钱,合肥本地有没有比较靠谱的交友平台?
如何彻底卸载建站之星软件?
自助网站制作软件,个人如何自助建网站?
建站之星上传入口如何快速找到?
桂林网站制作公司有哪些,桂林马拉松怎么报名?
西安市网站制作公司,哪个相亲网站比较好?西安比较好的相亲网站?
如何有效防御Web建站篡改攻击?
如何高效利用亚马逊云主机搭建企业网站?
山东云建站价格为何差异显著?
建站之星如何取消后台验证码生成?
建站VPS配置与SEO优化指南:关键词排名提升策略
北京专业网站制作设计师招聘,北京白云观官方网站?
建站之星伪静态规则如何正确配置?
非常酷的网站设计制作软件,酷培ai教育官方网站?
高端建站三要素:定制模板、企业官网与响应式设计优化
企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?
购物网站制作公司有哪些,哪个购物网站比较好?
道歉网站制作流程,世纪佳缘致歉小吴事件,相亲网站身份信息伪造该如何稽查?
昆明高端网站制作公司,昆明公租房申请网上登录入口?
网站制作的步骤包括,正确网址格式怎么写?
如何优化Golang Web性能_Golang HTTP服务器性能提升方法
网站制作软件免费下载安装,有哪些免费下载的软件网站?
如何确保FTP站点访问权限与数据传输安全?
建站之星代理如何获取技术支持?
如何在IIS服务器上快速部署高效网站?
无锡制作网站公司有哪些,无锡优八网络科技有限公司介绍?
如何通过WDCP绑定主域名及创建子域名站点?
韩国服务器如何优化跨境访问实现高效连接?
公司网站设计制作厂家,怎么创建自己的一个网站?
个人摄影网站制作流程,摄影爱好者都去什么网站?
定制建站流程解析:需求评估与SEO优化功能开发指南
图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?
如何用低价快速搭建高质量网站?
c++怎么实现高并发下的无锁队列_c++ std::atomic原子变量与CAS操作【详解】
如何配置IIS站点权限与局域网访问?
制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?
天河区网站制作公司,广州天河区如何办理身份证?需要什么资料有预约的网站吗?
如何用PHP工具快速搭建高效网站?
如何高效配置香港服务器实现快速建站?
制作销售网站教学视频,销售网站有哪些?
宝塔建站助手安装配置与建站模板使用全流程解析
香港服务器租用每月最低只需15元?
新网站制作渠道有哪些,跪求一个无线渠道比较强的小说网站,我要发表小说?
Android使用GridView实现日历的简单功能
建站之星如何保障用户数据免受黑客入侵?
实惠建站价格推荐:2025年高性价比自助建站套餐解析
建站之星会员如何解锁更多建站功能?
*请认真填写需求信息,我们会在24小时内与您取得联系。