以下是 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 添加最终的润色,并将他们的体验提升到新的水平。就像科斯坦扎追逐他的梦想一样。
我还在寻找海鸥……不过有很多鸽子。
不错的文章:-)
非常棒,David。您是否考虑过 Web Animation API 选项?我知道——浏览器支持——但未来呢?
不错的文章,David,很好地展示了可用的不同选项。我在我的笔中注入了 animation-delay:http://codepen.io/CodeBoomer/pen/pbONgz 使用 JQuery,很高兴看到 JavaScript 方法。使用 transition-delay 方法,是否有办法检查过渡持续时间,并根据元素数量计算有多少元素已过渡以“取消过渡”。然后可以相应地调整内联延迟以减轻导致暂停的延迟?
Isotope 看起来也很棒!
不错的文章。我宁愿将
new Date
更改为Date.now()
以节省一些 CPU 时间。