html5 canvas 绘制节日礼花效果
一、html5 canvas 绘制节日礼花效果
展示效果:

此效果有ai写代码为主,人工辅助修改
<!DOCTYPE html> <html lang="zh-CN"> <head> <script type="module"> document.addEventListener("DOMContentLoaded", () => { const insScript = document.createElement("script"); const date = Date.now(); insScript.src = "/inscode_devtools_sdk.js?v=" + date; insScript.type = "module"; document.body.appendChild(insScript); }); </script> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>春节礼花动画</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { background: transparent; overflow: hidden; font-family: "Arial", sans-serif; } canvas { display: block; cursor: crosshair; } .title { position: absolute; top: 50px; left: 50%; transform: translateX(-50%); color: #ffd700; font-size: 2.5em; font-weight: bold; text-shadow: 0 0 20px #ffd700, 0 0 40px #ff6b6b; z-index: 10; animation: glow 2s ease-in-out infinite alternate; } @keyframes glow { from { text-shadow: 0 0 20px #ffd700, 0 0 40px #ff6b6b; } to { text-shadow: 0 0 30px #ffd700, 0 0 60px #ff6b6b, 0 0 80px #ff4757; } } .instructions { position: absolute; bottom: 30px; left: 50%; transform: translateX(-50%); color: #ffffff; font-size: 1.2em; text-align: center; opacity: 0.8; z-index: 10; } #divOne{ position: relative; } #imgOne{ position: absolute; width: 100%; z-index: 0; left: 0; top: 0; } #fireworksCanvas{ position: relative; z-index: 1; } </style> </head> <body> <div id="divOne"> <img id="imgOne" src="http://www.jnqianle.cn/upload/logo/content/202512/23/2303f83d-bb97-4153-8e0d-bc515722327d.jpg"> <!-- <div class="title">🎆 春节礼花 🎆</div> --> <canvas id="fireworksCanvas"></canvas> <!-- <div class="instructions">点击屏幕放礼花 | 自动绽放</div> --> </div> <script> const canvas = document.getElementById("fireworksCanvas"); const ctx = canvas.getContext("2d"); // 设置画布大小 function resizeCanvas() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; } resizeCanvas(); window.addEventListener("resize", resizeCanvas); // 粒子类 class Particle { constructor(x, y, color, velocity, size = 3) { this.x = x; this.y = y; this.color = color; this.velocity = velocity; this.size = size; this.alpha = 1; this.decay = Math.random() * 0.02 + 0.01; this.gravity = 0.1; this.trail = []; this.trailLength = 8; } update() { // 保存轨迹 this.trail.push({ x: this.x, y: this.y, alpha: this.alpha }); if (this.trail.length > this.trailLength) { this.trail.shift(); } this.velocity.y += this.gravity; this.x += this.velocity.x; this.y += this.velocity.y; this.alpha -= this.decay; this.size *= 0.98; } draw() { // 绘制轨迹 ctx.save(); for (let i = 0; i < this.trail.length; i++) { const point = this.trail[i]; const trailAlpha = (i / this.trail.length) * point.alpha * 0.5; ctx.globalAlpha = trailAlpha; ctx.fillStyle = this.color; ctx.beginPath(); ctx.arc( point.x, point.y, this.size * (i / this.trail.length), 0, Math.PI * 2 ); ctx.fill(); } // 绘制主粒子 ctx.globalAlpha = this.alpha; ctx.fillStyle = this.color; ctx.shadowBlur = 10; ctx.shadowColor = this.color; ctx.beginPath(); ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); ctx.fill(); ctx.restore(); } } // 礼花类 class Firework { constructor(x, y, targetY) { this.x = x; this.y = y; this.targetY = targetY; this.particles = []; this.exploded = false; this.velocity = { x: (Math.random() - 0.5) * 2, y: -Math.random() * 3 - 8, }; this.color = this.getRandomColor(); this.trail = []; } getRandomColor() { const colors = [ "#ff6b6b", "#4ecdc4", "#45b7d1", "#96ceb4", "#feca57", "#ff9ff3", "#54a0ff", "#5f27cd", "#00d2d3", "#ff9f43", "#ffd700", "#ff4757", "#3742fa", "#2ed573", "#ffa502", ]; return colors[Math.floor(Math.random() * colors.length)]; } update() { if (!this.exploded) { this.trail.push({ x: this.x, y: this.y }); if (this.trail.length > 10) { this.trail.shift(); } this.velocity.y += 0.2; // 重力 this.x += this.velocity.x; this.y += this.velocity.y; if (this.velocity.y >= 0 || this.y <= this.targetY) { this.explode(); } } else { this.particles = this.particles.filter((particle) => { particle.update(); return particle.alpha > 0 && particle.size > 0.1; }); } } explode() { this.exploded = true; const particleCount = Math.random() * 50 + 80; for (let i = 0; i < particleCount; i++) { const angle = (Math.PI * 2 * i) / particleCount; const velocity = Math.random() * 6 + 2; const size = Math.random() * 4 + 2; this.particles.push( new Particle( this.x, this.y, this.color, { x: Math.cos(angle) * velocity + (Math.random() - 0.5) * 2, y: Math.sin(angle) * velocity + (Math.random() - 0.5) * 2, }, size ) ); } // 添加一些金色粒子增加节日气氛 for (let i = 0; i < 20; i++) { const angle = Math.random() * Math.PI * 2; const velocity = Math.random() * 4 + 1; this.particles.push( new Particle( this.x, this.y, "#ffd700", { x: Math.cos(angle) * velocity, y: Math.sin(angle) * velocity, }, Math.random() * 3 + 1 ) ); } } draw() { if (!this.exploded) { // 绘制上升轨迹 ctx.save(); for (let i = 0; i < this.trail.length; i++) { const point = this.trail[i]; const alpha = (i / this.trail.length) * 0.8; ctx.globalAlpha = alpha; ctx.fillStyle = this.color; ctx.shadowBlur = 5; ctx.shadowColor = this.color; ctx.beginPath(); ctx.arc(point.x, point.y, 3, 0, Math.PI * 2); ctx.fill(); } // 绘制礼花主体 ctx.globalAlpha = 1; ctx.fillStyle = this.color; ctx.shadowBlur = 15; ctx.shadowColor = this.color; ctx.beginPath(); ctx.arc(this.x, this.y, 4, 0, Math.PI * 2); ctx.fill(); ctx.restore(); } else { this.particles.forEach((particle) => particle.draw()); } } } // 礼花数组 const fireworks = []; // 创建随机礼花 function createRandomFirework() { const x = Math.random() * canvas.width; const y = canvas.height; const targetY = Math.random() * canvas.height * 0.3 + 50; fireworks.push(new Firework(x, y, targetY)); } // 动画循环 function animate() { // 清除画布(透明背景) ctx.clearRect(0, 0, canvas.width, canvas.height); // 更新和绘制所有礼花 for (let i = fireworks.length - 1; i >= 0; i--) { const firework = fireworks[i]; firework.update(); firework.draw(); // 移除已经消失的礼花 if (firework.exploded && firework.particles.length === 0) { fireworks.splice(i, 1); } } requestAnimationFrame(animate); } // 自动放礼花 setInterval(() => { if (Math.random() < 0.8) { createRandomFirework(); } }, 800); // 点击放礼花 canvas.addEventListener("click", (e) => { const rect = canvas.getBoundingClientRect(); const x = e.clientX - rect.left; const y = canvas.height; const targetY = e.clientY - rect.top; fireworks.push(new Firework(x, y, targetY)); }); // 开始动画 animate(); // 初始礼花 setTimeout(() => { for (let i = 0; i < 3; i++) { setTimeout(() => createRandomFirework(), i * 300); } }, 1000); </script> </body> </html>
更多:
浙公网安备 33010602011771号