程序员都有自己的小浪漫,比如用程序表白,用代码请假(老板没法拒绝的那种)。
最近也快圣诞和元旦了,接近年底烟花是少不了的。那就来点“代码版仪式感”——
用 SVG 写一段烟花动画。
我这次研究了两个版本:
- 纯 SVG 动画版:
用<circle> + <animate>画出烟花绽放的效果,每朵烟花都包含:外圈光环 + 多个彩色颗粒向四周炸开再消失; - 叠加特效版:
用「背景图 + 烟花 GIF 叠加层」的方式,把一张烟花 GIF 叠到任意图片上,看起来就像这张图自己在放烟花。
(这个思路是参考 SVG 编辑器 E2 里的一个组件改出来的。)
下面分别拆一下。
方法一:一段纯 SVG 的烟花(不依赖 JS)
用法很简单:
- 新建一个
fireworks.html - 把下面整段代码贴进去
- 浏览器打开,就能看到烟花循环绽放 ✨
这段 SVG 在干什么?思路捋一下
-
整体:
viewBox="0 0 400 400"→ 一个 400×400 的坐标系 + 深色背景。 -
中间主烟花:
- 外圈光晕:一个
<circle>,半径从0 → 80,同时透明度从1 → 0; - 烟花颗粒:先画一个「往上飞」的小圆,再用
transform="rotate(...)"复制成一整圈; - 每个颗粒的
cy从-10 → -110 → -140,模拟向外飞散的轨迹,同时半径和透明度都慢慢减小。
- 外圈光晕:一个
-
侧边两朵小烟花:
- 整个
<g>用scale(0.6 / 0.7)缩小; begin="0.8s"、begin="1.5s"错后启动,避免所有烟花一起炸,看起来更自然。
- 整个
-
星星只是点缀:
几个小<circle> + animate opacity,当成背景星空。
怎么改成你自己的“告白烟花版”?
可以改的点很多:
- 颜色:
改<circle>的fill,比如做一个全粉色、全蓝色主题,或者按品牌色改一组。 - 炸开的大小:
改cy的终点值(-140→-200),烟花炸得更开。 - 密度:
多复制几段g transform="rotate(...)",角度改密一点,颗粒会更密集。 - 节奏:
改dur(整轮时长)和begin(每朵烟花的延迟),从“佛系慢放”调到“疯狂连环炸”都可以。
方法二:用一张烟花 GIF,让任何图片都“放烟花”(SVG 实现)
上面那个是完全用 SVG 动画画出来的烟花。
但很多时候,我们只是想让一张图“稍微有点节日气氛”,并不想写这么多 <animate>。
第二种方法就很适合这种场景:
用一个透明背景的烟花 GIF,叠加到任意图片上。
效果上看起来就是:这张图自己在放烟花。
这个套路非常适合:
- 封面图 / Banner
- 节日贺卡、跨年海报
- 产品宣传图 / 页面头图
- 博客 / 公众号配图加一点动态氛围
而且关键是:不需要自己写烟花轨迹逻辑。
思路:一层底图 + 一层烟花特效层
结构很简单,可以理解为两层:
- 底层:任何你想展示的背景图(JPG / PNG 都行)
- 上层:一张黑底的烟花 GIF,通过混合模式叠加,黑色背景自动变透明
视觉上就像某张照片突然有了烟花特效。
实现方式:SVG 当容器,CSS 做混合
下面是一个精简可复用的结构,你只需要改图片地址即可:
<section style="-webkit-touch-callout:none;user-select:text;overflow:hidden;text-align:center;line-height:0;">
<!-- 底图:任意背景图 -->
<svg
viewBox="0 0 744 790"
style='
background-image:url("你的背景图地址.jpg");
background-size:cover;
background-repeat:no-repeat;
display:inline;
line-height:0;
'>
</svg>
<!-- 叠加烟花特效层 -->
<section
style="
text-align:center;
height:0;
line-height:0;
width:100%;
margin:0 auto;
transform:rotate(180deg);
pointer-events:none;
mix-blend-mode:screen;
opacity:1;
">
<section style="transform:rotate(180deg);pointer-events:none;">
<svg
viewBox="0 0 744 790"
style='
background-image:url("你的烟花-gif-地址.gif");
background-size:cover;
background-repeat:no-repeat;
display:block;
line-height:0;
transform:scale(1);
background-position:50% 50%;
'>
</svg>
</section>
</section>
</section>
你只需要改两处:
你的背景图地址.jpg→ 换成任意一张你想要的底图你的烟花-gif-地址.gif→ 换成一张黑底烟花 GIF
关键技术点拆一下
1)为什么用 <svg> 而不是 <img>?
这里用 SVG 做容器,主要是为了:
- 方便统一画布尺寸:
viewBox="0 0 744 790"相当于给上下两层都定了同一块“画布”,方便对齐; - 背景图 / GIF 都能用
background-size: cover自适应; - 后续如果想继续叠别的 SVG 动效,也能在同一个体系里玩。
可以简单理解成:SVG 在这里就是一个更好调的 div。
2)mix-blend-mode: screen:让黑底 GIF 自动“抠图”
大部分烟花 GIF 结构是:
- 背景黑色;
- 烟花颗粒是各种亮色。
mix-blend-mode: screen 的特性是:
- 黑色会被“吃掉”,近似看成透明;
- 亮色会和底图以“变亮”的方式叠加,看起来更像光照在画面上。
所以你不需要自己去 PS 抠图,浏览器帮你搞定“黑底去掉 + 光效叠加”。
3)pointer-events: none:让特效层不挡交互
我们给烟花层加了一句:
pointer-events: none;
意思是:这层只用来展示,不参与鼠标事件。
好处就是:
- 下方如果有按钮 / 链接 / 滚动操作,都不会被挡住;
- 特效层完全是“视觉挂件”。
在 Web UI 里做装饰性动效时,这个属性很实用。
适用场景 & 改造方向
你可以很轻松地把这个结构变成自己的:
- 年终总结页顶部加一层烟花;
- 博客 / 掘金文章封面来点烟花氛围;
- 小活动落地页的 Banner 做成“节日特别款”;
- 产品页面里,用来强调某个“重大更新”。
改造点:
- 想更炫:可以叠不止一个烟花 GIF,多放几个位置;
- 想更克制:把
opacity调低一点,烟花会更“克制地闪烁在后面”。
顺带一提:不想写代码,可以怎么做?(聊聊 SVG 编辑器 E2)
上面两个方法,都是手写 SVG 代码实现的。
如果你本身是前端 / 喜欢折腾代码,写一写其实挺好玩。
但如果你更多是做 运营 / 设计 / 内容制作,只是偶尔想要“来点 SVG 高级感”,
手写 <circle>、<animate> 这些标签就会显得有点硬核了。
这时候,其实可以考虑用一类专门的 在线 SVG 编辑器。
比如这篇里灵感来源的 E2 SVG 编辑器,就是典型的这类工具:
-
提供可视化界面,用拖拽和参数面板配置动效,而不是直接改 SVG 源码;
-
内置了一批可复用的 SVG 动画组件,比如:
- 烟花特效
- 全屏下雪
- 高级轮播 / 卡片进场
- 点击掉落、视差滚动等交互元素;
-
支持一键导出 SVG 代码,可以直接贴到网页、Markdown、富文本编辑器里用。
对于「我想要 SVG 高级感,但又不想每次都从 0 写代码」的同学,这类编辑器会比较省时间。
这个烟花特效,在 E2 里是怎么用的?
我这里写的第二种「GIF 叠加烟花」实现,思路就参考了 E2 编辑器里的一个组件:
- 在编辑器里选一个 背景图组件;
- 再叠加一个 烟花特效组件,本质上就是一层设置好混合模式的 GIF;
- 通过可视化的方式调位置、缩放和透明度;
- 最后导出 SVG,一整段代码就生成好了。
如果你日常要频繁做节日活动页、封面图、公众号 / 企业号图文页面,
不想每次都从头写 SVG 动画,
完全可以用这类 SVG 编辑器(比如 E2)先搭好效果,再把导出的 SVG 当“素材组件”用在自己的项目里。
最后小结
这次其实就是围绕一个小目标:
用 SVG 实现“程序员自己的烟花”。
我们用了两种思路:
- 纯 SVG 动画版:
适合想练练 SVG 动画语法、对动效节奏和粒子分布有强控制欲的同学; - GIF 叠加版:
更偏实用主义,适合需要快速产出节日氛围图、动态 Banner、活动封面的场景。
额外再加一条:
- 如果你是前端 / 动效爱好者:可以多玩玩方法一,把它改成自己的“告白烟花”“项目发布烟花”;
- 如果你是内容 / 运营方向:可以记住方法二 + 一些 SVG 编辑器(比如 E2),当作一个随时能拿出来用的小工具。
本文仅做学习与代码实践分享,不涉及任何组件的售卖或商业化。如有涉及到他人作品或素材的引用,请以官方授权为准,如有不当之处欢迎联系我调整。