学习 SVG 动画来丰富我的 GitHub 个人资料

2025-06-10

学习 SVG 动画来丰富我的 GitHub 个人资料

TLDR:我为我的 GitHub 个人资料创建了一个动画 SVG,请在此处查看

一切始于 GitHub 发布了一项功能,允许在你的个人资料中添加 Readme 文件,以展示你所有已完成/正在做的精彩工作。没想到,大家竟然发现它还能用来在个人资料中添加 GIF 动图。🥳

但我当时觉得,GIF 已经过时了,SVG 才是新潮💩。只有一个问题,我对 SVG 一无所知。我是说,我的确用它做过图标和一些插图。有时我会用一些工具生成一个,然后贴到页面上。但我从未深入研究过如何从零开始创建一个 SVG 并添加动画。

无事可做,我开始谷歌搜索,惊讶地发现 MDN 上有关于 SVG 元素的详尽文档。原来,添加基本形状很简单。有像rectcirclepolygonlinepolyline这样的标签。然后只需编写 CSS 即可实现动画效果。

太棒了!👍

所以现在我只需在屏幕上移动一个标志,就能让婴儿潮一代连续几个小时盯着它看!💪

办公室参考

跑题了。回到 SVG 动画。上面提到的形状或许足以让一个有创造力的人创作出一些非常酷炫的插画。但我的创造力相当有限,所以我决定做一个动态的波浪。为了弥补我的创造力不足,我学习了另一个名为 的标签path,它能帮我创作这个波浪。🌊

想法🤓

这个想法很简单。创建多个移动的波浪,每个波浪的速度不同,并使其稍微透明一些。透明度会使波浪相交的区域变暗,从而产生多种颜色的色调。

至于横幅的尺寸,我选择了 1440 x 320,因为我喜欢这个长宽比。它不算太大,但足以添加背景信息。考虑到它在 GitHub 上显示的区域会比较小,我可以确保有足够的空间来添加其他内容。

<路径 />

所以,我开始学习如何创建路径。这很简单。路径标签有一个d属性。获取它并不难😉。有 6 种不同类型的命令。

  • 移至
  • LineTo
  • 三次贝塞尔曲线
  • 二次贝塞尔曲线
  • 椭圆弧曲线
  • 关闭路径

我们只需要学习前三个。每个命令都用一个字母表示,后面跟着一些属性,这些属性是
点(xy 坐标)。

移动

MoveToM命令以字母或m后跟点表示。因此,aM10,10会将当前位置移动到点10,10

线

类似地,LineTo也包含三个命令。
Ll会从当前位置到给定点创建一条线。例如,L10,10会从当前位置到 创建一条线10,10Hh会创建一条到给定 x 坐标的水平线。 最后,Vv会创建一条到给定 y 坐标的垂直线。

三次贝塞尔曲线稍微复杂一些,用字母Cc表示,以 3 个点作为参数。

三次贝塞尔曲线

因此,当前位置是起点。从当前位置到点的线段x1 y1定义了曲线在起点处的切线。从到点的线段x2 y2定义x3 y3了曲线在终点处的切线。x3 y3是终点。想了解更多关于三次贝塞尔曲线的知识,请参阅这篇博文,我觉得它简短但描述性很强。你也可以参考MDN 上的 SVG 路径教程来了解更多信息。

为了巩固我们现在学到的知识,让我们解码以下 SVG。

<svg
  viewbox="0 0 100 100"
  width="100" height="100" 
  xmlns="http://www.w3.org/2000/svg">
  <path
    d="M10,10 V50 C10,90,90,90,90,50 V10 H10 V50"
  />
</svg>
Enter fullscreen mode Exit fullscreen mode

上述代码生成的 SVG 效果如下图所示。为了清晰起见,我在图片周围添加了绿色边框。

SVG示例

我们的路径从 开始0,0,第一个命令M10,10将点移动到10,10。然后第二个命令V50创建一条垂直路径到10,50。接下来,以为参考点,C10,90,90,90,90,50创建一条曲线,为端点。然后创建一条到 的路径。接下来,创建一条到 的路径,最后闭合路径,我们就得到了最终的图像。很简单吧?👌10,9090,9090,50V1090,10H1010,10V50

实施✍️

步骤

我将图像分成四个象限,并计划在第二和第三象限添加一条曲线,如上图第一部分所示。然后,我可以稍微向内移动切线来减弱曲线。最后,我用线条闭合路径。我稍微移动了中心点,使曲线略有不同。但要确保切线与垂直轴的夹角保持不变。这确保了曲线在动画时看起来是连续的。最终,我得到了如下所示的路径。

<path d="M0,160 C320,300,420,300,740,160 C1060,20,1120,20,1440,160 V0 H0" />
Enter fullscreen mode Exit fullscreen mode

如果您对上述路径理解有困难,请查看上图的最后一部分。为了更清晰,我已将路径的每个部分用颜色标记。您也可以将其与上一节进行比较,以更好地理解要点。如果您能跟上我到现在,那么我们已经顺利渡过了难关。😁

<defs /> 和 <use />

虽然,我们现在可以直接复制粘贴上面的路径,创建其他略有不同的 wave,然后就完成了。我想介绍一下defs标签use,这将帮助我们以更易读的方式完成所有这些操作。defs可以用来存储图形元素,例如path,然后稍后可以使用use标签来使用。

我们需要做的就是给id我们一个path并将其放入defs标签内,然后使用标签href中的属性使用它use,如下所述。

<svg
  viewbox="0 0 1440 320"
  width="1440" height="320" 
  xmlns="http://www.w3.org/2000/svg">
  <defs>
    <path
      id='sineWave'
      d="M0,160 C320,300,420,300,740,160 C1060,20,1120,20,1440,160 V0 H0"
    />
  </defs>
  <use href="#sineWave" />
</svg>
Enter fullscreen mode Exit fullscreen mode

现在渲染的是黑色的波浪。为了解决这个问题,我们在 中使用了fillfill-opacity属性path。因此,更新后的路径如下所示。

<path
  fill="#0099ff" fill-opacity="0.2"
  id='sineWave'
  d="M0,160 C320,300,420,300,740,160 C1060,20,1120,20,1440,160 V0 H0"
/>
Enter fullscreen mode Exit fullscreen mode

动画🤤

如果你已经熟悉 CSS 动画,那么本节对你来说应该轻而易举。思路很简单。将两个波浪(我们上面创建的)水平堆叠,然后简单地将它们从 0 平移到 100%。重复以上步骤。如下所示。

最终的

这里的黑框代表用户的视口。

为了实现这一点,我们添加了另一个use标签,但将x属性设置为-100%。将wave类应用于这两个use标签。然后创建一个动画,将 x 从 平移到0%100%并将此动画应用于我们的wave类。

<svg
  viewbox="0 0 1440 320"
  width="1440" height="320" 
  xmlns="http://www.w3.org/2000/svg">
  <defs>
    <style type="text/css">
      .wave {
        animation: wave 8s linear infinite;
      }
      @keyframes wave {
        0% {
          transform: translateX(0%);
        }
        100% {
          transform: translateX(100%);
        }
      }
    </style>
    <path
      fill="#0099ff" fill-opacity="0.2"
      id='sineWave'
      d="M0,160 C320,300,420,300,740,160 C1060,20,1120,20,1440,160 V0 H0"
    />
  </defs>
  <use class="wave" href="#sineWave"/>
  <use class="wave" x="-100%" href="#sineWave"/>
</svg>
Enter fullscreen mode Exit fullscreen mode

最后,我又添加了两个类似的波浪,唯一的区别是我使用了scaleYtransform CSS 属性来改变波浪的振幅。你可以在CodePen上查看最终的 SVG 效果。

额外提示🤗

我还在横幅上添加了一些文字。这本来很简单,因为 SVG 支持 Google 字体,但GitHub 的内容安全策略不允许从外部来源下载字体。因此,我使用这个实用程序创建了一个 SVG 路径,并将其复制到最终的 SVG 文件中。可以在我的GitHub 个人资料中查看

结论

我对 SVG 动画的了解还只是皮毛,但已经创作出了一些我认为很酷的东西。有没有更好的方法?还有其他值得我探索的有趣内容吗?请在下方评论区留言,或在Twitter上给我留言。

更新

我的朋友向我展示了SVG Path Visualizer,我发现它对于可视化变化路径非常有用。

我们还发现网上有很多 SVG 示例,可以使用defsuse标签轻松调整。为了测试这一点,我修改了这个 Codepen示例,并为他创建了一个横幅,您可以在他的GitHub 个人资料中查看。

鏂囩珷鏉ユ簮锛�https://dev.to/pushkar8723/learning-svg-animation-to-spice-up-my-github-profile-1o1d
PREV
Android Vitals - 现在几点?现在几点? uptimeMillis() 与 nanoTime() 对比总结
NEXT
Shell脚本