Id喜欢一个基于requestAnimationFrame的动画循环,在x之后停止。我试图通过一个在x之后删除cb的setTimeout来实现这一点。但是,由于setTimeout是事件循环中最后一个调用的对象,所以有时在调用删除之前会再呈现一个动画帧。
尽管增量(应该已经取消但不是)总是很小,但这会扰乱我的迭代逻辑。最后一个名为animationFrame 的必须在给定的时间范围x内。
如果已经超过最大值,我非常希望而不是在每个循环中签入。
有什么高优先级的setTimeout吗?也许是基于承诺?
发布于 2019-12-22 04:26:22
setTimeout不是事件循环中最后被调用的东西,相反,实际上,在事件循环模型中,运行动画框架回调是最后要调用的东西之一。
所以我不知道您做了什么,但是使用setTimeout应该很好:
let stopped = false;
const startTime = performance.now();
let rafTime;
let frame_id = requestAnimationFrame( loop );
setTimeout(() => {
cancelAnimationFrame(frame_id);
stopped = true;
console.log( 'stopped' );
console.log( "rAF loop ran for %sms", rafTime - startTime );
}, 2000);
function loop() {
if( stopped ) { console.log( 'failed' ); }
rafTime = performance.now();
frame_id = requestAnimationFrame( loop );
}
另一种解决方案是检查传递给回调的时间戳,因为您可能需要在rAF中使用增量时间。这是个非常快速的手术,别担心这里的香水。
let startTime;
requestAnimationFrame( loop );
function loop( time ) {
if( !startTime ) { startTime = time; }
if( time - startTime >= 2000 ) {
console.log( 'ran for %sms', time - startTime )
return;
}
requestAnimationFrame( loop );
}
这种方法的一件事是,稍后您将知道时间过去了,这意味着您可能会晚一帧。
您可以尝试从持续时间中减去frameRate,但是rAF速率取决于监视器的刷新速率,因此很难计算。
但这也可能是一个优势,因为你也将能够执行最后的帧渲染,通常有用时,做动画,以便最终调用绘制在准确的静态位置。
现在请注意,Chrome已经知道问题了使用他们调用rAF的方式,可能您的代码会因为类似的事情而中断,也许因为其他逻辑而中断,但是如果没有您的代码,我们只能说它应该工作。
https://stackoverflow.com/questions/59441166
复制相似问题