如何在 Web Animation API 中反转无限动画?

How to reverse an infinate animation in Web Animation API?

Web Animation API, we can animate elements by Element.animate interface. The returned 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

当我尝试 reverse() 动画时出现此错误:

Cannot play reversed Animation with infinite target effect end.

reverse() 的行为与 play() 一样,如果动画在“结尾”,它会跳回开头并开始播放。

对于reverse(),这意味着如果调用它时当前时间为零(如您的示例所示),那么它应该跳回到开头。但是,如果您的动画有无限长,那就意味着要跳到无限长!

如果你只是想运行动画的关键帧向后,你可以使用direction 属性.

例如:

animation.effect.updateTiming({ direction: 'reverse' });

但是请注意,与 reverse() 不同的是,在动画进行时更新方向可能会导致它跳转位置。

如果你想前后改变动画方向它正在进行时让它永远重复,你可以:

  1. 设置一个非常长的迭代次数并在该范围的中间开始动画,或者

  2. 使用updateTiming({ direction: 'reverse' })并调整currentTime使其不跳动。像下面这样的东西可能会起作用:

     const ct = animation.effect.getComputedTiming();
     animation.currentTime =
         ct.currentInteration * ct.duration +
         (ct.duration - ct.localTime % ct.duration);
    

进一步注意,即使在 (2) 中使用 updateTiming 如果动画是异步的 运行(例如大多数变换和不透明动画),也会导致动画跳动一点,因为可以在 Javascript 运行 的主线程和 thread/process 动画 运行.

的主线程之间有一些小的延迟

在 (1)(或 updatePlaybackRate())中使用 reverse() 可避免该问题,因为它会在更新之前同步任何异步动画。