如何将动画帧锁定为1秒

How do I lock animeframe to exactly 1 second?

本文关键字:锁定 1秒 动画      更新时间:2023-09-26

如果我尝试运行在JSfiddle多次发布的代码,我会得到不同数量的div(我假设animeframe在1秒内没有完全完成)

http://jsfiddle.net/ghjKC/133/

    // shim layer with setTimeout fallback
window.requestAnimFrame = (function(){
    return  window.requestAnimationFrame       || 
        window.webkitRequestAnimationFrame || 
        window.mozRequestAnimationFrame    || 
        window.oRequestAnimationFrame      || 
        window.msRequestAnimationFrame     || 
        function(/* function */ callback, /* DOMElement */ element){
            return window.setTimeout(callback, 1000 / 60);
        };
})();
window.cancelRequestAnimFrame = ( function() {
    return window.cancelAnimationFrame            ||
        window.webkitCancelRequestAnimationFrame    ||
        window.mozCancelRequestAnimationFrame         ||
        window.oCancelRequestAnimationFrame        ||
        window.msCancelRequestAnimationFrame        ||
        clearTimeout
} )();
var request;
(function animloop(){
    console.log("render() should be done here and now");
    request = requestAnimFrame(animloop, $("#time").append("<div></div>"));
})();
// cancelRequestAnimFrame to stop the loop in 1sec
console.log("will do cancelRequestAnimFrame in 1sec...")
setTimeout(function(){
    console.log("1sec expired doing cancelRequestAnimFrame() now")
    cancelRequestAnimFrame(request);                
}, 1*1000)

我的问题是如何确保我得到相同的确切数量的div ?

不能保证setTimeoutrequestAnimationFrame回调的精度。

setTimeout是相当不精确的。

requestAnimationFrame取决于系统渲染页面的速度。如果页面非常复杂并且帧速率下降,则回调将被调用的次数远远少于每秒60次。

现在如果你解释一下你的实际问题是什么,我们可以试着找到一个好的解决方案。

您说您希望<div>的数量恒定,这意味着执行的数量恒定。这是时间无法控制的。根据您的用例,您可以直接控制执行的数量。例如,运行60次回调(理想情况下,requestAnimationFrame接近15次)。

编辑根据你的评论:如果你想做一个进度条,在1秒内顺利填充,最好的方法是:使用requestAnimationFrame,第一个参数传递给你的回调是一个高精度的时间。从这个计算你应该填多少进度条。如果时间> 1秒,不要再请求另一帧。

主旨:

var startTime;
function startProgress() {
  startTime = null;
  requestAnimationFrame(progress);
}
function progress(time) {
  if (startTime === null) startTime = time;
  // Compute progress since last frame
  var ratio = (time - startTime) / 1000; // time is in [ms]
  // Here you should update your progress, maybe this:
  // Note I've used Math.min because we might go over 100% due to callback time.
  $(".progressDiv").width(Math.min(ratio, 1) * 300);
  // If we're not done yet, request a new animation frame
  if (ratio < 1) requestAnimationFrame(progress);
}