Javascript 停止渲染

Javascript 停止渲染,javascript,three.js,lag,Javascript,Three.js,Lag,我正在一个基本的3d场景中使用ThreeJS,这个场景有轨道控制。一切都很好,但它会导致我的整个网站滞后,因为即使用户不看它,它也会自动循环。我想要一个函数,当满足某些条件时(在本例中,用户没有查看画布),我可以调用该函数来启动和停止渲染。我有一个启动功能,工作得很好,但停止功能似乎不起作用,因为我的网站在ThreeJS初始化后速度慢得令人无法忍受 我一直在寻找这个问题的解决方案,并找到了一些“解决方案”,但无论出于什么原因,它们都不能与我的应用程序一起工作。我的假设是这些解决方案来自Three

我正在一个基本的3d场景中使用ThreeJS,这个场景有轨道控制。一切都很好,但它会导致我的整个网站滞后,因为即使用户不看它,它也会自动循环。我想要一个函数,当满足某些条件时(在本例中,用户没有查看画布),我可以调用该函数来启动和停止渲染。我有一个启动功能,工作得很好,但停止功能似乎不起作用,因为我的网站在ThreeJS初始化后速度慢得令人无法忍受

我一直在寻找这个问题的解决方案,并找到了一些“解决方案”,但无论出于什么原因,它们都不能与我的应用程序一起工作。我的假设是这些解决方案来自ThreeJS的旧版本

以下是我在main.js文件中的代码:

var scene, 
    camera, 
    controls,
    render,
    requestId = undefined;


function init() {
    scene = new THREE.Scene();
    var threeJSCanvas = document.getElementById("threeJS");
    camera = new THREE.PerspectiveCamera( 75, threeJSCanvas.width / threeJSCanvas.height, 0.1, 1000 );

    controls = new THREE.OrbitControls( camera );

    // Controls and Camera settings

    // Create Geometry.

}

function render() {
    requestId =  requestAnimationFrame(render);
    renderer.render(scene, camera);

}

function start() {
    render();
}

function stop() {
   window.cancelAnimationFrame(requestId);
   requestId = undefined;


}
在我的另一个javascript文件中,我的pageChange函数(这是一个多页应用程序)中有一个条件,如下所示:

if (page == 5) { // The page with the canvas on it
    if (!locationsRendered) {
    init();
    locationsRendered = true;
}
} else { // If the page is not the page with the canvas on it
    if (locationsRendered) {
        stop();
    }
}
locationsRendered
在本地范围的第二个javascript文件中初始化


任何帮助都将不胜感激,因为我不能让这个简单的3D场景在加载后延迟我的整个应用程序。这是不现实的

如果场景是静态的,则没有理由进行动画循环。仅当相机由于鼠标或触摸事件而移动时,才需要重新渲染

只需使用以下模式:

controls = new THREE.OrbitControls( camera, renderer.domElement );

controls.addEventListener( 'change', render );

function render() {

    renderer.render( scene, camera );

}

three.js r.67

我在场景中使用了轨迹球控件,因此无法使用上述解决方案(因为轨迹球控件在鼠标事件完成触发后继续更新)

为了解决这个问题,我使用了:

function animate() {
  renderer.render(scene, camera);
  controls.update();
}
renderer.setAnimationLoop(animate);
无限期运行动画循环的。要暂停动画,可以指定
null
作为动画循环:

renderer.setAnimationLoop(null);        // pause the animation
要恢复动画,只需再次传递动画循环:

renderer.setAnimationLoop(animate);     // resume the animation

完全停止渲染循环的另一种解决方案是降低每秒帧数,从而减少资源消耗

如果您需要对场景进行响应性更新,而不一定要设置动画,但需要在需要时恢复正常速度,则此方法特别有用

一个简单的setTimout()可以很好地实现这一点

var fps 10;

function render() {

   //reduce framerate
   setTimeout(()=>{

        requestAnimationFrame(render);

        //must be called to enable rotating
        controls.update();
        renderer.render(scene, camera);


   }, 1000/fps)

};

您的场景看起来是静态的。对吗?如果是这样,您不需要每秒重新渲染60次。这是非常正确的,除了控件之外,没有任何动画。出于某种原因,我认为为了使控件平稳运行,它需要以60fps的速度渲染。我会解决的,我会回来报到的!只需添加
controls.addEventListener('change',render)这对性能有很大帮助。非常感谢你!现在我只需要修改一些东西来隐藏画布,或者至少在不需要的时候禁用它的控件。有没有什么方法可以将您的响应转换为一个答案,以便我选择它作为最佳答案?我这样做了,如果event.target.id!=“threeJS”和我的应用程序运行得更快、更高效。非常感谢你的帮助!