Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions packages/viewer/src/components/viewer/frame-limiter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,31 @@ const FrameLimiter: React.FC<FrameLimiterProps> = ({ fps = 50 }) => {
set({ frameloop: 'never' })
raf = requestAnimationFrame(tick)

// Browsers throttle requestAnimationFrame when the tab is hidden, the
// window is unfocused, or the system marks the tab as occluded. With
// frameloop="never" rAF is the only render driver, so when it stalls the
// canvas freezes — Linux Firefox/Chrome and Zen show this as the viewer
// "turning off" between cursor interactions. Force one synchronous
// advance whenever the page resumes so the next visible frame matches the
// current scene state.
function kick() {
i += 1 / 1000
advance(i)
}
function onVisibilityChange() {
if (document.visibilityState === 'visible') kick()
}
document.addEventListener('visibilitychange', onVisibilityChange)
window.addEventListener('focus', kick)
window.addEventListener('pageshow', kick)

return () => {
if (raf) {
cancelAnimationFrame(raf)
}
document.removeEventListener('visibilitychange', onVisibilityChange)
window.removeEventListener('focus', kick)
window.removeEventListener('pageshow', kick)
set({ frameloop: initFrameloop })
}
}, [fps, advance, set, initFrameloop])
Expand Down