为什么与两个动画共享一个关键帧效果会导致一个动画永远不会结束?

Why does sharing a KeyframesEffect with two Animations cause one animation to never end?

在下面的示例中,一个动画将完成,另一个将继续(因为 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)
}

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

AnimationEffects,其中KeyframeEffect是子类,不能在Animations之间共享。这是因为他们依赖于与其 Animation.

相关的各种状态

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

因此,如果您尝试将 AnimationEffectAnimation 关联,它将从之前关联的任何 Animation 中删除。这在 set the associated effect of an animation.

的过程中指定

顺便说一下,这就是为什么 KeyframeEffect 接口有一个 "copy constructor" 以便您可以克隆 KeyframeEffects.

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

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

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