我目前正在尝试使用three.js,它依赖于requestAnimationFrame来执行动画。
问题:在立方体旋转和renderer.render函数调用之前,以下代码不会导致无限递归吗?
function render() {
requestAnimationFrame(render);
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render(scene, camera);
}
render();
代码有效,但我正在努力提高我对javascript的整体理解。
我看到它的方式是将render作为回调函数调用。但这是否意味着javascript继续运行 函数中的代码 停止继续下一次调用?
答案 0 :(得分:4)
这只要求浏览器在下一个渲染循环之前调用你的回调:
只要您准备好在屏幕上更新动画,就应该调用此方法。这将请求在浏览器执行下一次重绘之前调用您的动画函数。
所以这里没有递归,你的函数继续执行。
您还可以使用cancelAnimationFrame
取消回叫请求。
看here。
答案 1 :(得分:0)
requestanimationframe的最简单用法是一次又一次地调用它,直到没有必要为止
我在开发小型图书馆时学到了本课
https://github.com/allenhwkim/jsanimation
用法
import {slideInRight} from 'jsanimation';
slideInRight(el);
答案 2 :(得分:0)
不,堆栈不会爆炸,因为 requestAnimationFrame
的回调是异步执行的。在整个调用堆栈被清除之前,异步代码永远不会运行。有关事件循环的说明,请参阅 this video。
考虑这个演示来说明:
const fakeRAF = cb => setTimeout(cb);
(function rerender() {
fakeRAF(rerender);
console.log(Date.now());
})();
你可以让它运行一整天。当然,requestAnimationFrame
比 fakeRAF
做的工作要多得多,因为它在计算何时触发 cb
方面非常聪明,但是这个简单的演示足以证明它不是递归的,这要归功于setTimeout
提供异步 API。
顺便说一下,doesn't matter 无论是在函数的顶部还是底部调用 requestAnimationFrame
或 fakeRAF
。函数中的所有同步代码都必须在回调被触发之前运行,这样就不会出现下一帧踩到前一帧之类的问题。
答案 3 :(得分:-1)
在第一次render()调用之后,RequestAnimationFrame将异步处理你的渲染函数,每秒约60次调用它。您的函数不是递归的,因为Javascript将继续执行代码。
但是,您应该仅在渲染函数的最末端使用RequestAnimationFrame,作为函数的最后一个命令。想象一下,你有一个大场景,有很多动画:在完成参数更新之前请求下一帧,可能会造成巨大的混乱。
您还可以使用setTimeout处理动画,使用所需的帧速率调用render方法,如下所示:
var desideredFrameRate = 60;
window.myRequestAnimationFrame = function(callback) {
setTimeout(callback, 1000/desiredFrameRate);
}