如果我有一个像这样使用requestAnimationFrame的循环:
function render() {
// Rendering code
requestAnimationFrame(render);
}
如果我将requestAnimationFrame
放在函数的开头,会有什么不同,比如:
function render() {
requestAnimationFrame(render);
// Rendering code
}
我没有注意到有什么不同,但我看到了这两种实现,它们中的一种在任何方面都更好,还是它们是相同的呢?
编辑:我想过的一件事是,如果我把它放在开头,并且渲染代码需要相当长的时间来运行,比如说10 is,那么将它放在最后不会使10 is的帧率下降吗?
发布于 2016-07-06 08:59:08
requestAnimationFrame
总是异步调用它的回调,所以只要您的呈现代码是同步的,并且不抛出异常,就不会有任何区别。
这基本上是一个风格的选择,选择自己的方法更干净。将其放在顶部可能会强调render
正在调度自己,即使在呈现过程中出现错误时也是如此。将其放在底部允许有条件地脱离呈现循环(例如,当您想暂停游戏时)。
发布于 2016-07-06 09:19:04
很可能不会有任何变化。requestAnimationFrame
方法是异步的,因此无论哪种方式,您的呈现函数都将按预期工作。但是..。停下来的时候有个陷阱。假设您有以下代码:
function render() {
requestAnimationFrame(render);
// Rendering code
}
为了停止下一个呈现,需要调用cancelAnimationFrame
方法,如下所示:
function render() {
requestAnimationFrame(render);
// Rendering code
if (noLongerInterested) {
cancelAnimationFrame();
}
}
否则,render
方法就会无限期地运行。或者,你也可以这样做:
function render() {
// Rendering code
if (stillInterested) {
requestAnimationFrame(render);
}
}
至于帧丢弃,您可以将requestAnimationFrame
看作是一个固定的时间表(以每秒60帧的速度,大约是16 As的间隔)。如果您的代码花费更长的时间,浏览器将开始删除框架。有关如何负责框架的说明,请查看帕特里克·罗伯茨的回答,并使用它进行更一致的呈现。
我希望这能帮上忙!
发布于 2016-07-06 09:23:55
为了回答您的问题,这两个函数只在呈现代码超过动画帧速度(通常为16-33ms左右,取决于浏览器实现)时,才会改变异步回调所需的时间。但是,如果您按照预期使用这个API,那么即使这样也不会有什么不同。
请注意,您选择不使用从requestAnimationFrame
传递的可选参数-- timestamp
。
如果您有任何与增量时间相关的动画要渲染,请确保计算三角形。通常,将动画的“速度”与timestamp
增量(当前的timestamp
减去以前的timestamp
)相乘,以获得对象应该在屏幕上传播的有效距离。当您的呈现代码没有始终如一地花费相同的时间来执行每个帧时,它的效果尤其明显。
演示
var untimed = 20;
var timed = 20;
function untimedRender() {
var then = performance.now() + Math.random() * 100;
while (performance.now() < then) {}
// estimated velocity
untimed += 50 / 30;
document.querySelector('#untimed').style.left = Math.min(Math.floor(untimed), 200) + 'px';
if (untimed < 200) {
requestAnimationFrame(untimedRender);
} else {
last = performance.now();
requestAnimationFrame(timedRender);
}
}
var last;
function timedRender(timestamp) {
var delta = timestamp - last;
var then = timestamp + Math.random() * 100;
last = timestamp;
while (performance.now() < then) {}
// calculated velocity
timed += delta / 30;
document.querySelector('#timed').style.left = Math.min(Math.floor(timed), 200) + 'px';
if (timed < 200) {
requestAnimationFrame(timedRender);
}
}
requestAnimationFrame(untimedRender);
div {
position: absolute;
left: 20px;
width: 10px;
height: 10px;
}
#untimed {
background-color: #F00;
top: 20px;
}
#timed {
background-color: #00F;
top: 50px;
}
<div id="untimed"></div>
<div id="timed"></div>
注意,蓝色方格似乎保持了一个更一致的整体速度。这就是目的所在。
https://stackoverflow.com/questions/38229386
复制相似问题