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