

🌈个人主页: 鑫宝Code
🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础
💫个人格言: "如无必要,勿增实体"
闲谈
大家回家过年可能都多多少少放过些🧨,但是有些在城市上过年的小伙伴可能就没有机会放鞭炮了。不过没关系,我们懂技术,我们用技术自娱自乐,放电子烟花,总不可能被警长叔叔敲门问候吧。


开干
首先,我们先明确一下思路,我觉得可以分解为如下2
个步骤。涉及到Canvas
+requestAnimationFrame
+物理知识
,🐶。
- 我们先画出一个烟花爆炸出来的粒子,这涉及到技术
Canvas
+物理知识
- 最后通过动画将多个粒子的运动轨迹连在一起即可。
大家看下,我感觉应该没什么问题了,于是深入细节分析。
初始化粒子
我们先分析一下这个粒子有哪些属性,我罗列如下
- 粒子的初始坐标(
x
,y
) - 粒子的初始速度(
Vx
,Vy
) - 粒子的颜色(
Color
) - 粒子的半径(
Radius
) - 粒子的透明度,随着粒子的落下,粒子的亮度会逐渐减小(
opacity
)
属性分析完了,接下来我们思考一个问题,粒子在爆炸那一刹那,是如何运动的呢?
很显然,是带着初速度的自由落体运动。
我们将速度分成水平方向Vx
以及竖直方向Vy
,于是我们可以得到
Vx
在运动中是不变的Vy
的速度为Vy = Vy - gt
,也就是每秒会速度下降g
,由于g
是个定值,在模拟的时候我们就取每帧(屏幕刷新率,大概10ms
一次)下降0.15px
速度。
注意:
Vy
的速度在代码里是Vy += 0.15
,为什么是加呢,因为对于屏幕而言,右上角的px是(0,0),所以想下的速度是正,向上的速度是负。
于是我们便可撰写如下代码
class Dot {
constructor(x, y, color, Vx, Vy) {
this.x = x;
this.y = y;
this.Vx = Vx;
this.Vy = Vy;
this.color = color;
this.radius = 2.5;
this.opacity = 1;
}
update() {
// 每一帧x和y轴移动的距离
this.x += this.Vx;
this.y += this.Vy;
// 每一帧速度变化
this.Vy += 0.15;
// 每一帧清晰度较小
this.opacity = this.opacity - 0.01;
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = this.color;
ctx.globalAlpha = this.opacity;
ctx.fill();
}
}
粒子聚合成烟花
如何将粒子聚合成烟花呢,我们声明一个烟花类即可。对于一个烟花,我们只需要知道这个研发爆炸在什么位置就可以了,也就是x
和y
的坐标。
- 粒子的颜色? 为了让粒子的颜色更加饱和一点,我们采用的是
HSL
颜色,跟RGB
和HEX
记录颜色不同,这个是用色相、饱和度和明度(HSL)来指定颜色。这里我们采用的代码为
// 是JavaScript中动态生成一个随机色相、饱和度为100%、亮度为50%的HSL颜色值。
const color = `hsl(${
Math