问题描述
在Web Animation API中,我们可以通过Element.animate界面对元素进行动画处理。返回的Animation对象可以通过.play()
,.pause()
和.reverse()
播放,暂停或反转。
let img = document.querySelector('#happy-boy');
const boy_animation = [
{ transform: 'rotate(0)' },{ transform: 'rotate(360deg)' },];
const boy_timing = {
duration: 3000,iterations: Infinity,}
let animation = img.animate(boy_animation,boy_timing);
animation.reverse(); // <-- fails with DOM exception
当我尝试反转动画时出现此错误:
Cannot play reversed Animation with infinite target effect end.
解决方法
reverse()
的行为与play()
一样,是如果动画在“结尾”,则它会跳回到起点并开始播放。
对于reverse()
,这意味着如果在调用时当前时间为零(如您的示例中所示),则它应跳回到开头。但是,如果动画的长度是无限的,那意味着跳到无限!
如果只想向后运行动画的关键帧,则可以使用direction
属性。
例如:
animation.effect.updateTiming({ direction: 'reverse' });
但是请注意,与reverse()
不同的是,在动画进行过程中更新方向可能会导致其跳转位置。
如果要在 进行中 使其前后方向改变动画方向,并使其永久重复,则可以:
-
设置非常长的迭代计数,然后在该范围的中间开始动画,或者
-
使用
updateTiming({ direction: 'reverse' })
并调整currentTime
,使其不会跳动。可能会发生以下情况:const ct = animation.effect.getComputedTiming(); animation.currentTime = ct.currentInteration * ct.duration + (ct.duration - ct.localTime % ct.duration);
请注意,如果动画异步运行(例如,大多数变换和不透明度动画),则即使在(2)中使用updateTiming
也会导致动画略微跳动,因为时间之间可能会有一些小的延迟在运行Javascript的主线程和正在运行动画的线程/进程上。
在(1)(或reverse()
)中使用updatePlaybackRate()
可以避免该问题,因为它会在更新异步动画之前对其进行同步。