请求返回结果的动画帧

Request animation frame returning a result?

本文关键字:动画 结果 返回 请求      更新时间:2023-09-26

我脑子里有这个想法,但我想知道它是如何完成的,或者它是否可能。

我有一个这样的请求动画帧:

  window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       || 
          window.webkitRequestAnimationFrame || 
          window.mozRequestAnimationFrame    || 
          window.oRequestAnimationFrame      || 
          window.msRequestAnimationFrame     || 
          function( callback,  element){
            window.setTimeout(callback, 1000 / 60);
          };
})();

我想做的是当它调用一个函数并且动画结束时......我希望它停止调用某种方式。

所以这将是我的想法的伪逻辑:

do{
var result = requestAnimFrame( my_function.bind(null,start) );
}while(result == true);
//rest of code should not run until animation is finished

这可能吗? 如果是这样,我将如何更改我的函数以支持返回?

编辑这是我的动画功能。

function my_function(start){
var now = new Date().getTime() / 1000;
var into_anim = now - start;
    amount = 0.5000;
    opacity = amount * (into_anim - 10);
    opacity = parseFloat(opacity.toFixed(5))
    if(opacity > 1){ opacity = 1; }
if(opacity != 1){
    requestAnimFrame(my_function.bind(null,start));
  }
}

不,requestAnimationFrame 是异步的,就像setTimeout一样。因此,您需要从您的my_function"递归"调用它 - 通过在满足条件时进行另一次调用来结束它。

如果要在动画之后执行某些内容,请使用在满足条件后调用的回调。请注意,您的函数会立即返回,它们只会对函数(自身和回调)在将来的某个时候执行。

function my_function(callback) {
    var start = Date.now();
    frame(); // begin first frame
    function frame() {
        var into_anim = Date.now() - start;
        var opacity = 0.5 * (into_anim - 10);
        if(opacity > 1) {
            opacity = 1;
            callback(); // this was the last frame, do the next thing
        } else
            requestAnimFrame(frame);
     }
}

称之为:

my_function(function(){ alert("It's done"); });
alert("It just began");

好吧,requestAnimationFrames 返回一个 ID,该 ID 可用于通过调用 cancelAnimationFrame(ID) 或每个浏览器中的浏览器等效来停止动画。

您可能想要做的是设置一个可从回调函数访问的 var。 或者在回调函数中定义一些东西来运行cancelAnimationFrame();

也许像这样:

编辑:

我误解了请求动画框架。 它实际上要求您每次准备好新帧时调用它。 因此,只是不调用它会阻止动画继续。 更新了以下示例:

requestAnimFrame(animCallback);
var postAnimCallback = function(){
     alert('called after animation done');
}    
function animCallback(){
    if(typeof animCallback.count == 'undefined'){
        animCallback.count=0;
    }
    animCallback.count++;
    if(animCallback.count < 300){// or whatever condition you want to check to be sure you are ready for it to animate again.
        requestAnimFrame();
    } else { //since we aren't calling animateframe again, run callback code
        alert('animation done');
        // or run a previously defined animation callback
        postAnimCallback();
    }
}

希望对您有所帮助!

如果我正确理解您的问题,您希望在满足某些条件后停止动画。为此,最佳做法是使用条件语句。如果满足条件,则调用requestAnimationFrame否则通过调用 cancelRequestAnimationFramecancelAnimationFrame 来停止重绘流,具体取决于您使用的浏览器版本。对于不同的填充代码,我们可以使用以下回退解决方案:

window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] 
                               || window[vendors[x]+'CancelRequestAnimationFrame'];

requestAnimationFrame 的基本前提是,我们不是强制浏览器以给定的恒定帧速率刷新浏览器,即使它无法这样做,我们依靠浏览器功能来管理刷新率,从而直接进入浏览器刷新/重绘,在刷新时,我们可以告诉浏览器对 requestAnimationFrame 执行特定操作。

但回到最初的想法,你可以按如下方式完成希望的任务:

(function() {
    var lastTime = 0;
    var vendors = ['ms', 'moz', 'webkit', 'o'];
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
        window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] 
                               || window[vendors[x]+'CancelRequestAnimationFrame'];
    }
    if (!window.requestAnimationFrame)
        window.requestAnimationFrame = function(callback, element) {
            var currTime = new Date().getTime();
            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
            var id = window.setTimeout(function() { callback(currTime + timeToCall); }, 
              timeToCall);
           lastTime = currTime + timeToCall;
        return id;
    };
    if (!window.cancelAnimationFrame)
        window.cancelAnimationFrame = function(id) {
            clearTimeout(id);
    };
}());
var updating = true,
    animationRequest = null;
animationRequest = requestAnimationFrame(function(func) {
    if (updating) {
        // THE DRAWING FUNCTION. WE SKIP THIS SECTION
        animationRequest = requestAnimationFrame(func);
    }
    else {
        updating = false;
        animationRequest = requestAnimationFrame(func);
    }
}));

希望这有帮助!