JavaScript Animate
Saturday Jul 3 2010
Sort of an old topic for these times, but I thought I'd share a small snippet I wrote about a year ago for the live updating Twitter widgets which required a tad bit of animation without the use of a library. Of course, anyone doing a large amount of animation will use some JavaScript library or, when available in a browser - CSS transitions. Ultimately, the goal for the widgets - which would end up on thousands of websites, was to make them as lightweight as possible - so you can't just go around and make jQuery, YUI, or Prototype a requirement. Thus, a simple animation class was in order. One that will work in any browser that supports JavaScript - and can animate any CSS property that is enumerable. Eg: height, weight, font-size, top, left... not color, background-image, text-decoration, etc.Animation class
/**
* @constructor Animate
* @param {HTMLElement} el the element we want to animate
* @param {String} prop the CSS property we will be animating
* @param {Object} opts a configuration object
* object properties include
* from {Int}
* to {Int}
* time {Int} time in milliseconds
* callback {Function}
*/
function Animate(el, prop, opts) {
this.el = el;
this.prop = prop;
this.from = opts.from;
this.to = opts.to;
this.time = opts.time;
this.callback = opts.callback;
this.animDiff = this.to - this.from;
}
/**
* @private
* @param {String} val the CSS value we will set on the property
*/
Animate.prototype._setStyle = function(val) {
switch (this.prop) {
case 'opacity':
this.el.style[this.prop] = val;
this.el.style.filter = 'alpha(opacity=' + val * 100 + ')';
break;
default:
this.el.style[this.prop] = val + 'px';
break;
};
};
/**
* @private
* this is the tweening function
*/
Animate.prototype._animate = function() {
var that = this;
this.now = new Date();
this.diff = this.now - this.startTime;
if (this.diff > this.time) {
this._setStyle(this.to);
if (this.callback) {
this.callback.call(this);
}
clearInterval(this.timer);
return;
}
this.percentage = (Math.floor((this.diff / this.time) * 100) / 100);
this.val = (this.animDiff * this.percentage) + this.from;
this._setStyle(this.val);
};
/**
* @public
* begins the animation
*/
Animate.prototype.start = function() {
var that = this;
this.startTime = new Date();
this.timer = setInterval(function() {
that._animate.call(that);
}, 4);
};
The background on its design was from a technique Y.U.I. came up with in its initial launch in the Animation internals. It's time-based, overclocked, and plays catchup for browsers that tend to run slower. Hence, the animation looks smoother in faster browsers, but does not get ahead of itself.
Bonus
Use transitions when possible. Generally speaking, the faster browsers tend to be ahead of their time anyway, and provide an alternative to animations with CSS transitions - so why not take advantage of this.transition
/**
* @static
* @boolean
* allows us to check if native CSS transitions are possible
*/
Animate.canTransition = function() {
var el = document.createElement('foo');
el.style.cssText = '-webkit-transition: all .5s linear;';
return !!el.style.webkitTransitionProperty;
}();
How does it all work in practice?
Fade In Example
if (Animate.canTransition) {
el.style.webkitTransition = 'opacity 0.5s ease-out';
el.style.opacity = 1;
}
new Animate(el, 'opacity', {
from: 0,
to: 1,
time: 500,
callback: done
}).start();
In the end, it's barebones, but works efficiently. If you need more out of it, tweak it to your liking, or really, just use a library – which won't be uncommon.
Oh right, yeah, almost forgot - these wouldn't be proper without a demo page. Cheers.
recent
- Matador: The Obvious MVC Framework for Node
- Sandboxing JavaScript
- Crouching Ender, hidden command
- Ender.js - The open submodule library
- Qwery - The Tiny Selector Engine
- Klass
- Smallest DOMReady code, ever.
- $script.js - Another JavaScript loader
- About that slowness on Twitter...
- Autocomplete Fuzzy Matching
- JavaScript Cache Provider
- JavaScript Animate
- Asynchronous method queue chaining in JavaScript
- Something changed
- Unofficial Twitter Widget Documentation
i am dustin diaz

