Early 2001, I decided to exercise my javascript and DHTML skills by creating a javascript toolkit for animations.It had to be flexible, and reusable for any kind of animations. The result of this hard labor was the aniMagiX javascript code that makes the little geckos wander around this page; just add the next four lines, and these 5 cute geckos will wander around:

<!-aniMagiX code by x.singy, xavier@singyfamily.com, http://www.singyfamily.com -->
<link rel="stylesheet" type="text/css" href="http://www.singyfamily.com/Hob/tech/aniMagiX/aniMagiX.css">
<script src=http://www.singyfamily.com/Hob/tech/aniMagiX/gecko/geckos.js></script>
<script src=http://www.singyfamily.com/Hob/tech/aniMagiX/aniMagiX.js></script>

Last year, in 2005, my stats show that these cute geckos have been viewed more than 600'000 times during the year!!! I'm glad you like it ;-)

As this script has so much success, I will be building a new more efficient version, to take advantage of the latest techniques in the field. More info coming soon...

If you want to do more, learn about javascript animations and this framework, read the tutorial below and get a blast :D

Table of content

I. The basics
      a. Introduction
      b. Features
      c. Javascript advanced techniques
      d. The files
      e. Code in your HTML pages
               mandatory code
               additional code
                     debugging
                     onload

II. Your customAnimation.js
      a. Overall Concept and Structure
      b. set initial values
      c. initStates()
      d. setSpriteObjects()
      e. custom functions

III. Bugs

IV. Terms of use, etc

I. The basics

a. introduction

The information in this tutorial is for these who are interested to make the next step! You will also find examples and tips to use this framework effectively.

b. features

This code is not just about geckos. In fact, it's a framework for anyone who wants to add life to a web page.
  • sprites behavior is defined by custom states and scenarios
  • each state/scenario defines the sets of possible next states/scenarios to switch to when the following events are triggered:
    • scenario animation loop is over
    • onborderleft (optional)
    • onborderright (optional)
    • ontop (optional)
    • onbottom (optional)
    • mouseover (optional)
    • mouseclick (optional)
    • contact with other sprites (optional)
  • next states/scenarios are selected by random in the set of possible next states/scenarios
This, plus a bunch of other features, makes this code really versatile. It shouldn't be too hard for someone else to use the aniMagiX code to create their own living creatures! If you are interested in creating your own, please check the explanations below.

c. Advanced javascript techniques

The aniMagiX code uses s a bunch of advanced javascript techniques (mostly gathered from the excellent irt.org - JavaScript FAQ Knowledge Base):
  • fully IE4+ and NS4+ compliant (as far as I have tested)
  • uses DHTML
  • dynamically write layers/images at page load
  • swap image of different sizes
  • move images around
  • check if images are available or not
  • get images dimensions
  • get window and body dimensions
  • handle mouseclick event (and position)
  • handle mouseover event (and position)
  • create objects
  • generate random numbers
  • workaround for the settimeout memory leak in Netscape
  • handle netscape resize bug
  • visually debug javascript application with a javascript "console"
  • get browser version
  • check if browser is IE or NS

d. The files

to use aniMagiX, the following files are required:

  • aniMagiX.js
    the magic engine. No need to change it, just use it as a package. Of course, you can have a look, and steal any ideas you want.

  • aniMagiX.css
    defines the basic style that makes the images float. No need to change it.

  • your customAnimation.js (for example gecko.js, or machaon.js, or balls.js, or ...)
    defines the behavior of the sprites. It's a little bit tricky, but hopefully the explanations below will make it clear enough, so you can make your own.

  • your custom images
    what people see. There's a plenty of images to do to achieve some kind of valuable animation. Your artisitc gift will make the difference!

e. Code in your HTML pages

mandatory code

to use these files, you must add some code in your HTML pages:

<!-aniMagiX code by x.singy, xavier@singyfamily.com, http://www.singyfamily.com -->
<link rel="stylesheet" type="text/css" href="http://www.singyfamily.com/Hob/tech/aniMagiX/aniMagiX.css">
<script src=http://www.singyfamily.com/Hob/tech/aniMagiX/gecko/geckos.js></script>
<script src=http://www.singyfamily.com/Hob/tech/aniMagiX/aniMagiX.js></script>

the link to the files must be placed in that same order, otherwise the animation won't work

additional code

debugging

If your animation doesn't seem to work properly, you can debug it by adding this line:

<!-aniMagiX code by x.singy, xavier@singyfamily.com, http://www.singyfamily.com -->
<link rel="stylesheet" type="text/css" href="http://www.singyfamily.com/Hob/tech/aniMagiX/aniMagiX.css">
<script src=http://www.singyfamily.com/Hob/tech/aniMagiX/gecko/geckos.js></script>
<script>debugAMX=true</script>

<script src=http://www.singyfamily.com/Hob/tech/aniMagiX/aniMagiX.js></script>

It will show you exactly what the aniMagiX code is doing, like this: geckos.html.

onload

If your HTML page handles the onload event to launch some javascript, it will be overriden by aniMagiX code. So you need to put it back. Ex: your code was:

<body onload="dothis();dothat();">
<!-aniMagiX code by x.singy, xavier@singyfamily.com, http://www.singyfamily.com -->
<link rel="stylesheet" type="text/css" href="http://www.singyfamily.com/Hob/tech/aniMagiX/aniMagiX.css">
<script src=http://www.singyfamily.com/Hob/tech/aniMagiX/gecko/geckos.js></script>

<script src=http://www.singyfamily.com/Hob/tech/aniMagiX/aniMagiX.js></script>

you need to change it into this:

<body>
<!-aniMagiX code by x.singy, xavier@singyfamily.com, http://www.singyfamily.com -->
<link rel="stylesheet" type="text/css" href="http://www.singyfamily.com/Hob/tech/aniMagiX/aniMagiX.css">
<script src=http://www.singyfamily.com/Hob/tech/aniMagiX/gecko/geckos.js></script>

<script src=http://www.singyfamily.com/Hob/tech/aniMagiX/aniMagiX.js></script>

<script>
   function start(){
      dothis();
      dothat();

      initAnims();
   }
   window.onload=start;
</script>

II. Your customAnimation.js

a. Overall Concept and Structure

The basic idea is that a sprite can be in several states, and in each of these states, it acts according to some scenarios. The scenarios consist of several steps that define the images and the moves of the sprites, and the reactions of the sprites to various events. The reactions consist into switching to some other state/scenario, and eventually trigger some custom functions.

The customAnimation.js file consists of four parts, covered in detail further:

  1. a few basic values
  2. a definition of the states and scenarios
  3. an instantiation of the sprites
  4. some custom functions

First, let's have a quick look at a very basic custom animation code: simpleball.js (see it working here: simpleball.html)

/*##############
set initial values
3 lines of code to set quantity of sprites, base path for the animation images, and whether we should debug the animation.
*/
var AMXq = 2;
var images_basic_path = "";
var debugAMX = false;

/*##############
define states & scenarios
launched by the aniMagiX code, the initStates() function defines the states and scenarios that will make the sprites act on your own rules.
*/
function initStates(){

states = new Array;

/* b0 */
st_n = "b0";
states[ st_n] = new state;
states[ st_n].onErrorScenario = "right";
states[ st_n].z = 3;

//scenario right
states[ st_n ].scenarios["right"] = new scenario;

with (states[ st_n ].scenarios["right"]) {

random_delay = 0;
steps[0] = new step( st_n, "ball.GIF", 2, 0, 2);
next_scenarios[0] = new next_scenario("right",10);
next_states[0] = new next_state("b0", "right", 99);
onright_next_states[0] = new next_state("b0", "left", 49);

}

//scenario left
states[ st_n ].scenarios["left"] = new scenario;

with (states[ st_n ].scenarios["left"]) {

random_delay = 0;
steps[0] = new step( st_n, "ball.GIF", -2, 0, 3);
next_scenarios[0] = new next_scenario("left",10);
next_states[0] = new next_state("b0", "left", 99);
onleft_next_states[0] = new next_state("b0", "right", 49);

}

checkStatus("b0","");

}

/*##############
initialize sprites
launched by the aniMagiX code, the setSpriteObjects() function actually instanciates the sprite objects, with initial state, scenario, position, and boundaries. To make it more organic, you may want to use some random so that all sprites do not start from the same place with the same state...
####*/
function setSpriteObjects(){

for (i=0;i<AMXq;i++){

AMXs[i]=new sprite('b0', 'right',-100*AMXrnd()-10,win_height*(1/2 + AMXrnd()/2 ),states[ 'b0' ].z , 0, 0, win_width, win_height);

}

}

/*##############
custom functions
well, you may want to do something even more special. The aniMagiX framework has an open door: whenever sprites change of state, any function of your own can be triggered, and add even more magic!
####*/



b. set initial values

This is an easy one:

var AMXq = 2; // how many instances of sprites you will create. This is used by the aniMagiX code, and the setSpriteObjects() function..
var images_basic_path = ""; //the path to the animation images. This path can be absolute, or relative to the page where the animagix HTML code is placed
var debugAMX = false; // set to yes to display the debug console

These values could also be defined or overriden outside this file, right in your HTML page (like in this example).

c. initStates()

Called by the aniMagiX code, this function instances the states and scenarios that make your sprites act the way you want. In a few words, you must define one or more states, with their scenarios. Once a state is defined, launch the function checkStatus(state_name, action) to make the program monitor the loading of the images of the state.

The best way to understand this section is to look at the different examples (simpleBall.js/simpleball.html, ball.js/balls.html, machaon.js/machaon.html, geckos.js ), and at the following object model:

  • state object:
    • instanciation: new state
    • properties must be set after the state was instanced:
      • z : position of the state in the z dimension. Set to 0 by default.
      • default_ontouch_next_states: optional array of possible next_state to launch when the sprite touches another sprite, if not defined at the scenario level. See description of next_state object below.
      • onErrorScenario: optional scenario to switch to if the sprite cannot change of state because the next state is not ready (=not all images were loaded)
      • scenarios: array of scenario. All the scenarios a sprite can follow while in that state.
        • scenario object
          • instanciation: new scenario
          • properties that must be set after the state was instanced
            • steps: array of step of the scenario: the list of images, move, and delay between each image of the scenario. When the loop between all steps is done, the sprite may switch of state or scenario.
              • step object
                • instanciation: new step(state_name, image, dx, dy, delay)
                  • state_name: name of the current state. You may want to store the name of the current scenario you're defining in a variable, to avoid typing it again and again.
                  • image: path of the image to display when doing that step. Relative to the images_basic_path variable. Usually, just the image file name.
                  • dx: x distance to move when doing that step
                  • dy: y distance to move when doing that step
                  • delay: time to wait (in about 10ms units) before doing the next step
            • random_delay: random delay added to the delays defined in each step. Default value:0.
            • next_states: array of possible next_state to switch to when the loop between all the steps of the scenario was done.
              • next_state object
                • instanciation: new next_state(next_state_name, next_scenario_name, probability_factor)
                  • next_state_name, next_scenario_name: name of a potential state and scenario
                  • probability factor: probability factor to swith to this state&scenario of the array of next_states. The highest the number in comparison to the other next_state.probability_factor, the more chances to switch to this state&scenario.
                • optional property that can be set after the next_state was instanced
                  • action: if the state&scenario is selected, a javascript function of your choice is evaluated. Ex: if the if the value of action is "shakeScreen()", shakeScreen() will be triggered. See the custom functions section for more details.
            • next_scenarios: array of possible next_scenario to switch to when the loop between all steps was done, if the sprite is not changing of state.
              • next_scenario object
                • instanciation: new next_scenario(next_scenario_name, probability_factor)
                  • next_scenario_name: name of a potential next_scenario
                  • probability factor: probability factor to swith to this scenario of the array of next_scenarios. The highest the number in comparison to the other next_scenario.probability_factor, the more chances to switch to this scenario.
      • optional properties that can be set after the state was instanced. They are all arrays of next_state.
        • ontop_next_states: array of potential next_states to switch to when the sprites reaches what was defined as its top border
        • onbottom_next_states: array of potential next_states to switch to when the sprites reaches what was defined as its bottom border
        • onleft_next_states: array of potential next_states to switch to when the sprites reaches what was defined as its left border
        • onright_next_states: array of potential next_states to switch to when the sprites reaches what was defined as its right border
        • ontouch_next_states: array of potential next_states to switch to when the sprites touches another sprite. To avoid slowing down the animation too much, the fact that the sprite touches or not another sprite is only evaluated when the sprite changes of scenario, every n times, depending of how many sprites are instanciated.
        • onclick_zones: array of on_zone defining the areas that can make a sprite switch to some next_states when clicked
          • on_zone object
            • instanciation: new on_zone(x, y, dx, dy)
              • x: left position of the sensible zone, relative to the image
              • y: top position of the sensible zone
              • dx: width of the sensible zone
              • dy: height of the sensible zone
            • property that must be set after the on_zone was instanced:
              • next_states: array of potential next_states to switch to when the sprite is clicked on that zone
        • onmouseover_zones: array of on_zone defining the areas that can make a sprite switch to some next_states when the mouse goes over it.


    With a little bit of trial and error, you sure can do something out of this!


d. setSpriteObjects()

Called by the aniMagiX code, this quite straightforward function instantiates the sprite objects, with initial state, scenario, position, and boundaries. All you really need is to run a loop from 0 to AMXq to create all the sprites.

the funtion that creates the sprites is the following:

AMXs[i]=new sprite(
                            state_name,
                            scenario_name,
                            initial_x_position,
                            initial_y_position,
                            initial_z_position,
                            left_border_position,
                            top_border_position,
                            right_border_position,
                            bottom_border_position
              );

To define all these positions, you have a few variables available:

  • AMXrnd() - returns a random value between 0 and 1
  • win_width : window width
  • win_height : window height
  • body_width: body width
  • body_height: body height

Then it's up to you to write a function that creates sprites that ar not all going the same direction...

e. custom functions

For every change of state, a javascript action can be evaluated. These actions are totally optional, and certainly not the heart of a very good animation. This is only when you want to spice your pages up even more. So I don't want to spend a lot of time on this one, as it is really for extra goodies. For whoever's really interested, please have a look at the machaon.js code, or the geckos.js code for some example of usage of a few custom functions.

III. Bugs

aniMagiX has no bug that I know of yet. Of course, there are still the browser's bugs... Netscape may crash because of the setInterval function and high layer usage, but there's not much I can do about that. If anyone has ideas to improve this code, please, please write me! Your help would be greatly appreciated.

IV. Terms of use, etc

All materials at this site are considered freeware, but if someone would like to donate a small token of appreciation, you can use the Paypal buttons below (both accept Paypal or Credit Card payments). It's fast, secure, easy, and greatly appreciated!

 

Xavier Singy
xavier@singyfamily.com
http://www.singyfamily.com

PS: check ScriptSearch.com, they're great...

Google