// An animation runs for a duration, in milliseconds. It's up to you,
// however, to start and stop the animation -- animations do not stop
// automatically. You can check to see if an animation is over with the
// isOver() method, and you can see if an animation is running with
// isRunning(). Note that animations can be over, but still running.
//
// You can also supply an optional timeWarp function that warps the percent
// completed for the animation. That warping lets you do easily incorporate
// non-linear motion, such as: ease-in, ease-out, elastic, etc.

/*
    var ANIMATION_DURATION = 1000;
    var pushTimer = new AnimationTimer(ANIMATION_DURATION);
    function animate(){
        var elapsed;
        if (!pushTimer.isOver()){
            updateAnimation(pushTimer.getElapsedTime());//更新时间,根据这个时间来更新动画的位置,这块需要调用getElapsedTime这个时间方法
        }
        window.requestNextAnimationFrame(animate);
    }
    pushTimer.start();
    window.requestNextAnimationFrame(animate);
    
    var linear    = AnimationTimer.makeLinear(),
    easeIn    = AnimationTimer.makeEaseIn(1),
    easeOut   = AnimationTimer.makeEaseOut(1),
    easeInOut = AnimationTimer.makeEaseInOut(),
    elastic   = AnimationTimer.makeElastic(4),
    bounce    = AnimationTimer.makeBounce(5),
    pushTimer.timeWarp = bounce;

*/
/* AnimationTimer..................................................................
    【1】它的大部分功能是代理了Stopwatch(),添加了一个isOver()方法,用来判断是否超过了规定的时间
    【2】@timeWarp:是一个时间扭曲对象,参考上倒做动画用的
*/
AnimationTimer = function (duration, timeWarp)  {
   this.timeWarp = timeWarp;

   if (duration !== undefined) this.duration = duration;
   else                        this.duration = 1000;

   this.stopwatch = new Stopwatch();
};

AnimationTimer.prototype = {
   start: function () {
      this.stopwatch.start();
   },

   stop: function () {
      this.stopwatch.stop();
   },

   getRealElapsedTime: function () {
      return this.stopwatch.getElapsedTime();
   },
   
   getElapsedTime: function () {
      var elapsedTime = this.stopwatch.getElapsedTime(),
          percentComplete = elapsedTime / this.duration;

      if (!this.stopwatch.running)    return undefined;
      if (this.timeWarp == undefined) return elapsedTime;

      return elapsedTime * (this.timeWarp(percentComplete) / percentComplete);
   },

   isRunning: function() {
      return this.stopwatch.running;
   },
   
   isOver: function () {
      return this.stopwatch.getElapsedTime() > this.duration;
   },

   reset: function() {
      this.stopwatch.reset();
   }
};
//下面是一些时间扭曲函数
//缓出:f(x) = 1-(1-X)平方
AnimationTimer.makeEaseOut = function (strength) {
   return function (percentComplete) {//percentComplete表示当前逝去的时间与总时间的百分比,即过去了多少时间
      return 1 - Math.pow(1 - percentComplete, strength*2);
   };
};
//缓入:f(x) = x平方
AnimationTimer.makeEaseIn = function (strength) {
   return function (percentComplete) {
      return Math.pow(percentComplete, strength*2);
   };
};
//缓入缓出:f(x) = x-sin(x*2PI)/2PI
AnimationTimer.makeEaseInOut = function () {
   return function (percentComplete) {
      return percentComplete - Math.sin(percentComplete*2*Math.PI) / (2*Math.PI);
   };
};
//弹簧:f(x) = (1-cos(x*Npasses*PI)*(1-x))+x;Npasses为穿过中轴的次数
AnimationTimer.makeElastic = function (passes) {
   passes = passes || 3;
   return function (percentComplete) {
       return ((1-Math.cos(percentComplete * Math.PI * passes)) *
               (1 - percentComplete)) + percentComplete;
   };
};
/*弹跳,需要用到弹簧的公式。
   当弹起的次数为偶数:f(x) = (1-cos(x*Npasses*PI)*(1-x))+x
   当弹起的次数为奇数:f(x) = 2- ((1-cos(x*Npasses*PI)*(1-x))+x)
*/
AnimationTimer.makeBounce = function (bounces) {
   var fn = AnimationTimer.makeElastic(bounces);
   return function (percentComplete) {
      percentComplete = fn(percentComplete);
      return percentComplete <= 1 ? percentComplete : 2-percentComplete;
   }; 
};
//匀束:f(x)=x
AnimationTimer.makeLinear = function () {
   return function (percentComplete) {
      return percentComplete;
   };
};