我有一个带有可配置3d对象的网站,它有一些属性,当我更改这些属性时,我用3d对象重新加载div以反映新属性。它工作正常,但脚本数据不断添加。 30次重新加载后脚本不仅运行速度变慢,而且会发生这种情况。我将旋转对象旋转添加到渲染功能,每次重新加载按钮都会保持旋转速度更快!在5次重新加载后,它疯狂地旋转。旋转功能很简单:
function animate() {
if (typeof(objektas) !== 'undefined') {
rotation++;
if (rotation >= 360) rotation = 0;
objektas.rotation.y = rotation * Math.PI * 2 / 360;
}
requestAnimationFrame(animate, renderer.domElement);
renderer.render(scene, camera);
}
我的猜测是,每次加载渲染时,这些动画函数都会被堆叠,例如在第二次重新加载时,它们被调用两次而不是一次。有人可以解释我该如何解决这个问题?
答案 0 :(得分:2)
首次调用animate
时,它将不断重新调用自身。您正在使用递归来创建连续循环。
我的理解是,每次重新加载时,都会重新调用animate
函数。如果再次调用它,则会发生两个连续的animate
循环,在同一个UI线程上交织。您的rotation
变量将以两倍的速度递增。
第三次调用它,现在有三个animate
循环。称之为30次,然后30个交织的循环将导致严重的性能问题。
解决方案:在您第一次调用它的地方,确保只调用一次。
拥有一个全局变量:
var hasCalledAnimate = false;
在你第一次调用它的地方:
if(!hasCalledAnimate) {
hasCalledAnimate = true;
animate();
}
如果你想绝对100%确定没有人可以再次调用它,请使用闭包。
var animate = (function () {
function _animate() {
if (typeof (objektas) !== 'undefined') {
rotation++;
if (rotation >= 360) rotation = 0;
objektas.rotation.y = rotation * Math.PI * 2 / 360;
}
requestAnimationFrame(_animate, renderer.domElement);
renderer.render(scene, camera);
}
var _hasInvoked = false;
return function () {
if (!_hasInvoked) {
_hasInvoked = true;
_animate();
}
}
})();
现在animate
将是真正幂等的 - 您可以根据需要多次调用它,但是您知道循环只会启动一次。