交错动画

Avatar of David DeSandro
David DeSandro

DigitalOcean 为您旅程的每个阶段提供云产品。从 免费获得 200 美元的信用额度! 开始。

以下是 David DeSandro 的客座文章。David 希望在 Isotope 中提供一项新功能:交错动画。像网络上的许多事物一样,他可以采用多种方法来实现它。在这里,他探讨了一些可能性、每种方法的优缺点,以及他最终为 Isotope 选择的方法。

考虑一下 这个具有电影感的 Seinfeld 片段

乔治穿过一群海鸥的画面触动了人们的情绪。他坚定信念中的能量与鸟儿爆发的能量相呼应。那么,我们如何才能用这种能量来制作动画呢?

乔治·科斯坦扎穿过鸟群

再仔细看看那些海鸥。它们的数量并不多。鸟儿是逐个起飞的。随着每一只鸟的飞翔,它们的数量逐渐增加,情感也随之升华。加油,乔治!

我们可以通过交错动画来重现这种效果,而不是同时为一组项目制作动画。当每个项目的动画都延迟一段时间后,它们会显得独立,但仍然作为一个整体集体移动。结果令人着迷,并且感觉更贴近生活。

我最近发布了 具有全新交错项目过渡的 Isotope v3

查看 David DeSandro (@desandro) 在 CodePen 上的笔 Isotope – stagger

虽然项目过渡很容易设置,但可能难以管理。在不同的时间间隔运行大量的动画会变得很复杂。因此,让我们来探讨如何交错项目过渡。

我们将使用一个简单的动画作为示例:水平移动一组项目。项目具有 CSS transition: transform 0.4s;。它们通过切换 .is-moved 类来移动。第一个演示同时移动所有项目。

查看 David DeSandro (@desandro) 在 CodePen 上的笔 single transition

setTimeout

我们可以使用 setTimeout 来交错触发过渡。setTimeout 将在 JavaScript 中使用延迟来稍后启动过渡。

查看 David DeSandro (@desandro) 在 CodePen 上的笔 setTimeout

这看起来确实不错。为了微调动画,我希望项目在移动时不会重叠。因此,向右移动时,右侧的项目首先开始移动;向左移动时,左侧的项目首先开始移动。如果要向右移动,我们需要反转 setTimeout 延迟。

查看 David DeSandro (@desandro) 在 CodePen 上的笔 setTimeout, forward & reversed

还不错!但现在任何动画系统的首要测试来了:动画过程中触发更改时会发生什么?这种边缘情况经常被忽视。任何新手开发人员都可以添加动画。但如果您关心用户,则您的动画在受到用户操作时应立即做出反应。动画不应妨碍用户操作。

尝试在过渡期间单击按钮以查看会发生什么。

它可以工作。所有项目最终都到达了它们应该在的位置。但我不喜欢它的行为方式。看起来项目好像有点混乱。还可以尝试未反转的演示。

向前/向后过渡会持续贯穿所有项目。这不好。在用户已经反转操作后,动画仍在继续。

transition-delay

让我们尝试其他方法。我们已经在使用 CSS 过渡,因此使用 transition-delay 是有意义的。此演示使用 JavaScript 在 JS 中设置增量 transition-delay(但如果需要,也可以使用 CSS 预处理器逻辑)。所有项目的过渡同时触发,但它们的延迟因 transition-delay 值而异。

查看 David DeSandro (@desandro) 在 CodePen 上的笔 transitionDelay

我们可以反转延迟,以获得与 setTimeout 演示类似的向左和向右移动行为。

查看 David DeSandro (@desandro) 在 CodePen 上的笔 transitionDelay, forward & reversed

至于启动和停止,此 transition-delay 演示的行为有所不同。向前/向后演示会在原地暂停片刻。

这或许可以,但其行为仍然不是理想的。

基于帧的动画

还有一种方法可以尝试:基于帧的动画。使用 requestAnimationFrame 使我们可以控制每个过渡的触发方式和触发时间。

查看 David DeSandro (@desandro) 在 CodePen 上的笔 frame animation

它具有完美的行为。启动和停止会在当前位置反转动画,因此没有延迟和多余的过渡。但是,这种良好的结果是以复杂性为代价的。此演示需要两倍的 JavaScript 代码量,并且必须在每一帧运行一个动画循环。


因此,如果您想要交错动画,您有很多选择。

  • setTimeout 可以工作,但很难取消。
  • transition-delay 可以工作,但可能会有延迟。
  • requestAnimationFrame 可以工作,但需要更多 JavaScript 代码。

并且还有更多解决方案:CSS 动画、jQuery .animate()、GreenSock、D3,等等等等。所有这些解决方案都可用于交错动画。但我鼓励您调查一下,当用户在动画期间执行操作时,它们在处理边缘情况方面的表现如何。

在开发 Isotope 时,我选择使用 transition-delay 技术。它提供了最佳的控制水平,而不会过于复杂。现在,Isotope 用户可以为他们的 UI 添加最终的润色,并将他们的体验提升到新的水平。就像科斯坦扎追逐他的梦想一样。