如何用CSS3和JS实现逼真的烟花绽放动画效果

来源:菜鸟站长作者:北京GEO公司头衔:草根站长
导读:本期聚焦于小伙伴创作的《如何用CSS3和JS实现逼真的烟花绽放动画效果》,敬请观看详情。不少初学者尝试用纯CSS做烟花,结果只能写出固定轨迹的方块闪烁,缺少随机扩散与渐隐的真实感。其实结合JS控制粒子生成、用CSS3的transform与opacity做过渡,才能在浏览器里还原夜空炸裂的层次。核心思路是先由JS算出爆炸点坐标与每颗粒子的角度速度,再批量创建DOM节点赋予随机动画时长,最后监听animationend回收节点防止内存占用攀升。相比canvas逐帧绘制,这种方案代码直观、便于调试,在低并发场景下性能足够。下文给出可直接运行的示例与参数调优方法。

在网页里做烟花效果,常见做法有两种:一种是使用canvas不断重绘粒子,另一种是用DOM节点配合CSS3动画。后者虽然节点数量一多会有性能瓶颈,但代码直观、容易理解,非常适合做教学示例或者并发量不高的氛围动画。下面我们用原生JavaScript创建烟花粒子,用CSS3的keyframes控制绽放与消失。

如何用CSS3和JS实现逼真的烟花绽放动画效果

一、整体实现思路

烟花动画可以拆成两个阶段。第一个阶段是烟花从地面升起到空中爆炸点,我们称之为“上升阶段”;第二个阶段是爆炸后产生大量粒子向四周散开并渐隐,我们称之为“爆炸阶段”。如果用纯CSS写,很难在运行时动态决定爆炸位置和粒子数量,因此我们用JS在运行时生成节点并写入随机参数。

具体来说,点击页面任意位置时,JS记录鼠标坐标作为爆炸中心,然后创建几十个div作为粒子。每个粒子通过CSS变量接收随机角度和距离,再利用transform做位移,用opacity做透明度衰减。这样不需要在JS里写复杂的运动方程,动画交给浏览器合成层处理,更加流畅。

二、HTML结构

页面本身只需要一个容器用来装烟花粒子,不需要提前写死任何烟花节点。所有粒子都由JS动态插入,避免HTML冗余。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>CSS3+JS烟花</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div id="sky"></div>
  <script src="firework.js"></script>
</body>
</html>

上面的<div id="sky">就是我们的夜空容器。后续所有烟花粒子都会作为它的子元素存在。保持结构简洁,有助于后面用JS批量操作。

三、CSS3样式与动画

粒子的外观用CSS定义,包括绝对定位、圆形外观和发光效果。真正的“绽放”动作放在keyframes里,通过读取JS写入的CSS变量来计算最终位移。这样同一套动画规则可以服务无数随机粒子。

#sky {
  position: fixed;
  inset: 0;
  background: #000;
  overflow: hidden;
}

.particle {
  position: absolute;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--color);
  box-shadow: 0 0 8px var(--color);
  opacity: 1;
  animation: burst var(--duration) ease-out forwards;
}

@keyframes burst {
  from {
    transform: translate(0, 0) scale(1);
    opacity: 1;
  }
  to {
    transform: translate(var(--tx), var(--ty)) scale(0.3);
    opacity: 0;
  }
}

这里用到了CSS自定义属性,比如--tx--ty表示粒子横向和纵向的位移量,--duration控制动画时长,--color决定粒子颜色。由于animation使用了forwards,动画结束后会停留在最后一帧,也就是透明度为0的状态,方便我们之后统一清理。

需要注意,如果粒子数量很大,建议把box-shadow的模糊半径调小,因为阴影是渲染开销较高的属性。在低配设备上可以仅保留纯色圆点,用数量弥补观感。

四、JavaScript控制逻辑

JS负责三件事:监听用户点击、计算随机粒子参数、创建节点并监听动画结束以回收。下面给出完整示例,其中包含角度均分加随机抖动、速度随机、颜色随机等细节。

const sky = document.getElementById('sky');

function createFirework(x, y) {
  const count = 60;
  const colors = ['#ff5252', '#ffd740', '#69f0ae', '#40c4ff', '#e040fb'];
  for (let i = 0; i < count; i++) {
    const p = document.createElement('div');
    p.className = 'particle';
    const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.3;
    const distance = 80 + Math.random() * 70;
    const tx = Math.cos(angle) * distance;
    const ty = Math.sin(angle) * distance;
    p.style.left = x + 'px';
    p.style.top = y + 'px';
    p.style.setProperty('--tx', tx + 'px');
    p.style.setProperty('--ty', ty + 'px');
    p.style.setProperty('--duration', 0.8 + Math.random() * 0.6 + 's');
    p.style.setProperty('--color', colors[Math.floor(Math.random() * colors.length)]);
    p.addEventListener('animationend', () => p.remove());
    sky.appendChild(p);
  }
}

sky.addEventListener('click', (e) => {
  createFirework(e.clientX, e.clientY);
});

在上面的代码中,我们把圆周均分成60份,再给每个角度加一点随机抖动,避免粒子排成死板的圆圈。distance控制爆炸半径,用随机数让烟花有粗细不均的尾巴。animationend事件触发后直接remove节点,能有效防止DOM节点无限累积导致页面卡顿。

如果你希望烟花自动燃放而不依赖点击,可以用setInterval随机生成坐标来调用createFirework。但在生产环境中要限制最大并发粒子数,比如同时不超过三团烟花,否则CSS动画过多会占用主线程合成资源。

五、性能与优化建议

这种DOM+CSS3方案在粒子总数低于三四百时表现良好。若想进一步提升性能,可以开启GPU加速,确保transform和opacity动画运行在合成层。我们已经使用了transform和opacity,这两个属性本身就不会触发重排重绘,属于浏览器优化最好的动画属性。

另一个常见优化是复用节点:提前创建对象池,爆炸时从池里取节点,结束后再放回。这样减少createElement和remove的频繁操作。对于教学和小场景,直接增删节点代码更清晰;对于长时段挂机动画,对象池更有价值。你也可以把粒子改成canvas绘制,用一支requestAnimationFrame循环统一渲染,那样可以轻松支撑上千粒子。

六、小结

用CSS3配合JS实现烟花,核心是把“运动计算”交给JS,把“运动表现”交给CSS。这种分工让代码易读、调试方便。掌握CSS变量与keyframes的结合,你还能做出雪花、流星、礼花筒等多种特效。建议先从点击爆炸练起,再逐步加入上升轨迹和声音,就能做出完整的烟花秀。

CSS3动画JavaScriptcanvas烟花修改时间:2026-08-09 17:24:49

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。