尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

11套烟花代码合集:Canvas粒子、CSS动画与jQuery实现路线详解

发布时间:2026/9/29 18:30:03

资讯中心
01
ARTICLE

11套烟花代码合集:Canvas粒子、CSS动画与jQuery实现路线详解

11套烟花代码合集:Canvas粒子、CSS动画与jQuery实现路线详解
简介这是一份面向前端初学者与进阶开发者的烟花特效代码合集收录11套基于HTML、jQuery与CSS实现的烟花动画方案可用于节日页面、活动庆祝场景或动画原理学习。压缩包共59个文件约4.6MB以js脚本、html页面、css样式、png图片及json数据为主另含README说明文档结构清晰便于逐套对照研究。已有2983人学习下载热度较高。各套代码实现思路不同有的借助HTML5 canvas逐帧绘制烟花轨迹与爆炸效果有的通过jQuery绑定点击事件与定时器触发烟花秀还有的利用CSS3的transform、transition与keyframes模拟升空、绽放与消散。读者可从中掌握Math随机数生成方向与速度、requestAnimationFrame流畅动画、DOM操作与事件处理、性能优化及响应式适配等关键技能适合作为前端动画练手素材与教学参考。1. 烟花代码合集到底能拿来干什么从节日彩蛋到前端练手项目每年跨年、春节、中秋前后总有人翻出「烟花代码」这个词来搜。搜的人大致分两类一类是运营、行政、老师想给活动页、课件、大屏加个应景的动效另一类是刚学完 HTML、CSS、JS 基础的前端新手想找一个「看得见效果、又不至于太难」的练手项目。11 套烟花代码、多种实现方式的合集正好同时喂饱这两种需求——它把基于 HTML、jQuery、CSS 的烟花实现拆成不同难度、不同技术路线的样本你可以直接抄一个能跑的也可以顺着源码把粒子系统、Canvas 绘制、CSS 动画这几条线摸一遍。但这里有个反直觉的结论烟花代码的难点从来不在「放烟花」而在「怎么让几百上千个粒子同时动起来还不卡」。新手写的版本往往一放就掉帧手机直接发烫而合集里那些看起来更朴素的实现反而因为用了 CSS 动画或 requestAnimationFrame 的节流技巧跑得又稳又省电。所以这篇不是给你贴一堆代码就完事而是把「11 套」背后的几条技术路线讲清楚哪套适合塞进活动页、哪套适合当学习模板、哪套只能本地跑着玩以及参数怎么调、坑在哪。如果你只是想要一个能立刻用的烟花效果看完第 2、3 章就能动手如果你想借这个项目把 Canvas 和 CSS 动画吃透第 4、5 章的参数拆解和排查清单更值得细读。下面按「先选路线、再动手、最后避坑」的顺序展开。2. 三条主流实现路线Canvas 粒子、CSS 动画、jQuery DOM 各适合谁在动手抄任何一套之前先搞清楚这 11 套代码大致落在哪条技术路线上。选错路线后面调参数会非常痛苦。常见做法是把它们归成三类Canvas 粒子型、纯 CSS 动画型、jQuery/DOM 操作型。三者的性能上限、可定制程度、上手难度差别很大。2.1 Canvas 粒子型性能最好也最像「真烟花」Canvas 路线的核心思路是用一块canvas作为画布每一帧清屏后重新绘制所有粒子粒子有位置、速度、重力、生命周期四个基本属性。爆炸时生成一批粒子每个粒子按初速度向外飞散同时受重力影响逐渐下落透明度随生命周期衰减最后被回收。这套逻辑的好处是粒子数量可以轻松上到几百甚至上千因为绘制走的是 GPU 加速的 2D 上下文比操作 DOM 快一个数量级。缺点是代码量偏大需要自己管理粒子的生成、更新、销毁新手第一次看容易懵。// Canvas 烟花核心粒子类 动画循环 class Particle { constructor(x, y, color) { this.x x; this.y y; // 初速度随机角度 随机大小决定爆炸形状 const angle Math.random() * Math.PI * 2; const speed Math.random() * 4 1; this.vx Math.cos(angle) * speed; this.vy Math.sin(angle) * speed; this.color color; this.life 1; // 生命周期1 表示满血 this.decay 0.015; // 每帧衰减速度越大消失越快 } update() { this.x this.vx; this.y this.vy; this.vy 0.05; // 重力加速度让粒子下落 this.vx * 0.99; // 空气阻力让扩散变慢 this.life - this.decay; } draw(ctx) { ctx.globalAlpha this.life; // 透明度跟随生命周期 ctx.fillStyle this.color; ctx.beginPath(); ctx.arc(this.x, this.y, 2, 0, Math.PI * 2); ctx.fill(); } }这段代码里几个参数直接决定观感speed控制爆炸半径0.05是重力调大粒子掉得快、像礼花调小则飘得久、像蒲公英decay控制拖尾长度越小尾巴越长。vx * 0.99是空气阻力去掉它粒子会一直匀速飞出去看起来就很假。实际项目里我一般把粒子数控制在 150300 之间超过 500 在中低端手机上就开始掉帧。2.2 纯 CSS 动画型零 JS 依赖适合塞进静态页CSS 路线的思路完全不同不逐帧计算而是用keyframes定义一条从中心向外扩散并淡出的动画然后生成若干个带随机延迟、随机方向的元素去跑这条动画。浏览器会把动画交给合成层处理性能其实不差而且完全不需要 JS 参与。/* 单个烟花粒子的扩散动画 */ keyframes firework-burst { 0% { transform: translate(0, 0) scale(1); opacity: 1; } 100% { /* --dx / --dy 由内联样式注入控制每个粒子的方向 */ transform: translate(var(--dx), var(--dy)) scale(0.2); opacity: 0; } } .spark { position: absolute; width: 6px; height: 6px; border-radius: 50%; animation: firework-burst 1.2s ease-out forwards; }这里的关键是--dx、--dy两个 CSS 变量用内联样式给每个粒子注入不同的位移值就能让同一套动画跑出放射状效果。forwards保证动画结束后停在最后一帧不会闪回。CSS 路线的短板是粒子数量受限于 DOM 节点数一般 60100 个就到头了再多浏览器布局压力会明显上升。它最适合的场景是活动页里放一两朵点缀而不是满屏炸开。2.3 jQuery/DOM 操作型老项目兼容首选但别指望性能第三类是早年最常见的写法用 jQuery 动态创建div然后靠setInterval或animate()改left、top、opacity。这类代码在合集里通常占好几套因为写起来直观改颜色、改数量都方便。但它的性能是三者里最差的。每创建一个粒子就是一个真实 DOM 节点几百个节点同时改样式浏览器要反复重排重绘。如果你的项目本身还在用 jQuery比如一些后台管理系统、老活动页拿它做个轻量烟花没问题但如果是新项目我建议直接用 Canvas 或 CSS 方案别为了省事引入 jQuery。提示判断该选哪条路线先问自己三个问题——粒子要不要超过 200 个页面是不是纯静态项目里有没有现成的 jQuery三个答案基本就能定位到唯一路线。3. 从零跑通一套 Canvas 烟花最小可运行代码与四个必调参数选定 Canvas 路线后接下来把它跑起来。这一章给出一份最小可运行的完整代码你复制到一个.html文件里双击就能看到效果然后再逐个调参数感受变化。这也是合集里最值得当模板的那一套。3.1 最小可运行结构一个 canvas 加一个动画循环!DOCTYPE html html langzh-cn head meta charsetutf-8 titleCanvas 烟花最小示例/title style html, body { margin: 0; height: 100%; background: #050510; overflow: hidden; } canvas { display: block; } /style /head body canvas idfw/canvas script const canvas document.getElementById(fw); const ctx canvas.getContext(2d); let W, H; function resize() { W canvas.width window.innerWidth; H canvas.height window.innerHeight; } resize(); window.addEventListener(resize, resize); const particles []; const colors [#ff4d6d, #ffd166, #06d6a0, #4cc9f0, #f72585]; function explode(x, y) { const color colors[Math.floor(Math.random() * colors.length)]; const count 120; // 每次爆炸的粒子数 for (let i 0; i count; i) { const angle (Math.PI * 2 * i) / count; // 均匀分布角度 const speed Math.random() * 3 2; particles.push({ x, y, vx: Math.cos(angle) * speed, vy: Math.sin(angle) * speed, life: 1, color }); } } function loop() { // 用半透明黑覆盖形成拖尾而不是硬清屏 ctx.fillStyle rgba(5, 5, 16, 0.25); ctx.fillRect(0, 0, W, H); for (let i particles.length - 1; i 0; i--) { const p particles[i]; p.x p.vx; p.y p.vy; p.vy 0.04; // 重力 p.vx * 0.985; // 阻力 p.vy * 0.985; p.life - 0.012; if (p.life 0) { particles.splice(i, 1); continue; } ctx.globalAlpha p.life; ctx.fillStyle p.color; ctx.beginPath(); ctx.arc(p.x, p.y, 2, 0, Math.PI * 2); ctx.fill(); } ctx.globalAlpha 1; requestAnimationFrame(loop); } // 每 800ms 随机位置炸一朵 setInterval(() { explode(Math.random() * W, Math.random() * H * 0.6 H * 0.1); }, 800); loop(); /script /body /html逻辑说明explode负责在指定坐标生成一批粒子角度用(Math.PI * 2 * i) / count均匀铺开保证爆炸是圆形而不是一坨。loop是主循环用requestAnimationFrame驱动比setInterval更贴合屏幕刷新率。注意清屏用的是半透明矩形而不是clearRect这样上一帧的粒子会留下淡淡残影形成拖尾——这是烟花「好看」的关键很多人第一次写忘了这步画面就很生硬。3.2 四个必调参数粒子数、重力、阻力、衰减代码能跑之后真正决定观感的是这四个值建议逐个改、逐个看参数位置作用推荐范围调过头会怎样粒子数 countexplode 内爆炸密度80300超过 500 中低端机掉帧重力p.vy 0.04下落速度0.020.08太大像下雨太小像失重阻力p.vx * 0.985扩散减速0.970.995太接近 1 粒子飞太远衰减p.life - 0.012存活时长0.0080.02太大一闪就没太小糊成一片我一般先定粒子数再调重力和衰减最后微调阻力。顺序反了会来回改很费时间。另外颜色数组别放太多高饱和色三到五种就够多了反而显脏。3.3 让烟花「像真的」拖尾、二次爆炸与随机性基础版跑通后加三个小改动就能明显提升质感。第一是拖尾前面已经用半透明清屏实现把0.25调小到0.1拖尾更长。第二是二次爆炸在粒子生命衰减到某个阈值时再触发一次小规模explode模拟礼花的子母效果。第三是随机性别让每朵烟花都一样——给count、speed、颜色都加随机区间画面立刻活起来。// 二次爆炸粒子快消失时再炸一次小的 if (p.life 0.3 !p.hasSplit Math.random() 0.02) { p.hasSplit true; for (let k 0; k 20; k) { const a Math.random() * Math.PI * 2; const s Math.random() * 2 1; particles.push({ x: p.x, y: p.y, vx: Math.cos(a) * s, vy: Math.sin(a) * s, life: 0.6, color: p.color }); } }hasSplit标记防止同一个粒子反复分裂Math.random() 0.02控制分裂概率太高会瞬间把粒子数翻好几倍导致卡顿。这段加在粒子更新循环里即可。4. CSS 与 jQuery 两套方案的落地细节什么时候该放弃 Canvas不是所有场景都值得上 Canvas。如果你的页面是纯静态的、或者项目里已经有一堆 jQuery 代码硬塞一套 Canvas 反而增加维护成本。这一章讲清楚另外两条路线怎么落地以及各自的边界在哪。4.1 纯 CSS 烟花用变量注入方向零 JS 也能炸CSS 方案的核心是「一套动画 多个元素 内联变量」。先定义好扩散动画再用 JS或干脆手写生成一批.spark元素每个元素通过style注入不同的--dx、--dy和animation-delay。// 生成 CSS 烟花粒子注入随机方向 function cssFirework(container, x, y, count 60) { for (let i 0; i count; i) { const spark document.createElement(div); spark.className spark; const angle (Math.PI * 2 * i) / count; const dist Math.random() * 120 60; // 扩散距离 spark.style.left x px; spark.style.top y px; spark.style.setProperty(--dx, Math.cos(angle) * dist px); spark.style.setProperty(--dy, Math.sin(angle) * dist px); spark.style.animationDelay Math.random() * 0.2 s; spark.style.background [#ff4d6d, #ffd166, #4cc9f0][i % 3]; container.appendChild(spark); // 动画结束后移除节点避免 DOM 无限增长 spark.addEventListener(animationend, () spark.remove()); } }这里最关键的一行是spark.addEventListener(animationend, () spark.remove())。CSS 烟花最容易翻车的地方就是节点不回收跑几分钟页面里堆几千个 div直接卡死。animationend事件保证每个粒子动画播完就删内存不会涨。dist控制扩散半径animationDelay加一点随机让粒子不是整齐划一地飞出去。CSS 方案的适用边界很明确粒子总数别超过 100页面别频繁触发否则布局压力会盖过它的「零 JS」优势。4.2 jQuery 版烟花老项目里的兼容写法与性能红线如果项目里已经有 jQuery用animate()写烟花是最省事的。核心是创建 div 后用animate改left、top、opacity动画结束回调里remove()。// jQuery 版创建粒子并动画扩散 function jqFirework($container, x, y, count 40) { for (let i 0; i count; i) { const angle (Math.PI * 2 * i) / count; const dist Math.random() * 100 50; $(div classjq-spark/div) .css({ left: x, top: y, background: #ffd166 }) .appendTo($container) .animate( { left: x Math.cos(angle) * dist, top: y Math.sin(angle) * dist, opacity: 0 }, 1000, function () { $(this).remove(); } // 动画完必须删 ); } }性能红线就一条count别超过 50触发频率别高于每秒一次。jQuery 的animate底层还是改样式节点一多就卡。如果你的老项目里烟花要满屏放我的建议是别硬扛直接换成 Canvas 方案jQuery 只负责触发。4.3 三套方案横向对比一张表决定用哪个维度Canvas 粒子纯 CSS 动画jQuery DOM粒子上限3001000601003050JS 依赖需要可零 JS需要 jQuery上手难度中低低移动端表现好好差适合场景满屏烟花、大屏静态页点缀老项目兼容定制灵活度高中中看完这张表选型基本不用纠结了。新项目优先 Canvas静态页用 CSS老项目实在动不了再上 jQuery。5. 烟花代码避坑清单五个让新手反复翻车的点这一章是我自己踩过、也见过别人反复踩的坑按「现象 → 原因 → 解决」写。每一条都对应真实会遇到的报错或卡顿照着排查能省不少时间。5.1 现象页面越跑越卡几分钟后直接卡死原因粒子数组或 DOM 节点没有回收。Canvas 版常见于particles数组只 push 不 spliceCSS/jQuery 版常见于动画结束后没remove()节点。解决Canvas 版在更新循环里判断life 0就splice掉DOM 版一定要绑animationend或animate回调做remove()。可以在控制台打印particles.length或document.querySelectorAll(.spark).length观察是否持续增长。5.2 现象烟花只在左上角炸位置全错原因Canvas 的坐标和鼠标/随机位置没对齐常见于 canvas 尺寸和 CSS 尺寸不一致或者没处理devicePixelRatio。解决确保canvas.width等于window.innerWidth并且 CSS 里canvas { display: block }去掉默认间隙。高分屏想更清晰可以按devicePixelRatio放大画布再ctx.scale但新手先别碰容易把坐标算乱。5.3 现象动画一顿一顿的像幻灯片原因用了setInterval驱动动画或者每帧做了大量 DOM 操作。解决动画循环统一用requestAnimationFrame它跟着屏幕刷新率走。DOM 方案如果非要用把粒子数砍到 30 以内并且避免在循环里读offsetWidth这类会触发重排的属性。5.4 现象手机上烟花糊成一团或者干脆不显示原因没做响应式canvas 尺寸写死或者移动端对requestAnimationFrame的节流导致粒子更新变慢。解决监听resize重设 canvas 尺寸粒子数在移动端按屏幕宽度动态调整比如count window.innerWidth 768 ? 80 : 200。另外移动端别用box-shadow做发光性能开销很大用globalAlpha或颜色本身控制亮度更稳。5.5 现象复制了代码但浏览器控制台报错烟花不出现原因多半是canvas的 id 和 JS 里getElementById对不上或者脚本放在了head里、DOM 还没加载就执行。解决脚本放到/body前或者用DOMContentLoaded包一层。检查 id 拼写getContext(2d)的引号别写错。这类错误控制台会直接指出行号照着改就行。注意排查烟花问题时先看控制台有没有报错再看粒子数是否异常增长最后才怀疑性能。顺序反了会浪费很多时间。6. 把 11 套代码用出价值二次开发与效果验证的几个技巧合集拿到手别只是双击看看效果就完了。真正让它产生价值的方式是「拆一套、改一套、合一套」。我一般会挑 Canvas 那套当底子把 CSS 方案的配色和 jQuery 方案的触发逻辑揉进去做成一个能配置的烟花组件。具体做法是抽出一个配置对象把粒子数、颜色、重力、触发间隔都变成参数const config { count: 150, // 粒子数 colors: [#ff4d6d, #ffd166, #4cc9f0], gravity: 0.04, // 重力 decay: 0.012, // 衰减 interval: 800, // 触发间隔 ms maxParticles: 1200 // 粒子上限超过就不再生成 };maxParticles是我后来加的最有用的一个参数。它给粒子总数设了个天花板不管触发多频繁超过就不再生成新粒子从根上避免卡死。验证效果时我习惯打开 Chrome 的 Performance 面板录 10 秒看帧率是否稳定在 55 以上如果掉到 30 以下先把count砍半再看。另一个技巧是给烟花加「开关」。很多活动页只需要在特定时间点放几秒没必要一直跑。用一个isRunning标志控制requestAnimationFrame是否继续页面切到后台时用document.hidden暂停能省不少电。这些细节合集里的代码不一定都有但你自己加上去这套烟花就从「能看」变成「能用」。最后说个我自己的习惯每次改完参数我都会在手机和一台老笔记本上各跑一遍。桌面浏览器流畅不代表移动端流畅很多翻车都是在真机上才暴露的。希望帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。