前言
在开发之前,我们要了解一下烟花从上升到爆炸的过程:
1. 设定烟花初始位置,爆炸位置,朝终点飞行
2. 受重力作用, 上升速度逐渐减慢
3. 烟花到达爆炸位置,爆炸散发出火花,烟花圆点消失
4. 火花以爆炸位置为圆心,向四周扩散,并且高度缓慢下降
5. 经过短暂时间,火花消失
由此,我们可以先列出主要对象和属性:
- 烟花
- 实时坐标:
(x, y)
- 颜色:
color
- 半径:
radius
- 携带爆炸火花:
booms
- 发生爆炸坐标:
boomPoint
- 是否已经爆炸:
dead
- 实时坐标:
- 火花
- 实时坐标:
(x, y)
- 爆炸圆心:
(centerX, centerY)
- 飞行目标坐标:
dieX, dieY
- 颜色:
color
- 半径:
radius
- 是否已经消失:
dead
- 实时坐标:
基本框架
const canvas = document.querySelector("#canvas")
const ctx = canvas.getContext("2d")
const _W = canvas.width = window.innerWidth
const _H = canvas.height = window.innerHeight
class FireWork {
constructor(x, radius, color, boomPoint) {
this.x = x
this.y = _W
this.radius = radius
this.color = color
this.booms = []
this.boomPoint = boomPoint
this.dead = false
}
}
class Spark {
constructor(centerX, centerY, radius, color, dieX, dieY) {
this.dieX = dieX;
this.dieY = dieY;
this.x = centerX;
this.y = centerY;
this.dead = false;
this.centerX = centerX;
this.centerY = centerY;
this.radius = radius;
this.color = color;
}
}
// 动画函数,实时清空画布并重新绘制
const animation = function () {
window.requestAnimationFrame(animation);
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 绘制...
};
animation()
烟花飞行
const random = function (min, max) {
return Math.random() * (max - min) + min
}
class FireWork {
constructor(x, radius, color, boomPoint) {
this.x = x
this.y = _W
this.radius = radius
this.color = color
this.booms = []
this.boomPoint = boomPoint
this.boomArea = random(60, 150) // 距离范围
this.dead = false
}
move() {
// 与爆炸位置的距离,逐渐变小
let dx = this.boomPoint.x - this.x
let dy = this.boomPoint.y - this.y
// 跟随距离改变上升速度,逐渐变慢
this.x = this.x + dx * 0.01
this.y = this.y + dy * 0.01
// 后期烟花移动速度过慢,故给一个距离范围,进入范围便爆炸
if (Math.abs(dx) <= this.boomArea && Math.abs(dy) <= this.boomArea) {
this.dead = true
}
}
draw() {
ctx.save()
ctx.beginPath()
ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI)
ctx.fillStyle = this.color
ctx.fill()
ctx.restore()
}
// 模拟烟花尾随特效
drawTail() {
ctx.save()
ctx.fillStyle = "rgba(186,186,86,0.3)"
ctx.beginPath()
ctx.arc(this.x, this.y, random(this.radius, this.radius + 4), 0, 2 * Math.PI)
ctx.fill()
ctx.restore(