vasturiano / react-globe.gl

React component for Globe Data Visualization using ThreeJS/WebGL
https://vasturiano.github.io/react-globe.gl/example/world-population/
MIT License
818 stars 150 forks source link

Globe autorotates very quickly if the page is in background for a while #157

Closed mighty-phoenix closed 8 months ago

mighty-phoenix commented 8 months ago

Hey @vasturiano If I switch to some other tab for a while after opening the globe, and switch back to it, the globe autorotates very quickly for a while. Kindly see screen recording for reference.

https://github.com/vasturiano/globe.gl/assets/32777813/ad1ccbd0-4b57-48ab-b0a5-32c56e2992c1

How can I disable this behaviour and allow the globe to keep autorotating at the same speed as before? Quick help would be highly appreciated. Also, is there a way I can autorotate while playing the altitude animation(globeRef.current.pointOfView({ altitude: 1.66 }, 1500);) Thanks! @vasturiano

vasturiano commented 8 months ago

@mighty-phoenix thanks for reaching out.

It might not be immediately obvious why, but this is actually the intended behavior of ThreeJS Orbit Controls.

The value of autoRotateSpeed is set as units of RPM. To keep this average rotation velocity, the orbit controls looks at the time elapsed since the previous animation frame and compensates for that delta, in order to keep up. If you switch to another tab and then return, the previous animation frame was triggered before the tab lost focus, and therefore the time delta will be a longer duration. Thus, when animation is resumed on tab re-focus, what you observe is the controls making up for lost time by accelerating the rotation to its target position.

I should add that this is functionality from the core ThreeJS itself, not this module in specific.

mighty-phoenix commented 8 months ago

@vasturiano Understood. Thanks. And what about my other question: Also, is there a way I can autorotate while playing the altitude animation(globeRef.current.pointOfView({ altitude: 1.66 }, 1500);)? Thanks!

vasturiano commented 8 months ago

@mighty-phoenix that's kind of tricky to do because both the controls autorotate and the altitude change via pointOfView are manipulating the position of the camera.

If the jump towards the new altitude is immediate it's fine, but when you animate the transition they start conflicting, resulting in auto-rotation stopping while the POV animation is running its course.

What you can do is try to compensate for the rotation halting by setting a target longitude at the end of the animation, so that it appears that the rotation continues. It's an approximation, but it might be sufficient for your use case.

Something like this:

const world = globeRef.current;
world.pointOfView({ lng: world.pointOfView().lng - 45, altitude: 1.66 }, 1500)

Adjust the longitude delta (45º) to taste, depending on your auto rotation speed.