使用多步骤动画和过渡

Avatar of Geoff Graham
Geoff Graham

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

CSS 动画很酷,概念也很简单。命名动画,在 @keyframes 中定义运动,然后在元素上调用该动画。如果您没有使用过它们,您可以在这里的年鉴中 提升您的语法知识

虽然概念很简单,但有一些小技巧可以让动画看起来很复杂,其中之一就是多步骤过渡。这就是我们将在本文中探讨的内容。

关键帧可以是“步骤”

如果我们设置一个关键帧动画,将元素的背景颜色在 5 秒内从橙色更改为黑色(毕竟橙色是新的黑色),它将完全按照预期执行。它会将这种变化在时间内进行划分,并进行过渡。

body {
  background: black;
  animation: color-me-in 5s; /* other keywords like "infinite alternate" can be useful here */
}

@keyframes color-me-in {
  /* You could think of as "step 1" */
  0% {
    background: orange;
  }
  /* You could think of as "step 2" */
  100% {
    background: black;
  }
}

查看 CodePen 上 CSS-Tricks (@css-tricks) 编写的 ZbePzr 笔记。

我们可以在关键帧动画中添加任意数量的步骤。例如,以下是在过渡中间添加蓝色。

@keyframes color-me-in {
  0% {
    background: orange;
  }
  /* Adding a step in the middle */
  50% {
    background: blue;
  }
  100% {
    background: black;
  }
}

查看 CodePen 上 CSS-Tricks (@css-tricks) 编写的 meWoyy 笔记。

这就是多步骤动画的概念的简要概述:在动画从头到尾的过渡中,有多个变化发生。

关键帧会进行插值和过渡,除非您不想进行插值和过渡

请注意,上面的颜色在每一步中都会相互淡化。这是很好的默认值。它们甚至会“缓动”到彼此,因为这是默认的 animation-timing-function,另一个很好的默认值,因为它比一般来说具有计算机感觉的 linear 更平滑和放松,尽管每种都有其用途。

使用 steps() 函数,您可以强制插值为精确的关键帧数。演示

查看 CodePen 上 CSS-Tricks (@css-tricks) 编写的 bEdKaW 笔记。

将多步骤动画付诸实践

一个很好的例子是 Apple Music 中的音频均衡器。您可能已经见过它,或者至少见过类似的东西:一系列垂直条,它们以一种给人以它随着音乐节奏跳舞的错觉的方式上下波动。

以下是非活动版本,我们正在谈论的是什么

查看 CodePen 上 CSS-Tricks (@css-tricks) 编写的 Apple Music 音频均衡器 (SVG) 笔记。

五条垂直条,想让它们以不同的高度上下移动。让我们创建一个名为 equalize 的动画,其中包含 25 个关键帧步骤。每个步骤占动画的 4%,然后将其调用到 .bar 元素。

查看 CodePen 上 CSS-Tricks (@css-tricks) 编写的 Apple Music 音频均衡器 (SVG) 笔记。

很好,但它们都以相同的速度同时移动。这看起来不像一个很酷的均衡器。但是,我们可以在调用动画时,为每个 .bar 添加不同的 animation-duration,从而产生它们以不同速度移动的效果。

查看 CodePen 上 Geoff Graham (@geoffgraham) 编写的 Apple Music 音频均衡器 (SVG) 笔记。

我们做到了!一个均衡器,当它处于活动状态时,看起来像是随着歌曲的节奏移动,即使我们在每个元素上都使用相同的 multi-step 动画。

以下是一个使用 animation-delay(负值,因此它们仍然同时开始)的替代方案

查看 CodePen 上 CSS-Tricks (@css-tricks) 编写的 Apple Music 音频均衡器 (SVG) 笔记。

等等,还有多步骤 transition

Transition 就像更简单的动画。它们从一组固定的属性移动到另一组固定的属性。简写

.move-me {
  transition: [transition-property] [transition-duration] [transition-timing-function] [transition-delay];
}

而且,就像 animation 一样,我们可以动画化 同一组属性

让我们通过将 background-colorwidth 属性链接起来,在悬停时将红色方框过渡到橙色矩形。

.box {
  width: 150px;
  height: 150px;
  background-color: red;
  transition: 1s;
}

.box:hover {
  width: 300px;
  background-color: orange;
}

这告诉我们的 .box 元素在悬停时过渡 widthbackground-color 属性,并在 1 秒内进行过渡。

查看 CodePen 上 Geoff Graham (@geoffgraham) 编写的 CSS Transition Property 笔记。

还不是真正的 multi-step,但这是可能的!

将多个步骤添加到过渡

我们可以使用逗号将过渡链接在一起,使事情变得更有意思,然后通过调整它们的持续时间和延迟,创建与关键帧动画中相同的 multi-step 运动效果。

让我们以上面的例子为例,先改变宽度,然后在完成之后改变颜色。

.box {
  transition: 
    /* step 1 */
    width      1s,
    /* step 2 */
    background 0.5s 1s;
}

查看 CodePen 上 CSS-Tricks (@css-tricks) 编写的 CSS Transition Property 笔记。

在这里,我们可以变得更加花哨,编排额外的动作。

  • 在悬停时立即将宽度从 150px 更改为 300px,持续 1 秒
  • 立即将 background-color 从红色更改为橙色,持续 1 秒
  • 立即添加 box-shadow 并更改它的方向,持续 1 秒
  • 添加一行文本,在 widthheight 过渡后,淡出并向左移动
  • 添加另一行文本,在第一行文本消失后,出现并从右侧滑入

我们可以通过在每个元素上链接我们的过渡来做到这一点,在这些元素上需要过渡多个属性!

/* Our box element */
.box {
  width: 150px;
  height: 150px;
  background-color: red;
  box-shadow: 5px 5px 25px #000;
  transition: all 1s;
}

/* On hover... */
.box:hover {
  /* Increase width */
  width: 300px;
  /* Change color */
  background-color: orange;
  /* Move the shadow */
  box-shadow: -5px 5px 25px #000;
}

/* The first line of text */
.box__blurb {
  /* Start with full opacity and centered */
  opacity: 1;
  transform: translateX(45px);
  /* Then transition these chained properties */
  transition:
    opacity 0.5s 2s,
    transform 0.5s 0.5s;
}

/* On .box hover... */
.box:hover .box__blurb {
  /* Fade out */
  opacity: 0;
  /* Move over to the right */
  transform: translateX(-500px);
}

/* The second line of text */
.rect__blurb {
  /* Start with no opacity and pushed off the element */
  opacity: 0;
  transform: translateX(500px);
  /* Then transition these chained properties */
  transition: 
    opacity 0.5s 1s,
    transform 0.5s 1s;
}

/* On .box hover... */
.box:hover .rect__blurb {
  /* Face in */
  opacity: 1;
  /* While entering from the right */
  transform: translateX(-100px);
}

以下是我们的成果。为了演示,添加了一些修饰

查看 CodePen 上 Geoff Graham (@geoffgraham) 编写的 Multi-Step Transitions 笔记。

以下是一个按钮的另一个示例,其中所有悬停效果都清晰地分阶段进行

查看 CodePen 上 Chris Coyier (@chriscoyier) 编写的 zrGvaq 笔记。

总结

多步骤动画和过渡是我们可利用的有趣的小技巧,用于在 CSS 中创建丰富、动态的运动。本文中均衡器的例子是一个实际的应用,但 multi-step 过渡还有很多其他用途。事实上,Ana Tudor 在她发表在 CSS-Tricks 上的文章中利用它们 制作了一个令人惊叹的动画。Rémi Lacorne 也 提供了一个很酷的示例,说明如何使用过渡。

您在 CSS 动画中在哪里使用过 multi-step 动画和过渡?您是否制作了一些非常复杂的东西来展示您的动画技巧?或者是一个微妙的触感来增强用户体验?请在评论中告诉我们。