如果您曾经想在 CSS @keyframes
动画的每次迭代之间添加一个暂停,您可能已经很沮丧地发现 CSS 中没有内置的方法来做到这一点。当然,我们可以使用 animation-delay
延迟一组 @keyframes
的开始,但是没有办法在关键帧的第一次迭代和后续每次运行之间添加时间。
当我想要调整 这个流星动画 以用作太空主题员工门户网站主页横幅的背景时,出现了这种情况。我想使用更少的星星来减少对主要内容的干扰,防止 CPU 过热,并且仍然使流星看起来是随机的。
不暂停
为了比较起见。
“原始”延迟方法
这是一个示例,说明我在我的流星动画分支中应用了 传统的关键帧延迟技术。
这种方法包括确定我们希望迭代之间的延迟时间有多长,然后将关键帧压缩到 100% 的一部分。然后,我们将动画的最终状态保持到它达到 100% 以实现暂停。
@keyframes my-animation {
/* Animation happens between 0% and 50% */
0% {
width: 0;
}
15% {
width: 100px;
}
/* Animation is paused/delayed between 50% and 100% */
50%, 100% {
width: 0;
}
}
我体验了这种方法的主要缺点:每个关键帧都必须手动调整,这有点痛苦,而且肯定容易出错。如果需要在心理上将所有关键帧重新转换回 100%,那么也更难理解动画在做什么。
新技术:在延迟期间隐藏
另一种技术是创建一个新的 @keyframes
集,它负责在延迟期间隐藏动画。然后,同时应用该动画和原始动画。
.target-of-animation {
animation: my-awesome-beboop 1s, pause-between-iterations 4s;
}
@keyframes my-awesome-beboop {
...
}
@keyframes pause-between-iterations {
/* Other animation is visible for 25% of the time */
0% {
opacity: 1;
}
25% {
opacity: 1;
}
/* Other animation is hidden for 75% of the time */
25.1% {
opacity: 0;
}
100% {
opacity: 0;
}
}
此技术的局限性在于,动画之间的暂停必须是“暂停”关键帧的整数倍。这是因为无限重复的关键帧将立即再次执行,即使有更长时间运行的关键帧应用于同一元素。
有趣的一点:当我开始撰写这篇文章时,我错误地认为缓动函数在 0% 时应用并在 100% 时结束。事实证明,缓动函数应用于每个 CSS 属性,从定义值的第一个关键帧开始,到定义值的下一个关键帧结束(例如,如果关键帧为 25% { left: 0 } 75% { left: 50px}
,则缓动曲线将从 25% 应用到 75%)。事后看来,这完全说得通,因为如果它是总缓动曲线的一个子集,则很难调整您的动画,但我的大脑有点被震撼了。
在上面的 my-awesome-beboop
关键帧示例中,my-awesome-beboop
将在 pause-between-animations
关键帧期间在后台运行三次,然后才会显示给用户,这看起来像是它的第二次循环(实际上是它第五次执行)。
这是一个使用此方法在流星之间添加延迟的示例
无法在延迟期间隐藏您的动画?
如果您需要在延迟期间将动画保持在屏幕上,除了隐藏之外还有另一个选项。您仍然可以使用第二组 @keyframes
,但以抵消或抵消主要动画运动的方式为 CSS 属性设置动画。例如,如果您的主要动画使用 translateX
,则可以在延迟 @keyframes
集中为 left
或 margin-left
设置动画。
以下是一些示例
通过更改 transform-origin
暂停
通过抵消 transform: translateX
并为 left
属性设置动画来暂停
在暂停 translateX
动画的情况下,如果需要暂停动画超过一个迭代,则需要使用更复杂的 @keyframes
。
/* pausing the animation for three iterations */
@keyframes slide-left-pause {
25%, 50%, 75% {
left: 0;
}
37.5%, 62.5%, 87.5% {
left: -100px;
}
100% {
left: 0;
}
}
在暂停期间,您可能会遇到一些轻微的抖动。在上面的 translateX
示例中,球在 slide-left-pause
期间存在一些轻微的振动,因为动画争夺主导地位。
总结
从性能方面来看,最佳选择是在延迟期间隐藏元素或为 transform
设置动画。为 left
、margin
、width
等属性设置动画比为 opacity
设置动画对处理器的占用要大得多(尽管 contain
属性似乎正在改变这一点)。
如果您对此有任何见解或意见,请告诉我!
感谢 Yusuke Nakaya 提供了 我在 CodePen 上分叉的原始流星 CSS 动画。
哇,不错!
感谢您提供的很棒的起始动画,Yusuke!这是最终横幅的代码笔: https://codepen.io/ericdjohnson/pen/fcddfa17891b88a11e483a6e4be47e3a
很棒的东西!感谢分享!帮助我解决了我在动画开始前屏幕上闪烁的一些内容的问题。