In the following example, one animation will complete, and the other will keep going (because playState is not equal to 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)
}
Why does one animation never get "finished"?
AnimationEffects, of whichKeyframeEffectis a subclass, cannot be shared betweenAnimations. This is because they rely on various state associated with theirAnimation.(In particular, they need to know if they are associated with a transition / CSS animation in order to stack correctly, and they need to know their animation's playback rate in order produce the right value at the ends of their active interval.)
As a result, if you try to associate an
AnimationEffectwith anAnimation, it is removed from anyAnimationit was previously associated with. This is specified in the procedure to set the associated effect of an animation.Incidentally, this is why the
KeyframeEffectinterface has a "copy constructor" so that you can cloneKeyframeEffects.So in your example you could address this using:
Now, as for why one of the animations never finishes, that appears to be a bug in Chrome. In Firefox the first animation (which lost its
AnimationEffect) will terminate almost immediately after starting because its associated effect end becomes zero.