【问题标题】:How to reverse an infinate animation in Web Animation API?如何在 Web Animation API 中反转无限动画?
【发布时间】:2020-11-09 08:06:09
【问题描述】:

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

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

Cannot play reversed Animation with infinite target effect end.

【问题讨论】:

  • 它告诉你可以反转动画,但如果目标计数为Infinity,则不能反转循环。一种解决方法是设置一个任意大的数字,例如Number.MAX_SAFE_INTEGER

标签: javascript css web-animations web-animations-api


【解决方案1】:

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 的主线程和运行动画的线程/进程。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-25
    • 1970-01-01
    • 2012-07-10
    • 2016-07-23
    • 2015-11-06
    • 2022-01-05
    相关资源
    最近更新 更多