形状变形

我们可以在网页上用多种方式来动画或过渡一个形状到另一个形状。我不是说旋转箭头或放大对勾,而是说观察一个形状从它由的点移动到新的位置。

网页上有很多运动的可能性。您可以很容易地为任何元素的 opacitycolortransform 属性(例如 translatescalerotate)制作动画,仅举几例。例如

.kitchen-sink {
  opacity: 0.5;
  background-color: orange;
  transform: translateX(-100px) scale(1.2) rotate(1deg);
}
.kitchen-sink:hover {
  opacity: 1;
  background-color: black;
  transform: translateX(0) scale(0) rotate(0);
}

顺便说一句,对 transformopacity 属性进行动画是理想的,因为正如人们所说,浏览器可以“廉价地”做到这一点。这意味着浏览器在实现移动时需要做的工作更少,并且可以利用“硬件加速”。

鲜为人知的是,您可以为元素的实际形状制作动画!我不仅是说对 border-radius 进行动画或移动一些伪元素(尽管这当然有用),而是说真正地变形元素的矢量形状。

对于我们的第一个技巧,让我们通过 clip-path 创建矢量形状。我们可以像这样在元素的百分比坐标处剪切掉部分内容

.moving-arrow {
  width: 200px;
  height: 200px;
  background: red;
  clip-path: polygon(100% 0%, 75% 50%, 100% 100%, 25% 100%, 0% 50%, 25% 0%);
}

Clippy 是一个生成 polygon() 形状数据的绝佳工具。Firefox 开发者工具在应用 polygon() 形状数据后,也提供了非常不错的内置工具来操作它。

然后,我们可以在某种状态更改时更改该 clip-path。它可以是类的更改,但让我们在这里使用 :hover。顺便说一下,让我们添加一个过渡,以便我们看到形状的更改!

.moving-arrow {
  ...
  transition: clip-path 0.2s;
  clip-path: polygon(100% 0%, 75% 50%, 100% 100%, 25% 100%, 0% 50%, 25% 0%);
}
.moving-arrow:hover {
  clip-path: polygon(75% 0%, 100% 50%, 75% 100%, 0% 100%, 25% 50%, 0% 0%);
}

由于 polygon() 具有相同数量的坐标,因此过渡有效。

使用 clip-path 绘制矢量形状很好,但它可能不是绘制矢量形状的完美工具。绘制矢量形状实际上是 SVG 的语言。SVG 的元素具有专门用于绘制的属性。核心元素是具有 自身特殊语法 用于绘制的元素。

你可能会看到这样的路径

<svg viewBox="0 0 20 20">
  <path d="
     M 8 0
     L 12 0
     L 12 8
     L 20 8
     L 20 12
     L 12 12
     L 12 20
     L 8 20
     L 8 12
     L 0 12
     L 0 8
     L 8 8
     L 8 0
  "></path>
</svg>

它绘制了一个“+”形状。

d 属性的值可能看起来像乱码,但它实际上只是控制虚拟笔的运动。将笔移动到这里,在这个方向上画一条这么长的线,等等。

在上面的示例中,只使用了两个命令,您可以从每个行之前的前缀字母中看出

  • M:将笔移动到这些精确坐标(不绘制)
  • L:从笔的当前坐标绘制一条线到这些精确坐标

SVG 本身拥有一种用于更改这些坐标的语言,如果需要的话,包括动画。它被称为 SMIL,但它的主要问题是它很古老,而且从未得到过很好的支持。

好消息是,一些浏览器支持 SMIL 在 CSS 中可以做到的一些功能。例如,我们可以像这样在 CSS 中更改 :hover 上的 path

svg:hover path {
    d: path("
      M 10 0 
      L 10 0
      L 13 7
      L 20 10
      L 20 10
      L 13 13
      L 10 20
      L 10 20
      L 7 13
      L 0 10
      L 0 10
      L 7 7
      L 10 0
    ");
}
path {
  transition: 0.2s;
}

这将我们的加号形状变成一个飞镖形状,并且过渡是可能的,因为它们具有相同数量的点。

如果你真的想变形形状,并想要一个非常强大的工具来帮助你做到这一点,请查看 Greensock 的 MorphSVG 插件。它允许对形状变形的方式进行大量控制,并且不限于相同数量的点过渡。