three.js未捕获的RangeError:渲染循环中超出的最大调用堆栈大小
问题描述:
好吧..对于JS和three.js来说这么新,我很好奇为什么我在函数自我调用中获得堆栈超出, three.js自然地调用每个设计。然而,只有当我从主功能中删除呼叫时才会发生。three.js未捕获的RangeError:渲染循环中超出的最大调用堆栈大小
我已经基本上采用了 three.js-Documentation的立方体示例,我试图设置动画,以便动态添加和减去场景中的对象以及将其发送到特定的画布。从three.js所
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 5;
var render = function() {
requestAnimationFrame(render);
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render(scene, camera);
};
render();
上的动画调用render();
聚焦
原始代码被称为reqestAnimationFrame()
功能的自我。为了打破以备将来使用的程序结构,我将它设置了像这样(在后视线不是最好的选择):
function e3Dview(){
// Set the e Canvas
this.canvas = document.getElementById("eplot3D")
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, this.canvas.width/this.canvas.height, 0.1, 1000);
renderer = new THREE.WebGLRenderer({ canvas: eplot3D });
renderer.setSize(this.canvas.width, this.canvas.height);
var geo = new THREE.BoxGeometry(1, 1, 1);
var mat = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
mat.wireframe = true
this.cube = new THREE.Mesh(geo, mat);
scene.add(this.cube);
camera.position.z = 5;
controls = new THREE.OrbitControls(camera, renderer.domElement);
// Execute render
this.renderloop();
};
e3Dview.prototype.renderloop = function(){
requestAnimationFrame(this.renderloop());
this.cube.rotation.x += 0.01;
this.cube.rotation.y += 0.01;
renderer.render(scene, camera);
};
e3Dview.prototype.sceneClear = function(){
scene.children.forEach(function(object){
scene.remove(object);
});
};
一旦我移动渲染循环的inital父外呼,我得到一个“计算器”错误....
未捕获的RangeError:最大调用堆栈大小超过
所以我的问题是怎么回事,当在requestAnimationFrame没关系,但是当同样的事情发生外渲染调用本身父母叫s大头钉未被清除并且失败?
我错过了什么?
答
的问题是这一行:
requestAnimationFrame(this.renderloop());
这里您可以有效调用renderloop()立即,而不是传递函数为回调requestAnimationFrame,从而导致无限递归循环。
当然人们可能会尝试将其更改为以下,但这样做也不行,因为传递函数原型未绑定任何对象:
requestAnimationFrame(this.renderloop); // This won't work, either.
这里的一个解决方案是结合所述函数应用于所述对象的范围:
requestAnimationFrame(this.renderloop.bind(this)); // This will work, but overhead at 60FPS might not be worth it
我建议移动renderloop功能到e3Dview构造为私有方法,像这样:
function e3Dview(){
var $this = this; // Hold the current object's scope, for accessing properties from within the callback method.
...
function renderloop() {
requestAnimationFrame(renderloop);
$this.cube.rotation.x += 0.01;
$this.cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
renderloop();
}
这不是很漂亮,但通常是这样做的。如果你真的需要将renderloop作为公共函数公开,那么你可以 - 但我怀疑没有理由这么做。
谢谢你队友,这关闭了我的JS知识中的一些空白。真的很有帮助。 – CromeX