Reputation: 3155
I'm making a simple globe render that spins. So far so good, but I'd like to basically pause the render when the user is no longer looking at the dom element that the renderer is a child of, as the element is a ways down on the page and valuable resources are being used where they don't have to be. Here's what I have so far—
window.addEventListener('scroll', () => {
let scrollPosition = document.body.scrollTop;
//element is almost about to be visible, time to start rendering
if (scrollPosition >= topOfElement - 200) {
if (everythingIsLoaded && !isRendering) {
render();
console.log('render has been started');
} else {
//wait until everythingIsLoaded is true
}
//element is not visible, stop rendering
} else {
//need to stop rendering here!
//this doesn't work, dunno how to do this
if (animationFrame) {
stopRendering(render);
console.log('render has been halted');
}
}
});
and my render()
function looks like this—
const render = () => {
animationFrame = requestAnimationFrame( render );
sphere.rotation.y += 0.001;
renderer.render( scene, camera );
isRendering = true;
};
Is there a way to stop the render when the user is no longer able to see the webGL render region?
I tried to do something like this (as you can see in the above code)—
var stopRendering = (af) => {
cancelAnimationFrame(af);
isRendering = false;
};
but that doesn't seem to actually stop the render at all.
Upvotes: 0
Views: 2647
Reputation: 32076
window.cancelAnimationFrame
accepts the id returned by window.requestAnimationFrame
, which in your case is the variable named animationFrame
. It's the same as setTimeout and clearTimeout.
Right now you're passing it an entire function reference, the render()
function. It's hard to track your use of global variables in the code provided, but you probably just want to do:
if (animationFrame) {
stopRendering(animationFrame);
}
Since in your case you're assigning the id returned by requestAnimationFrame
to the variable animationFrame
.
Upvotes: 1