Files
openlayers/lib/OpenLayers/Tween.js
Tim Schaub c151b04257 Use requestAnimationFrame for tweening.
Instead of using an arbitrary interval for tweening, we let the device decide the best animation frame rate.  Where requestAnimationFrame is not available, this will default to 60 fps.
2012-01-02 20:52:46 -07:00

312 lines
7.5 KiB
JavaScript

/* Copyright (c) 2006-2011 by OpenLayers Contributors (see authors.txt for
* full list of contributors). Published under the Clear BSD license.
* See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
* @requires OpenLayers/BaseTypes/Class.js
*/
/**
* Namespace: OpenLayers.Tween
*/
OpenLayers.Tween = OpenLayers.Class({
/**
* APIProperty: easing
* {<OpenLayers.Easing>(Function)} Easing equation used for the animation
* Defaultly set to OpenLayers.Easing.Expo.easeOut
*/
easing: null,
/**
* APIProperty: begin
* {Object} Values to start the animation with
*/
begin: null,
/**
* APIProperty: finish
* {Object} Values to finish the animation with
*/
finish: null,
/**
* APIProperty: duration
* {int} duration of the tween (number of steps)
*/
duration: null,
/**
* APIProperty: callbacks
* {Object} An object with start, eachStep and done properties whose values
* are functions to be call during the animation. They are passed the
* current computed value as argument.
*/
callbacks: null,
/**
* Property: time
* {int} Step counter
*/
time: null,
/**
* Property: animationId
* {int} Loop id returned by OpenLayers.Util.loopAnimation
*/
animationId: null,
/**
* Property: playing
* {Boolean} Tells if the easing is currently playing
*/
playing: false,
/**
* Constructor: OpenLayers.Tween
* Creates a Tween.
*
* Parameters:
* easing - {<OpenLayers.Easing>(Function)} easing function method to use
*/
initialize: function(easing) {
this.easing = (easing) ? easing : OpenLayers.Easing.Expo.easeOut;
},
/**
* APIMethod: start
* Plays the Tween, and calls the callback method on each step
*
* Parameters:
* begin - {Object} values to start the animation with
* finish - {Object} values to finish the animation with
* duration - {int} duration of the tween (number of steps)
* options - {Object} hash of options (for example callbacks (start, eachStep, done))
*/
start: function(begin, finish, duration, options) {
this.playing = true;
this.begin = begin;
this.finish = finish;
this.duration = duration;
this.callbacks = options.callbacks;
this.time = 0;
OpenLayers.Util.stopAnimation(this.animationId);
this.animationId = null;
if (this.callbacks && this.callbacks.start) {
this.callbacks.start.call(this, this.begin);
}
this.animationId = OpenLayers.Util.loopAnimation(
OpenLayers.Function.bind(this.play, this)
);
},
/**
* APIMethod: stop
* Stops the Tween, and calls the done callback
* Doesn't do anything if animation is already finished
*/
stop: function() {
if (!this.playing) {
return;
}
if (this.callbacks && this.callbacks.done) {
this.callbacks.done.call(this, this.finish);
}
OpenLayers.Util.stopAnimation(this.animationId);
this.animationId = null;
this.playing = false;
},
/**
* Method: play
* Calls the appropriate easing method
*/
play: function() {
var value = {};
for (var i in this.begin) {
var b = this.begin[i];
var f = this.finish[i];
if (b == null || f == null || isNaN(b) || isNaN(f)) {
throw new TypeError('invalid value for Tween');
}
var c = f - b;
value[i] = this.easing.apply(this, [this.time, b, c, this.duration]);
}
this.time++;
if (this.callbacks && this.callbacks.eachStep) {
this.callbacks.eachStep.call(this, value);
}
if (this.time > this.duration) {
this.stop();
}
},
/**
* Create empty functions for all easing methods.
*/
CLASS_NAME: "OpenLayers.Tween"
});
/**
* Namespace: OpenLayers.Easing
*
* Credits:
* Easing Equations by Robert Penner, <http://www.robertpenner.com/easing/>
*/
OpenLayers.Easing = {
/**
* Create empty functions for all easing methods.
*/
CLASS_NAME: "OpenLayers.Easing"
};
/**
* Namespace: OpenLayers.Easing.Linear
*/
OpenLayers.Easing.Linear = {
/**
* Function: easeIn
*
* Parameters:
* t - {Float} time
* b - {Float} beginning position
* c - {Float} total change
* d - {Float} duration of the transition
*/
easeIn: function(t, b, c, d) {
return c*t/d + b;
},
/**
* Function: easeOut
*
* Parameters:
* t - {Float} time
* b - {Float} beginning position
* c - {Float} total change
* d - {Float} duration of the transition
*/
easeOut: function(t, b, c, d) {
return c*t/d + b;
},
/**
* Function: easeInOut
*
* Parameters:
* t - {Float} time
* b - {Float} beginning position
* c - {Float} total change
* d - {Float} duration of the transition
*/
easeInOut: function(t, b, c, d) {
return c*t/d + b;
},
CLASS_NAME: "OpenLayers.Easing.Linear"
};
/**
* Namespace: OpenLayers.Easing.Expo
*/
OpenLayers.Easing.Expo = {
/**
* Function: easeIn
*
* Parameters:
* t - {Float} time
* b - {Float} beginning position
* c - {Float} total change
* d - {Float} duration of the transition
*/
easeIn: function(t, b, c, d) {
return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
},
/**
* Function: easeOut
*
* Parameters:
* t - {Float} time
* b - {Float} beginning position
* c - {Float} total change
* d - {Float} duration of the transition
*/
easeOut: function(t, b, c, d) {
return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
},
/**
* Function: easeInOut
*
* Parameters:
* t - {Float} time
* b - {Float} beginning position
* c - {Float} total change
* d - {Float} duration of the transition
*/
easeInOut: function(t, b, c, d) {
if (t==0) return b;
if (t==d) return b+c;
if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
},
CLASS_NAME: "OpenLayers.Easing.Expo"
};
/**
* Namespace: OpenLayers.Easing.Quad
*/
OpenLayers.Easing.Quad = {
/**
* Function: easeIn
*
* Parameters:
* t - {Float} time
* b - {Float} beginning position
* c - {Float} total change
* d - {Float} duration of the transition
*/
easeIn: function(t, b, c, d) {
return c*(t/=d)*t + b;
},
/**
* Function: easeOut
*
* Parameters:
* t - {Float} time
* b - {Float} beginning position
* c - {Float} total change
* d - {Float} duration of the transition
*/
easeOut: function(t, b, c, d) {
return -c *(t/=d)*(t-2) + b;
},
/**
* Function: easeInOut
*
* Parameters:
* t - {Float} time
* b - {Float} beginning position
* c - {Float} total change
* d - {Float} duration of the transition
*/
easeInOut: function(t, b, c, d) {
if ((t/=d/2) < 1) return c/2*t*t + b;
return -c/2 * ((--t)*(t-2) - 1) + b;
},
CLASS_NAME: "OpenLayers.Easing.Quad"
};