SVG 形状变形的工作原理

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 $200 免费积分!

虽然 使用 CSS 动画 SVG 很容易且舒适,但 CSS 无法动画所有可能动画的 SVG 属性。 例如,所有定义元素实际形状的属性都不可能在 CSS 中更改或动画。 但是,您可以通过 SMIL 对其进行动画处理。 Sara Soueidan 在她 关于 SMIL 的指南 中涵盖了这一点,该指南发布在 CSS-Tricks 上,但我认为我应该重点介绍这种特殊能力。

更新: 本文重点介绍使用 SMIL 进行 SVG 形状变形。 SMIL 的未来尚不确定(可能不佳)。 如果您对形状变形非常感兴趣(您应该感兴趣,这太棒了!),我建议您查看 GreenSock 的 MorphSVG 插件,该插件不需要 SMIL,并且功能更强大,因为它可以变形任何数量的点的形状,无论元素类型如何,并且跨浏览器兼容。
另一个更新: Chrome 已开始允许通过 CSS 进行形状变形。 这是一个演示文稿,它演示了这一点。 不过,它比 SMIL 更有限,仅限于一个浏览器,并且需要具有相同数量的点的路径。 此外,它不像所有 SVG 一样是硬件加速的。

最重要的事实:形状需要具有相同数量的点

否则,动画将失败。 形状不会消失或任何东西,但它不会动画。

仅仅通过查看d(在path的情况下)或points属性(在多边形的情况下)并不完全清楚形状有多少点,因此您可能只需要从一个矢量编辑程序开始,使用一个形状并从那里开始。

1. 从最复杂的形状开始

在这个演示中,我将从一个星形变形到一个勾号。 星形更复杂

保存该 SVG 的副本,然后为下一个形状创建一个新的副本。

2. 使用相同的点创建下一个形状。

拖动点直到您得到下一个形状。

3. 在 SVG 形状元素本身使用起始形状

<svg viewBox="0 0 194.6 185.1">

  <polygon fill="#FFD41D" points=" ... shape 1 points ... ">

  </polygon>

</svg>

4. 添加一个动画元素,使其动画到下一个形状

<svg viewBox="0 0 194.6 185.1">

  <polygon fill="#FFD41D" points=" ... shape 1 points ... ">

    <animate attributeName="points" dur="500ms" to=" ... shape 2 points ... " />

  </polygon>

</svg>

该动画将立即运行,因此我们需要对其进行一些修复。

5. 根据需要触发动画

SMIL 能够处理交互,例如点击和悬停,只要所有这些交互都在 SVG 本身内发生。 例如,您可以通过点击它来开始动画,例如

<polygon id="shape" points=" ... shape 1 points ... ">

  <animate begin="shape.click" attributeName="points" dur="500ms" to=" ... shape 2 points ... />

</polygon>

这很不错,但它有点限制,因为您只能处理来自同一 SVG 中其他元素的点击。 也许这个 SVG 只是<button>的一部分,您希望在该按钮上的任何点击上运行动画。

首先,为动画指定一个 ID,以便我们能够使用 JavaScript 找到它,然后阻止它运行,使用

<animate id="animation-to-check" begin="indefinite" ... />

现在,您可以获取对该动画的引用,并根据需要启动它

animationToCheck = document.getElementById("animation-to-check");

// run this on a click or whenever you want
animationToCheck.beginElement();

演示

此演示实际上有四个动画。 一个是将星形变形为勾号,一个是更改颜色,然后是这两个相同的动画的反向动画。 点击该按钮会检查该按钮的状态,然后运行相应的动画。

查看 Pen 形状变形按钮,作者 Chris Coyier (@chriscoyier) 在 CodePen 上。

对于图表来说很酷,就像这个 旧的 Raphael 演示