LottieFiles / dotlottie-web

Official LottieFiles player for rendering Lottie and dotLottie animations in the web. Supports React, Vue, Svelte, SolidJS and Web Components.
https://developers.lottiefiles.com/docs/dotlottie-player/
MIT License
191 stars 11 forks source link

Bug: Play() method fails with most intersection observer thresholds #356

Closed joe-westcott closed 1 month ago

joe-westcott commented 2 months ago

Overview

https://codepen.io/joewestcott/pen/eYwqMjL

Hi team, there might be a bug with the dotLottie web player, when using intersection observers with a custom threshold value.

We're trying to lazy load and lazy play animations, using vanilla JS, and the animation fails to play if we use an intersection observer with a custom threshold such as 0.5 to run the play() method.

You can see a simple recreation of this bug at the Codepen link above.

The animation is supposed to load immediately but not play until at least 50% of the animation is visible.

To create the problem, scroll scroll down beyond 50% of the animation, and look at the browser console messages as you do this.

In most cases, the animation will not play, even though dotLottie reports that isPlaying is true, as seen in the browser console messages.

If you scroll past the animation repeatedly in both directions, eventually it will play. (This code calls play() every time that the animation intersection occurs, so eventually the play() method starts to work.)

Maybe there's some sort of race condition where the play() method isn't available right away?

There's no error message when we call play(), so it's unclear why this method is not working.

...

Consuming repo

https://github.com/LottieFiles/dotlottie-web

...

Labels

theashraf commented 1 month ago

Hi @joe-westcott,

As you mentioned, the issue seems to be a race condition. The player has an internal Intersection Observer for lazy playing, which freezes/unfreezes the animation loop when it's offscreen as a performance optimization, and this behavior is enabled by default.

If you plan to manage this behavior manually, you can disable it by passing a renderConfig object with the freezeOnOffscreen property set to false:

const dotLottie = new DotLottie({
  canvas,
  src,
  loop: true,
  autoplay: false,
  renderConfig: {
    freezeOnOffscreen: false
  }
});

I also suggest pausing the animation when it's off the viewport, as this can help save resources.

I've updated the example -> https://codepen.io/lottiefiles/pen/qBeEaVz?editors=0010

theashraf commented 1 month ago

also investigating why play is not available when the offscreen optimization is applied...

joe-westcott commented 1 month ago

Thank you, @theashraf , for sharing this freezeOnOffscreen option and forking the Codepen to show it in action.

This seems great!

Is there a repo where we can contribute to the web player renderconfig documentation -- https://developers.lottiefiles.com/docs/dotlottie-player/dotlottie-web/api/render-config/ -- to make a PR to add documentation about freezeOnOffscreen and also the autoResize option that I happened to find in a release note but which also doesn't seem to be in the docs yet?

Apart from that, I created this observer to manage play and pause partly because animations didn't seem to be freezing offscreen by default, but maybe I got that wrong or maybe that was a limitation in an older version of the player, so I'll test again, thank you.

theashraf commented 1 month ago

@joe-westcott Thank you for your feedback! I've updated the documentation to include details about both the freezeOnOffscreen and autoResize options. ~I'm also investigating the issue of not handling offscreen animations properly, and will keep you posted on any further improvements.~ Feel free to check the updated docs.

I've updated the example here https://codepen.io/lottiefiles/pen/qBeEaVz?editors=0010 to show that the player doesn't render when the canvas is offscreen

joe-westcott commented 1 month ago

This is all great! Thank you, @theashraf!