January 25, 2010
jQuery has animate method which is just awesome. Today I looked into jQuery source code to see exactly how animate works.
I will take a simple case of animating a div
from height of 34
to 100
.
Here is test case.
$(function () {
$("#lab").css({ background: "yellow", height: "34px", margin: "10px" });
$("a").click(function () {
$("#lab").animate({ height: "100" });
return false;
});
});
Html markup is .
<a href="">click me</a>
<div id="lab">Hello World</div>
Inside the animate
for each property an fx object is created.
jQuery.each( prop, function( name, val ) {
var e = new jQuery.fx( self, opt, name );
}
Calling new on jQuery.fx returns a JavaScript object instance.
fx: function( elem, options, prop ) {
this.options = options;
this.elem = elem;
this.prop = prop;
if ( !options.orig ) {
options.orig = {};
}
}
Next in the animate method is a call to e.custom
.
start = 34;
end = 100;
unit = "px";
e.custom(start, end, unit);
start, end and unit values are gleaned from the current state of div.
Here is custom method .
custom: function( from, to, unit ) {
this.startTime = now();
this.start = from;
this.end = to;
this.unit = unit || this.unit || "px";
this.now = this.start;
this.pos = this.state = 0;
var self = this;
function t( gotoEnd ) {
return self.step(gotoEnd);
}
t.elem = this.elem;
if ( t() && jQuery.timers.push(t) && !timerId ) {
timerId = setInterval(jQuery.fx.tick, 13);
}
},
As you can see every 13 milliseconds a call to step
method is made.
step
method is where real calculation is done. Here is the code.
step: function( gotoEnd ) {
var t = now();
var n = t - this.startTime;
this.state = n / this.options.duration;
pos = jQuery.easing['swing'](this.state, n, 0, 1, this.options.duration);
this.now = this.start + ((this.end - this.start) * this.pos);
this.update();
}
this.startTime
is the time when the call to animate
was invoked. The step
method is called periodically from custom method. So the value of t
is
constantly changing. Based on the value of t
, value of n
will change. Some
of the values of n
I got was 1, 39, 69, 376 and 387.
While invoking animate method I did not specify a speed. jQuery picked up the
default speed of 400. In this case the value of this.options.duration is 400
.
The value of state would change in each run and it would something along the
line of 0.0025, 0.09, 0.265, 0.915 and 0.945 .
If you don't know what easing is then you should read
this article
by Brandon Aaron. Since I did not specify easing option, jQuery will pickup
swing
easing .
In order to get the value of next position this easing algorithm needs state, n
and duration. When all of it was supplied then pos
would be derived. The value
of pos
over the period of animation would change and it would be something
like 0, 0.019853157161528467, 0.04927244144387716, 0.9730426794137726,
0.9973960708808632.
Based on the value of pos
value of now
is derived. And then update
method
is called to update the screen.
update
method has following code that invokes _default
method.
jQuery.fx.step._default)( this )
_default
method has following code which finally updates the element.
fx.elem.style[fx.prop] = Math.max(0, fx.now);
fx.now value was set in the custom method and here that value was actually applied to the element.
You will have much better understanding of how animate works if you look at the source code. I just wanted to know at a high level what's going on and these are my findings.
If this blog was helpful, check out our full blog archive.