请求动画帧返回结果?

时间:2012-05-31 20:37:11

标签: javascript

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

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

  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

这有可能吗?如果是这样,我将如何改变我的功能以支持退货?

EDIT 这是我的动画功能......

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));
  }
}

3 个答案:

答案 0 :(得分:3)

不,requestAnimationFramesetTimeout一样异步。所以,你需要从你的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");

答案 1 :(得分:0)

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

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

可能是这样的:

编辑:

我误解了requestAnimationFrame。它实际上要求您每次准备好新帧时都调用它。因此,不调用它将阻止动画继续。更新后的示例:

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();
    }
}
希望有所帮助!

答案 2 :(得分:0)

如果我正确理解了您的问题,您希望在满足某些条件后停止动画。要做到这一点,最佳做法是使用条件语句。如果已满足条件,则调用requestAnimationFrame,否则通过调用cancelRequestAnimationFramecancelAnimationFrame来停止重绘流程,具体取决于您使用的浏览器版本。对于不同的polyfill,我们可以使用以下后备解决方案:

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);
    }
}));

希望这有帮助!