0

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

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

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

3 回答 3

3

不,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");
于 2012-05-31T20:44:07.837 回答
0

如果我正确理解您的问题,您希望在满足某些条件后停止动画。为此,最佳实践是使用条件语句。如果条件已满足,则根据您使用的浏览器版本,通过调用orrequestAnimationFrame来调用 else 停止重绘流程。对于不同的 polyfill,我们可以使用以下后备解决方案: 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);
    }
}));

希望这有帮助!

于 2012-06-07T12:12:24.020 回答
0

好吧,requestAnimationFrames 返回一个 ID,该 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();
    }
}

希望有帮助!

于 2012-05-31T20:44:54.827 回答