1 // VIEW
  2 
  3 /**
  4  * @class
  5  */
  6 function Animation(subject, callback, time) {
  7     //subject: what's being animated
  8     //callback: function to call at the end of the animation
  9     //time: time for the animation to run
 10     if (subject === undefined) return;
 11     //don't want a zoom and a slide going on at the same time
 12     if ("animation" in subject) subject.animation.stop();
 13     this.index = 0;
 14     this.time = time;
 15     this.subject = subject;
 16     this.callback = callback;
 17 
 18     var myAnim = this;
 19     this.animFunction = function() { myAnim.animate(); };
 20     // number of milliseconds between frames (e.g., 33ms at 30fps)
 21     this.animID = setTimeout(this.animFunction, 33);
 22 
 23     this.frames = 0;
 24 
 25     subject.animation = this;
 26 }
 27 
 28 Animation.prototype.animate = function () {
 29     if (this.finished) {
 30 	this.stop();
 31 	return;
 32     }
 33 
 34     // number of milliseconds between frames (e.g., 33ms at 30fps)
 35     var nextTimeout = 33;
 36     var elapsed = 0;
 37     if (!("startTime" in this)) {
 38         this.startTime = (new Date()).getTime();
 39     } else {
 40         elapsed = (new Date()).getTime() - this.startTime;
 41         //set the next timeout to be the average of the
 42         //frame times we've achieved so far.
 43         //The goal is to avoid overloading the browser
 44         //and getting a jerky animation.
 45         nextTimeout = Math.max(33, elapsed / this.frames);
 46     }
 47 
 48     if (elapsed < this.time) {
 49         this.step(elapsed / this.time);
 50         this.frames++;
 51     } else {
 52 	this.step(1);
 53         this.finished = true;
 54 	//console.log("final timeout: " + nextTimeout);
 55     }
 56     this.animID = setTimeout(this.animFunction, nextTimeout);
 57 };
 58 
 59 Animation.prototype.stop = function() {
 60     clearTimeout(this.animID);
 61     delete this.subject.animation;
 62     this.callback.call(this.subject,this);
 63 };
 64