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:
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
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.
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:
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:
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:
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(){
//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(){
/*############## 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.
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:
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!