JavaScript Pixel Graphics
It is surprising: despite the JavaScript "hype", the "browser war" between
Netscape and Microsoft and all the activities of standardization bodies there
is still no common procedure for line or pixel graphics handling from within
JavaScript! [1,2]
This page documents the author's activities in that area and presents a
(browser-independent) JavaScript library for the creation and manipulation
of small(!) pixel graphics.
 |
While this page may be risklessly displayed with any browser and even
on computer systems with only moderate processor and memory capacity, visiting
the Demonstrator page may occupy your computer
for several dozens of seconds and - probably - crash browser and/or operating
system! (The author recommends Opera 5.12 (or newer) for a good
performance!) |
Please, also consider my "Hints for Reading"
and the "List of Recent Changes".
Overview
Principally, there are several possibilities for the implementation of
(interactive!) pixel graphics with pure JavaScript (i.e., without the need
for additional components such as Java applets):
-
as a table with empty cells
The display area may be realized as a (huge) table with one cell per pixel.
The background color of a cell then determines the color of the corresponding
pixel. This approach sounds relatively "efficient", but will require DOM
support in order to access a specific table cell at run-time to manipulate
its color;
-
as a rectangular collection of images (with one image per pixel)
In this approach, each scanline of the final graphics display consists of
a sequence of pixel images (with an explicit line break between consecutive
scanlines) - the color of a pixel is determined by the content of the
corresponding image. Since HTML images may be identified by an associated
name (or id) even without explicit DOM support, this approach also works
with older browsers;
Both methods may also be combined in order to guarantee a fixed layout of
pixel images within the display area or to assist the browser in its layout
operations. The approach used for the author's "PixelGraphics" library can
be characterized as follows:
-
the display area consists of a table with one cell per scanline;
-
each scanline is realized as a sequence of images, each the size of a single
pixel. These images can by directly accessed through an associated (unique)
name.
"PixelGraphics" will thus work even on browsers without explicit support
for the HTML Document Object Model (DOM). However, the large number of images
needed to represent a graphics display consumes a huge amount of processor
and memory resources - the display dimensions should therefore be kept as
small as possible.
In order to see a "live" demonstration of the package, you may visit the
author's Demonstrator page with a display
area of 80x60 pixels. But be warned:
-
it may take several seconds for the page to build up (the author's machine
- Pentium III with 650MHz - requires approx. seconds for the initial rendering);
-
it may take several seconds for the browser to redraw the display (e.g. after
removal of a window which obscured the pixel display);
-
"PixelGraphics" occupies a huge amount of resources - systems with limited
memory capacity may need additional virtual memory or refuse to show the
page at all;
-
because of this consumption of processor and memory resources your browser
may simply crash - and your operating system may "follow" (according to the
author's experiences with Windows 98SE);
The following snapshot gives an impression of what you may see after running
all individual demos of the demonstrator (without clearing the display area
after each run):

Snapshot of "PixelGraphics" demonstrator after running all its demos
Usage Instructions
The integration of "PixelGraphics" into a HTML document is rather simple:
-
load the "PixelGraphics" library
the script library itself may be loaded by adding the following HTML tags
to the <head>...</head> section of a web page:
<script language="JavaScript1.2" type="text/javascript"
src="http://www.Andreas-Rozek.de/Scripts/PixelGraphics/PixelGraphics.js" >
</script>
The "PixelGraphics" package is now ready for use;
-
ensure the availability of all required pixel images
the actual implementation of "PixelGraphics" loads its pixel images from
the same directory where also the HTML document resides.You should therefore
download the PixelGraphics archive (found near the end of this page) and
extract all pixel image files into the folder with your HTML document;
-
create a pixel display
within your HTML document, a new graphics display may be constructed using
<script language="JavaScript1.2" type="text/javascript">
<!-- **** hide this script from browsers without JavaScript ****
createDisplay (80,60);
// **** end of JavaScript **** -->
</script>
On the authors machine, a pixel display of that size still responds fast
enough not to become boring for the visitor. Only one display per HTML document
may be constructed;
-
access the pixel display
from now on, the pixel display will be available and may be manipulated using
the functions listed below. A common code snippet looks as follows
setPenColor(Red);
drawArc(10,10, 50,50, 0,Math.PI/2)
Function Reference
"PixelGraphics" provides the following functions for creation and manipulation
of pixel graphics displays (listed in alphabetical order):
-
clearDisplay ()
-
sets the contents of all display pixels to white - and, thus, effectively
erases any display contents;
-
createDisplay ([Width, [Height, [Color]]])
-
creates a new pixel display with the given dimensions and fills it with the
given (background) color. Defaults for not explicitly given arguments are:
Width = 160, Height = 120, Color = White;
-
drawArc (x1,y1, x2,y2, phi1,phi2)
-
draws a (regular) oval arc defined by its bounding box (x1,y1)...(x2,y2)
and the angle range phi1...phi2 using the actual pen color. Angles should
be specified in Radians;
-
drawChord (x1,y1, x2,y2, phi1,phi2)
-
draws a (regular) oval chord defined by its bounding box (x1,y1)...(x2,y2)
and the angle range phi1...phi2 using the actual pen color. Angles should
be specified in Radians;
-
drawImage (Bitmap, x,y)
-
draws a "Bitmap" at the given coordinates. A "Bitmap" is represented by a
rectangular two-dimensional Array of (f.e., numeric) Color values. E.g.,
the JavaScript instructions
var Bitmap = new Array(
new Array(0,1,2,3), new Array(4,5,6,7),
new Array(8,9,10,11), new Array(12,13,14,15)
);
construct a bitmap of size 4x4 showing any available pixel color;
-
drawLine (x1,y1, x2,y2)
-
draws a straight line between its endpoints at (x1,y1) and (x2,y2) using
the actual pen color;
-
drawOval (x1,y1, x2,y2)
-
draws a (regular) oval defined by its bounding box (x1,y1)...(x2,y2) with
the actual pen color;
-
drawPie (x1,y1, x2,y2, phi1,phi2)
-
draws a (regular) oval pie defined by its bounding box (x1,y1)...(x2,y2)
and the angle range phi1...phi2 using the actual pen color. Angles should
be specified in Radians;
-
drawPixel (x,y)
-
sets the color of the given pixel (x,y) to the actual pen color;
-
drawPolygon (NodeX[], NodeY[], NodeCount)
drawPolygon (NodeList[], NodeCount)
-
draws a (closed) polygon defined by the given nodes. The first format passes
the x and y coordinates of each node in separate arrays, the second format
as a sequence of x-y-x-y-... coordinates within the same array. In both cases
NodeCount specifies the number of nodes rather than the number
of array elements;
-
drawPolyline (NodeX[], NodeY[], NodeCount)
drawPolyline (NodeList[], NodeCount)
-
draws a sequence of interconnected lines (i.e., an "open" polygon) defined
by the given nodes. The first format passes the x and y coordinates of each
node in separate arrays, the second format as a sequence of x-y-x-y-...
coordinates within the same array. In both cases NodeCount specifies
the number of nodes rather than the number of array elements;
-
drawRectangle (x1,y1, x2,y2)
-
draws a (regular) rectangle defined by its bounding box (x1,y1)...(x2,y2)
with the actual pen color;
-
getDisplayHeight () -> number
-
yields the actual display height (in pixels);
-
getDisplayWidth () -> number
-
yields the actual display width (in pixels);
-
getPenColor () -> (color object)
-
yields the actual color setting used for drawing - in form of a color object
which may be used to restore the original setting later:
var oldPenColor = getPenColor();
... <= any drawing instructions may be inserted here
setPenColor(oldPenColor);
-
min (a,b) -> number
-
yields the smaller of two given values (similar to Math.min);
-
max (a,b) -> number
-
yields the larger of two given values (similar to Math.max);
-
setPenColor (Color)
-
sets the color used to draw pixels, straight lines and other shapes to the
given Color. The argument may contain an integral number from 0
to 15, a literal color name or a color object (see below for a list of supported
colors);
All these functions manipulate the same pixel graphics display. Thus, only
a single display per HTML document is supported. Any given pixel coordinates
will be rounded to integral values before drawing, and lines outside the
visible display area will be properly clipped.
Supported Colors
"PixelGraphics" supports the following 16 colors:
|
 |
Black |
(0) |
|
 |
Maroon |
(2) |
|
 |
Green |
(4) |
|
 |
Olive |
(6) |
|
 |
Gray |
(1) |
|
 |
Red |
(3) |
|
 |
Lime |
(5) |
|
 |
Yellow |
(7) |
|
 |
Navy |
(8) |
|
 |
Purple |
(10) |
|
 |
Teal |
(12) |
|
 |
Silver |
(14) |
|
 |
Blue |
(9) |
|
 |
Fuchsia |
(11) |
|
 |
Aqua |
(13) |
|
 |
White |
(15) |
Whenever a function expects a color argument, this color may be specified
either numerically, literally or as a color object: the statements
setPenColor(0); // numeric argument, 0..15
setPenColor("black"); // literal argument, case-insensitive
setPenColor(Black); // color variable (see above for list of names)
all define "Black" as the actual drawing color.
Technical Description
As indicated above, a "PixelGraphics" display is represented by a single
HTML table with one table cell per scanline (i.e. row of pixels). Every scanline
consists of a sequence of bitmap images, each of these images represents
a single pixel within the display. In order to be able to access every individual
pixel, an unique name of the form
"Display<x>_<y>"
has been assigned to each image
(<x> stands for the horizontal,
<y> for the vertical coordinate of
a given pixel).
From a programmer's point of view, the coordinates of visible pixels range
from (0,0) (upper left pixel) to
(<width-1>,<height-1>)
(lower right pixel) where
<width> and
<height> denote the horizontal or
vertical display dimension, resp. (Interesting note: as the (JavaScript)
conversion of a number 0 to a string value may yield "-0"(!), the actual
"PixelGraphics" implementation always increments any given (x,y) coordinate
by 1 before searching for the corresponding pixel image).
The drawing functions of "PixelGraphics" are just straight-forward
implementations of common algorithms for raster graphics [3,4].
Caveats
Apart from its resource consumption, the actual implementation of "PixelGraphics"
has the following drawbacks:
-
because of a fixed "display name" the package supports only a single graphics
display per web page. As the high resource consumption of "PixelGraphics"
will usually forbid having several such displays within the same HTML document
anyway, this design decision should not cause any problems;
-
Image names and ids following the pattern "Display#_#" (with "#" representing
a number) should be avoided as they may affect the identification of individual
pixel images;
-
for performance reasons, "PixelGraphics" functions perform only very limited
argument checking. While pixel coordinates outside the visible area will
be clipped and non-existing colors replace by "Black", severe misuse may
just result in a "crash";
When DOM support becomes widely available, it will be useful to replace the
actual "PixelGraphics" implementation by an alternative based on "pure" tables
(with individually colored cells and without the need for bitmap images to
form the pixels). For the time being, however, such an implementation would
be supported by a small number of browsers only.
Source Code
The source code of this script "library" is available for download:
The whole "package" consists of this script file and a number of GIF images.
All these files may be downloaded as a single ZIP archive:
References
| [1] |
David Flanagan
JavaScript - Das umfassende Referenzwerk
O'Reilly Köln 1997, ISBN 3-930673-56-8 |
| [2] |
Stefan Münz
SELFHTML - HTML-Dateien selbst erstellen
(see
http://www.teamone.de/selfaktuell/) |
| [3] |
William M. Newman, Robert F. Sproull
Principles of Interactive Computer Graphics, Second Edition
McGraw-Hill 1984, ISBN 0-07-Y66455-2 |
| [4] |
Josef Pöpsel, Ute Claussen, Rolf-Dieter Klein, Jürgen
Plate
Computergrafik - Algorithmen und Implementierung
Springer Verlag, München 1994, ISBN 3-540-57248-1 |
|