高性能 CSS 动画示例

在这篇文章中,了解一下 CodePen 上一些流行的动画是如何创建的。这些动画都使用了本节其他文章中讨论的高性能技术。

请参阅为什么有些动画速度慢?,了解这些建议背后的理论,以及动画指南,获取实用技巧。

向导加载动画

在 CodePen 上查看向导加载动画

此加载动画完全使用 CSS 构建。图像和所有动画都是在 CSS 和 HTML 中创建的,没有图像或 JavaScript。要了解它是如何创建的以及性能如何,您可以使用 Chrome DevTools。

使用 Chrome DevTools 检查动画

在动画运行时,打开 Chrome DevTools 中的“性能”标签页,并录制几秒钟的动画。您应该在“摘要”中看到,浏览器在运行此动画时没有执行任何布局或绘制操作。

Summary in DevTools
分析向导动画后的摘要。

要了解如何在不引起布局和绘制的情况下实现此动画,请在 Chrome DevTools 中检查任何移动元素。您可以使用 动画面板 找到各种动画元素,单击任何元素将在 DOM 中突出显示它。

The Animations Panel showing the various parts of our animation.
在 Chrome DevTools 动画面板中查看和选择项目。

例如,选择三角形,并观察元素的框在其空中旅程中、旋转时以及返回起始位置时如何变换。

视频展示了我们如何在 Chrome DevTools 中跟踪三角形的路径。

在元素仍处于选中状态时,查看“样式”面板。在那里,您可以看到绘制三角形形状的 CSS,以及正在使用的动画。

工作原理

三角形是通过使用 ::after 伪元素添加生成的内容,并使用边框创建形状来创建的。

.triangle {
    position: absolute;
    bottom: -62px;
    left: -10px;
    width: 110px;
    height: 110px;
    border-radius: 50%;
}

.triangle::after {
    content: "";
    position: absolute;
    top: 0;
    right: -10px;
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 0 28px 48px 28px;
    border-color: transparent transparent #89beb3 transparent;
}

动画是通过以下 CSS 行添加的:

animation: path_triangle 10s ease-in-out infinite;

停留在 Chrome DevTools 中,您可以通过向下滚动“样式”面板来找到关键帧。在那里,您会发现动画是通过使用 transform 来更改元素的位置并旋转它来创建的。transform 属性是动画指南中描述的属性之一,它不会导致浏览器执行布局或绘制操作(这是动画缓慢的主要原因)。

@keyframes path_triangle {
  0% {
    transform: translateY(0);
  }
  10% {
    transform: translateY(-172px) translatex(10px) rotate(-10deg);
  }
  55% {
    transform: translateY(-172px) translatex(10px) rotate(-365deg);
  }
  58% {
    transform: translateY(-172px) translatex(10px) rotate(-365deg);
  }
  63% {
    transform: rotate(-360deg);
  }
}

此动画的每个不同的移动部分都使用了类似的技术。结果是一个复杂的动画,但运行流畅。

脉动圆

在 CodePen 上查看脉动圆

这种类型的动画有时用于吸引页面上某些内容的注意。要了解动画,您可以使用 Firefox DevTools。

使用 Firefox DevTools 检查动画

在动画运行时,打开 Firefox DevTools 中的“性能”标签页,并录制几秒钟的动画。停止录制,在瀑布图中,您应该看不到 重新计算样式 的条目。您现在知道此动画不会导致样式重新计算,因此也不会导致布局和绘制操作。

details of the animation in the Firefox Waterfall
Firefox DevTools 瀑布图。

停留在 Firefox DevTools 中,检查圆圈以查看此动画的工作原理。带有 pulsating-circle 类的 <div> 标记了圆圈的位置,但它本身不会绘制圆圈。

.pulsating-circle {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translateX(-50%) translateY(-50%);
    width: 30px;
    height: 30px;
}

可见的圆圈和动画是使用 ::before::after 伪元素实现的。

::before 元素创建了白色圆圈外部的opaque环,使用名为 pulse-ring 的动画,该动画为 transform: scaleopacity 设置动画。

.pulsating-circle::before {
    content: '';
    position: relative;
    display: block;
    width: 300%;
    height: 300%;
    box-sizing: border-box;
    margin-left: -100%;
    margin-top: -100%;
    border-radius: 45px;
    background-color: #01a4e9;
    animation: pulse-ring 1.25s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;
}

@keyframes pulse-ring {
  0% {
    transform: scale(0.33);
  }
  80%, 100% {
    opacity: 0;
  }
}

查看正在动画处理哪些属性的另一种方法是在 Firefox DevTools 中选择 动画 面板。然后,您将看到正在使用的动画的可视化效果,以及正在动画处理的属性。

选择 ::before 伪元素后,我们可以看到哪些属性正在动画处理。

白色圆圈本身是使用 ::after 伪元素创建和动画处理的。pulse-dot 动画使用 transform: scale 在动画期间放大和缩小点。

.pulsating-circle::after {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  display: block;
  width: 100%;
  height: 100%;
  background-color: white;
  border-radius: 15px;
  box-shadow: 0 0 8px rgba(0, 0, 0, 0.3);
  animation: pulse-dot 1.25s cubic-bezier(0.455, 0.03, 0.515, 0.955) -0.4s infinite;
}

@keyframes pulse-dot {
  0% {
    transform: scale(0.8);
  }
  50% {
    transform: scale(1);
  }
  100% {
    transform: scale(0.8);
  }
}

像这样的动画可以用在应用程序的各个位置,重要的是这些小细节不会影响应用程序的整体性能。

纯 CSS 3D 球体

在 CodePen 上查看纯 CSS 3D 球体

此动画看起来非常复杂,但它使用了我们在之前的示例中已经看到的技术。复杂性来自于动画处理大量元素。

打开 Chrome DevTools 并选择一个带有 plane 类的元素。球体由一组旋转的平面和辐条组成。

平面似乎在旋转。

这些平面和辐条位于包装器 <div> 内,正是这个元素使用 transform: rotate3d 进行旋转。

.sphere-wrapper {
  transform-style: preserve-3d;
  width: 300px;
  height: 300px;
  position: relative;
  animation: rotate3d 10s linear infinite;
}

@keyframes rotate3d {
  0% {
    transform: rotate3d(1, 1, 1, 0deg);
  }
  25% {
    transform: rotate3d(1, 1, 1, 90deg);
  }
  50% {
    transform: rotate3d(1, 1, 1, 180deg);
  }
  75% {
    transform: rotate3d(1, 1, 1, 270deg);
  }
  100% {
    transform: rotate3d(1, 1, 1, 360deg);
  }
}

点可以嵌套在 planespoke 元素内找到,它们使用一个使用 transform 来缩放和平移它们的动画。这创建了脉动效果。

点随着球体旋转和脉动。
.spoke-15 .dot,
.spoke-21 .dot {
  animation: pulsate 0.5s infinite 0.83333333s alternate both;
  background-color: #55ffee;
}

@-webkit-keyframes pulsate {
  0% {
    transform: rotateX(90deg) scale(0.3) translateZ(20px);
  }
  100% {
    transform: rotateX(90deg) scale(1) translateZ(0px);
  }
}

创建此动画所涉及的工作是使时序正确,以创建转动和脉动效果。动画本身非常简单,并且使用了性能非常好的方法。

您可以通过打开 Chrome DevTools 并在运行时录制性能来查看此动画的性能。初始加载后,动画不会触发布局或绘制,并且运行流畅。

结论

从这些示例中,您可以看到如何使用高性能方法动画处理一些属性可以创建一些非常酷的动画。通过默认使用动画指南中描述的高性能方法,您可以将时间花在创建您想要的效果上,而无需过多担心使页面变慢。