<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>烟花特效</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #000;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
canvas {
position: fixed;
top: 0;
left: 0;
z-index: 1;
}
.link {
position: fixed;
bottom: 20px;
color: white;
font-family: Arial, sans-serif;
z-index: 2;
text-decoration: none;
font-size: 14px;
}
.link:hover {
color: #ffcc00;
}
</style>
</head>
<body>
<canvas id="fireworks"></canvas>
<script>
const canvas = document.getElementById('fireworks');
const ctx = canvas.getContext('2d');
// 设置画布大小为窗口大小
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// 烟花粒子类
class Particle {
constructor(x, y, color) {
this.x = x;
this.y = y;
this.color = color;
this.radius = Math.random() * 2 + 1;
this.velocity = {
x: (Math.random() - 0.5) * 8,
y: (Math.random() - 0.5) * 8
};
this.friction = 0.95;
this.gravity = 0.2;
this.life = 100;
this.opacity = 1;
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = `rgba(${this.color}, ${this.opacity})`;
ctx.fill();
ctx.closePath();
}
update() {
this.velocity.x *= this.friction;
this.velocity.y *= this.friction;
this.velocity.y += this.gravity;
this.x += this.velocity.x;
this.y += this.velocity.y;
this.life--;
this.opacity = this.life / 100;
this.draw();
return this.life > 0;
}
}
// 烟花类
class Firework {
constructor(x, y, targetX, targetY, color) {
this.x = x;
this.y = y;
this.targetX = targetX;
this.targetY = targetY;
this.color = color;
this.velocity = {
x: (targetX - x) / 100,
y: (targetY - y) / 100
};
this.particles = [];
this.trail = [];
this.size = 3;
this.exploded = false;
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.fillStyle = `rgb(${this.color})`;
ctx.fill();
ctx.closePath();
// 绘制尾迹
for (let i = 0; i < this.trail.length; i++) {
const pos = this.trail[i];
ctx.beginPath();
ctx.arc(pos.x, pos.y, this.size * 0.7, 0, Math.PI * 2);
ctx.fillStyle = `rgba(${this.color}, ${i / this.trail.length})`;
ctx.fill();
ctx.closePath();
}
}
update() {
this.trail.push({ x: this.x, y: this.y });
if (this.trail.length > 10) {
this.trail.shift();
}
if (!this.exploded) {
this.x += this.velocity.x;
this.y += this.velocity.y;
// 检查是否到达目标位置
const distance = Math.hypot(this.targetX - this.x, this.targetY - this.y);
if (distance < 5) {
this.explode();
}
}
// 更新粒子
for (let i = this.particles.length - 1; i >= 0; i--) {
if (!this.particles[i].update()) {
this.particles.splice(i, 1);
}
}
this.draw();
return this.exploded && this.particles.length === 0;
}
explode() {
this.exploded = true;
for (let i = 0; i < 150; i++) {
this.particles.push(new Particle(this.x, this.y, this.color));
}
}
}
// 烟花数组
const fireworks = [];
// 随机颜色
function getRandomColor() {
const r = Math.floor(Math.random() * 255);
const g = Math.floor(Math.random() * 255);
const b = Math.floor(Math.random() * 255);
return `${r}, ${g}, ${b}`;
}
// 创建烟花
function createFirework() {
const x = Math.random() * canvas.width;
const y = canvas.height;
const targetX = Math.random() * canvas.width;
const targetY = Math.random() * canvas.height * 0.6;
const color = getRandomColor();
fireworks.push(new Firework(x, y, targetX, targetY, color));
}
// 动画循环
function animate() {
requestAnimationFrame(animate);
ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 随机创建烟花
if (Math.random() < 0.03) {
createFirework();
}
// 更新烟花
for (let i = fireworks.length - 1; i >= 0; i--) {
if (fireworks[i].update()) {
fireworks.splice(i, 1);
}
}
}
// 窗口大小改变时调整画布大小
window.addEventListener('resize', () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
});
// 点击屏幕创建烟花
canvas.addEventListener('click', (e) => {
const x = e.clientX;
const y = canvas.height;
const targetX = e.clientX;
const targetY = e.clientY;
const color = getRandomColor();
fireworks.push(new Firework(x, y, targetX, targetY, color));
});
// 开始动画
animate();
</script>
</body>
</html>
html烟花特效
于 2025-06-06 17:07:29 首次发布
9958

被折叠的 条评论
为什么被折叠?



