HTML5庆祝生日蛋糕烟花特效
<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>HTML5 Birthday Cake Fireworks</title> <style> canvas { position: absolute; top: 0; left: 0; z-index: -1; } </style></head><body> <canvas id="fireworks"></canvas> <script> // 烟花特效 (function () { var canvas = document.getElementById('fireworks'), ctx = canvas.getContext('2d'), fireworks = [], particles = [], hue = 120, limiterTotal = 5, limiterTick = 0, timerTotal = 80, timerTick = 0, mousedown = false, mx, my; canvas.width = window.innerWidth; canvas.height = window.innerHeight; function random(min, max) { return Math.random() * (max - min) + min; } function calculateDistance(p1x, p1y, p2x, p2y) { var xDistance = p1x - p2x, yDistance = p1y - p2y; return Math.sqrt(Math.pow(xDistance, 2) + Math.pow(yDistance, 2)); } function Firework(sx, sy, tx, ty) { this.x = sx; this.y = sy; this.sx = sx; this.sy = sy; this.tx = tx; this.ty = ty; this.distanceToTarget = calculateDistance(sx, sy, tx, ty); this.distanceTraveled = 0; this.coordinates = []; this.coordinateCount = 3; while (this.coordinateCount--) { this.coordinates.push([this.x, this.y]); } this.angle = Math.atan2(ty - sy, tx - sx); this.speed = 2; this.acceleration = 1.05; this.brightness = random(50, 70); this.targetRadius = 1; } Firework.prototype.update = function (index) { this.coordinates.pop(); this.coordinates.unshift([this.x, this.y]); if (this.targetRadius < 8) { this.targetRadius += 0.3; } else { this.targetRadius = 1; } this.speed *= this.acceleration; var vx = Math.cos(this.angle) * this.speed, vy = Math.sin(this.angle) * this.speed; this.distanceTraveled = calculateDistance(this.sx, this.sy, this.x + vx, this.y + vy); if (this.distanceTraveled >= this.distanceToTarget) { createParticles(this.tx, this.ty); fireworks.splice(index, 1); } else { this.x += vx; this.y += vy; } } Firework.prototype.draw = function () { ctx.beginPath(); ctx.moveTo(this.coordinates[this.coordinates.length - 1][0], this.coordinates[this.coordinates.length - 1][1]); ctx.lineTo(this.x, this.y); ctx.strokeStyle = 'hsl(' + hue + ', 100%, ' + this.brightness + '%)'; ctx.stroke(); ctx.beginPath(); ctx.arc(this.tx, this.ty, this.targetRadius, 0, Math.PI * 2); ctx.stroke(); } function createParticles(x, y) { var particleCount = 30; while (particleCount--) { particles.push(new Particle(x, y)); } } function Particle(x, y) { this.x = x; this.y = y; this.coordinates = []; this.coordinateCount = 5; while (this.coordinateCount--) { this.coordinates.push([this.x, this.y]); } this.angle = random(0, Math.PI * 2); this.speed = random(1, 10); this.friction = 0.95; this.gravity = 1; this.hue = random(hue - 20, hue + 20); this.brightness = random(50, 80); this.alpha = 1; this.decay = random(0.015, 0.03); } Particle.prototype.update = function (index) { this.coordinates.pop(); this.coordinates.unshift([this.x, this.y]); this.speed *= this.friction; this.x += Math.cos(this.angle) * this.speed; this.y += Math.sin(this.angle) * this.speed + this.gravity; this.alpha -= this.decay; if (this.alpha <= this.decay) { particles.splice(index, 1); } } Particle.prototype.draw = function () { ctx.beginPath(); ctx.moveTo(this.coordinates[this.coordinates.length - 1][0], this.coordinates[this.coordinates.length - 1][1]); ctx.lineTo(this.x, this.y); ctx.strokeStyle = 'hsla(' + this.hue + ', 100%, ' + this.brightness + '%, ' + this.alpha + ')'; ctx.stroke(); } function loop() { ctx.globalCompositeOperation = 'destination-out'; ctx.fillStyle = 'rgba(0, 0, 0, 0.5)'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.globalCompositeOperation = 'lighter'; var i = fireworks.length; while (i--) { fireworks[i].draw(); fireworks[i].update(i); } var i = particles.length; while (i--) { particles[i].draw(); particles[i].update(i); } if (timerTick >= timerTotal) { if (!mousedown) { fireworks.push(new Firework(canvas.width / 2, canvas.height, random(0, canvas.width), random(0, canvas.height / 2))); timerTick = 0; } } else { timerTick++; } if (limiterTick >= limiterTotal) { if (mousedown) { fireworks.push(new Firework(canvas.width / 2, canvas.height, mx, my)); limiterTick = 0; } } else { limiterTick++; } requestAnimationFrame(loop); } window.onload = function () { canvas.addEventListener('mousemove', function (e) { mx = e.pageX - canvas.offsetLeft; my = e.pageY - canvas.offsetTop; }); canvas.addEventListener('mousedown', function (e) { e.preventDefault(); mousedown = true; }); canvas.addEventListener('mouseup', function (e) { e.preventDefault(); mousedown = false; }); loop(); }; })(); </script></body></html>
以上代码使用HTML5的元素和JavaScript实现了一个简单的生日蛋糕烟花特效。在页面加载完成后,会自动启动动画,当鼠标点击页面时,会在鼠标位置发射一个烟花。