Closed Ihor0k closed 2 years ago
I've realized that this fix would still not fulfill finished
promise before switching back to the tab.
For those who iterested, I've used this workaround to fake animations while tab is not active:
function runAnimation(animation): Promise<void> {
let timeoutId: number | null = null;
let raf: number | null = null;
function useRequestAnimationFrame() {
if (timeoutId) {
clearTimeout(timeoutId);
timeoutId = null;
}
function loop(t) {
animation.tick(t);
raf = requestAnimationFrame(loop);
}
raf = requestAnimationFrame(loop);
}
function useTimeout() {
if (raf) {
cancelAnimationFrame(raf);
}
animation.tick(performance.now());
timeoutId = setTimeout(() => {
animation.tick(performance.now());
}, animation.duration - animation.currentTime);
}
function run() {
if (document.hidden) {
useTimeout();
} else {
useRequestAnimationFrame();
}
}
document.addEventListener("visibilitychange", run);
run();
return animation.finished.then(() => {
if (timeoutId) clearTimeout(timeoutId);
if (raf) cancelAnimationFrame(raf);
document.removeEventListener("visibilitychange", run);
});
}
When
play()
is called on an inactive tab, the code execution stops at line #851 because in most browsersrequestAnimationFrame
is paused when the tab is inactive. Then animation starts only when switching back to the tab. The fix setsstartTime
toperformance.now()
if play is called on hidden document. It allows to resume an animation from the place where it must be when switching back to the tab.Codepen with the issue: https://codepen.io/Ihor0k/pen/PoRVXWR