[Contents] [Prev page] [Next page] [Index]

Dynamic HTML in Netscape Communicator
Part 2. Positioning HTML Content

Chapter 11

Swimming Fish Example

This example is presented in two parts. The second part is an advanced version of the first part.


Figure 10.1 The fish and three poles in their initial positions


Positioning and Moving the Fish and Poles

In this example, a fish and 3 poles appear in the window along with a button saying "Move the Fish." When you click the button, the fish moves from the left side of the window to the right, swimming in front of the two outer poles and swimming behind the middle one.When it reaches the far right, it jumps back to the far left and starts swimming across the screen again.

The fish is an animated GIF, and the three poles are static GIFS.

To run the example that uses the <LAYER> tag, select:

fish1.htm

To run the style sheet version of the example, select:

fish1css.htm

To view the complete code for either version of the example, use the Page Source command of the View menu in the Navigator browser that is displaying the example.

In the <LAYER> version, the layer containing the form is initially hidden, and a waiting layer is temporarily displayed while the fish images are downloading. This version uses a showForm() function to hide the waiting layer and show the form layer.

In the style sheet version, the form layer is visible immediately. This version does not have a waiting layer or showForm() function.

The sections in the first part of this example are:


Defining the onLoad Handler for the BODY Element

This page has a form containing a button whose action is to start the fishing swimming. The form is contained in a layer that is initially hidden. The BODY element has an onLoad handler that makes the form layer visible. This approach ensures that the user cannot start the fish swimming until the form is visible which will not happen until all the contents in the document, including all the frames in the animated image of the fish, have finished loading.

The following statement defines the BODY element:

<BODY BGCOLOR="#FFFFFF" ONLOAD="showForm();">

Positioning the Fish and Poles

Here's the code that creates the three pole layers:

  <HTML>
  <HEAD>
  <TITLE>Swimming Fish</TITLE>
  </HEAD>
  <BODY>

  <LAYER ID="bluepole"LEFT=160 TOP=150>
  <IMG SRC=images/bluepole.gif>
  </LAYER>

  <LAYER ID="greenpole" LEFT=360 TOP=150>
  <IMG SRC=images/greenpol.gif>
  </LAYER>

Here's the code that creates the fish layer.

  <LAYER ID="fish" LEFT=40 TOP=170 above="redpole"
    ONLOAD="showForm();">
  <IMG ALIGN=RIGHT SRC=images1.gif >
  </LAYER>

After the definition of the fish layer comes the definition for the red pole layer.


  <LAYER ID="redpole" LEFT=260 TOP=150>
  <IMG SRC=images/redpole.gif>
  </LAYER>

By default, each subsequent layer is placed on top of the one before it in the stacking order. So to start with, the blue pole is on the "bottom," the green pole is above the blue pole, and the fish is directly below the red pole (that is between the green pole and the red pole.) The red pole is on top of everything, as far as the stacking order goes. (It might help to imagine that all the images are slid into the center of the page so that they all overlap each other. This scenario might help you visualize that the blue pole is on the bottom, and the red pole is on the top.)

Defining the Form

The layer containing the form is initially this layer is hidden. The form has a button that the user clicks to start the fish swimming. The only reason for putting the form in a layer is to hide it initially. Since you don't need to set TOP or LEFT attributes, you can let this be an inflow layer so that it falls at the natural place in the page.

Here's the definition of the form layer:

<ILAYER ID=formlayer VISIBILITY=HIDE>
  <H1>Fish Example 1</H1>
  <FORM>
  <INPUT type=button value="Move the fish"
    OnClick="movefish(); return false;">
  </FORM>
</ILAYER>

There's also another "temporary" layer that displays a message while the fish is loading. The definition for this layer is:

<LAYER ID=waiting TOP=100 LEFT=50>
  <H3>Please wait while the fish loads...</H3>
</LAYER>

Moving the Fish

The file contains a script that has the definitions for the moveFish() and showForm() functions.

The following code defines the function showForm(), which makes the waiting layer become invisible and makes the form layer become visible.

<SCRIPT>
function showForm() {
 document.waiting.visibility="hide";
 document.formlayer.visibility="show";
 return false;
}

The following code defines the function moveFish(), which causes the fish to move repeatedly across the window.


<!-- Simple move function -->
function movefish() {
  var fish = document.fish;
  if (fish.left < 400) {
    fish.moveBy(5, 0);}
  else {
    fish.left = 10;}
  // use the windows method setTimeOut
  setTimeout(movefish, 10);
}
</SCRIPT>

This function binds the variable fish to the layer named "fish." The function checks if the horizontal location of the fish layer is less than 400, in which case it uses the moveBy() method to move the layer 10 pixels to the right. If the horizontal location is greater than 400, the function sets the horizontal location back to 10.

Then the function waits 10 milliseconds and calls movefish() (that is, itself) again.

The net result is that when this function is invoked, the fish swims across the screen to the 400th pixel, then reappears at the left of the screen and swims across the screen again, ad infinitum.

Because of the stacking order of the poles, the fish seems to swim in front of the blue pole, behind the red (middle) pole, and in front of the green pole.


Changing the Stacking Order of Fish and Poles

This example extends the previous example, Positioning and Moving the Fish and Poles.

In this extended version, when the fish reaches the far right, it turns around and swims back again. On the way back, it swims in front of the green pole, behind the red (middle) pole, and in front of the blue pole. To enable the fish to swim in front of a pole on the way out and swim behind it on the way back, you need to change the stacking order of the layers each time the fish changes direction.

Both fishes (one for each direction) are animated GIFs, and the three poles are static GIFs.

To run the <LAYER> version of the example, select:

fish2.htm

To run the style sheet version of the example, select:

fish2css.htm

To view the complete code for either version of the example, use the Page Source command of the View menu in the Navigator browser that is displaying the example.

The sections in the first part of this example are:


Adding Another Layer to Contain the Reverse Fish Image

When the fish reaches the right edge, the image of the fish needs to change to a fish swimming in the reverse direction. The change needs to occur very quickly, perhaps too quickly for there to be time for the new fish image to download across the network. If the image of the reverse fish does not download quickly enough, the image will continue coming in as the fish moves back across the screen. To start with, you'll see only bits of the fish.

To ensure that the fish is whole as soon as it starts swimming back, you can preload the fish image.The easiest way to do this is to create a new, hidden layer that contains the reverse fish image. Even if a layer is hidden, all its images are downloaded when the layer is loaded.

The following code creates a hidden layer containing an image of the fish swimming in the reverse direction.

<LAYER ID="fishB" VISIBILITY="hide">
 <IMG SRC=images2.gif>
</LAYER>

Initializing the Fish to Have a Direction Variable

The following function initializes the fish layer so that it has a direction variable which keeps track of which way the fish is swimming. To start with, the fish swims forward. The fish also has forwardimg and backwardimg properties that hold the appropriate fish images.

function initializeFish() {
 // create the backward fish image to force it to preload now
 var fish = document.fish;
 var fishB = document.fishB;
 fish.direction = "forward";
 fish.forwardimg = fish.document.images["fish"].src;
 fish.backwardimg = fishB.document.images["fishB"].src;
}

Moving the Fish Backward and Forward

The following code defines the function movefish2(), which moves the fish to the right, changes the image of the fish (so that it faces left), moves the fish back to the left, and repeats the process continuously.

In more detail, the function specifies that if the fish is moving forward and hasn't reached a horizontal position of 450, it keeps moving forward. If it has reached 450, it changes direction.

If it's moving backward and hasn't reached 10, it keeps moving backward. If it has reached 10, it changes direction.

Each time the fish changes direction, the function changes the stacking order of the layers, by calling either the changePoles() function or the resetPoles() function, depending on which way the fish is turning.

function movefish2() {
 var fish = document.fish;
 if (fish.direction == "forward") {
   if (fish.left < 450) {fish.moveBy(5, 0);}
   else {changePoles();changeDirection();}
 }
 else {
  if (fish.left > 10) {fish.moveBy(-5, 0);}
  else {resetPoles();changeDirection();}
 }
 setTimeout("movefish2()", 10);
 return;
}

Changing the Direction of the Fish

The changeDirection() function changes the image of the fish, so that it faces in the correct direction. The function also sets the value of the direction variable to the new direction.

function changeDirection () {
 var fish = document.fish;
 if (fish.direction == "forward") {
  fish.direction = "backward";
  fish.document.images["fish"].src = fish.backwardimg;
 }
 else {fish.direction = "forward";
  fish.document.images["fish"].src = fish.forwardimg;
 }
 return;
}

Changing the Stacking Order of the Poles and the Fish

The functions changePoles() and resetPoles() change the stacking order (z-order) of the layers. You can change the stacking order of a layer in the following ways:

To keep your stacking order straight, it is a good idea to consistently use one of these ways. If you mix them, it could be hard to keep track of the exact stacking order. For example, if you use moveAbove() to move the blue pole layer above the green pole layer, then you set the zIndex value of the fish layer to 3, you may not know where the fish is in the stacking order in relation to the green and blue poles.

The following functions, changePoles() and resetPoles(), consistently use the moveAbove() function to set the stacking order of the three layers containing the poles and the layer containing the fish.

function changePoles () {
 var redpole = document.redpole;
 var bluepole = document.bluepole;
 var greenpole = document.greenpole;
 var fish = document.fish;
 fish.moveAbove(redpole);
 bluepole.moveAbove(fish);
 greenpole.moveAbove(bluepole);
}

// reset the stacking order of the poles and the fish 
function resetPoles () {
 var redpole = document.redpole;
 var bluepole = document.bluepole;
 var greenpole = document.greenpole;
 var fish = document.fish;
 greenpole.moveAbove(bluepole);
 fish.moveAbove(greenpole);
 redpole.moveAbove(fish);
}

Updating the Button That Gets the Fish Going

Here is the definition of the layer that contains the form:

<H1>Fish Example 2</H1>
<LAYER ID="fishlink" LEFT=10 TOP=100 >
 <FORM>
  <INPUT type=button value="Move the Fish" 
  OnClick="initializeFish(); movefish2(); return false;">
 </FORM>
</LAYER>

This time, the OnClick() method initializes the fish to initialize the direction variable on the fish before it calls movefish2().



[Contents] [Prev page] [Next page] [Index]

Last Updated: 08/07/97 15:21:59


Copyright 1997 Netscape Communications Corporation