The new minFrameRate option is used to make sure that an animation does not run longer than the time calculated from that frame rate. Time is made up by skipping frames, i.e. skipping execution of the eachStep callback.
360 lines
8.6 KiB
JavaScript
360 lines
8.6 KiB
JavaScript
/* Copyright (c) 2006-2012 by OpenLayers Contributors (see authors.txt for
|
|
* full list of contributors). Published under the 2-clause BSD license.
|
|
* See license.txt in the OpenLayers distribution or repository for the
|
|
* full text of the license. */
|
|
|
|
/**
|
|
* @requires OpenLayers/BaseTypes/Class.js
|
|
* @requires OpenLayers/Animation.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,
|
|
|
|
/**
|
|
* APIProperty: minFrameRate
|
|
* {Number} The minimum framerate for animations. After each step, the time
|
|
* spent in the animation is compared to the calculated time at this frame
|
|
* rate. If the animation runs longer than the calculated time, the next
|
|
* step is skipped.
|
|
*/
|
|
minFrameRate: 30,
|
|
|
|
/**
|
|
* Property: startTime
|
|
* {Number} The timestamp of the first execution step. Used for skipping
|
|
* frames
|
|
*/
|
|
startTime: null,
|
|
|
|
/**
|
|
* Property: animationId
|
|
* {int} Loop id returned by OpenLayers.Animation.start
|
|
*/
|
|
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;
|
|
this.startTime = new Date().getTime();
|
|
OpenLayers.Animation.stop(this.animationId);
|
|
this.animationId = null;
|
|
if (this.callbacks && this.callbacks.start) {
|
|
this.callbacks.start.call(this, this.begin);
|
|
}
|
|
this.animationId = OpenLayers.Animation.start(
|
|
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.Animation.stop(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) {
|
|
// skip frames if frame rate drops below threshold
|
|
if ((new Date().getTime() - this.startTime) / this.time <= 1000 / this.minFrameRate) {
|
|
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
|
|
*
|
|
* Returns:
|
|
* {Float}
|
|
*/
|
|
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
|
|
*
|
|
* Returns:
|
|
* {Float}
|
|
*/
|
|
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
|
|
*
|
|
* Returns:
|
|
* {Float}
|
|
*/
|
|
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
|
|
*
|
|
* Returns:
|
|
* {Float}
|
|
*/
|
|
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
|
|
*
|
|
* Returns:
|
|
* {Float}
|
|
*/
|
|
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
|
|
*
|
|
* Returns:
|
|
* {Float}
|
|
*/
|
|
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
|
|
*
|
|
* Returns:
|
|
* {Float}
|
|
*/
|
|
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
|
|
*
|
|
* Returns:
|
|
* {Float}
|
|
*/
|
|
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
|
|
*
|
|
* Returns:
|
|
* {Float}
|
|
*/
|
|
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"
|
|
};
|