首页 > 解决方案 > 为什么与两个动画共享一个 KeyframesEffect 会导致一个动画永远不会结束?

问题描述

在以下示例中,一个动画将完成,而另一个将继续播放(因为 playState 不等于已完成):

const keyframes = new KeyframeEffect(null, [
    { // from
        opacity: 0,
    },
    { // to
        opacity: 1,
    }
], {duration: 2000, easing: 'ease'})

{
    const anim = new Animation(
        keyframes,
        document.timeline
    )

    anim.play()

    requestAnimationFrame(function loop() {
      console.log('1', keyframes.getComputedTiming().progress)
      if (anim.playState != 'finished') requestAnimationFrame(loop)
    }, 100)
}


{
    const anim = new Animation(
        keyframes,
        document.timeline
    )

    anim.play()

    requestAnimationFrame(function loop() {
      console.log('2', keyframes.getComputedTiming().progress)
      if (anim.playState != 'finished') requestAnimationFrame(loop)
    }, 100)
}

为什么一部动画永远不会“完成”?

标签: javascriptweb-animations

解决方案


AnimationEffectsKeyframeEffect是一个子类,s 之间不能共享Animation。这是因为它们依赖于与其相关的各种状态Animation

(特别是,他们需要知道它们是否与过渡/CSS 动画相关联以便正确堆叠,并且他们需要知道其动画的播放速率以便在其活动间隔结束时产生正确的值。)

因此,如果您尝试将 anAnimationEffect与 an关联Animation,它将从Animation之前关联的任何内容中删除。这是在设置动画相关效果的过程中指定的。

顺便说一句,这就是KeyframeEffect接口具有“复制构造函数”以便您可以克隆KeyframeEffects 的原因。

因此,在您的示例中,您可以使用以下方法解决此问题:

const anim = new Animation(
  new KeyframeEffect(keyframes),
  document.timeline
)

现在,至于为什么其中一个动画永远不会完成,这似乎是 Chrome 中的一个错误。在 Firefox 中,第一个动画(丢失它的AnimationEffect)将在开始后几乎立即终止,因为它的关联效果结束变为零。


推荐阅读