Chapter Twenty-Two
Image Swaps and Animation


Changing Stuff On-Screen Without Reloads

With the advent of Netscape 3.0® a new call was supported: new Image();

Complementing this call is the .src specification.

With these new calls, you can initially display an image on screen when it first loads and then change it at will without triggering a Reload of the whole page.

This capability is more powerful than it might at first glance appear.

For example, you can cause an image to be animated without specifying an animated .gif file.

You can include "action" buttons on your pages that "light" or in some other fashion "repond" to a visitor's actions interactively, and then appear to "depress" when the visitor clicks on them.

Indeed, the capability to change images - either via a timing call or a visitor action -- is a first glimpse of what the much-overused term "Multimedia" really means on the World Wide Web.

What you can now do on your pages is only limited by your own creativity.

variable=new Image();

If you plan to preload images for animation, this is an important call to understand.

variable is an array element or a string variable which you "condition" as an image holding element.

Once it has been thus "conditioned", you can specify a "source" file name for it, using the .src specification.

If, for example, you have a series of .gif files that you wish to swap to create an animation, say ten of them, named "0.gif" through "9.gif" sequentially, you might use the following loop to preload the images:

var img=new Array();
function loadEm(){
 for (var i=0 ; i<10 ; i++){
  img[i]=new Image();
  img[i].src=i+".gif";
  }
 }

Then the following routine could be used to create the animation. Note that the setTimeout(); call has been set to 300 milliseconds between changes. Each animation will dictate the time between changes that is appropriate:

var ctr=0;
function animEm(){
 ctr++
 if (ctr>9){
  ctr=0;
  }
 document.imagename.src=img[ctr].src;
 setTimeout("animEm()",300);
 }

Changing Images Without Using the Image(); Call

You are not obliged to use the Image(); call to swap images on screen. In fact, if preloading the images is not a prerequisite for the display, you may find it more practical to simply specify the source for the new image.

function simpleSwap(){
 document.imagename.src="0.gif";
 }

Other Ways of Preloading Images

It may be better for the kind of display you are using to preload certain images "manually" -- that is, a few at a time, sequentially, just before they are needed.

You can cause the image to be downloaded to the visitor more or less as straight ASCII and very quickly by more or less disabling the browser graphic rendering engine.

How? By specifying the image (regardless of size) to be displayed in a mini-scaled version just one pixel high by one pixel wide.

Because it does not have to "think" about it, the image is cached on the visitor's computer, but is almost invisible on screen.

Then, when you swap that image later, since it is already in cache, the redisplay of this .gif or .jpg file "full size" can be accomplished at the local computer speeds, rather than having to first fetch it from the server and download it at modem and internet packet transfer speeds.

There is one more reason that such one pixel by one pixel preloads are necessitated.

There is a "bug" at present that displays "transparent" .gifs the first time to screen as non-transparent.

If you are creating so-called "overlays" of images on top of previously displayed images, you'll be obliged to preload them so that your display isn't hidden by subsequent images.

Yet another reason for preloading is present in this JavaScript Book Reader. Each of the pages is a 3k to 4k image file. Since it would be displeasing to the eye to watch the interlaced graphics "fill" as you click from page to page, the next two pages are preloaded on this page while you are reading these two.

Then, when you click the "Next Page" button, they are "popped" to screen because they are displayed from cache.

OK. Now for a couple scripts you can play with to see how it all works. First, a simple animation:

<HTML><HEAD>
<TITLE>Simple Animation</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!-- Hide from JS-Impaired Browsers
var ctr=1;
/* First, create a new array and then
   create an image holder and load it
   with the logo animation images. */
isn=new Array();
for (i=1;i<9;i++){
 isn[i]=new Image();
 isn[i].src="anim/0"+i+".gif";
 }
 
function startIt(){
 document.ugly.src=isn[ctr].src;
 ctr=(ctr>7?1:++ctr);
 /* Here we put a "hook" on the
    setTimeout() call by naming it.
    This allows the clearTimeout()
    call to know which one (there
    might be others) to stop. */
 tstop=setTimeout("startIt()",750);
 }
 
function stopIt(){
 /* We put a hook on setTimeout()
    by naming it "tstop". Now the
    browser will know which of
    the timeouts to clear. */
 clearTimeout(tstop);
 }
 
// End Hiding -->
</SCRIPT>
</HEAD>
<BODY BGCOLOR="white"><CENTER>
<P><B>JavaScript for Simple
 Animation</B>
<P><IMG SRC="anim/01.gif" WIDTH="100"
 NAME="ugly" HEIGHT="75" BORDER="0">
<P><FORM>
<INPUT TYPE="radio" NAME="rb"
 onClick="startIt()"> Start Animation
    
<INPUT TYPE="radio" NAME="rb"
 onClick="stopIt()" CHECKED> Stop
 Animation
</FORM>
</BODY>
</HTML>

Click Here to See This Script.

Now, for a slightly more complicated script that gives the user more control than just a start and stop.

This script should be useful, as well, for giving you a feel for delays to use when creating your own animations.

<HTML><HEAD>
<TITLE>Screen Control of
 Animation</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!-- Hide from JS-Impaired Browsers
var ctr=1;
var speed=1000; // set initial speed
var ns="0123456789"; // number index
/* First, create a new array and then
   create an image holder and load it
   with the logo animation images. */
isn=new Array();
for (i=1;i<9;i++){
 isn[i]=new Image();
 isn[i].src="anim/0"+i+".gif";
 }
 
/* Next do the same for the number
   images to display speed. */
nr=new Array();
for (i=0;i<10;i++){
 nr[i]=new Image();
 nr[i].src="nr/"+i+".gif";
 }
 
function startIt(){
 document.ugly.src=isn[ctr].src;
 ctr=(ctr>7?1:++ctr);
 /* Here we put a "hook" on the
    setTimeout() call by naming it.
    This allows the clearTimeout()
    call to know which one (there
    might be others) to stop. */
 tstop=setTimeout("startIt()",speed);
 }
 
function stopIt(){
 clearTimeout(tstop);
 }
 
function speedIt(){
 speed=(speed>50?speed-50:50);
 /* Convert numeric to string and
    then pad with leading zeros. */
 disp=""+speed;
 while (disp.length<4){
  disp="0"+disp;
  }
 /* Then step through the four
    characters and display to
    screen. */
 for (var i=0;i<4;i++){
  num=disp.charAt(i);
  document.images[i+1].src=nr[ns.indexOf(num)].src;
  }
 }
 
function slowIt(){
 speed=(speed>1950?2000:speed+50);
 /* Convert numeric to string and
    then pad with leading zeros. */
 disp=""+speed;
 while (disp.length<4){
  disp="0"+disp;
  }
 /* Then step through the four
    characters and display to
    screen. */
 for (var i=0;i<4;i++){
  num=disp.charAt(i);
  document.images[i+1].src=nr[ns.indexOf(num)].src;
  }
 }
// End Hiding -->
</SCRIPT>
</HEAD>
<BODY BGCOLOR="white"><CENTER>
<P><B>JavaScript for Screen Control of
 Animation</B>
<P><IMG SRC="anim/01.gif" WIDTH="100"
 NAME="ugly" HEIGHT="75" BORDER="0">
<P><FORM>
<INPUT TYPE="radio" NAME="rb"
 onClick="startIt()"> Start Animation
    
<INPUT TYPE="radio" NAME="rb"
 onClick="stopIt()" CHECKED> Stop
 Animation
<P><INPUT TYPE="button" NAME="b1"
 onClick="speedIt()" VALUE=" Speed it up ">
    
<INPUT TYPE="button" NAME="b2"
 onClick="slowIt()" VALUE=" Slow it down ">
</FORM>
<P>Present delay (milliseconds):
<IMG SRC="nr/1.gif" WIDTH="7" HEIGHT="10" BORDER="0">
<IMG SRC="nr/0.gif" WIDTH="7" HEIGHT="10" BORDER="0">
<IMG SRC="nr/0.gif" WIDTH="7" HEIGHT="10" BORDER="0">
<IMG SRC="nr/0.gif" WIDTH="7" HEIGHT="10" BORDER="0">
<P>(Range 50 to 2000 milliseconds)
</BODY>
</HTML>

Click Here to See This Script.



© Copyright 1997, John H. Keyes john.keyes@intellink.net