Sick of fuzzy images?
In 2001 business graphics, maps, charts, CAD drawings
usually did't look very good on the web. Again and again
we came across pages where we had to squint our eyes and
ask ourself "What's that".
The reason was that these drawings were converted to GIF or JPeG files.
Drawing packages are vector based and GIF or JPeG are not, so a
lot of sharpness, contrast, and detail is lost during conversion. GIF
and JPeG are great for photos and other half tone images, but for
vector drawings they are not.
SVG was just in the making at that time and we needed a quick solution.
That's why we came up with the CGM viewer applet (cgmVA).
Most drawing packages
could export CGM (Computer Graphic Metafile, an ISO standard). The
applet was written in Java, is quite small (54k), and should
run on virtually any platform.
By now, cgmVA has been downloaded many times. In todays
environments, I would recommend using Flash, SVG, or HTML5 for vector
based graphics. Nevertheless, this applet is used freqently when it
comes to displaying engineering data and the like on the web.
The following
images demonstrate the difference between bitmapped images and the
vector graphics of
cgmVA.
| GIF - 10k |
JPeG medium quality - 9k |
CGM zipped -11k |
 |
 |
|
|
Try to zoom in
|
Try to zoom in
|
Click on
image to zoom in
|
While in this example the CGM file is the largest of the three,
CGM files don't get larger if you decide to display the image in a
larger size. You can display a drawing full
screen, without download time penalties.
Our cgmVA is interactive - users can zoom
into an image and can pan within the applet window. For
practical reasons we have limited the zoom factor to 16:1. The mouse controls are explained in the browsers
status line (move the mouse over the picture). cgmVA can also
be controlled via a toolbar using Javascript. For
an example please see here.
But that is only where the fun starts: cgmVA supports animation. Instead of inventing an own
animation script language, we decided to offer an animation interface
instead and to use JavaScript to control the animation. This
allows very sophisticated animations mixed with other multimedia
elements. For an example, see below.
Platforms
cgmVA runs on any Java-enabled browser that supports at
least JavaSE
1.3.
Animation requires a JavaScript/ECMAScript enabled browser. Popular
browsers
such as Microsoft Internet Explorer or Firefox should have no trouble
executing
this applet. However, you may want to make sure that both Java and
JavaScript
are enabled.
top
In addition to cgmVA, we provide cgmPanel, a Java class
library for CGM support in Java applications. This class
library
implements a CGM enabled subclass of JPanel under Java Swing and Java
1.3 or
later. It supports all features of the cgmVA (plus some more) including
animation. A demo version can be downloaded from here.
Also available is cgmSwt, an Eclipse
plug-in
for CGM support. This includes a SWT based library supporting all the
features of the cgmVA (plus some more)
including animation, and an CGM viewer plug-in for the Eclipse
platform. cgmSwt
requires Java 1.4, GDI+ on Windows (Windows XP) or the Cairo Vector
Engine under
Linux GTK. A demo version can be downloaded from here.
top
CGM functionality
cgmVA can read binary and ASCII CGM files, but not ISO
character encoded CGM files.
cgmVA supports most of the functionality of CGM
Version 1 with a few exceptions:
- the advanced text attribute Character Expansion is
only supported for Hershey fonts.
- only hollow, empty, solid, horizontal and vertical
hatching is supported for Interior Style.
- Generalized Drawing Primitives are not supported
(GDPs are mostly used for proprietary extensions).
In addition cgmVA supports Bezier polylines
from the CGM 3 standard.
top
The following HTML code displays the image my.cgm in a
400x400 area (Please refer to the Java Applet documentation for an
explanation of the parameters).
We start by specifying the applet itself. We assume that the applet
classes are all stored in a subdirectory called cgmva/.
<applet
code="CgmViewApplet.class" codebase="cgmva/" width=400
height=400>
Alternatively you can use the JAR file cgmVA.jar (54k)
supplied in the download package.
<applet
code="CgmViewApplet.class" archive="cgmva.jar"
codebase="cgmva/"
width=400 height=400>
Next we define which CGM files to display:
<param name="filename"
value="cgmva/cgms/my.cgm">
You can specify several filenames separated by commas. All
these images will be displayed in Layer 0 (see
below) on top of each other. For instance:
<param name="filename" value="cgmva/cgms/back.cgm,cgmva/cgms/front.cgm">
In this case it might be better to specify the directory for
the images separately:
<param name="imagebase"
value="cgmva/cgms/">
<param name="filename" value="back.cgm,front.cgm">
For security reasons, Java applets can only access files
within the codebase directory. Images must be stored
in the same directory as the applet classes or in a subdirectory.
Note: The file extension ".cgm" can be
omitted - it is the default file extension for CGM images.
Finally, we close the applet definition:
</applet>
top
Using zipped archives
It is possible to pack all image files into a zipped archive
specifying an optional parameter cgmArchive.
cgmVA will load the whole archive and will satisfy requests for
individual image files from this archive. This can result in dramatic
download speed improvements, especially with animations, where
many images are used.
Note: These ZIP-archives should not
contain path names.
Example:
<param name="imagebase"
value="cgmva/cgms/">
<param name="filename" value="scene">
<param name="cgmArchive" value="hello.zip">
The file scene.cgm will be retrieved from
archive hello.zip.
(If not found there it will be retrieved from its own URL.)
Note: The file extension ".zip" can be
omitted - it is the default file extension for ZIP archives.
top
Pixel based images
GIF-, JPeG-, and PNG-images can be displayed along with CGM
images.
Pixel based images are especially useful if you want to use a
photograph as background of a drawing:
<param name="filename"
value="cgmva/cgms/back.gif,cgmva/cgms/front.cgm">
Note: Pixel based images files cannot
be placed into a zipped archive, but are loaded individually.
top
Fonts
Normally, cgmVA uses native fonts for text
output. In addition,
it is possible to use Hershey fonts.
To use your own Hershey fonts, simply put them into the zipped
cgmArchive. Alternatively, you may specify a font list to load font
files individually:
<param name="fontbase"
value="cgmva/fonts/">
<param name="hersheyFonts"
value="Times,GillSans,GillSans_BoldItalic">
Note: The default extension for font file names
is ".jhf".
cgmVA uses these Hershey fonts if their file names
match with
the specified font names in the drawing. A typical font name
consists of the font family name, like "GillSans", and an
optional style modifier: "_BoldItalic", "_Bold", "_Italic".
To find out which fonts are used in a drawing, open the drawing with a
text editor and look for font names.
Hershey fonts are available from http://www.nyx.net/~jbuzbee/font.html
| Note: Some advanced text features
like character expansion are not available with native fonts but only
with Hershey fonts. cgmVA switches automatically to the the Hershey
font Futura light when rotated text is to be displayed in a
native font. You must place the file futural.jhf
into the fontbase and declare it like shown above, when your drawing
contains character expansion text. |
top
Rendering Quality
By default, cgmVA uses the antialiasing settings of the host
platform. However, you may influence antialiasing behavior by setting
the parameter:
<param name="antialiasing"
value="on">
or:
<param name="antialiasing"
value="off">
By default, cgmVA uses a compromise between quality and speed
when rendering images. However, you may influence rendering behavior by
setting the parameter:
<param name="rendering"
value="speed">
or:
<param name="rendering"
value="quality">
top
Background colour
The background colour can be specified with the parameter
<param name="bgcolor"
value="#rrggbb">
The colour encoding is the same as in HTML (#ffffff
for white, #000000 for black).
If this parameter is not specified, the background colour is
determined by
the first image. If this image does not set
the background colour, cgmVA defaults to the applet
background colour, which is grey.
Note, that many CGM images establish an own canvas in form of
a filled
rectangle. This will, of course, override the background setting.
top
Inverse colours
The parameter
<param name="inverse"
value="true">
makes all CGM-colours to appear inverse.
top
cgmVA can notify a JavaScript function about Animation
and Navigation events. You can specify
the name of a JavaScript function as an element handler with
<param name="eventHandler"
value="myHandler">
The default value is "appletEvent". To enable event
notification you must also specify a mayscript attribute in the applet clause:
<applet
code="CgmViewApplet.class" ... mayscript ...>
top
Fail safe
What do we do with browsers that don't support Java or where
the
user has disabled Java? In this case we use a pixel based version of
the drawing to fall back on. Here is the way how it is done. Just
include the GIF image between the <applet> and </applet>
tags:
<applet
code="CgmViewApplet.class" codebase="cgmva/" width=400 height=400>
<IMG SRC="Images/my.GIF" width=400 height=400>
</applet>
top
Running under the Java2 plug-in
cgmVA can run under the Java2 plug-in. We do not recommend
this because:
- loading is much slower
- The HTML code to embed an applet is platform specific. The
old
APPLET tag is replaced by OBJECT for IE4/5 and by EMBED for Navigator.
Pages that must run on all platforms get rather complex. If you still
want to do it, use JavaSoft's java-plug-in-html-converter
to convert APPLET tags into EMBEDs or OBJECTs.
- NO scripting! Back to basics!
top
Mouse
controls
Zooming and scrolling is achieved by using the mouse. Mouse controls
can be used , too, when an animation is running.
By default, mouse controls are enabled and a help text is
displayed in the browsers status bar as the user moves the mouse
across the applet area. This help text moves with the mouse
movement to be fully readable in short status lines. You can avoid
this movement by specifying a text that starts with a period.
The default text is:
Click/drag=Zoom in, AltClick=Zoom out, AltDrag=Pan,
AltDoubleClick=Reset, ShiftClick=Centre
You can supply your own message with the
parameter controls:
<param name="controls" value="What else would you want?">
If you supply an empty or blank string, the
mouse controls are switched off:
<param name="controls" value="">
The zoom factor can be set with:
<param name="zoomFactor" value="1.2">
The default value is 1.414...
top
The parameter
<param name="keyActions"
value="true">
enables the keyboard for scrolling and panning. This is to
allow mouseless
operation. The following keys are available:
| + |
zoom in |
| - |
zoom out |
| Enter |
fire hyperlink |
| Spacebar |
reset |
| ! |
find next hotspot |
| Cursor keys |
panning |
top
Imagemaps
Using image maps with cgmVA is easy. Just
specify another parameter
<param name="imagemap" value="mapname,url1,url2,...">
mapname specifies another CGM file relative
to imagebase. This CGM file contains a drawing that
determines the hot areas in the drawing. Please note, that cgmVA
can only recognize filled elements as hot areas. If you move the mouse
over such an area, cgmVA displays the attached URL in the
status line. When you click, the URL well be fetched.
If no URL is attached to an image map element, cgmVA displays
the
number of the element in the status line. This helps to find out
element numbers during development and to attach the correct URLs.
Optional, an hyperlink can be highlighted when the mouse
enters the hotspot
region. Specify
<param
name="showHotspots" value="true">
When
<param
name="keyActions" value="true">
is specified, the "!" key can be used to jump from hotspot to
hotspot.
Image maps override other mouse controls.
An example is seen in the toolbar
demonstration.
top
You can define a define a separate JavaScript event handler
for each instance of cgmVA (see above).
You must then supply a JavaScript function that will be invoked for
each key and mouse action:
function appletEvent(task,device,event) { .... }
This function is supplied with the following parameter values:
task
| "Navigation" |
A navigation event (scroll, zoom) |
| "Animation" |
An animation event (mouse animation event or key event) |
device
| "Mouse" |
A mouse event |
| "Key" |
A key event |
event
| "Down" |
mouse button or key was pressed |
| "Up" |
key was released |
| "Click" |
mouse click (button released) |
| "DoubleClick" |
mouse double click |
| "Drag" |
during dragging (button still pressed) |
| "Drop" |
Dragging finished (button released) |
| "Move" |
mouse was moved |
An example is seen in the toolbar
demonstration.
top
Animation
The applet version string can be obtained with
string=getVersion()
Layers, Images, Panes, Components
cgmVA organises each scene in up to 16 layers (0-15).
Each
layer can contain an unlimited number of images. Each image is
represented by a separate file and can contain many components
organised in several panes.
Layers with higher numbers are in front of layers with lower numbers.
The same is true for panes and components.
It is possible to control each image separately or to apply controls to
whole layers. A limited set of controls is available for panes and
components within images. By default new layers are visible and
are located at (0,0) with a magnification of (1,1). When the applet is
invoked, the main image (specified in the "filename" parameter) is
located in layer 0 at position 0,0 with normal size.
top
Coordinates
The base image also defines the coordinates for all subsequent
operations. (0,0) is the left upper corner of the image, and the
longest edge of the image has the length of 1000.
Each image is automatically scaled to fit into a 1000x1000 square when
loaded. Translating operations are used to position and size the image
as required. The aspect of images is maintained but can be changed by
translating operations.
The working area for all animation operations is the square (0,0)
(1000,1000). cgmVA finally maps this area to the actual
applet area.
top
Visibility
There are four visibility levels that can be applied to single
layers or single pictures:
- show
The image is displayed with all lines and fills, find operations
succeed on fills.
show(l,name)
Loads the image "name" into layer "l" if not already loaded. The
image is set to "visible".
You can also specify a comma separated name list.
show(l) Sets
layer "l" to "visible", all visible or wire images in this layer
are displayed.
show(l,name,c) sets
component "c" in image "name" in layer "l" to visible.
- wire
The image is displayed without fills, but find operations succeed on
the invisible fills.
wire(l,name)
Loads the image "name" into layer "l" if not already loaded. The
image is set to "wire".
You can also specify a comma separated name list.
wire(l) Sets
layer "l" to "wire", all visible or wire images in this layer are
displayed in transparent fashion.
wire(l,name,c) sets
component "c" in image "name" in layer "l" to "wire".
- map
The image is not displayed, but find operations succeed on
the invisible fills. Used for image maps.
map(l,name)
Loads the image "name" into layer "l" if not already loaded. The
image is set to "map".
You can also specify a comma separated name list.
map(l) Sets
layer "l" to "map", all images in this layer are not displayed.
map(l,name,c) sets
component "c" in image "name" in layer "l" to "map".
- hidden
The image is not displayed. Find operations fail.
hide(l,name) Loads
the image "name" into layer "l" if not already loaded. The image is set
to "invisible".
You can also specify a comma separated name list.
hide(l)
Sets layer "l" to "invisible", all images in this layer are
hidden.
hide(l,name,c) sets
component "c" in image "name" in layer "l" to "invisible".
For example, hide(l,name,0) can
be used to hide the first component of a picture which usually contains
the background rectangle.
- clip(x,y,w,h)
- Sets a clipping rectangle at position (x,y) with with w and
height h for the whole scene.
Can be used for blending effects.
- clip(l,x,y,w,h)
- Sets a clipping rectangle at position (x,y) with with w and
height h for layer "l". Can be used for blending effects.
-
replaceText(l,name,n,text)
- Replaces the text in the n-th text element of image "name"
in layer
"l" with the specified text string. This operation changes all clones,
too. Counting begins at 1.
Good for reusing images where only the text changes.
top
Streaming
preload(names)
- Specify a comma separated name list. The list can contain
zipped
archives (.zip), sounds (.au), Hershey fonts (.jhf), and cgm files
(.cgm). The default file extension is .cgm. The files are preloaded for
later use. The use of this command is optional, but can result in
a smoother animation.
- unload(names)
- Specify a comma separated name list. The list can contain
sounds
(.au), Hershey fonts (.jhf), and cgm files (.cgm). The default
file extension is .cgm. The files are removed from memory. This
command is only necessary for very long animations with changing
scenes when memory space becomes an issue.
(Sound files can be removed while playing - the
sound file will be removed after it has stopped playing).
- top
Translating Operations
Layer translations are relative to the base image area. Image
translations are relative to the containing layer.
- translate(x,y)
- translate the whole scene by a (x,y) distance. This has
only effect on scenes magnified by a scale operation (see
below). With translate x- and y- values are move-to
values, not move-by values.
translate(l,x,y)
- translate layer "l" by a (x,y) distance. Layer numbering
starts at 0.
- translate(l,name,x,y)
- translate picture "name" in layer "l" by a (x,y) distance
relative to layer origin.
scale(mx,my)
- scale the whole scene horizontally by factor mx
and vertically by factor my. Factors between 1 and 16 are
allowed.
- scale(l,mx,my)
- scale layer "l" horizontally by factor mx and
vertically by factor my. Factors between 0 and 16 are
allowed.
- scale(l,name,mx,my)
- scale picture "name" in layer "l" horizontally by factor mx
and vertically by factor my. Factors between 0 and 16 are
allowed.
- scroll(x,y)
- scrolls the visible window by
a (x,y) distance. This is equivalent to a user scroll operation.
-
- setViewX(x)
- sets the visible window to scene x-position.
- setView(y)
- sets the visible window to scene position y on the
Y-axis.
- getViewX()
- returns the x-position of the visible window within the
scene
- getViewY()
- returns the y-position of the visible window within the
scene
- getViewWith()
- returns the width of the visible window in scene units
- getViewHeight()
- returns the height of the visible window in scene units
-
- zoom(m,x,y)
- set zoom magnification to"m" towards point (x,y).
This has
the same effect as a user zoom action. It overrides user zoom
actions and can be overridden by user zoom actions.
- zoom(m)
- set zoom magnification to"m" towards centre of window.
- getZoom()
- returns the current zoom magnification.
- setZoomFactor(f)
- sets the factor by which the zoom magnification is
increased or decreased. The default value is sqrt(2).
- getZoomFactor()
- returns the zoom factor.
getLayerX(l)
getX(l)
(deprecated)
- get horizontal position of layer "l".
- getCgmX(l,name)
getX(l,name)
(deprecated)
- get horizontal position of picture "name" in layer "l"
relative to layer origin.
getComponentX(l,name,comp)
getX(l,name,comp)
(deprecated)
- get horizontal position of component "comp" in picture
"name" in layer "l" relative to layer origin.
getLayerY(l)
- getY(l)
(deprecated)
- get vertical position of layer "l".
- getCgmY(l,name)
getY(l,name)
(deprecated)
- get vertical position of picture "name" in layer "l"
relative to layer origin.
- getComponentY(l,name,comp)
getY(l,name,comp)
(deprecated)
- get vertical position of component "comp" in picture
"name" in layer "l" relative to layer origin.
- movePane(l,name,p,x,y)
- Moves pane "p" within image "name" in layer "l" by the
distance specified in "x" and "y". Pane numbering starts at 0.
- moveComponent(l,name,c,x,y)
- Moves component "c" within image "name" in layer "l" by the
distance specified in "x" and "y". Component numbering starts at
0.
top
Cloning
To use several instances of the same image append an
identification to the name. Identification must start with a "#"
character. For instance,
show(3,dolly.cgm#2)
shows a clone of dolly.cgm in layer 3.
Clones can be translated, scaled, shown and hidden
individually. However, text replacements affect all clones
simultaneously.
top
Rendering
- render()
- This will redraw the whole scene.
Show, hide, and display do not have any effect on the display until render() is called.
- top
User
interaction
- setEventMask(modifiers)
By default, all mouse events with the CTRL-key pressed are regarded as
animation mouse events.
You can change this with setEventMask. (Values 1-4 can be combined).
| 0 |
pass all mouse events to the animation interface.
(disables user zoom). |
| 1 |
Shift-modifier |
| 2 |
CTRL-modifier (default) |
| 4 |
Meta-modifier or right mouse button |
modifier=getModifier()
- returns the modifier value from the last mouse event.
| 1 |
Shift |
| 2 |
CTRL |
| 4 |
Meta or right mouse button |
| 8 |
Alt or middle mouse button |
-
- setModifier(modifier,mode)
- sets the modifier keys for the next key or mouse click or
drag event.
modifier
| 0 |
No modifier |
| 1 |
Shift |
| 2 |
CTRL |
| 4 |
Meta or right mouse button |
| 5 |
Meta+Shift. This enables drag but inhibits zoom.
The cursor changes to a hand. |
| 8 |
Alt or middle mouse button |
| 16 |
Double Click |
mode
| 0 |
Switch off |
| 1 |
Only for next mouseclick/keypress |
| 2 |
until switched off |
-
- event = mouseControl(statusline)
- Shows the specified text in the status line and returns a
mouse event.
If no new mouse event happened during the last invocation of
mouseControl an empty string is returned.
Otherwise:
| "Down" |
mouse button was pressed |
| "Click" |
mouse click (button released) |
| "DoubleClick" |
mouse double click |
| "Drag" |
during dragging (button still pressed) |
| "Drop" |
Dragging finished (button released) |
| "Move" |
mouse was moved |
event = mouseControl()
- Same as above, but status line remains untouched.
- event = mouseControl("")
- Same as above, but status line is reset to the state before
animation was started.
getSceneX()
-
getX()
(dropped)
- returns horizontal mouse position for recent mouse control.
- getSceneY()
getY()
(dropped)
- returns vertical mouse position for recent mouse control.
- getKey()
- returns the key code of the most recent key pressed. If the
key is
still down, the value is negative, if the key is up again, the value is
positive.
Note: Key events are not buffered.
- getKeyModifier()
- returns the modifier for the last key (key down) event.
Modifier values same as above.
- top
Finding
objects
cgmVA can find the foremost object in a scene for a
specified
(x,y) position and returns filename and clone id of the found picture.
The algorithm used is:
- fail on hidden objects or layers (returns empty string)
- CGM-pictures: succeed on foremost object that has a fill
at the search position.
The visibility status of the objects must be "show", "wire" or "map".
- GIF-images: succeed on all non transparent pixels of
the image.
name=findPicture(x,y)
find the picture at position x,y.
- Removed: Use findPicture(-1,x,y).
- name=findPicture(l,x,y)
- find the picture at position x,y in layer "l". Specify -1
for the layer number to search in all layers
name=findPicture(event)
- same as above, but the position is derived from the event:
| "Down", "Click", "DoubleClick" |
Position when mouse button was pressed |
| "Drag" or "Drop" |
Current mouse position during drag operation |
| "Move" |
Mouse position during mouse move |
-
- name=findPicture(l,event)
- as above, but restricts the search to layer "l".
- name=findText(t)
- find the specified string t in a text element. A matching
text
element is marked. Supply the empty string to find the next occurence.
- name=findText(l,t)
- as above, but restricts the search to layer "l".
- number=getComponent()
- returns the index of the image component that caused a
previous "find" operation to succeed.
-
- number=getLayer()
- returns the layer index that caused a previous "find"
operation to succeed.
- top
Sound
Although you can use the browsers sound facilities from
JavaScript, we provide methods to play sound (.au) files.
The advantage is that this is truly platform independent and does not
require plug-ins.
- playSound(filename)
- plays the specified sound file. The default file extension
is .au.
- stopSound(filename)
- stops the playing of the specified sound file.
- loopSound(filename)
- play the specified sound file continuously.
Optionally you can use the sound-parameter in the applet
definition to preload sound files:
<param name="soundbase"
value="cgmva/sounds/">
<param name="sound" value="sound1,sound2">
top
Invocation from JavaScript
Note:
Invoking Java-Methods from JavaScript requires Netscape Navigator with
LiveConnect/LiveWire or MicroSoft InterExplorer 4.0.
First embed the applet into HTML. For instance:
<applet
code="CgmViewApplet.class" codebase="cgmva/" name="cgm1" width=400
height=400>
<param name="imagebase" value="cgmva/cgms/">
<param name="filename" value="my">
</applet>
Note the name definition cgm1.
This name is used in the following JavaScript function to address the
specific applet instance.
Now we define a JavaScript function in the HTML header section:
<html><head><title>Test</title>
<script
language="JavaScript">
function test(i) {
// we run 100 times
if (i < 100) {
// each time make layer 0 a bit smaller
document.cgm1.scale(0,(100-i)/100,(100-i)/100);
// done, now display the result
document.cgm1.render();
// increment counter
i++;
// now post a timer event with "test(i+1)" to be executed
timerOne=window.setTimeout("test(" + i + ")",100);
}
}
</script>
</head>
top
Finally, you have to invoke the JavaScript function somewhere. Here we
define a button and an event handler:
<form name="Input">
<input type=button value="Test" onclick="test(0)">
</form>
Note:
JavaScript functions can be contained in separate files, so they can be
used from different HTML pages.
top
Hello, world
"Hello, world" illustrates several animation techniques:
- use mouse controls to zoom into the scene
(left click to zoom in, drag to scroll, right click to zoom out)
- start the animation by pressing the Start-button
below
When the animation is running you can
- move the mouse over the dinosaur. This will make the
dinosaur issue a statement.
press the Ctrl-key and
- drag the dinosaur across the scene.
- click on the planet. Surprise!
Applet Definition:
<APPLET code="CgmViewApplet.class" archive="cgmVA.jar" codebase="cgmva/" name="hi" width=450 height=450 MAYSCRIPT> <PARAM name="imagebase" value="cgmva/cgms/"> <PARAM name="cgmArchive" value="hello.zip"> <PARAM name="filename" value="Scene"> <PARAM name="soundbase" value="cgmva/sounds/"> <PARAM name="sound" value="hi"> </APPLET> <FORM name="Input"> <INPUT type=button value="Start" onclick="hello(0)"> <INPUT type=button value="Stop" onclick="cancel_hello()"> <BR> <BR> </FORM>
The JavaScript definitions for hello(0)
and
cancel_hello() are in the
HTML
header.
Please see the HTML code of this page.
top
History and Status
Acknowledgements
This project was initiated by Alexander Larsson (alla@lysator.liu.se), who wrote
V0.1.
Text objects, mouse control, animation, ZIP- and GIF-support were added
by Berthold Daum (berthold.daum@online.de).
The Hershey-class was contributed by James P. Buzbee (jbuzbee@nyx.net).
Dirk Bosmans (dirk.bosmans@tijd.com)
simplified the fail safe clause.
Some algorithms were imported from
Core Web Programming from Prentice Hall Publishers, 1997
Marty Hall, hall@apl.jhu.edu.
top
Download
If you wish to be notified
about new versions of cgmVA please leave your name and email
address here:
Download latest
version of cgmVA
top
To include CGM functionality
into your own
Java applications we provide the packages CgmCanvas
and CgmSWT. See here.
top
|