JavaScript Animations from Scratch
Unnecessary UI animations are neat the first time and annoying the second time. The first thing I did with my Mac was turn off the Dock's fish-eye magnification and Finder's genie window minimization. I can think of many websites that have similarly annoying animations. Visual goo that slows me down or makes me leave. It is almost as bad as background music, endless-loop animated gifs and the blink tag.
Sometimes UI animations are functional. I like my Mac Dock hidden to save screen space. When I mouse over to the side of my monitor the Dock slides out quickly. The quickly part is important. I also think that when a web page dynamically adds an item to a list that the famous yellow fade effect usefully draws attention to that new item in a tolerably subtile way.
So if we want to make one of these good JavaScript animations in a web page how should we do it? With an animation library or just code it scratch? Below is the yellow fade animation written both ways.
Yellow Fade
If you don't know what the yellow fade technique is just add an item to the following list.
- item
- item
Using an Animation Library
Using the Yahoo! UI animation library the code for the above example is 115 characters (minimized). Here it is...
function yellowFade(el) {
(new YAHOO.util.ColorAnim(el,
{backgroundColor:{from:'#FFFF66',
to:'#FFFFFF'}})).animate();
}
In order to write the above code we need to include the yahoo.js, dom.js and animation.js libraries which total 28336 bytes minimized or 8162 bytes when minimized and gzipped. That is hefty overhead for our 115 characters if this is the only bit of JavaScript on our page using these library files. Just to get a small animation going there needs to be a new object created and a function property called on that object. It seems over engineered.
Beyond download size, there may be problems hiding in the library files. Many libraries use browser sniffing which reduces the life expectancy of code. Also, for motion animations, library authors frequently assume it is possible to determine the absolute position of an element on a page which is a problem that is not solved, cross-browser, in general. And as always, more code likely means more bugs.
From Scratch
The yellow fade animation written from scratch is only 130 characters.
function yellowFade(el) {
var b = 155;
function f() {
el.style.background = 'rgb(255,255,'+ (b+=4) +')';
if (b < 255) {
setTimeout(f, 40);
}
};
f();
}
This code is simple, self-contained and not difficult to maintain. Just one function call to get the animation started. No need for creating new objects. This simple animation serves as a nice example of closures for someone new to JavaScript. Most importantly there is no need for over 28 KB of library code that you didn't read and don't understand.
JavaScript libraries have been very successful and clearly I like them for many tasks: events and Ajax in particular. I'm not a library nay-sayer. If I was writing a web page with many animations (canvas tag cartoons?) then I'd likely use an animation library. However if I was writing a regular CRUD web page with many animations I'd start to wonder how annoying it would be to use.
Libraries can be deceptively seductive and developers may think the underlying task is so complex that it is beyond their JavaScript ability and needs to be wrapped in a big library. The above example shows using libraries blindly may be unnecessarily costly in bandwidth. The time spent learning the library API could be just as well spent learning JavaScript and writing lean 'n' mean code. Learning JavaScript has a much bigger pay off in the long run.
Comments
Have something to write? Comment on this article.
Yes, for many applications, 28 KB is still big overhead these days. Developers usually have broadband connections and forget that even in the technologically advanced USA, for example, 23% of houses still have dial-up . According to the stats on that linked page, if you are writing a site for black or suburban users in the USA then a bigger fraction of the users will have dial-up. If you are writing a site with a target audience worldwide then the fraction could be much higher. So if you you let 28 KB slide here and there on one page or in various places across your site the cumulative effect will be a noticeably slower site.
My point is to avoid libraries but that using a big library for a small job is probably a mistake. Optimizing for infinite scalability at the expense of other important factors can be one form of premature optimization.
Well. Although many people only have dial-up, the 28KB library can be well cached at the client side. Users may suffer slow reaction the first time but then the library will not be fetched anymore. I agree that using library to solve a simple problem is not worthy. But what if the library can help you do many other things. If you use a 28KB library, you probably won't only use it to play animation. I think the real risk is that if things go wrong in library, you might over work through the whole night trying to find the root cause.
To me, what's important is that JavaScript developers don't use the libraries as a crutch. Peter's point about learning to actually write JavaScript, rather than just learn a library's API, is an excellent one. It's like using Dreamweaver in that you can use DW much more effectively if you understand what it's doing under the hood. Most of the code in the big JavaScript libraries is barely computer science, much less rocket science. I find it very helpful to use Firebug to step through not only my own code, but the library code I'm using so I truly understand everything that's happening in my apps.
Peter, good point!
Understanding Javascript animations is an excellent way to make nice animations on website without being stick to animation libraries that sometimes can make it difficult to create animations beyond the common ones.
Have a look at the one we did on our website at the page: www.vision-sensors-illuminators.com/vision-sensors-svs2-b1.html
We did not use any animation libraries, because no library would have been really useful for this task.
On the other side I have to agree with kangax point of view. Watch out, that web is really changing too fast to allow web-designers to develop their own animations libraries. At the beginning of my careers I wasted some time doing an animation library that now I had through away because of cross-browsers problems and other stuff/bugs that I don't have the time to look into.
Dear Peter, you probably love coding (like most of us), but web designing is becoming more and more sw integration rather than coding from scratch.
Hard coding an animation library will become soon like having the idea of hard-coding a new browser.
Thank, work very nice, this is only the effect I use from Scriptaculous. Now, 100k less in my application. :)
Its been a great job of urs that u r providing us some more material in javscript animation part its help us to increase our creativity a lot, becaz first u give us an idea and then we all just keep on making that idea more effective and attractive thanks for such an important job u r doing for all of us.The starting point of something is the most important part becaz after starting anything any task every other thing just keep omn going with us. soo, that's why i m highly thankful to u..........
Peter,
Great example.
I have a different reason than just dialup users - small embedded web servers.
Almost finished on a project for a configuration and monitoring tool for an expensive special purpose piece of equipment. It has a web server built in, will not have access to the outside world (and the browser may not either).
Problem? I have 150k total to work with - images, script, css, html, webserver configuration file, etc.
To those that commented about not writing your own effects due to a perceived need for constant rewrites. You missed the point entirely.
Two choices:
A. Write these (very simple) scripts once and they work forever. Alternatively, get the code from somebody who knows what they are doing. Most of my effects were written in the 90's with IE4 in mind. None have ever had major rewrites due to browser incompatibilities.
B. Use the currently popular (and bloated) libraries to guarantee constant rewrites due to browser sniffing (among other problems.) Needless to say, the authors of these things did not (and do not) know what they are doing.
So which approach is appropriate, regardless of "how fast the Web is changing?"
Dear David,
after a wrote my porevious comment, unfortunately I have to agree with you. I gave a try to the libraries and most of them are crapy and buggy, for web developer that are not interested in building either reliable websites or webapplication.
i tried with jQuery and TinyMCE, they seem to be the main drivers now. The 1st adds thousands of useless attribute like jQuery="20727248272" in almost all elements of my HTML code.
The 2nd has got a long learning curve and at the end it's not so great.
Hi,
I got started once with a routine like this, and coincidentally, also a nice color fade :) There's a lot of subtle things you can do for design and js-based animation (it doesn't have to be annoying if you know how to build a good interface ;) ). However, with setTimout based functions, I ran into the fact that too much concurrently running timeouts or intervals at high framerates slow things down considerably.
So for those who want to really go all out with animation (and it's worth it, because you can do many things that will never be possible or easy with flash) here's a tip (my own engine works like this as well): use a unified timeline! That is to say, build one function that acts like a continuously running timeline at a set framerate, and build some constructs around it to tie events into it (or event chains, like all the steps of a color fade). This way you can also easily control the events, and let them influence each other, and the page never slows down, because instead of having to wait for all the out-of-reach timeouts that do their own thing in their own time-thread, you can have the engine "drop frames" (e.g. cancel a bunch of trivial actions meant for a certain timeframe) and keep things happening at the intended speed and in the intended harmony.
I know, maybe this sounds a little complicated, but I made the whole thing work cross browser (ok maybe it won't work on netscape 4) without any weird html, browser sniffing, any libraries from other parties, or even any knowledge of prototyping or proper use of javascript techniques (which I'm reading about on this site now thinking aaah.. so that's what that's for.. every two minutes), so that is just to say, whoever you are, there's still hope for you too to do some real animation ;)
And thanks for taking the time to post such clear and informative articles!
Have something to write? Comment on this article.
I took such approach once and started building site without third-party overhead... In the beginning there were only few things to implement and everything was fine... Later on, though, as things started adding up, I realized that this was a mistake... I ended up writing more and more of reusable modules - something that I could have save time with by simply using library in the beginning...
My point is that it's not about using such things blindly - it's about making sure your app scales nicely and can be easily extended in the future. Considering how fast web environment evolves these days, I think that's a pretty smart thing to do... and seriously, is 28 KB really that big of an overhead with current bandwidth speeds? :)