| |||
| [Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] |
I've created a general purpose Animation class that uses the Timer class from http://www.codingforums.com/showthread.php?t=10531. The underlying animation algorithm is the same as the Apple code, however being encapsulated in a class allows independent animations to be easily created. I'm fairly new to _javascript_, so let me know if there's a better way to do things. |
/*
* Source code found at http://www.codingforums.com/showthread.php?t=10531
*/
// The constructor should be called with
// the parent object (optional, defaults to window).
function Timer(){
this.obj = (arguments.length)?arguments[0]:window;
return this;
}
// The set functions should be called with:
// - The name of the object method (as a string) (required)
// - The millisecond delay (required)
// - Any number of extra arguments, which will all be
// passed to the method when it is evaluated.
Timer.prototype.setInterval = function(func, msec){
var i = Timer.getNew();
var t = Timer.buildCall(this.obj, i, arguments);
Timer.set[i].timer = window.setInterval(t,msec);
return i;
}
Timer.prototype.setTimeout = function(func, msec){
var i = Timer.getNew();
Timer.buildCall(this.obj, i, arguments);
Timer.set[i].timer = window.setTimeout("Timer.callOnce("+i+");",msec);
return i;
}
// The clear functions should be called with
// the return value from the equivalent set function.
Timer.prototype.clearInterval = function(i){
if(!Timer.set[i]) return;
window.clearInterval(Timer.set[i].timer);
Timer.set[i] = null;
}
Timer.prototype.clearTimeout = function(i){
if(!Timer.set[i]) return;
window.clearTimeout(Timer.set[i].timer);
Timer.set[i] = null;
}
// Private data
Timer.set = new Array();
Timer.buildCall = function(obj, i, args){
var t = "";
Timer.set[i] = new Array();
if(obj != window){
Timer.set[i].obj = obj;
t = "Timer.set["+i+"].obj.";
}
t += args[0]+"(";
if(args.length > 2){
Timer.set[i][0] = args[2];
t += "Timer.set["+i+"][0]";
for(var j=1; (j+2)<args.length; j++){
Timer.set[i][j] = args[j+2];
t += ", Timer.set["+i+"]["+j+"]";
}}
t += ");";
Timer.set[i].call = t;
return t;
}
Timer.callOnce = function(i){
if(!Timer.set[i]) return;
eval(Timer.set[i].call);
Timer.set[i] = null;
}
Timer.getNew = function(){
var i = 0;
while(Timer.set[i]) i++;
return i;
}/*
* Animation.js
*
* Usage:
*
* function MyAnimation() {
* this.init(500, 0.0, 0.0, 0.0);
* }
* MyAnimation.prototype = new Animation;
*
* MyAnimation.prototype.renderFrame = function() {
* // called once per frame to render
* }
*
* MyAnimation.prototype.animationComplete = function() {
* // called when the animation is complete
* }
* var myAnimation = new MyAnimation();
*
* myAnimation.animate(); // start the animation
*/
/*
* The Animation class should be subclassed to provide an implementation for
* the renderFrame() method.
*/
function Animation(duration, to, now, from, fps) {
if (arguments.length) {
this.init(duration, to, now, from, fps);
}
}
/*
* This method initializes the Animation instance. Subclasses should call it
* from their constructors.
*
* The 'duration' parameter is measured in milliseconds and is the only required
* parameter. The 'to', 'now', and 'from' parameters represent the destination,
* current, and original values for the timeline. They will default to 0. The
* 'fps' parameter specifies a target number of frames per second to render and
* will default to 60 if not specified.
*/
Animation.prototype.init = function(duration, to, now, from, fps) {
this.duration = duration;
this.starttime = null;
this.to = to ? to : 0;
this.now = now ? now : 0;
this.from = from ? from : 0;
this.timer = null;
this.intervalId = null;
this.fps = fps ? fps : 60;
}
/*
* The animate method performs the timeline interpolation using the information
* supplied at construction time. The interpolation starts at 'from' and runs
* to 'to'. The current value is stored in 'now'. The animate() method also
* manages timers and frame rendering occurs by calls to the subclass's
* renderFrame() method. When the animation is complete and if the subclass
* implements an animationComplete() method, animationComplete() is called to
* give the subclass a chance to do any final cleanup.
*/
Animation.prototype.animate = function() {
var T;
var ease;
var time = (new Date).getTime();
var mspf = 1000.0 / this.fps;
if (this.timer == null) {
this.starttime = time - mspf;
this.timer = new Timer(this);
this.intervalId = this.timer.setInterval("animate", mspf);
}
T = limit_3(time - this.starttime, 0, this.duration);
if (T >= this.duration) {
this.cancel();
this.now = this.to;
if (this.animationComplete) {
this.animationComplete();
}
}
else {
ease = 0.5 - (0.5 * Math.cos(Math.PI * T / this.duration));
this.now = computeNextFloat(this.from, this.to, ease);
}
this.renderFrame();
}
/*
* Cancels an in progress animation and clears the timer.
*/
Animation.prototype.cancel = function() {
if (this.timer != null) {
this.timer.clearInterval(this.intervalId);
this.timer = null;
}
}
/******************************************************************************
* Utility functions *
******************************************************************************/
function limit_3(a, b, c) {
return a < b ? b : (a > c ? c : a);
}
function computeNextFloat(from, to, ease) {
return from + (to - from) * ease;
}On 20-Jun-05, at 9:56 AM, Matt Drance wrote:
|
_______________________________________________ Do not post admin requests to the list. They will be ignored. Dashboard-dev mailing list (email@hidden) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/dashboard-dev/email@hidden This email sent to email@hidden
| References: | |
| >modify animate() function for independent image fades (From: Edward Anastas <email@hidden>) | |
| >Re: modify animate() function for independent image fades (From: Matt Drance <email@hidden>) |
| Home | Archives | FAQ | Terms/Conditions | Contact | RSS | Lists | About |
Visit the Apple Store online or at retail locations.
1-800-MY-APPLE
Contact Apple | Terms of Use | Privacy Policy
Copyright © 2007 Apple Inc. All rights reserved.