[ JAIMEAS home ]

Usage overview:

  • Applet definition
  • JAIDraw
  • Script file
  • Objects
  • Actions
  • Hints
  • Examples
  • Restrictions
  • Upgrading from version 1.2
  • Usage of the JAIMEAS applet


    Applet definition in HTML file

    <applet code="jaimeas.class" width=600 height=400 MAYSCRIPT>
      <param name="script" value="example.script">
    </applet>
    

    The MAYSCRIPT attribute is optional, but required if you want to call Javascript URLs from the script (in the load option of an action).

    If the script file becomes larger, you may also zip it (using a standard zip program like WinZip (Windows) or zip (Unix)). The script file must be the first file in the zip file. The name of the zip file should be the name of the unzipped script file, extended with ".zip".

    Since older browsers do not support decrypting zip files in Java, the JAIMEAS loader will strip the ".zip" from the filename and load the normal script file in older browsers.

    So the applet definition for a ZIPped script file would be:

    <applet code="jaimeas.class" width=600 height=400>
      <param name="script" value="example.script.zip">
    </applet>
    

    In the document directory containing the HTML file with this applet definition, also put the files example.script.zip and example.script (the latter for older browsers).


    Creating a script file

    There are basically two ways to create a script file for JAIMEAS.

    • Write it directly using a text editor.
    • Create the object definitions using JAIDraw, then add the actions with a text editor.

    The next section describes the syntax and semantics of the script file.

    JAIDraw

    We have a tool available to simplify placing the objects: JAIDraw. JAIDraw is a general purpose drawing program written in Java. Starting with version 1.3, it supports saving output in a format compatible with JAIMEAS.

    See http://www.west.nl/archive/java/jaidraw/ for more information. See also the interactive tutorial on JAIDraw and JAIMEAS, to learn how to use them.

    JAIDraw can not be used for entering actions, only for the object definitions. But since placing the objects is the most tricky part, it can save a lot of time. JAIDraw is ideal for specifying sensitive areas on an image.

    Since JAIDraw supports a superset of the objects available in JAIMEAS, not all objects you use in JAIDraw will be saved in the JAIMEAS format.


    Script file

    The script file must contain object definitions and actions on objects. Each object and action starts with a keyword, and ends in a semicolon. Whitespace between elements is in most cases ignored (except in strings). So you can split a definition or action over multiple lines if it becomes too long.

    Version of JAIMEAS in script file

    At the top of the script (possibly after comments) you should define the version of JAIMEAS you used to create the script. The line must look like:

    • JAIMEAS version;

    where version is the version (e.g. 1.3).

    If no such line is specified, it is assumed the script is for version 1.2 or before.

    In version 1.3 the interpretation of the y-coordinate of text objects has changed from top to baseline of the text. Therefore specifying the version is essential to get the right interpretation.

    Comments

    Lines starting with a "#" character in the first column are skipped. You can use it for comments.

    Including other script files

    You can include another script file in a script file with the command:

    • include url;

    where url is the url of the script file to load. The URL may be relative, in which case it is assumed to be relative to the directory containing the HTML file with the applet tag.

    You may use the include command as often as you like. You may also use it in included scriptfiles again, as long as you do not create an endless loop.


    Objects

    Simple objects

    In short the following simple object types, with their parameters, are available:

    • text id linecolor x y "font" size style "text";
    • poly id linecolor fillcolor x1,x2,x3... y1,y2,y3...;
    • rectangle id linecolor fillcolor x1 y1 width height;
    • roundedrectangle id linecolor fillcolor x1 y1 width height;
    • oval id linecolor fillcolor x1 y1 width height;
    • image id "image-URL" fillcolor x1 y1 width height;
    • audio id "audio-URL" loop;

    where

    • id is a string. Each object must have a unique identifier. The id can contain almost any character (in version 1.2 and before only digits were allowed). If you want non-alphanumeric characters in an id, you must enclose it in double quotes.
    • fillcolor may be -1 indicating no fill (for images with a transparent color, this will make it transparent).
      If linecolor equals -1, no line is drawn.
      So if both are -1, the object is not visible. This is useful for e.g. defining sensitive areas.
    • For text, x y is the top left corner. size is font size in points. style is a number: 0=normal, 1=bold, 2=italic, 3=bolditalic.
    • For text, text is the text to be displayed. It may consist of several lines, which are displayed left-aligned. To start a new line, end the previous line with a backslash ('\') and a new-line character. To get double quotes and real backslashes in the string precede them with a backslash. Otherwise, the double quotes signal the start and end of the string.
    • x1, y1, width, height are specified in screen pixels. x1 y1 is the top left corner of the object. Width and height are relative to x1 y1, and should be positive. Coordinate 0 0 is a the top left of the applet area.
    • For a polygon, x1,x2,x3... and y1,y2,y3... are the list of x and y coordinates defining the points of the polygon. The last point will be connected to the first.
    • For an image, the image-URL is a full or relative URL of the image file (GIF, JPEG or whatever Java accepts). If relative, it is relative to the DocumentBase of the applet (i.e. where the document containing the applet definition is located).
    • For an audio object, the audio-URL is a full or relative URL of the audio file. If relative, it is relative to the DocumentBase of the applet (i.e. where the document containing the applet definition is located). The loop parameter can have a value of 0 (indicating no loop), or 1 (indicating infinite looping of the audio clip). It can be stopped by "hiding" the object, it (re)starts when the object is shown.

    Each of the simple objects, except the audio object, may have an optional "herespot" option, which if present must be added at the end of the object definition, just before the semicolon. Parameters for herespot are the x and y pixels relative to the upper-left corner of the object (or first point for a poly). E.g.

    	rectangle SampleRect 0x777777 0x777777
    		  20 30 50 60 herespot 25 30;
    

    has a herespot in the center of the rectangle. The herespot is used by the "movehere" option for actions. If not specified, the herespot is the top-left corner (or first point for poly).


    Animation object

    • animate id interval wait-between-loops objid-list;

    An animation object will show the given object-ids one at a time, showing each for interval time (in milliseconds). After all objects have been shown, it waits for wait-between-loops amount of time (during which the last object is visible). If it is negative, it will wait for ever on the last object.

    objid-list is one or more object-ids, separated by comma's.

    When an animation is hidden and shown again, the animation restarts with the first object again (no matter how long the wait-between-loops is).

    You can nest animations, i.e. the ids in objid-list may refer to other animations (be sure not to make loops, or the applet will crash).

    Examples:

    animate SampleAnim1 500 0 SA1_1,SA1_2,SA1_3,SA1_4,SA1_5;
    when this animate object is shown, first object SA1_1 will become visible, after half a second SA1_1 is hidden and SA1_2 becomes visible, then SA1_3, SA1_4 and SA1_5 each shown for half a second. Then the loop restarts with SA1_1 again, etc.
    animate SampleAnim2 100 99999999 smallbullet,mediumbullet,bigbullet,boom;
    when this animate object is shown, object smallbullet becomes visible, then mediumbullet, and bigbullet each for only 100 milliseconds, then show object boom for a long long time. When the object SampleAnim2 (this animate object) is hidden and shown again, it restarts with object smallbullet.
    animate NestedAnin 30000 0 SampleAnim1, SampleAnim2;
    this animate object will show one of the previous two animations. Every 30 seconds it will switch to the other animation. Note that the nested animations are restarted every time they become the current animation.

    Group object

    • group id objid-list;

    The group object will show all objects from the objid-list when it is shown. You can use it to put a couple of related objects together, and refer to all of them via the id of the group object.

    Groups can be nested, i.e. an id in the objid-list can be an id of another group. Be careful not to make loops using this, because the applet will crash.

    You can use a group id in an animation, allowing you to show more than one object in each animation frame.

    You can also use an animation in a group, even several animations. They will work as before.

    The order of the objects being painted when using a group is similar to when there is no group. The objects are just painted as they are listed in the objid-list from left to right. When an id of a (sub)group is encountered, first all objects in the (sub)group are painted.

    If a group is visible, all its members are visible. So you can use an "ifvisible" action (see section on Actions for more info) on the group id, but also on object ids in a group.

    An "inside groupid" action will succeed if the mouse is inside any of the objects in the group.


    Actions

    • onload ...;

    will perform what is specified by the options as soon as the applet is loaded. Use it e.g. to display the initial objects.

    • onmousemove inside id ...;
    • onmousemove outside id ...;
    • onmousedown inside id ...;
    • onmousedown outside id ...;
    • onmouseup inside id ...;
    • onmouseup outside id ...;

    These actions will be activated if: mouse is moved (with or without button pressed), mouse button goes down, or mousebutton goes up, inside or outside the given object (identified with its id).

    Each action can have one or several of the following options:

    show objid-list
    will show the given objects. For the audio object, it will start playing the sound.
    hide objid-list
    will hide the given objects. For the audio object, it will stop the sound.
    ifvisible objid-list
    will activate the action only when all given objects are visible.
    ifnotvisible objid-list
    will activate the action only when all given objects are not visible.
    move x-coordinate y-coordinate objid-list
    Move the top-left corner. Normally move top-left corner to new absolute x- and y-coordinate. If x-coordinate or y-coordinate starts with a "+" or a "-", the objects are moved relative to their current position. It is possible to mix absolute x- with relative y-coordinate or vice versa. To move a coordinate to an absolute position with a negative value (i.e. outside the visible screen), precede the coordinate with an "=" sign (for consistency you may precede any absolute coordinate for the move command with an "=" sign).
    movehere objid-list
    Move the "herespot" of the given objects to the current location of the mouse.
    status "string"
    Show the string in the status bar of the browser.
    load "framename" "url"
    load the given URL in the given frame or window. You may also call Javascript using the "javascript:xxx" url syntax (xxx is a Javascript command). You must set the MAYSCRIPT attribute of the applet tag (see section on applet tag)

    Hints

    Background color

    • JAIMEAS will clear the drawing area before redrawing the objects. It also uses double-buffering to reduce flickering. By default the background color is the default background color of a page (not necessarily the same as the actual background color that you set in a BODY tag).
      If you want a different background, show it as the first object. E.g.
        rectangle background 0x0 0x0 0 0 -1 -1;
        onload show background,line1,line2;
        
      You can also use an image as background.

    sensitive areas

    • You can use a poly-object to specify sensitive areas that are not rectangles. Just specify a poly object (possibly not visible) and use the id as in:
      onmousemove inside id-of-poly-object ...
    • The "inside id" will succeed also when the object id is not visible (has no line and fill color, or is just not shown with the "show" option. This is very useful for "sensitive areas".

      Use the "ifvisible id" (or "ifnotvisible id") options to apply an action only when the object is visible (or not visible).

    Memory

    • You can use dummy objects (e.g. a rectangle with no color and size 0, but any object will do) as sort of memory. A result of an action can be to show the dummy object. Later on you can perform an action depending whether or not the dummy object is "visible".

      You can use it e.g. to remember that the mouse button is down, so dragging an object (with "onmousemove") will only happen while the mouse button is down.

    Order of actions

    • The order of specifying action is important. For each event (mouse move, button press,...) all actions are evaluated once from top to bottom. Only after the last action, if anything has changed, the screen will be redrawn. If one action will show an object, and a later one will act if it is visible, that action will trigger. This is a common source of problems. Also, if one action shows an object, and a later action hides it again, the screen will redrawn, but there will not be a noticeable difference.

    Order of objects

    • The order of defining objects is not important.
    • The order of showing objects is important for overlapping objects. The objects are drawn one after the other, so the last one is always on top. If you hide and show the same object in a single action, it means it will appear on top.

    Move objects

    • You can let an object follow mouse, e.g.
        onmousemove inside MyRectangle movehere MyImage show MyImage;
        

    Drag-and-drop

    • You can implement drag and drop, e.g.
        onmousedown inside MySourceRectangle movehere MyMoveImage show MyMoveImage
      	  status "Picked up on MySourceRectangle";
        onmousemove inside 1 ifvisible MyMoveImage movehere MyMoveImage;
        onmouseup inside MyDestPoly ifvisible MyMoveImage hide MyMoveImage
      	  status "Dropped on MyDestPoly";
        

    Pre-loading images

    • When you use images, they have to be fetched from the server, and have to be rendered (and optionally scaled). To make JAIMEAS start as quickly as possible, only the objects named in the "onload" action are loaded before start-up. All other objects are loaded on-demand.

      This may mean that when you want to display an image, it takes some time for it to appear. This is especially undesired in animations. The animation may have moved to the next frame before the loading and rendering is even finished. So it may seem the animation is not displaying.

      There are several solutions to this, one of them is on my TODO list (make JAIMEAS try to be smart about pre-loading images). For the time being, you can do the pre-loading in the script using some tricks.

      • Name the images you need in the "onload" action. To prevent them from already showing, hide them behind e.g. the background rectangle or image (i.e. put them in the object-id list before another object that covers it). Note that the rendering is not (yet) done before start-up, so it still takes a short while before all images are available.
        image frame1 "frame1.gif" -1 50 50 0 0;
        image frame2 "frame2.gif" -1 50 50 0 0;
        image frame3 "frame3.gif" -1 50 50 0 0;
        group preloadframes frame1,frame2,frame3;
        animate framesanim 250 0 frame1,frame2,frame3;
        rectangle background 0xffffff 0xffffff 0 0 -1 -1;
        text initial 0x0 50 20 "Helvetica" 14 0
              "Press button to show animation";
        onload show preloadframes,background,initial;
        onmousedown inside background
              hide preloadframes show framesanim;
        onmouseup inside background hide framesanim;
        
      • If you want to spread the load a bit, and prevent downloading of all images before start-up, you can do a similar thing based on actions. If you expect one action to follow another in a while, show the images to preload (behind a background) already in the first actions "show" option.
      • For an animation, you can show a group with all images that are used in the animation in the first frame, thus starting their loading and rendering. This will of course only help if the interval between the frames is long enough for the rendering to complete before the image is really needed.

    Miscellaneous

    • Using (partly) transparent GIF images can give interesting effects. See for example the puzzle example.
    • You can play an audioclip a given period by using it in an animate object, e.g. the following will make a cheerful noise for about 5 seconds (assuming the cheer.au sound is about 1 second long).
        Audio cheer "sounds/cheer.au" 0;
        Animate cheer_5s 1000 9999999999
      	  cheer,cheer,cheer,cheer,cheer;
        

    Examples

    There are a couple of examples, with the driving script files, available.


    Restrictions

    One of the driving factors for JAIMEAS was to keep the applet small. This is one of the reasons for some restrictions. Others are due to the relative immaturity of the product.

    Error checking

    • There is not much error checking and reporting on the script. Error messages only report the line number where the error occurred. It is even possible to make a script that will crash the applet (but using "correct" scripts it should not crash). So you may have to go through some trial and error before you get the script right.

    Nesting

    • Nesting animate objects is possible. But nesting an animate object with itself will crash the applet.

    Timing

    • The resolution of animations is half of the smallest interval or wait time used in any animation. In most cases this will give rather accurate timing. But if you have 2 animations, one with interval 1000, and one with 1100, the second will not work as well as desired, because the resolution is 500. If it is a problem, create a dummy animation, which is never used, with an interval of e.g. 100.

    Loading images

    • Images you use in the script must exist. If one of the images could not be loaded, the whole interface fails. The applet will show an error message in its area.

    Upgrading from version 1.2

    If you have written script for JAIMEAS version 1.2, you can keep using them un-modified.

    Because in version 1.3 the interpretation of the y-coordinate is different from version 1.2 (in v1.3 it is the baseline, in v1.2 and before the top of the text), and probably more portable, it is adviced to change the scripts. You can try to do this by hand, if you can guess the distance between top and baseline of the text correctly. You need to add a version line as well (see script file section).

    You can also use JAIDraw 1.4 or later. If you created the objects using JAIDraw, you can just save them again in JAIMEAS format using JAIDraw 1.4. Otherwise, you can use the perl-script jai2draw.pl to convert the JAIMEAS script into a JAIDraw file. Load that into JAIDraw, and save it again, and you have the objects in JAIMEAS 1.3 format. You need to copy the actions by hand from the old to the new file. JAIDraw 1.4 tries to keep the same object IDs as much as possible, so probably you do not need to change IDs, but be sure to check that.

    Marco Nijdam
    -- West Consulting bv
    -- marco@west.nl

    [ JAIMEAS Home ] [ Copyright ] [ Introduction ]
    [ Examples ] [ Usage ] [ Downloading ]