shan
shan

Reputation: 3155

three.js how to stop render when the user can't see the 3d space?

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

Answers (1)

Andy Ray
Andy Ray

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

Related Questions