【问题标题】:Why does sharing a KeyframesEffect with two Animations cause one animation to never end?为什么与两个动画共享一个关键帧效果会导致一个动画永远不会结束?
【发布时间】:2021-08-06 08:11:38
【问题描述】:

在下面的例子中,一个动画会完成,另一个会继续播放(因为playState不等于finished):

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)
}

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

【问题讨论】:

    标签: javascript web-animations


    【解决方案1】:

    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 变为零。

    【讨论】:

    • 啊,很好,我不知道复制构造函数。这很有用。但这(在我看来)表明设计不够好,因为它的工作方式允许用户以不起作用的免费方式传递引用。也许应该在创建动画时创建效果引用(因此效果已经关联,并且无法将它们传递给另一个动画),因此是一个耦合度更高的 API。否则,这种更松散的耦合会给错误或混乱留下空间。
    • 这是一个公平的观点。该设计的出现主要是因为 Web Animations 最初被指定为包含嵌套效果,但随后被移至第 2 级。嵌套效果遵循 DOM 树操作模型,其中添加一个节点作为另一个节点的子节点会将其从其先前的父节点中删除。同样的行为一直应用到效果树的根部。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-04
    • 2013-09-11
    • 1970-01-01
    • 2013-11-26
    • 1970-01-01
    相关资源
    最近更新 更多