程序员的烟火:我用 SVG 放了一场跨年烟花

120 阅读7分钟

程序员都有自己的小浪漫,比如用程序表白,用代码请假(老板没法拒绝的那种)。

最近也快圣诞和元旦了,接近年底烟花是少不了的。那就来点“代码版仪式感”——
用 SVG 写一段烟花动画。

我这次研究了两个版本:

  1. 纯 SVG 动画版
    <circle> + <animate> 画出烟花绽放的效果,每朵烟花都包含:外圈光环 + 多个彩色颗粒向四周炸开再消失;
  2. 叠加特效版
    用「背景图 + 烟花 GIF 叠加层」的方式,把一张烟花 GIF 叠到任意图片上,看起来就像这张图自己在放烟花。
    (这个思路是参考 SVG 编辑器 E2 里的一个组件改出来的。)

下面分别拆一下。


方法一:一段纯 SVG 的烟花(不依赖 JS)

用法很简单:

  1. 新建一个 fireworks.html
  2. 把下面整段代码贴进去
  3. 浏览器打开,就能看到烟花循环绽放 ✨

这段 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
  • 节日贺卡、跨年海报
  • 产品宣传图 / 页面头图
  • 博客 / 公众号配图加一点动态氛围

而且关键是:不需要自己写烟花轨迹逻辑。


思路:一层底图 + 一层烟花特效层

结构很简单,可以理解为两层:

  1. 底层:任何你想展示的背景图(JPG / PNG 都行)
  2. 上层:一张黑底的烟花 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 实现“程序员自己的烟花”。

我们用了两种思路:

  1. 纯 SVG 动画版
    适合想练练 SVG 动画语法、对动效节奏和粒子分布有强控制欲的同学;
  2. GIF 叠加版
    更偏实用主义,适合需要快速产出节日氛围图、动态 Banner、活动封面的场景。

额外再加一条:

  • 如果你是前端 / 动效爱好者:可以多玩玩方法一,把它改成自己的“告白烟花”“项目发布烟花”;
  • 如果你是内容 / 运营方向:可以记住方法二 + 一些 SVG 编辑器(比如 E2),当作一个随时能拿出来用的小工具。

本文仅做学习与代码实践分享,不涉及任何组件的售卖或商业化。如有涉及到他人作品或素材的引用,请以官方授权为准,如有不当之处欢迎联系我调整。