在新对象内运行requestAnimationFrame

9

我在运行动画时遇到了问题。这个动画是在 var ob1 = function() {}; 里面的。当调用它时,它会运行一段时间,然后出现错误 Uncaught RangeError: Maximum call stack size exceeded。然而,这个相同的结构在对象外部运行时没有任何问题。

/////////////// Render the scene ///////////////
this.render = function (){

        renderer.render(scene,camera);
        if(isControls == true) controls.update(clock.getDelta());
        this.animate();
        //console.log(true);
        requestAnimationFrame(this.render());
}

/////////////// Update objects ///////////////
this.animate = function (){
        console.log("!");
}

1
requestAnimationFrame 需要一个回调函数,但你只传递了 undefined - elclanrs
2个回答

24
你应该传递一个函数引用给requestAnimationFrame,而不是调用这个函数。
requestAnimationFrame(this.render);

由于您在render函数中使用了this,因此您可能需要使用bind

requestAnimationFrame(this.render.bind(this));

你的版本引起了堆栈溢出(该函数同步调用自身,直到调用栈已满)。



这实际上是我首先尝试的,因为这是我通常做的事情,但它不起作用。它只运行一次并告诉我this.animate()不存在,之后运行this.animate()。如果我把它放在第一位,我会得到“未捕获的类型错误:Type error cleanedupmenufunctions.php:167 render”。 - JVE999
我刚刚更新了我的答案,你需要一个绑定函数,带有固定的 this 值。 - bfavaretto
啊,这行代码 requestAnimationFrame(this.render.bind(this)); 很好用!多次刷新后没有出现任何错误。 - JVE999
1
请注意,在旧版浏览器上不支持bind。我提供的MDN链接包括一个polyfill。 - bfavaretto
2
你不想以这种方式使用bind,因为每次调用bind时都会创建一个新的函数对象。相反,你希望在初始化时提前绑定,例如 const render = this.render.bind(this);,然后在循环中调用 requestAnimationFrame(render)。你也可以按照React的方式,在构造函数中执行 this.render = this.render.bind(this);,然后可以调用 requestAnimationFrame(this.render); - gman

0

我为了让这个类运行起来所做的一些事情,是从另一个示例中看到的。

requestAnimationFrame(() => {
      this.animate()
})

这似乎也可以解决问题,而且没有任何问题!

这是一个threeJS的例子,我在类内部使用它。

https://jsfiddle.net/gentleman_goat66/o5wn3bpf/107/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接