天之道创业网 发表于 2024-10-28 00:00:00

【炫酷!在你的网页上来场烟花秀吧!】(附源码)

<p></p>
<p>技术揭秘</p>
<p>在HTML5中,&lt;canvas&gt;元素为我们提供了一个强大的绘图平台,允许我们通过JavaScript进行绘画。烟花表演,本质上就是这种绘图技术的运用。以下是实现烟花效果的简要步骤:</p>
<p>初始化画布:设置画布尺寸,确保画布能够适应不同的屏幕大小。</p>
<p>定义烟花行为:通过编写JavaScript函数来定义烟花的运动轨迹、颜色和消失方式。</p>
<p>绘制烟花:使用路径(Path)和填充(fill)命令在画布上绘制圆形,模拟烟花的爆炸效果。</p>
<p>动画循环:通过requestAnimationFrame实现动画循环,不断地更新和重绘烟花的位置和状态。</p>
<p>1、创建一个 index.html 复制以下代码</p>
<p>&nbsp;&lt;!DOCTYPE html&gt;</p>
<p>&lt;html lang="en"&gt;</p>
<p>&lt;head&gt;</p>
<p>&nbsp; &lt;meta charset="UTF-8"&gt;</p>
<p>&nbsp; &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;</p>
<p>&nbsp; &lt;title&gt;烟花&lt;/title&gt;</p>
<p>&lt;/head&gt;</p>
<p>&lt;style&gt;</p>
<p>&nbsp; body {</p>
<p>&nbsp; &nbsp; margin: 0;</p>
<p>&nbsp; &nbsp; padding: 0;</p>
<p>&nbsp; &nbsp; overflow: hidden;</p>
<p>&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp; .canvasBox {</p>
<p>&nbsp; &nbsp; width: 100%;</p>
<p>&nbsp; &nbsp; height: 100%;</p>
<p>&nbsp; &nbsp; display: flex;</p>
<p>&nbsp; &nbsp; justify-content: center;</p>
<p>&nbsp; &nbsp; align-items: center;</p>
<p>&nbsp; }</p>
<p>&nbsp; canvas {</p>
<p>&nbsp; &nbsp; border: 1px solid;</p>
<p>&nbsp; &nbsp; background-color: #000;</p>
<p>&nbsp; }</p>
<p>&lt;/style&gt;</p>
<p>&nbsp;</p>
<p>&lt;body&gt;</p>
<p>&nbsp; &lt;div class="canvasBox"&gt;</p>
<p>&nbsp; &nbsp; &lt;canvas id="canvas"&gt;&lt;/canvas&gt;</p>
<p>&nbsp; &lt;/div&gt;</p>
<p>&lt;/body&gt;</p>
<p>&nbsp;</p>
<p>&lt;/html&gt;</p>
<p>&lt;script src="./index.js"&gt;&lt;/script&gt;</p>
<p>&lt;script&gt;</p>
<p>&nbsp; const canvas = document.getElementById('canvas')</p>
<p>&nbsp; const canvasWidth = document.documentElement.clientWidth || document.body.clientWidth</p>
<p>&nbsp; const canvasHeight = document.documentElement.clientHeight || document.body.clientHeight</p>
<p>&nbsp; const ratio = Math.max(window.devicePixelRatio, 2)</p>
<p>&nbsp; canvas.width = canvasWidth * ratio</p>
<p>&nbsp; canvas.height = canvasHeight * ratio</p>
<p>&nbsp; canvas.style.width = canvasWidth + 'px'</p>
<p>&nbsp; canvas.style.height = canvasHeight + 'px'</p>
<p>&nbsp;</p>
<p>&nbsp; const ctx = canvas.getContext('2d')</p>
<p>&nbsp; ctx.scale(ratio, ratio)</p>
<p>&nbsp;</p>
<p>&nbsp; const getRandom = (min, max) =&gt; {</p>
<p>&nbsp; &nbsp; return Math.random() * (max - min) + min</p>
<p>&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp; const drawCircle = ({ opacity = 1, x, y, radius, color }) =&gt; {</p>
<p>&nbsp; &nbsp; ctx.save()</p>
<p>&nbsp; &nbsp; ctx.globalAlpha = opacity</p>
<p>&nbsp; &nbsp; ctx.beginPath()</p>
<p>&nbsp; &nbsp; ctx.arc(x, y, radius, 0, Math.PI * 2)</p>
<p>&nbsp; &nbsp; ctx.fillStyle = color</p>
<p>&nbsp; &nbsp; ctx.fill()</p>
<p>&nbsp; &nbsp; ctx.restore()</p>
<p>&nbsp; }</p>
<p>&nbsp; const deleteFromList = (list, target) =&gt; {</p>
<p>&nbsp; &nbsp; const index = list.findIndex(item =&gt; {</p>
<p>&nbsp; &nbsp; &nbsp; return item === target</p>
<p>&nbsp; &nbsp; })</p>
<p>&nbsp; &nbsp; list.splice(index, 1)</p>
<p>&nbsp; }</p>
<p>&nbsp; // 动画循环</p>
<p>&nbsp; // 烟花列表</p>
<p>&nbsp; const fireworkList = []</p>
<p>&nbsp; const draw = () =&gt; {</p>
<p>&nbsp; &nbsp; // 使用半透明清空画布,形成拖尾效果</p>
<p>&nbsp; &nbsp; ctx.fillStyle = 'rgba(0,0,0,0.3)'</p>
<p>&nbsp; &nbsp; ctx.fillRect(0, 0, canvasWidth, canvasHeight)</p>
<p>&nbsp;</p>
<p>&nbsp; &nbsp; ctx.save()</p>
<p>&nbsp;</p>
<p>&nbsp; &nbsp; // 修改坐标系</p>
<p>&nbsp; &nbsp; ctx.translate(0, canvasHeight)</p>
<p>&nbsp; &nbsp; ctx.scale(1, -1)</p>
<p>&nbsp;</p>
<p>&nbsp; &nbsp; const list = [...fireworkList]</p>
<p>&nbsp; &nbsp; list.forEach(firework =&gt; {</p>
<p>&nbsp; &nbsp; &nbsp; firework.update()</p>
<p>&nbsp; &nbsp; &nbsp; if (firework.isEnd()) {</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; deleteFromList(fireworkList, firework)</p>
<p>&nbsp; &nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; })</p>
<p>&nbsp;</p>
<p>&nbsp; &nbsp; ctx.restore()</p>
<p>&nbsp;</p>
<p>&nbsp; &nbsp; requestAnimationFrame(draw)</p>
<p>&nbsp; }</p>
<p>&nbsp; draw()</p>
<p>&nbsp;</p>
<p>&nbsp; // 烟花颜色列表</p>
<p>&nbsp; const createFireworkColor = () =&gt; {</p>
<p>&nbsp; &nbsp; const colorList = [</p>
<p>&nbsp; &nbsp; &nbsp; '#ff0043',</p>
<p>&nbsp; &nbsp; &nbsp; '#14fc56',</p>
<p>&nbsp; &nbsp; &nbsp; '#1e7fff',</p>
<p>&nbsp; &nbsp; &nbsp; '#e60aff',</p>
<p>&nbsp; &nbsp; &nbsp; '#ffbf36',</p>
<p>&nbsp; &nbsp; &nbsp; '#ffffff'</p>
<p>&nbsp; &nbsp; ]</p>
<p>&nbsp; &nbsp; return colorList</p>
<p>&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp; // 发射烟花</p>
<p>&nbsp; canvas.addEventListener('click', () =&gt; {</p>
<p>&nbsp; &nbsp; const firework = new Firework(</p>
<p>&nbsp;</p>
<p>{</p>
<p>&nbsp; &nbsp; &nbsp; color: createFireworkColor()</p>
<p>&nbsp; &nbsp; })</p>
<p>&nbsp; &nbsp; fireworkList.push(firework)</p>
<p>&nbsp; &nbsp; firework.launch()</p>
<p>&nbsp; })</p>
<p>&nbsp;</p>
<p>&lt;/script&gt;</p>
<p>2、创建一个 index.js 复制以下代码</p>
<p>&nbsp;</p>
<p>&nbsp;// 爆炸碎片类</p>
<p>class ExplosiveDebris {</p>
<p>&nbsp; constructor(opt) {</p>
<p>&nbsp; &nbsp; this.firework = opt.firework</p>
<p>&nbsp; &nbsp; this.x = opt.x</p>
<p>&nbsp; &nbsp; this.y = opt.y</p>
<p>&nbsp; &nbsp; this.color = Math.random() &gt; 0.2 ? opt.color : '#fff'</p>
<p>&nbsp; &nbsp; this.radius = opt.radius || 2</p>
<p>&nbsp; &nbsp; this.angle = getRandom(0, 2 * Math.PI)</p>
<p>&nbsp; &nbsp; this.speed = opt.speed || getRandom(0.1, 4)</p>
<p>&nbsp; &nbsp; this.vx = Math.cos(this.angle) * this.speed</p>
<p>&nbsp; &nbsp; this.vy = Math.sin(this.angle) * this.speed</p>
<p>&nbsp; &nbsp; this.g = opt.g || 0.98</p>
<p>&nbsp; &nbsp; this.time = getRandom(0.5, 1)</p>
<p>&nbsp; &nbsp; this.startTime = 0</p>
<p>&nbsp; &nbsp; // 痕迹碎片数量</p>
<p>&nbsp; &nbsp; this.debrisCount = opt.debrisCount || 3</p>
<p>&nbsp; &nbsp; // 是否要进行二次爆炸</p>
<p>&nbsp; &nbsp; this.secondBurst = opt.secondBurst || false</p>
<p>&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp; start() {</p>
<p>&nbsp; &nbsp; this.startTime = Date.now()</p>
<p>&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp; update() {</p>
<p>&nbsp; &nbsp; const duration = (Date.now() - this.startTime) / 1000</p>
<p>&nbsp; &nbsp; const vy = this.vy - this.g * duration</p>
<p>&nbsp; &nbsp; this.x += this.vx</p>
<p>&nbsp; &nbsp; this.y += vy</p>
<p>&nbsp; &nbsp; const progress = duration / this.time</p>
<p>&nbsp; &nbsp; let opacity = progress &gt; 0.7 ? 1 - 1 * progress : 1</p>
<p>&nbsp; &nbsp; if (opacity &lt; 0) opacity = 0</p>
<p>&nbsp; &nbsp; drawCircle({</p>
<p>&nbsp; &nbsp; &nbsp; x: this.x,</p>
<p>&nbsp; &nbsp; &nbsp; y: this.y,</p>
<p>&nbsp; &nbsp; &nbsp; color: this.color,</p>
<p>&nbsp; &nbsp; &nbsp; radius: this.radius,</p>
<p>&nbsp; &nbsp; &nbsp; opacity: opacity</p>
<p>&nbsp; &nbsp; })</p>
<p>&nbsp; &nbsp; // 添加痕迹碎片</p>
<p>&nbsp; &nbsp; if (this.debrisCount &gt; 0 &amp;&amp; Math.random() &gt; 0.8) {</p>
<p>&nbsp; &nbsp; &nbsp; this.debrisCount--</p>
<p>&nbsp; &nbsp; &nbsp; this.firework.addDebris({</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; x: this.x + getRandom(-2, 2),</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; y: this.y + getRandom(-2, 2),</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; color: this.color,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; radius: 0.5,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; g: 0.1</p>
<p>&nbsp; &nbsp; &nbsp; })</p>
<p>&nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; return {</p>
<p>&nbsp; &nbsp; &nbsp; x: this.x,</p>
<p>&nbsp; &nbsp; &nbsp; y: this.y,</p>
<p>&nbsp; &nbsp; &nbsp; isEnd: progress &gt;= 1</p>
<p>&nbsp; &nbsp; }</p>
<p>&nbsp; }</p>
<p>}</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>// 爆炸器类</p>
<p>class Explosive {</p>
<p>&nbsp; constructor(opt) {</p>
<p>&nbsp; &nbsp; this.firework = opt.firework</p>
<p>&nbsp; &nbsp; this.x = opt.x</p>
<p>&nbsp; &nbsp; this.y = opt.y</p>
<p>&nbsp; &nbsp; this.color = opt.color</p>
<p>&nbsp; &nbsp; // 爆炸碎片列表</p>
<p>&nbsp; &nbsp; this.debrisList = []</p>
<p>&nbsp; &nbsp; // 爆炸碎片数量</p>
<p>&nbsp; &nbsp; this.debrisNum = opt.debrisNum || getRandom(50, 400)</p>
<p>&nbsp; &nbsp; // 是否要二次爆炸</p>
<p>&nbsp; &nbsp; this.secondBurst = opt.secondBurst || this.debrisNum &lt;= 100</p>
<p>&nbsp; &nbsp; //是否是第一次爆炸</p>
<p>&nbsp; &nbsp; this.isFirstBurst = true</p>
<p>&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp; start(debrisNum, opt = {}) {</p>
<p>&nbsp; &nbsp; const num = debrisNum || this.debrisNum</p>
<p>&nbsp; &nbsp; opt.x = opt.x || this.x</p>
<p>&nbsp; &nbsp; opt.y = opt.y || this.y</p>
<p>&nbsp; &nbsp; opt.secondBurst = this.secondBurst &amp;&amp; this.isFirstBurst</p>
<p>&nbsp; &nbsp; for (let i = 0; i &lt; num; i++) {</p>
<p>&nbsp; &nbsp; &nbsp; const explosiveDebris = new ExplosiveDebris({</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; firework: this.firework,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; color: this.color,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; ...opt</p>
<p>&nbsp; &nbsp; &nbsp; })</p>
<p>&nbsp; &nbsp; &nbsp; explosiveDebris.start()</p>
<p>&nbsp; &nbsp; &nbsp; this.debrisList.push(explosiveDebris)</p>
<p>&nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; this.isFirstBurst = false</p>
<p>&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp; update() {</p>
<p>&nbsp; &nbsp; const list = [...this.debrisList]</p>
<p>&nbsp; &nbsp; list.forEach(debris =&gt; {</p>
<p>&nbsp; &nbsp; &nbsp; const res = debris.update()</p>
<p>&nbsp; &nbsp; &nbsp; if (res.isEnd) {</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; deleteFromList(this.debrisList, debris)</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; // 二次爆炸</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; if (debris.secondBurst) {</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.start(5, {</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x: res.x,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; y: res.y,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; speed: 1</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; })</p>
<p>&nbsp; &nbsp; return {</p>
<p>&nbsp; &nbsp; &nbsp; isEnd: list.length &lt;= 0</p>
<p>&nbsp; &nbsp; }</p>
<p>&nbsp; }</p>
<p>}</p>
<p>&nbsp;</p>
<p>// 痕迹碎片类</p>
<p>class Debris {</p>
<p>&nbsp; constructor(opt = {}) {</p>
<p>&nbsp; &nbsp; // 颜色</p>
<p>&nbsp; &nbsp; this.color = opt.color || '#fff'</p>
<p>&nbsp; &nbsp; // 透明度</p>
<p>&nbsp; &nbsp; this.opacity = getRandom(0.1, 0.5)</p>
<p>&nbsp; &nbsp; // 半径</p>
<p>&nbsp; &nbsp; this.radius = opt.radius || 1</p>
<p>&nbsp; &nbsp; // 存在时间</p>
<p>&nbsp; &nbsp; this.time = getRandom(0.5, 1)</p>
<p>&nbsp; &nbsp; // 重力,px/s2</p>
<p>&nbsp; &nbsp; this.g = opt.g || 0.98</p>
<p>&nbsp; &nbsp; // 位置</p>
<p>&nbsp; &nbsp; this.x = opt.x</p>
<p>&nbsp; &nbsp; this.y = opt.y</p>
<p>&nbsp; &nbsp; // 创建的时间</p>
<p>&nbsp; &nbsp; this.startTime = 0</p>
<p>&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp; start() {</p>
<p>&nbsp; &nbsp; this.startTime = Date.now()</p>
<p>&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp; update() {</p>
<p>&nbsp; &nbsp; const duration = (Date.now() - this.startTime) / 1000</p>
<p>&nbsp; &nbsp; this.y -= this.g * duration</p>
<p>&nbsp; &nbsp; drawCircle({</p>
<p>&nbsp; &nbsp; &nbsp; opacity: this.opacity,</p>
<p>&nbsp; &nbsp; &nbsp; x: this.x,</p>
<p>&nbsp; &nbsp; &nbsp; y: this.y,</p>
<p>&nbsp; &nbsp; &nbsp; radius: this.radius,</p>
<p>&nbsp; &nbsp; &nbsp; color: this.color</p>
<p>&nbsp; &nbsp; })</p>
<p>&nbsp; &nbsp; return {</p>
<p>&nbsp; &nbsp; &nbsp; x: this.x,</p>
<p>&nbsp; &nbsp; &nbsp; y: this.y,</p>
<p>&nbsp; &nbsp; &nbsp; isEnd: duration &gt; this.time</p>
<p>&nbsp; &nbsp; }</p>
<p>&nbsp; }</p>
<p>}</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>// 发射器类</p>
<p>class Launcher {</p>
<p>&nbsp; constructor(opt = {}) {</p>
<p>&nbsp; &nbsp; // 烟花实例</p>
<p>&nbsp; &nbsp; this.firework = opt.firework</p>
<p>&nbsp; &nbsp; // 颜色</p>
<p>&nbsp; &nbsp; this.color = opt.color</p>
<p>&nbsp; &nbsp; // 初始位置</p>
<p>&nbsp; &nbsp; this.x = opt.x || canvasWidth * getRandom(0.2, 0.8)</p>
<p>&nbsp; &nbsp; this.y = opt.y || 0</p>
<p>&nbsp; &nbsp; // 目标位置</p>
<p>&nbsp; &nbsp; this.ty = canvasHeight * getRandom(0.6, 0.8)</p>
<p>&nbsp; &nbsp; // 半径</p>
<p>&nbsp; &nbsp; this.radius = opt.radius || getRandom(2, 5)</p>
<p>&nbsp; &nbsp; // 发射的持续时间</p>
<p>&nbsp; &nbsp; this.duration = opt.duration || getRandom(2000, 3500)</p>
<p>&nbsp; &nbsp; // 发射时的时间</p>
<p>&nbsp; &nbsp; this.startTime = 0</p>
<p>&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp; start() {</p>
<p>&nbsp; &nbsp; this.startTime = Date.now()</p>
<p>&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp; easeOutCubic(t, b, c, d) {</p>
<p>&nbsp; &nbsp; return c * ((t = t / d - 1) * t * t + 1) + b</p>
<p>&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp; update() {</p>
<p>&nbsp; &nbsp; const x = this.x</p>
<p>&nbsp; &nbsp; let y = this.easeOutCubic(</p>
<p>&nbsp; &nbsp; &nbsp; Date.now() - this.startTime,</p>
<p>&nbsp; &nbsp; &nbsp; this.y,</p>
<p>&nbsp; &nbsp; &nbsp; this.ty - this.y,</p>
<p>&nbsp; &nbsp; &nbsp; this.duration</p>
<p>&nbsp; &nbsp; )</p>
<p>&nbsp; &nbsp; y = Math.min(y, this.ty)</p>
<p>&nbsp; &nbsp; // 透明度变小</p>
<p>&nbsp; &nbsp; let opacity = 1 - 1 * (y / this.ty)</p>
<p>&nbsp; &nbsp; if (opacity &lt; 0) opacity = 0</p>
<p>&nbsp; &nbsp; this.draw(x, y, opacity)</p>
<p>&nbsp; &nbsp; // 添加痕迹碎片</p>
<p>&nbsp; &nbsp; if (Math.random() &gt; 0.7 &amp;&amp; opacity &gt;= 0.1) {</p>
<p>&nbsp; &nbsp; &nbsp; this.firework.addDebris({</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; x: x + getRandom(-2, 2), // x坐标添加一段随机量</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; y</p>
<p>&nbsp; &nbsp; &nbsp; })</p>
<p>&nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; return {</p>
<p>&nbsp; &nbsp; &nbsp; x,</p>
<p>&nbsp; &nbsp; &nbsp; y,</p>
<p>&nbsp; &nbsp; &nbsp; isEnd: y &gt;= this.ty //返回true代表发射结束</p>
<p>&nbsp; &nbsp; }</p>
<p>&nbsp; }</p>
<p>&nbsp; draw(x, y, opacity) {</p>
<p>&nbsp; &nbsp; // 外圆,烟花的颜色</p>
<p>&nbsp; &nbsp; drawCircle({</p>
<p>&nbsp; &nbsp; &nbsp; opacity: opacity,</p>
<p>&nbsp; &nbsp; &nbsp; x: x,</p>
<p>&nbsp; &nbsp; &nbsp; y: y,</p>
<p>&nbsp; &nbsp; &nbsp; radius: this.radius,</p>
<p>&nbsp; &nbsp; &nbsp; color: this.color</p>
<p>&nbsp; &nbsp; })</p>
<p>&nbsp; &nbsp; // 内圆,白色</p>
<p>&nbsp; &nbsp; drawCircle({</p>
<p>&nbsp; &nbsp; &nbsp; opacity: opacity,</p>
<p>&nbsp; &nbsp; &nbsp; x: x,</p>
<p>&nbsp; &nbsp; &nbsp; y: y,</p>
<p>&nbsp; &nbsp; &nbsp; radius: this.radius / 2,</p>
<p>&nbsp; &nbsp; &nbsp; color: '#fff'</p>
<p>&nbsp; &nbsp; })</p>
<p>&nbsp; }</p>
<p>}</p>
<p>&nbsp;</p>
<p>// 烟花类</p>
<p>class Firework {</p>
<p>&nbsp; constructor(opt = {}) {</p>
<p>&nbsp; &nbsp; // 颜色</p>
<p>&nbsp; &nbsp; this.color = opt.color || tinycolor.random().toHexString()</p>
<p>&nbsp; &nbsp; // 发射器</p>
<p>&nbsp; &nbsp; this.launcher = null</p>
<p>&nbsp; &nbsp; // 爆炸器</p>
<p>&nbsp; &nbsp; this.explosive = null</p>
<p>&nbsp; &nbsp; // 烟花状态:waiting(等待发射)、launching(发射中)、bursting(爆炸中)、end(烟花结束)</p>
<p>&nbsp; &nbsp; this.status = 'waiting'</p>
<p>&nbsp; &nbsp; // 痕迹碎片列表</p>
<p>&nbsp; &nbsp; this.debrisList = []</p>
<p>&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp; // 发射</p>
<p>&nbsp; launch() {</p>
<p>&nbsp; &nbsp; this.launcher = new Launcher({</p>
<p>&nbsp; &nbsp; &nbsp; firework: this,</p>
<p>&nbsp; &nbsp; &nbsp; color: this.color</p>
<p>&nbsp; &nbsp; })</p>
<p>&nbsp; &nbsp; this.launcher.start()</p>
<p>&nbsp; &nbsp; this.status = 'launching'</p>
<p>&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp; // 爆炸</p>
<p>&nbsp; burst({ x, y }) {</p>
<p>&nbsp; &nbsp; this.explosive = new Explosive({</p>
<p>&nbsp; &nbsp; &nbsp; firework: this,</p>
<p>&nbsp; &nbsp; &nbsp; x,</p>
<p>&nbsp; &nbsp; &nbsp; y,</p>
<p>&nbsp; &nbsp; &nbsp; color: this.color</p>
<p>&nbsp; &nbsp; })</p>
<p>&nbsp; &nbsp; this.explosive.start()</p>
<p>&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp; // 更新</p>
<p>&nbsp; update() {</p>
<p>&nbsp; &nbsp; if (this.status === 'launching') {</p>
<p>&nbsp; &nbsp; &nbsp; const res = this.launcher.update()</p>
<p>&nbsp; &nbsp; &nbsp; if (res.isEnd) {</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; this.status = 'bursting'</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; this.burst(res)</p>
<p>&nbsp; &nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; } else if (this.status === 'bursting') {</p>
<p>&nbsp; &nbsp; &nbsp; const res = this.explosive.update()</p>
<p>&nbsp; &nbsp; &nbsp; if (res.isEnd) {</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; this.status = 'end'</p>
<p>&nbsp; &nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; // 更新痕迹碎片</p>
<p>&nbsp; &nbsp; this.updateDebris()</p>
<p>&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp; // 添加痕迹碎片</p>
<p>&nbsp; addDebris(opt = {}) {</p>
<p>&nbsp; &nbsp; const debris = new Debris({</p>
<p>&nbsp; &nbsp; &nbsp; ...opt,</p>
<p>&nbsp; &nbsp; &nbsp; color: opt.color || this.color</p>
<p>&nbsp; &nbsp; })</p>
<p>&nbsp; &nbsp; debris.start()</p>
<p>&nbsp; &nbsp; this.debrisList.push(debris)</p>
<p>&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp; // 更新痕迹碎片</p>
<p>&nbsp; updateDebris() {</p>
<p>&nbsp; &nbsp; const list = [...this.debrisList]</p>
<p>&nbsp; &nbsp; list.forEach(debris =&gt; {</p>
<p>&nbsp; &nbsp; &nbsp; const res = debris.update()</p>
<p>&nbsp; &nbsp; &nbsp; if (res.isEnd) {</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; deleteFromList(this.debrisList, debris)</p>
<p>&nbsp; &nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; })</p>
<p>&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp; isEnd() {</p>
<p>&nbsp; &nbsp; return this.status === 'end'</p>
<p>&nbsp; }</p>
<p>}</p>
<p>&nbsp;</p>
<p>3、给自己放个烟花秀吧</p>
<p>创建一个文件夹,将以上两个文件 index.html &amp; index.js 放到创建的文件夹中</p>
<p>在电脑端双击打开 index.html,即可在浏览器中打开页面,点击屏幕给自己放个烟花秀吧</p>
<p>!!!</p>
页: [1]
查看完整版本: 【炫酷!在你的网页上来场烟花秀吧!】(附源码)