Using JavaScript and graphics

The easy way to make your images dynamic

1 2 Page 2
Page 2 of 2

Creating graphics on-the-fly with JavaScript

If you're not an X Window user, you probably haven't heard of the XBM graphics format. This format is supported by Netscape and many other browsers. It's a simple format that offers only black-and-white rendition and is intended to be used in X Window applications for basic icons. It's occasionally used in Web pages to produce icons and hit counter digits, and for various other graphic images.

What makes the XBM format particularly interesting to us "JavaScripters" is that you can create the XBM image in JavaScript and display it in Netscape. This allows you to create and manipulate simple images in real time, using nothing more than JavaScript. The images are limited to black-and-white only.

Understanding the XBM format

The XBM format is really a C-language variable assignment. The XBM file format begins with two define statements that indicate the width and height, in pixels, of the image. The width is usually, but not always, stated in multiples of eight. The height can be any value.

Next comes the bit representation of the image. This consists of one or more values, specified in hexadecimal format. Each value defines an area of up to eight pixels wide by one pixel in height. For instance, the following XBM file produces a small 8-by-1-pixel line:

#define text_width 8
#define text_height 1
static unsigned char text_bits[] = {0xff};

Note that you can make the line shorter by specifying a smaller width. But you cannot make a line longer without adding more hex values. You can do this by separating each value with a comma, like this:

#define text_width 16
#define text_height 1
static unsigned char text_bits[] = {0xff,0xff};

This defines a 16-by-1-pixel line. Each 0xff value is used for eight pixels of the line. Of course, an XBM graphic of just a very short line isn't too useful. Most of the time you will want to add height to the image. This is done by increasing the height value, and by adding more hex values in the list. Netscape will read the image going from left to right, top to bottom. You can better visualize the arrangement of the values if you put them in "spreadsheet" column/row format. Each column represents eight bits of width; each row represents one bit of height.

The following produces a 16 by 8 bar. Notice the formatting of the 0xff values. This is purely for easy readability. It helps you visualize that there are two 8-pixel columns (for a total of 16 pixels), and eight rows.

#define text_width 16
#define text_height 8
static unsigned char text_bits[] = {
    0xff,0xff,
    0xff,0xff,
    0xff,0xff,
    0xff,0xff,
    0xff,0xff,
    0xff,0xff,
    0xff,0xff,
    0xff,0xff};

In all of the above examples the graphic is composed of all-black line segments. You can use other hex values to produce line segments with black and white bits. White (actually, the absence of black) is represented by a 0 bit; black is represented by a 1 bit. Put eight bits together and you get a value from 0 to 255. The hex value 0xff is decimal 255, or binary 11111111. All those ones create the all-black line. Conversely, 0x00 will make an all-white line, as it's decimal 0, or binary 00000000.

To make an image different, number values are used to represent the bit pattern desired. The pattern 1000001, which is decimal 128 (or hex 0x81), produces a line with only one bit turned on at each end. The middle is white. The bits of the digit are organized right to left with respect to how the bits appear on the screen. Remember this when calculating the bits to make a picture.

A practical XBM example

One practical use for XBM graphics is a hit counter. JavaScript provides all the images for each number. By itself, JavaScript is not capable of storing the number of times someone visits your Web site; this requires a CGI program. For the following example, though, we'll create a "fake" hit counter that can be used instead. This hit counter makes up an absurdly large number and displays that as the number of people who have visited the page. It's intended to serve as comic relief; of course you should not actually represent the number as valid, because some people take "hit counters" pretty seriously.

The random hit-counter script shown below uses a randomizing function based on the Park-Miller random number generator algorithm. A specific random number routine is used instead of JavaScript's Math.random property because in Netscape 2.0 the random property only functions when using the Unix platform. Here is the complete random_hit.html example.

Random hit count

<HTML> <HEAD> <TITLE>Random Hit Count</TITLE> <SCRIPT> function setHits() { RandNum = new randomNumberGenerator(); val = RandNum.next() + "" val = val.substring (2, 12) PicSize = "HEIGHT=16 WIDTH=8 ALIGN='absmiddle'>"; Digit = new Array(); Head = "#define count_width 8\n#define count_height 16\nstatic char count_bits[] = {" Digit[0]=Head+"0xff,0xff,0xff,0xc3,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0xc3,0xff,0xff,0xff};" Digit[1]=Head+"0xff,0xff,0xff,0xcf,0xc7,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xcf,0xc7,0xff,0xff,0xff};" Digit[2]=Head+"0xff,0xff,0xff,0xc3,0x99,0x9f,0x9f,0xcf,0xe7,0xf3,0xf9,0xf9,0x81,0xff,0xff,0xff};" Digit[3]=Head+"0xff,0xff,0xff,0xc3,0x99,0x9f,0x9f,0xc7,0x9f,0x9f,0x9f,0x99,0xc3,0xff,0xff,0xff};" Digit[4]=Head+"0xff,0xff,0xff,0xcf,0xcf,0xc7,0xc7,0xcb,0xcb,0xcd,0x81,0xcf,0x87,0xff,0xff,0xff};" Digit[5]=Head+"0xff,0xff,0xff,0x81,0xf9,0xf9,0xf9,0xc1,0x9f,0x9f,0x9f,0x99,0xc3,0xff,0xff,0xff};" Digit[6]=Head+"0xff,0xff,0xff,0xc7,0xf3,0xf9,0xf9,0xc1,0x99,0x99,0x99,0x99,0xc3,0xff,0xff,0xff};" Digit[7]=Head+"0xff,0xff,0xff,0x81,0x99,0x9f,0x9f,0xcf,0xcf,0xe7,0xe7,0xf3,0xf3,0xff,0xff,0xff};" Digit[8]=Head+"0xff,0xff,0xff,0xc3,0x99,0x99,0x99,0xc3,0x99,0x99,0x99,0x99,0xc3,0xff,0xff,0xff};" Digit[9]=Head+"0xff,0xff,0xff,0xc3,0x99,0x99,0x99,0x99,0x83,0x9f,0x9f,0xcf,0xe3,0xff,0xff,0xff};" for (Count = 0; Count < val.length; Count++) { dig= val.substring (Count, Count+1) setDigit (dig, PicSize) } }

function setDigit (Dig, PicSize) { // this function to overcome a bug if (Dig=="0") { document.write ("<IMG SRC='JavaScript:Digit[0]'" + PicSize) } else if (Dig=="1") { document.write ("<IMG SRC='JavaScript:Digit[1]'" + PicSize) } else if (Dig=="2") { document.write ("<IMG SRC='JavaScript:Digit[2]'" + PicSize) } else if (Dig=="3") { document.write ("<IMG SRC='JavaScript:Digit[3]'" + PicSize) } else if (Dig=="4") { document.write ("<IMG SRC='JavaScript:Digit[4]'" + PicSize) } else if (Dig=="5") { document.write ("<IMG SRC='JavaScript:Digit[5]'" + PicSize) } else if (Dig=="6") { document.write ("<IMG SRC='JavaScript:Digit[6]'" + PicSize) } else if (Dig=="7") { document.write ("<IMG SRC='JavaScript:Digit[7]'" + PicSize) } else if (Dig=="8") { document.write ("<IMG SRC='JavaScript:Digit[8]'" + PicSize) } else if (Dig=="9") { document.write ("<IMG SRC='JavaScript:Digit[9]'" + PicSize) } }

function nextRandomNumber () { var Hi = this.seed / this.Q; var Lo = this.seed % this.Q; var Test = this.A * Lo - this.R * Hi; if (Test > 0) this.seed = Test else this.seed = Test + this.M; return (this.seed * this.oneOverM); }

function randomNumberGenerator() { var D = new Date(); this.seed = 2345678901 + (D.getSeconds() * 0xFFFFFF) + (D.getMinutes() * 0xFFFF); this.A = 48271; this.M = 2147483647; this.Q = this.M / this.A; this.R = this.M % this.A; this.oneOverM = 1.0 / this.M; this.next = nextRandomNumber; } </SCRIPT> </HEAD> <BODY> A whopping <SCRIPT>setHits();</SCRIPT> people have visited this page since tea-time yesterday. Click Reload to see the number magically change. </BODY> </HTML>

Using JavaScript for on-the-fly image sizing

As mentioned earlier in this column, Netscape will scale images to fit the HEIGHT and WIDTH attributes you have defined for them. One common application of this resizing capability is using a small GIF image to create any length of bar you want. Suppose the original GIF file is 16 by 16 pixels. An <IMG> tag like the following will "stretch" it to 16 by 200 pixels:

<IMG SRC="small_box.gif" HEIGHT=16 WIDTH=200>

As long as the image is a solid color, it will not degrade when you resize it. The image can even contain stripes of other colors, but the colors must be horizontal. The stripes stretch with the rest of the image, and it looks like one long bar.

Now here's where JavaScript comes in. Instead of hard coding the width and/or height of the image, have JavaScript do it for you. You can use this technique to create horizontal bar charts or to design special effects for your page. Here's an example of using JavaScript to make a bar chart. The function stretches a small solid GIF image (the actual size is unimportant; the smaller the better for transmission speed) to the width specified.

JavaScript graphic sizing example

<HTML> <HEAD> <TITLE>JavaScript Graphic Sizing Example</TITLE> <SCRIPT> makeBar ("250", "Cat"); makeBar ("175", "Dog"); makeBar ("80", "Rat");

function makeBar (Width, Text) { var GifName = pathOnly (location.href) + "blu.gif"; var Height = 12; var Temp = "<IMG SRC='" + GifName + "' HEIGHT='" + Height + "' WIDTH=" + Width + "' ALIGN=baseline> " + Text + "<P>"; document.write (Temp); }

function pathOnly (InString) { LastSlash=InString.lastIndexOf ('/', InString.length-1); OutString=InString.substring (0, LastSlash+1); return (OutString); } </SCRIPT> </HEAD> <BODYv This is body text. </BODY> </HTML>

You can readily modify the script to use a different GIF image and to increase or decrease the height of the bars. I have the bars set at 12 pixels high.

Conclusion

Graphics can enhance any Web page, no matter what its content. Combining JavaScript with graphics is a quick and simple way to give your Web page a dynamic element and will help set it apart from the rest. You can use JavaScript to select the graphic to use, to size a graphic, and even to create the graphic, using the convenient XBM graphic format.

Gordon McComb is an author, consultant, and lecturer. He has written 50 books and over a thousand magazine articles during his 20 years as a professional writer. More than a million copies of his books are in print. Gordon also writes a weekly syndicated newspaper column on computers, reaching several million readers worldwide. Gordon's latest book is The JavaScript Sourcebook>, out this month from Wiley Computer Publishing.

Learn more about this topic

1 2 Page 2
Page 2 of 2