Simple Object-Oriented Fade Animation
Normally, I'd just use MooTools for fade animations, but a long-time client wanted a simple, one-time popup that notified her patients that her doctor's office had moved—a temporary courtesy to be removed in a few months.To make the custom popup just a little nicer, I wanted a simple fade effect without the extra framework code. Of course, I could have just copied and pasted the methods in MooTools, but I was feeling creative and shopped around to see if any native JS solutions existed.
I found a solution I liked, though it lacks the greater flexibility of a more object-oriented approach. It also sets foreign attributes, FadeState and FadeTimeLeft, directly on the element
<div id="fadeEl" FadeState="-2" FadeTimeLeft="33">
I am the fade element.
</div>and passes a spliced-together variable that looks up the same element over and over again: document.getElementById(eid),setTimeout("animateFade(" + new Date().getTime() + ",'" + eid + "')", 33);neither of which are optimal.The logic was there, however, and it wasn't hard to convert into an object. The nice thing about objects is that an object is just that: A flexible model of something that once modeled can be easily reused. So, I revamped the function provided there to make it less intrusive and more modular.
I'd originally posted the following re-working in the comments on that site, but this is a slightly more polished example.
Basic Object
The AnimateFade Class
// declare class so we can use the "new" keyword to create unique instances
var AnimateFade = function(elmOrElmId, duration, state) {
this.setOptions(elmOrElmId, duration, state);
this.animate();
};
// prototype its methods
AnimateFade.prototype = {
setOptions: function(elmOrElmId, duration, state) {
this.fadeDuration = duration;
this.element = (typeof elmOrElmId == 'string') ? document.getElementById(elmOrElmId) : elmOrElmId;
this.fadeState = (state && state == 1) ? 1 : 0;
this.fadeTimeLeft = duration;
this.lastTick = this.newTick();
},
newTick: function() {
return (new Date).getTime();
},
getElapsedTicks: function() {
return this.currentTick - this.lastTick;
},
animate: function() {
this.currentTick = this.newTick();
var self = this;
var elapsedTicks = this.getElapsedTicks();
// helper function, called in the timeout below,
// recurses with correct reference to "this"
var helper = function() {
self.animate();
};
if (this.fadeTimeLeft <= elapsedTicks) {
this.element.style.opacity = this.fadeState;
this.element.style.filter = 'alpha(opacity = ' + (this.fadeState * 100) + ')';
return;
}
this.fadeTimeLeft -= elapsedTicks;
var newOptVal = this.fadeTimeLeft / this.fadeDuration;
newOptVal = (this.fadeState == 1) ? (1 - newOptVal) : newOptVal;
this.element.style.opacity = newOptVal;
this.element.style.filter = 'alpha(opacity = ' + (newOptVal * 100) + ')';
this.lastTick = this.currentTick;
this.currentTick = this.newTick();
setTimeout(helper, 24);
}
};
// initializer function
var init = function(elmsOrElmIdArr, duration, state) {
for (var i = 0, l = elmsOrElmIdArr.length; i < l; i++) {
// "new" keyword creates unique instance
new AnimateFade(elmsOrElmIdArr[i], duration, state);
}
};
Instantiations
Single/Multiple Elements, Single Duration and Fade State
To instantiate with one or more elements that will all fade in or out for the same duration:// pass in either string id or element reference
// Example A: fade just one element
var myOnlyElement = ['myUniqueId'];
// Example B: fade multiple elements
var myMultElms = ['myId', document.getElementsByTagName('div')[7], 'anotherId'];
// how long fade should last
var myDuration = 1000;//1,000 milliseconds, or 1 second
// start fading out
init(myMultElms, myDuration);
// or fading in
init(myMultElms, myDuration, 1);Multiple Elements, Durations, and Fade States
Or retool the initializer function...// initializer function capitalizing on parallel arrays
var init = function(elmsOrElmIdArr, duration, state) {
for (var i = 0, l = elmsOrElmIdArr.length; i < l; i++) {
// "new" keyword creates unique instance
new AnimateFade(elmsOrElmIdArr[i], duration[i], state[i]);
}
};
...to take full advantage of arrays, simultaneously fading multiple elements in and out for different lengths of time:
// set parallel arrays var myElms = [elm1, elm2, elm3]; var myDurations = [1000, 2500, 300]; var myStates = [0, 1, 0]; // start effects init(myElms, myDurations, myStates); // elm1 fades out in 1 second // elm2 fades in in 2-and-a-half seconds // elm3 fades out in 3/10ths of a secondThis could be useful if you wanted to fade in one set of elements while simultaneously fading out another set, perhaps a confirmation dialog and its acknowledge that the user's choice has either been implemented or canceled. Or whatever.



