three.js Uncaught RangeError:渲染循环中超过了最大调用堆栈大小
three.js Uncaught RangeError: Maximum call stack size exceeded in render loop
好的。。对JS和three.JS来说是个新手,我很想知道为什么我在函数自调用中会获得堆栈超越,即three.jss在每个设计中都会自然调用。然而,只有当我将调用从主函数中移除时,才会发生这种情况。
我基本上已经从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父调用之外,我就会得到一个"stackoverflow"错误。。。。
未捕获范围错误:超出了最大调用堆栈大小
所以我的问题是,当render在requestAnimationFrame中调用自己时,这是怎么回事,但当在父调用之外发生同样的事情时,堆栈没有被清除,它失败了?
我错过了什么?
问题出在这一行:
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公开为一个公共函数,你可以——但我怀疑没有任何理由这样做
- Javascript在实现时似乎跳过了一行(如果count==1)
- 我需要迭代一个JSON数组——不知道如何做到——已经搜索过了,但仍然可以'我一点也不知道
- Hammer.js过了一段时间就停止工作了
- grunt contrib jshint-error在定义之前就已经使用过了
- 进行自动实时聊天/虚假聊天,我的javascript跳过了第一个响应
- 正在跳过Ajax调用
- 如果我丢失了调用对象,如何杀死 setInterval()/setTimout()
- 再次调用时跳过了 Ajax
- Mootools 类扩展了调用重写的父方法
- 我试过了,但调用成员单击不适用于输入按钮,它与其他按钮非常不同
- 窗口位置不起作用,我已经尝试过了
- 引导程序下拉不起作用.什么都试过了..(引导2.3.2)
- 为什么将一个值推入我的数组被跳过了
- 七吃九:为什么我的索引8在这个d3选择中被跳过了
- 为什么这个复选框不触发jquery代码onchange?我什么都试过了,但都不起作用
- 尽管通过id进行了调用,但Javascript无法访问jsf outputText(label)元素
- jQuery不工作-'jQuery在定义之前就已经使用过了;
- getElementById有时为null.已经试过了.加载完毕.准备好了
- Javascript跳过函数调用中的参数
- AJAX调用跳过了发送一些参数,或者PHP丢失了一些参数