深入 WordPress 预览加载动画

Avatar of Geoff Graham
Geoff Graham

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

WordPress 推出了 区块编辑器 (aka Gutenberg) 在 5.0 版本中,随之而来的是一个新颖的帖子预览屏幕,它显示了 WordPress 徽标在预览加载时的绘制过程。

当您保存帖子草稿并点击编辑器中的“预览”按钮时,就会出现这种情况。他们是怎么做到的?我很难查看页面的源代码,因为预览加载速度很快,但我确实看到 SVG 用于 WordPress 徽标。这正是我需要的,因为我的脑海中立即回想起 Chris 在 2014 年写的一篇文章,它使用 stroke-dasharraystroke-dashoffset 属性来创建相同的效果。

这是 Chris 在那篇文章中分享的示例

查看 CodePen 上 Chris Coyier (@chriscoyier) 的 bGyoz

后来,我终于看到了 CSS 代码,确认了 WordPress 绘制确实使用了相同的技术,但我将分享我尝试反向工程时,我的思路是如何分解的。

我们正在使用内联 SVG

WordPress 版本的巧妙之处在于我们使用的是两个 SVG 路径,而不是一个。这意味着我们有两个似乎同时绘制的部分。这是内联在 HTML 中的 SVG。我们还有“生成预览”文本,它可以位于 SVG 之外。

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96" role="img" aria-hidden="true" focusable="false">
  <path d="M48 12c19.9 0 36 16.1 36 36S67.9 84 48 84 12 67.9 12 48s16.1-36 36-36" fill="none"></path>
  <path d="M69.5 46.4c0-3.9-1.4-6.7-2.6-8.8-1.6-2.6-3.1-4.9-3.1-7.5 0-2.9 2.2-5.7 5.4-5.7h.4C63.9 19.2 56.4 16 48 16c-11.2 0-21 5.7-26.7 14.4h2.1c3.3 0 8.5-.4 8.5-.4 1.7-.1 1.9 2.4.2 2.6 0 0-1.7.2-3.7.3L40 67.5l7-20.9L42 33c-1.7-.1-3.3-.3-3.3-.3-1.7-.1-1.5-2.7.2-2.6 0 0 5.3.4 8.4.4 3.3 0 8.5-.4 8.5-.4 1.7-.1 1.9 2.4.2 2.6 0 0-1.7.2-3.7.3l11.5 34.3 3.3-10.4c1.6-4.5 2.4-7.8 2.4-10.5zM16.1 48c0 12.6 7.3 23.5 18 28.7L18.8 35c-1.7 4-2.7 8.4-2.7 13zm32.5 2.8L39 78.6c2.9.8 5.9 1.3 9 1.3 3.7 0 7.3-.6 10.6-1.8-.1-.1-.2-.3-.2-.4l-9.8-26.9zM76.2 36c0 3.2-.6 6.9-2.4 11.4L64 75.6c9.5-5.5 15.9-15.8 15.9-27.6 0-5.5-1.4-10.8-3.9-15.3.1 1 .2 2.1.2 3.3z" fill="none"></path>
</svg>

<p>Generating preview...</p>

第一个路径是一个椭圆,充当第二个路径(WordPress 徽标的形状)的边框。最好为每个路径指定一个类,尤其是在这并非页面上唯一的元素的情况下,但我决定在这个演示中保留无类,因为这是唯一的元素。在这种情况下,我们可以使用 CSS 选择这两个路径,或者使用伪选择器(例如 path:nth-child(2))单独选择它们。

那里还有一些其他杂项操作。例如,SVG 获取属性以使其更易于访问,例如将其识别为图像、将其隐藏在屏幕阅读器中以及防止它被聚焦。

我们需要对 SVG 进行轻微的样式化

非常非常轻微的样式。我们需要一个描边,因为路径上没有填充颜色。否则我们将看到很多空白。或者说,是一个不可见的形状,本质上是一个“nothing burger”。

svg {
  stroke: #555;
  stroke-width: 0.5;
  width: 250px;
}

这为我们提供了两个路径的轮廓。stroke-width 属性的优点是可以接受小数,因此我们可以使线条更细一些。这样绘制看起来像是用铅笔画的。

宽度在这里相当随意,但它很重要,因为我们将要使用的 stroke-dasharraystroke-dashoffset 属性依赖于它。如果这些属性值小于 SVG 的大小,则绘制将无法完成。如果它太大,则绘制的速度会过快。

现在我们知道了宽度,并且可以看到路径描边,我们可以相应地设置 stroke-dasharraystroke-dashoffset

svg path {
  stroke-dasharray: 300;
  stroke-dashoffset: 300;
}

比 SVG 略大,并且虚线之间有很大的空间,这应该就可以了。这些值可以调整,以根据您的喜好调整动画。

剩下的只是使用 Chris 的技术

绘制是使用一个关键帧的 CSS 动画。如果我们将 stroke-dashoffset 从零开始,那么路径在初始加载时将不可见,并且当动画达到 100% 时,将增长到我们之前设置的 300 值。同样,我们将偏移量设置为 300,以便描边虚线和它们之间的空间将延伸到 SVG 之外,以覆盖整个内容。

所有的神奇之处仅仅用五行代码就能实现

@keyframes draw {
  0% {
    stroke-dashoffset: 0;
  }
}

将动画命名为任何您喜欢的名称。由于 100% 是隐式的,因此我们只需定义 0% 时的动画即可。

哦!我们还必须将动画附加到路径,所以

svg path {
  animation: draw 2s ease-out infinite alternate;
  stroke-dasharray: 300;
  stroke-dashoffset: 300;
}

您也可以调整这些值以加快或减慢速度。缓动效果使动画产生轻微的脉动效果,动画的开始和结束速度比中间部分慢一些。

现在全部合在一起!

查看 CodePen 上 Geoff Graham (@geoffgraham) 的
WordPress 预览加载状态

CodePen 上。

我之前提到过,但我最终还是从实际实现中获取了源代码,它非常接近,使用了相同的原理。