动画1
主要功能:
真实的发射轨迹 - 烟花从底部发射到指定位置
物理引擎效果 - 包含重力、摩擦力、缓动函数
多彩爆炸效果 - 多种颜色的粒子爆炸
渐变消失 - 粒子逐渐变淡并缩小
交互控制 - 点击、按钮控制等多种方式
技术亮点:
面向对象设计 - 使用ES6类封装烟花逻辑
高性能渲染 - 使用requestAnimationFrame优化动画
真实物理模拟 - 重力、速度、摩擦力计算
视觉效果增强 - 发光效果、缩放动画、透明度变化
响应式设计 - 适配不同屏幕尺寸
控制方式:
点击屏幕 - 在点击位置发射烟花
发射烟花按钮 - 随机位置发射
自动发射按钮 - 开启连续发射模式
停止发射按钮 - 停止自动发射
清空画面按钮 - 清除所有烟花效果
烟花效果包括发射轨迹、爆炸粒子、重力下落、渐变消失等真实物理效果,营造出高质量的视觉体验。
html
<!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;
background-color: #000;
overflow: hidden;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
font-family: Arial, sans-serif;
}
.fireworks-container {
position: relative;
width: 100%;
height: 100%;
}
.firework {
position: absolute;
width: 5px;
height: 5px;
border-radius: 50%;
pointer-events: none;
}
.controls {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
z-index: 100;
background: rgba(0, 0, 0, 0.7);
padding: 15px;
border-radius: 10px;
color: white;
text-align: center;
}
button {
background: linear-gradient(45deg, #ff6b6b, #ffa502);
border: none;
color: white;
padding: 10px 20px;
margin: 5px;
border-radius: 25px;
cursor: pointer;
font-weight: bold;
transition: all 0.3s ease;
}
button:hover {
transform: scale(1.05);
box-shadow: 0 0 15px rgba(255, 255, 255, 0.5);
}
.title {
position: absolute;
top: 20px;
left: 50%;
transform: translateX(-50%);
color: white;
font-size: 2em;
text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #e60073, 0 0 40px #e60073;
animation: glow 2s ease-in-out infinite alternate;
}
@keyframes glow {
from {
text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #e60073, 0 0 40px #e60073;
}
to {
text-shadow: 0 0 20px #fff, 0 0 30px #ff4da6, 0 0 40px #ff4da6, 0 0 50px #ff4da6;
}
}
</style>
</head>
<body>
<div class="title">🎆 高质量烟花秀 🎆</div>
<div class="fireworks-container" id="fireworksContainer"></div>
<div class="controls">
<button onclick="launchFirework()">发射烟花</button>
<button onclick="startAutoLaunch()">自动发射</button>
<button onclick="stopAutoLaunch()">停止发射</button>
<button onclick="clearFireworks()">清空画面</button>
</div>
<script>
class Firework {
constructor(container) {
this.container = container;
this.particles = [];
this.colors = [
'#ff0000', '#00ff00', '#0000ff', '#ffff00',
'#ff00ff', '#00ffff', '#ff7700', '#ff0077',
'#7700ff', '#00ff77', '#ffaa00', '#ff00aa'
];
}
launch(x, y) {
// 创建烟花发射轨迹
const rocket = document.createElement('div');
rocket.className = 'firework';
rocket.style.left = `${x}px`;
rocket.style.top = `${window.innerHeight}px`;
rocket.style.backgroundColor = this.getRandomColor();
rocket.style.boxShadow = `0 0 10px ${this.getRandomColor()}`;
this.container.appendChild(rocket);
// 发射动画
const startTime = Date.now();
const duration = 1000 + Math.random() * 500;
const targetY = y;
const animateRocket = () => {
const elapsed = Date.now() - startTime;
const progress = Math.min(elapsed / duration, 1);
// 使用缓动函数让运动更自然
const easeOutQuad = 1 - Math.pow(1 - progress, 2);
const currentY = window.innerHeight - (window.innerHeight - targetY) * easeOutQuad;
rocket.style.top = `${currentY}px`;
rocket.style.opacity = 1 - progress * 0.5;
if (progress < 1) {
requestAnimationFrame(animateRocket);
} else {
// 发射完成,爆炸效果
this.explode(x, targetY);
rocket.remove();
}
};
requestAnimationFrame(animateRocket);
}
explode(x, y) {
const particleCount = 100 + Math.floor(Math.random() * 50);
for (let i = 0; i < particleCount; i++) {
const particle = document.createElement('div');
particle.className = 'firework';
const angle = Math.random() * Math.PI * 2;
const speed = 2 + Math.random() * 5;
const size = 2 + Math.random() * 3;
const color = this.getRandomColor();
particle.style.width = `${size}px`;
particle.style.height = `${size}px`;
particle.style.left = `${x}px`;
particle.style.top = `${y}px`;
particle.style.backgroundColor = color;
particle.style.boxShadow = `0 0 ${size * 2}px ${color}`;
this.container.appendChild(particle);
// 粒子动画参数
const particleData = {
element: particle,
x: x,
y: y,
vx: Math.cos(angle) * speed,
vy: Math.sin(angle) * speed,
gravity: 0.05,
friction: 0.98,
life: 1.0,
decay: 0.01 + Math.random() * 0.02,
size: size
};
this.particles.push(particleData);
}
}
updateParticles() {
for (let i = this.particles.length - 1; i >= 0; i--) {
const p = this.particles[i];
// 更新位置
p.x += p.vx;
p.y += p.vy;
p.vy += p.gravity;
p.vx *= p.friction;
p.vy *= p.friction;
// 更新生命值
p.life -= p.decay;
// 更新元素位置和透明度
p.element.style.left = `${p.x}px`;
p.element.style.top = `${p.y}px`;
p.element.style.opacity = p.life;
p.element.style.transform = `scale(${p.life})`;
// 移除死亡粒子
if (p.life <= 0) {
p.element.remove();
this.particles.splice(i, 1);
}
}
}
getRandomColor() {
return this.colors[Math.floor(Math.random() * this.colors.length)];
}
clear() {
this.particles.forEach(p => p.element.remove());
this.particles = [];
}
}
// 全局变量
const container = document.getElementById('fireworksContainer');
const firework = new Firework(container);
let autoLaunchInterval = null;
// 点击发射烟花
container.addEventListener('click', (e) => {
firework.launch(e.clientX, e.clientY);
});
// 手动发射按钮
function launchFirework() {
const x = Math.random() * window.innerWidth;
const y = Math.random() * window.innerHeight * 0.6;
firework.launch(x, y);
}
// 自动发射
function startAutoLaunch() {
if (autoLaunchInterval) return;
autoLaunchInterval = setInterval(() => {
const x = Math.random() * window.innerWidth;
const y = Math.random() * window.innerHeight * 0.6;
firework.launch(x, y);
}, 800);
}
// 停止自动发射
function stopAutoLaunch() {
if (autoLaunchInterval) {
clearInterval(autoLaunchInterval);
autoLaunchInterval = null;
}
}
// 清空画面
function clearFireworks() {
firework.clear();
}
// 粒子更新循环
function update() {
firework.updateParticles();
requestAnimationFrame(update);
}
// 启动更新循环
update();
// 页面加载完成后开始自动发射
window.addEventListener('load', () => {
setTimeout(() => {
startAutoLaunch();
}, 1000);
});
</script>
</body>
</html>
动画2
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS烟花动画</title>
<style>
body {
background-color: #000;
overflow: hidden;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.firework {
position: absolute;
width: 5px;
height: 5px;
border-radius: 50%;
box-shadow: 0 0 10px 2px;
animation: explode 1s ease-out forwards;
opacity: 0;
}
@keyframes explode {
0% {
transform: translate(0, 0);
opacity: 1;
}
100% {
transform: translate(var(--tx), var(--ty));
opacity: 0;
}
}
.launch-area {
position: absolute;
bottom: 20%;
width: 100%;
text-align: center;
}
.launch-btn {
padding: 10px 20px;
background: linear-gradient(45deg, #ff3366, #ff9933);
color: white;
border: none;
border-radius: 30px;
font-size: 16px;
cursor: pointer;
box-shadow: 0 0 15px rgba(255, 51, 102, 0.7);
transition: all 0.3s;
}
.launch-btn:hover {
transform: scale(1.05);
box-shadow: 0 0 20px rgba(255, 51, 102, 0.9);
}
</style>
</head>
<body>
<div class="launch-area">
<button class="launch-btn" onclick="launchFirework()">发射烟花</button>
</div>
<script>
function launchFirework() {
const colors = ['#ff3366', '#ff9933', '#33ccff', '#9933ff', '#33ff66'];
const fireworkCount = 50;
for (let i = 0; i < fireworkCount; i++) {
const firework = document.createElement('div');
firework.className = 'firework';
// 随机颜色
const color = colors[Math.floor(Math.random() * colors.length)];
firework.style.backgroundColor = color;
firework.style.boxShadow = `0 0 10px 2px ${color}`;
// 随机位置偏移
const angle = Math.random() * Math.PI * 2;
const distance = 50 + Math.random() * 100;
const tx = Math.cos(angle) * distance;
const ty = Math.sin(angle) * distance;
firework.style.setProperty('--tx', `${tx}px`);
firework.style.setProperty('--ty', `${ty}px`);
// 随机起始位置(在屏幕中央附近)
const startX = 50 + (Math.random() - 0.5) * 20;
const startY = 50 + (Math.random() - 0.5) * 20;
firework.style.left = `${startX}%`;
firework.style.top = `${startY}%`;
// 随机动画延迟和持续时间
firework.style.animationDelay = `${Math.random() * 0.2}s`;
firework.style.animationDuration = `${0.5 + Math.random() * 0.5}s`;
document.body.appendChild(firework);
// 动画结束后移除元素
firework.addEventListener('animationend', function () {
firework.remove();
});
}
}
</script>
</body>
</html>