An Introduction to Javascript Animation
Animating elements with Javascript using DOM compliant, non-invasive code
Color fading and resizing to notify user for dynamic changes
created on 29.08.2005
Introduction
Javascript animations are seen more and more in our daily web routines. Most can be annoying too, if they simply serve the purpose to lamely look cool, while they may actually only distract the user.
However, when used properly, they can really add to the user experience, and increase the useability of your site. Also, with the advent of the DOM, the more widespread usage of new generation browsers, and the adoption of xmlHttpRequest and other technologies which all together are called AJAX, the need for notifying user with what is going on with simple animations can become a necessity, such as using fading colors and resizing elements. Actually, I am putting such an animation to good use on this very page, while step-by-step explaining the main animation function for resizing. The principles are all the same, but the color fading was inspired by the Yellow Fade Technique For Dummies, this one is a versatile function that you can fade any color to any color. It is also a very light-weight script that you can modify to use for any type of animation, as you see on this page. If you have specific questions for implementing the scripts in your own sites, feel free to drop me a mail using the contact page oh hesido.com.
Samples
Hover over me!
Hover over me!
Hover over me!
Hover over me!
Hover over me!
Hover over me!
Hover over me!
Hover over me!
Hover over me!
Hover over me!
Hover over me!
Hover over me!
Hover over me!
Hover over me!
Hover over me!
Hover over me!
Hover over me!
Hover over me!
Some details of this technique
- This technique uses for animation.
- Uses no global variables, and animation can be applied to any number of elements simultaneously
- The element is passed to animation function as an object and not with its ID. So it does not use ID's for the animated element, which makes it very comfortable to use; even tho the element can indeed be selected by its ID.
- Thread-safe: The function started with window.setInterval is self inhibiting, it terminates itself once animation is done, and same type of animation does not run with more than 1 instance at a time, so you do not have to worry about un-terminated timeout functions
- It has a "memory" so the terminated animation can be picked up by a newly initiated animation.
- It is very easy to implement and use.
- It sports a simple function to produce ease-in and ease-out motions between any given parameters
- A tip: Multiple varibles can be animated, the fades are actually using multiple parameters (RGB). It is quite a neat habit to pass those multiple parameters as a single array.
The animation code, explained
Doing the resize animation (Main function)
Javascriptfunction doWidthChangeMem(elem,startWidth,endWidth,steps,intervals,powr) { //Width changer with Memory by www.hesido.com if (elem.widthChangeMemInt) window.clearInterval(elem.widthChangeMemInt); var actStep = 0; elem.widthChangeMemInt = window.setInterval( function() { elem.currentWidth = easeInOut(startWidth,endWidth,steps,actStep,powr); elem.style.width = elem.currentWidth + "px"; actStep++; if (actStep > steps) window.clearInterval(elem.widthChangeMemInt); } ,intervals) }
Here is a step by step explanation of the function, please hover for highlighting the step:
- Terminate, if there is any, ongoing animation
- Reset animation step to 0
- Assign interval function with interval id passed to element
- Anonymous function declared within our function, so we can safely use variables from our parent function, even though it is an interval function that runs in the window scope.
- Get a value using , embedding onto the element.
- Use that value to set the object's width
- Increase step number
- If step number is bigger, self-terminate.
Here's a brief explanation of variables used:
elem: element that we're going to animate startWidth: starting width of animation endWidth: target width of animation steps: total steps of animation intervals: intervals the animation will be done in miliseconds powr: value used for determining ease-in and out. ---- elem.widthChangeMemInt: The interval animation value for self inhibition. elem.currenWidth: The objects 'memory' of its last set width. actstep: actual step of the animation, increased 1 per every execution.
Initiating animation (with memory)
here refers to the fact that the animation will be able to handle from a previously terminated or finished animation, and that for each step, will be embedded to the object. Same type of animations in your project should sport same type of variables, so animation can be picked up from where it was left, and different type of animations with different variables should not interfere with eachother.
There can be many events that may fire up the animation, here I use mouseover and mouseout events, and we'll be seeing the width sizer animation function. I must stress, for the simplicity, I used the .onevent type event attaching, which is the old and destructive method. To be able to attach multiple function to a particular type of event, you must use User Javascript, you should always use non destructive methods, should suffice.)
and . does not return element that we are attached the event to ' ', but it always returns the' ' element with ' '. There are ways to get around this but it is not the main issue of this article. (if you are programming a JavascriptmyElement.onmouseover = widthChange; myElement.onmouseout = widthRestore; function widthChange() { if (!this.currentWidth) this.currentWidth = 150; //if no memory is set, set it first; doWidthChangeMem(this,this.currentWidth,170,10,10,0.5); } function widthRestore() { if (!this.currentWidth) return; doWidthChangeMem(this,this.currentWidth,150,10,10,0.5); }
Here, I need an animation that will be reversible, as I want my object to return to its initial values after mouseout. The animation should be able to terminate early, and that's why I need an animation memory for the object. The reason I set the initial value right in javascript, instead of reading it from the style of the object is because there is currently big discrepancies between how browsers read active styles, it is much cleaner to set the initial value right in javascript. There are quite a number of ways you can read styles from objects if you really want it, so you can have it your way. Those numbers will make sense when you see the
function.Producing an animation step value at a given step
Javascriptfunction easeInOut(minValue,maxValue,totalSteps,actualStep,powr) { //Generic Animation Step Value Generator By www.hesido.com var delta = maxValue - minValue; var stepp = minValue+(Math.pow(((1 / totalSteps) * actualStep), powr) * delta); return Math.ceil(stepp) }
This generic animation step value churner is my best friend. We can simply give
/ , the of the animation, and the actual step we request the value of, with a power ( ) so we can decide for ease-in and ease-out type values: > 1 produces ease-in, < 1 produces ease-out, = 1 produces linear animations. By increasing the in every animation step, we simply have each animation value on request. Choosing between ease-in and ease-out is enough for me, but you can prepare a function that will return an ease-in + ease-out values, or you can break the animation into two parts and use this cute(!) little function.Final Words
I hope you like this piece of code. Solutions in the script required serious thinking!