[Home]
[Previous: Summary][Next: Part 2 - Creating the test]

Part 1 - The Introduction

Acknowledgements

First I would like to thank my employer InfoStream ASA [INFOSTREAM] for graciously donating both time and computer resources for this project. I am also very thankful that they've allowed me to publish my results on my web site.

I'd like to thank my fellow employers and my girlfriend for letting me borrow their computers for testing.

My thanks go to Jim Ley, Steven Champeon [DHTMLGUI] and Scott Porter [JSGAMES] for reading through a draft of this report and giving thoughtful comments and recommendations.

Thanks again to Jim Ley for coming up with the DirectAnimation test.

Also thanks again to Steven Champeon for being my favourite list mom, and for letting me look at his code and for supplying very useful comments.

Lastly I'd like to my girlfriend again, this time for being such a great person. :)

Introduction

What is DHTML?

DHTML is a combination of the words "Dynamic" and "HTML". HTML [HTML] is an acronym for "HyperText Markup Language". DHTML isn't a language of it's own though. Instead, it's a combination of HTML, Cascading Style Sheets (CSS) [CSS], a Document Object Model (DOM) [DOM] and a scripting language. HTML is used to create the document structure, CSS defines the presentation of the content. The Document Object Model is the representation of the document to the scripting language, whch in turn is used to make it all dynamic.

In this report the scripting language used is JavaScript. This is due to the fact that I want my code to work in more than one browser. Other commonly used languages are VBScript and JScript, both available from Microsoft. With JavaScript one can make DHTML that works in two browsers, Microsoft Internet Explorer (MSIE) [MSIE] and Netscape Navigator/Communicator [NSCOMM]. When JavaScript is run in MSIE it's actually JScript, due to the fact that MSIE doesn't have it's own JavaScript interpreter (JavaScript is an interpreted programming language, not compiled).

What is a layer?

The term "layer" usually has two meanings in the context of DHTML. One is the layer element created by Netscape and available in Netscape Navigator/Communicator v4 and later. The other meaning is a slightly more generic term because it is usable in both MSIE and Navigator. This generic approach doesn't use the layer element, but instead uses the div element positioned using CSS-positioning (often referred to as CSS-P). CSS-P is a part of the CSS level 2 specification [CSS2]. It first appeared in a working draft in January of 1997 [WD-POS] and was incorporated into the CSS2 specification. Both Netscape and Microsoft implemented some support for CSS-P into their version 4 browsers based on the working draft.

The code for a positioned DIV [HTML-DIV] can be:

<DIV ID="myDiv"
 STYLE="position: absolute; left: 100px; top: 100px;">
layer content goes here...
</DIV>

This code creates a layer with ID [HTML-ID] "myDiv" positioned 100 pixels in from the left and 100 pixels down from the top of the browser's document area. The ID is used because it makes it much easier to refer to the layer when we create scripts to move it. Such a layer can be referenced in MSIE as document.all['myDiv'] [D-ALL] and in Navigator as document.layers['myDiv'] [D-LAYERS]. Even though it's not created using the layer element it still appears in the document.layers array in Navigator. In Mozilla [MOZILLA] the DIV can be referenced by using the method "getElementById()" [DOM-GID].

The difference between the browsers lies in their respective Document Object Models (DOMs). Due to these differences you will need some way of knowing what browser you are talking to before you create animations. Good articles on the subject are Updating Your JavaScript and CGI Scripts for Version 5 Browsers and The Ultimate JavaScript Client Sniffer, Version 3.0

Cross-browser issues

Layers is not a cross-browser compatible thing. DHTML animation even less so. We rely on support for CSS-positioning and a scripting language, which naturally reduces the amount of supported browsers. Usage of layers in my opinion also focus more on presentation than structure and compatibility.

Most developers who write DHTML animation target the "two big" browser suppliers: Netscape & Microsoft. Focus is then put on their 4th generation browsers; Navigator 4.x and Internet Explorer 4 & 5. That is our target area, since trying to satisfy all users regardless of browser or system will force us to leave DHTML. This whole report therefore assumes that DHTML is something we want to use, and target users/browsers/systems accordingly.

Moving a layer

Once you've created a layer it's fairly easy to move it around. Netscape Navigator gives you the moveTo(x,y) [MOVETO] method which moves the layer you refer to the x- & y-coordinates you give to it. In MSIE you can do it several ways, but one way is to use the properties style.left [S-LEFT] and style.top [S-TOP]. You set the properties to the same x- and y-coordinate values as Navigator's moveTo() to move the layer to the same position.

When you target Navigator 4.x and MSIE 4/5 you can quite easily write one combined moveTo() function so you won't have to fiddle around with more than one way to move a layer. All you do is look for Navigator by checking for document.layers and MSIE by checking for document.all. Then you set values accordingly. The function I've ended up with, and that I use in all tests is:

function myMoveTo(layerID, xpos, ypos) {
/* moves layer 'layerID' to xpos, ypos */
  if(document.layers) {
    document.layers[layerID].moveTo(xpos, ypos);
  } else if(document.all) {
    document.all[layerID].style.left = xpos;
    document.all[layerID].style.top = ypos;
  }
}

This code can be optimized more for MSIE since it refers to the layer twice. It would be faster to create an object referring to the layer once, and then set the left & top properties. As you will see in the test results this hasn't been decisive at all though. If you're developing a large project and want to do things well you should optimize the function.

Animating a layer's movement

So far I've shown how to move a layer. This report isn't really about moving a layer from point A to point B though. It's about moving a layer from point A to point B and stopping at a whole bunch of places in between. In my case the whole bunch of points is in a straight line going from point A to point B.

"So how do you do that?" you might wonder. It's not very difficult. Instead of moving the layer directly from point A to point B you create a way of stepping through intermediate points between A and B, and then you use a loop to do it. In more pseudo-code like speak: You do a calculation of where you are and where you want to go, move the layer in the direction of where you want to go, and if you're not done yet you do it again.

A common way of doing this is to have a function for the layer movement which at the end checks whether it's finished, and if it's not the function call itself with a slight delay. The delay is usually created by calling the method setTimeout() [SETTIMEOUT]. setTimeout() takes two parameters, a string that's the function call it should do and a numerical value which is the delay in milliseconds. Pseudocodish the resulting function is:

function animateLayer() {
  xpos = some_calculation();
  ypos = some_calculation();
  myMoveTo(layerID, xpos, ypos);
  if(!done) {
    setTimeout(animateLayer, delay);
  }
}

The calculation to find where the layer should be moved to can be quite complicated, but in my case it's fairly simple. My functions look at what direction we're moving and then go 1 pixel in that direction. If you wanted to move in a circle, or an elliptical path the calculation would be slightly more complicated.

To achieve smooth animation you will need to do the movement at least 25 times per second. The delay is then too short for the eye to notice, so the layer will appear to move in a fluid motion. If you go below 25 times per second the eye will notice the steps. This is very important. You wouldn't want the layer movement to look like it's slowly stepping forward, simply because that wouldn't be appealing to the user. He'd probably be impressed by the animation the first time he's around, but the second time he'll notice the stepping.

To achieve 25 movements per second (or 25 frames per second, which is may also be called) you need to have a delay between each movement of less than 40ms (1000ms/25 = 40ms). The delay would preferably be slightly less than 40ms, but there's no need to do it even shorter than that since you'd spend CPU resource for no cause (this is simplified, but you probably get the idea).

This whole report has been written simply because I've tried to set the delay to less than 40ms without seeing any visual improvement. My system refused to give me anything that looked like smooth animation, no matter how hard I tried. This report and its tests tries to figure out where the problem is, and what can be done to fix the problem. To find out where the problem was I needed to create a test, let's look at how that was done.

[Previous: Summary][Next: Part 2 - Creating the test]
[Home]

Morten Wang <warnckew@online.no>
Last modified 1999-11-07 01:57