javascriptanimationplaybackweb-animationsweb-animations-api

Web Animations API - does negative playback rate impact iterations?


I'm following along with MDN's Web Animations API docs here (full pen here) and I'm running into the following:

I notice that the 'scenery' animations finish despite being created as follows:

const sceneryKeyframes = [
  {
    transform: 'translateX(100%)'
  },
  {
    transform: 'translateX(-100%)'
  }
]
const sceneryBgOptions = {
  duration: 360000,
  iterations: Infinity  // <- this works as long as I don't change the sign of the playback rate
}

// ...

const bg1Animation = $bg1.animate(
  sceneryKeyframes,
  sceneryBgOptions
)

Playback rate gets changed for example like this:

anim.updatePlaybackRate((2/aliceAnimation.playbackRate) * -1);

If I don't change the scenery playback rate, or only change it to positive values, the scenery animations run forever, as intended.

Any thoughts as to why changing the sign of the playback rate would... negate(?) / override(?) the iterations option provided upon initialization?


EDIT

If I explicitly re-play the animation on finish, like this:

sceneries.forEach(sc => {
  sc.addEventListener('finish', () => {
    console.log('animation "finished"')
    sc.play()
  })
})

I get the following console error: index.js:70 Uncaught DOMException: Failed to execute 'play' on 'Animation': Cannot play reversed Animation with infinite target effect end.


MORE EDITS

I think this describes the issue:

The behavior of reverse(), like play(), is that if the animation is at the “end”, it jumps back to the start and begins playing.

For reverse() this means that if the current time is zero when you call it (as in your example), then it should jump back to the beginning. However, if your animation has an infinite length, that would mean jumping to infinity!

That said, even if I set the iterations to some large number as suggested, the animations "finish" shortly after reversing playback rate


Solution

  • Unfortunately there is no concept of an animation that plays indefinitely in reverse with Web Animations.

    An animation plays from the iteration number defined by its iterationStart property (typically 0) and if you reverse it using reverse(), updatePlaybackRate(), or by setting playbackRate directly, it simply plays backwards until that point. i.e. it simply plays it back in reverse to its starting point.

    If you set the direction property, the animation will play backwards indefinitely but changing the direction while the animation is in play will not cause it to update smoothly (unlike using reverse() or updatePlaybackRate()).

    One approach you can use it to set the animation's startTime to a very long time in the past (e.g. -1000 * 60 * 60 for 1 hour in the past) and set its iterations value to a very large number or Infinity. Then you can use reverse() and the like and it will appear to play backwards indefinitely (at least for 1 hour or so depending on that startTime you used and the playback rate you set).