Transitions for Animation Effects
Doing animation with Ajax is harder than it seems.
The first most common mistake is to do all animation effects at a constant speed. For many types of effects, linear/constant speed animation looks clunky because the animation starts and stops and so abruptly. The solution is to adjust the speed of the animation based on a sinusoidal curve rather than a line so that the transition looks smoother -- basically, it should start slow and end slow and speed up in the middle.
The second most common mistake is to do all animation at a constant frame rate. Given the dramatic DOM performance differences between web browsers and operating systems, an animation with a constant number of frames can take an order of magnitude longer on some users' computers. The solution is to perform animation in a constant amount of time, adjusting the frame rate based on the performance of the user's browser.
The Transition class below is a recipe that can handle any type of animation (linear, sinusoidal, etc) with a variable frame rate:
function Transition(curve, milliseconds, callback) {
this.curve_ = curve;
this.milliseconds_ = milliseconds;
this.callback_ = callback;
this.start_ = new Date().getTime();
var me = this;
this.runCallback_ = function() {
me.run();
};
}
Transition.prototype.run = function() {
if (!this.hasNext()) return;
this.callback_(this.next());
setTimeout(this.runCallback_, 10);
}
Transition.prototype.hasNext = function() {
if (this.done_) return this.oneLeft_;
var now = new Date().getTime();
if ((now - this.start_) > this.milliseconds_) {
this.done_ = true;
this.oneLeft_ = true;
}
return true;
}
Transition.prototype.next = function() {
this.oneLeft_ = false;
var now = new Date().getTime();
var percentage = Math.min(1, (now - this.start_) / this.milliseconds_);
return this.curve_(percentage);
}
The Transition class is designed to be used with a function that defines the curve/speed of the animation. Here are sinusoidal and linear examples:
function SineCurve(percentage) {
return (1 - Math.cos(percentage * Math.PI)) / 2;
}
function LinearCurve(percentage) {
return percentage;
}
You can use one of the functions with the Transition class with the following pattern:
var transition = new Transition(SineCurve, 1000, function(percentage) {
// Move your element percentage of the way through the animation
});
transition.run();
Here is a practical example that moves text diagonally across the screen at a sinuoidal speed:
var element = document.getElementById("animated");
element.style.position = "absolute";
element.style.left = "0px";
element.style.top = "0px";
var transition = new Transition(SineCurve, 1000, function(percentage) {
var x = element.parentNode.offsetWidth - element.offsetWidth;
var y = element.parentNode.offsetHeight - element.offsetHeight;
element.style.left = Math.round(percentage * x) + "px";
element.style.top = Math.round(percentage * y) + "px";
});
transition.run();





Comments
var self = this;
this is AWFULL, self is a predefined variable, please dont modify it. This is FAR better :
var that = this;
Thanks for taking the time to explain this out !
Write a Comment