1 /*
  2  *  Copyright © 2009 Apple Inc. All rights reserved.
  3  */
  4 
  5 /* ==================== Constants ==================== */
  6 
  7 const TKAnimatorLinearType = 0;
  8 const TKAnimatorSplinesType = 1;
  9 const TKAnimatorInvalidArgsException = 2;
 10 
 11 const TKAnimatorAnimationDidIterate = 'animationDidIterate';
 12 const TKAnimatorAnimationDidEnd = 'animationDidEnd';
 13 
 14 /* ==================== TKAnimator ==================== */
 15 
 16 function TKAnimator (duration, delegate, spline) {
 17   // check validity of arguments number
 18   // if (arguments.length != 2 && arguments.length != 3 && arguments.length != 7) {  
 19   //   throw TKAnimatorInvalidArgsException;
 20   //   return false;
 21   // }
 22   // init some base properties
 23   this.ready = false;
 24   this.animating = false;
 25   this.timer = null;
 26   // handle arguments
 27   this.duration = duration; // ms
 28   this.delegate = delegate;
 29   // check we have the required delegation method
 30   // if (!TKUtils.objectHasMethod(this.delegate, TKAnimatorAnimationDidIterate)) {
 31   //   return;
 32   // }
 33   // handle splines arguments, if available
 34   if (arguments.length >= 3) {
 35     this.type = TKAnimatorSplinesType;
 36     this.x1 = spline[0];
 37     this.y1 = spline[1];
 38     this.x2 = spline[2];
 39     this.y2 = spline[3];
 40     this.init();
 41   }
 42   else { // linear animation
 43     this.type = TKAnimatorLinearType;
 44   }
 45   this.ready = true;
 46 };
 47 
 48 TKAnimator.prototype.init = function () {
 49   // calculate the polynomial coefficients
 50   this.cx = 3 * this.x1;
 51   this.bx = 3 * (this.x2 - this.x1) - this.cx;
 52   this.ax = 1 - this.cx - this.bx;
 53   this.cy = 3 * this.y1;
 54   this.by = 3 * (this.y2 - this.y1) - this.cy;
 55   this.ay = 1 - this.cy - this.by;
 56   // compute points
 57   var numberOfPoints = (this.duration / 1000) * 240;
 58   this.curve = new Array(numberOfPoints);
 59   var dt = 1.0 / ( numberOfPoints - 1 );
 60   for (var i = 0; i < numberOfPoints; i++) {
 61     var t = i * dt;
 62     this.curve[i] = {
 63       x : (this.ax * Math.pow(t, 3)) + (this.bx * Math.pow(t, 2)) + (this.cx * t),
 64       y : (this.ay * Math.pow(t, 3)) + (this.by * Math.pow(t, 2)) + (this.cy * t)
 65     };
 66   }
 67 };
 68 
 69 TKAnimator.prototype.start = function () {
 70   if (!this.ready) {
 71     var _this = this;
 72     this.timer = setTimeout(function () { _this.start() }, 0);
 73     return;
 74   }
 75   this.animating = true;
 76   this.lastIndex = 0;
 77   this.startTime = (new Date()).getTime();
 78   this.iterate();
 79 };
 80 
 81 TKAnimator.prototype.stop = function () {
 82   this.animating = false;
 83   clearTimeout(this.timer);
 84 };
 85 
 86 TKAnimator.prototype.iterate = function () {
 87   var ellapsedTime = (new Date()).getTime() - this.startTime;
 88   if (ellapsedTime < this.duration) {
 89     var x = ellapsedTime / this.duration;
 90     // handle splines case
 91     if (this.type == TKAnimatorSplinesType) {
 92       var y = 0;
 93       for (var i = this.lastIndex; i < this.curve.length; i++) {
 94         var point = this.curve[i];
 95         if (point.x >= x && i > 0) {
 96           var previous_point = this.curve[i - 1];
 97           if ((x - previous_point.x) < (point.x - x)) {
 98             this.lastIndex = i - 1;
 99             y = previous_point.y;
100           }
101           else {
102             this.lastIndex = i;
103             y = point.y;
104           }
105           break;
106         }
107       }
108     }
109     this.delegate[TKAnimatorAnimationDidIterate]((this.type == TKAnimatorSplinesType) ? y : x);
110     var _this = this;
111     this.timer = setTimeout(function () { _this.iterate() }, 0);
112   }
113   else {
114     this.delegate[TKAnimatorAnimationDidIterate](1);
115     if (TKUtils.objectHasMethod(this.delegate, TKAnimatorAnimationDidEnd)) {
116       this.delegate[TKAnimatorAnimationDidEnd]();
117     }
118     this.animating = false;    
119   }
120 };
121 
122 /* ==================== CLASS CREATION ==================== */
123 
124 TKClass(TKAnimator);
125