How animate really works in jQuery

Neeraj Singh

By Neeraj Singh

on 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.

1$(function () {
2  $("#lab").css({ background: "yellow", height: "34px", margin: "10px" });
3
4  $("a").click(function () {
5    $("#lab").animate({ height: "100" });
6    return false;
7  });
8});

Html markup is .

1<a href="">click me</a>
2<div id="lab">Hello World</div>

Inside the animate for each property an fx object is created.

1jQuery.each( prop, function( name, val ) {
2  var e = new jQuery.fx( self, opt, name );
3}

Calling new on jQuery.fx returns a JavaScript object instance.

1fx: function( elem, options, prop ) {
2	this.options = options;
3	this.elem = elem;
4	this.prop = prop;
5
6	if ( !options.orig ) {
7		options.orig = {};
8	}
9}

Next in the animate method is a call to e.custom .

1start = 34;
2end = 100;
3unit = "px";
4e.custom(start, end, unit);

start, end and unit values are gleaned from the current state of div.

Here is custom method .

1custom: function( from, to, unit ) {
2	this.startTime = now();
3	this.start = from;
4	this.end = to;
5	this.unit = unit || this.unit || "px";
6	this.now = this.start;
7	this.pos = this.state = 0;
8
9	var self = this;
10	function t( gotoEnd ) {
11		return self.step(gotoEnd);
12	}
13
14	t.elem = this.elem;
15
16	if ( t() && jQuery.timers.push(t) && !timerId ) {
17		timerId = setInterval(jQuery.fx.tick, 13);
18	}
19},

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.

1step: function( gotoEnd ) {
2  var t = now();
3  var n = t - this.startTime;
4  this.state = n / this.options.duration;
5  pos = jQuery.easing['swing'](this.state, n, 0, 1, this.options.duration);
6  this.now = this.start + ((this.end - this.start) * this.pos);
7  this.update();
8}

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.

1jQuery.fx.step._default)( this )

_default method has following code which finally updates the element.

1fx.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.

Stay up to date with our blogs. Sign up for our newsletter.

We write about Ruby on Rails, ReactJS, React Native, remote work,open source, engineering & design.