Bill Bellon -- SSEC/UW-Madison

JSani - a simple JavaScript animator

About JSani

Note: there is now a version 2 of JSani. It is currently a beta version and still being developed. This version will only updated for bug fixes and all future additions of new features will be added to version 2.

JSani is a free, lightweight, fast JavaScript/jQuery based animation tool. It is meant to animate a series of images (JPEGs, PNGs, GIFs ...) by switching between them like a flip book, creating an animation. It can also be used as a slideshow. Because it uses JavaScript, HTML and CSS only, it works well on smartphones (iPhone, Android ...). JSani is structured after Tom Whittaker's AniS Java applet.

Contact me if you have questions, need to report a bug or want to be put on a mailing list to be kept informed of new versions to JSani.

Examples

Download

Documentation

Step by step instructions for deploying JSani

  1. Download the JSani code, unpack the files and upload them to your web server
  2. refering to the general documentation and examples below, add the appropriately configured <form></form> JSani container into your web page
  3. add

    <script language="javascript" type="text/javascript" src="jsani/jsani.loader.js"></script>

    to the <head></head> section of your web page.

    Caching:
    If you are using a new version of JSani, please be aware that your users may see old, cached versions of the JSani files when viewing your animations depending on how you have caching setup. You can fix this by setting appropriate server cache control headers via .htaccess files. The JSani loader file (jsani/jsani.loader.js) will append query strings to the JSani JavaScript and CSS files it loads to ensure that when you upgrade to a new version of JSani, if your user is viewing the latest version of the JSani loader they will also get the latest related files. So another way to deal with caching issues is to ensure your user is viewing the latest version of the JSani loader file (jsani.loader.js) - besides server cache controls, you can simply just append a ?unique_query_string on the end of the filename for the jsani.loader.js file in the <script> tag - example: jsani.loader.js?2012_08_09.
    (only relevant to jsani.loader.js - all other related files will be appended with the version # of JSani when loaded so when you use a new version of JSani, as long as the new version jsani.loader.js file is served to your users they will get the new versions of the related files)
  4. in the above <script> tag that you add to your web page, modify the src="" attribute to point to the location where you put the jsani/ folder containing the JSani code (if you put it in the same folder as your web page then the above example should work).
  5. edit the following two lines in the jsani/jsani.loader.js file so that they specify the correct locations for the JSani and jQuery code:

    var jsani_dir = 'jsani'; // no trailing /
    var jquery_dir = 'jsani/jquery'; // no trailing /

    If you put the jsani/ folder in the same folder where your web page is, then you shouldn't have to modify these lines.
    (no longer needed)

General documentation

Example:

<html>
<head>
<script language="javascript" type="text/javascript" src="jsani/jsani.loader.js"></script>
</head>
<body>
<form name="jsani" id="jsani" action="#" style="width: 800px; height: 640px;">
    <input type="hidden" name="filenames" value="image0.jpg, image1.jpg, image2.jpg, image3.jpg">
    <input type="hidden" name="imgbaseurl" value="images">
    <input type="hidden" name="controls"
           value="previous, stopplay, next, looprock, slowfast, zoom, refresh">
    <input type="hidden" name="maxdwell" value="1400">
    <input type="hidden" name="mindwell" value="100">
    <input type="hidden" name="initdwell" value="300">
    <input type="hidden" name="nsteps" value="8">
    <input type="hidden" name="last_frame_pause" value="3">
    <input type="hidden" name="first_frame_pause" value="2">
    <input type="hidden" name="frame_pause" value="2:4,3:5">
</form>

</body>
</html>

The above is an example of how JSani can be used in a web page.

The config options can also be specified via an external configuration file (text file):

<html>
<head>
<script language="javascript" type="text/javascript" src="jsani/jsani.loader.js"></script>
</head>
<body>
<form name="jsani" id="jsani" action="#" style="width: 800px; height: 640px;">
    <input type="hidden" name="config_file" value="my_config_file.cfg">
</form>

</body>
</html>


# This is my_config_file.cfg (UNIX style comments are allowed in the config file).
# You can point JSani at the same config files that FlAniS uses.
filenames=image0.jpg, image1.jpg, image2.jpg, image3.jpg
imgbaseurl=images/
controls=previous, stopplay, next, looprock, slowfast, zoom, refresh
maxdwell=1400
mindwell=100
initdwell=300
nsteps = 8 # UNIX style comments are allowed
last_frame_pause=3
first_frame_pause = 2
frame_pause=2:4,3:5

Let's start with:

<script language="javascript" type="text/javascript" src="jsani/jsani.loader.js"></script>

This creates the necessary <link></link> and <script></script> tags in the header to link to the JSani and supporting JavaScript and CSS files. The jsani.loader.js must be linked to in the <head></head> section of your page or it will not work.

The actual container for your animation is dynamically generated inside this container:

<form name="jsani" id="jsani" action="#" style="width: 800px; height: 640px;">
</form>

It must have an id="jsani". It should also have a width and height specified for it, either via the style="" attribute or via CSS elsewhere (i.e., your own stylesheet or <style></style> section in the page). JSani will automatically resize the images in your animation to fit within the <form id="jsani"></form> container.

Configuring JSani

JSani is configured via one of three ways:

1) hidden form fields like this:

<input type="hidden" name="filenames" value="image0.jpg, image1.jpg, image2.jpg, image3.jpg">

2) By using the config_file option to specify an external configuration file (see example above).

3) Alternatively, options can be specified in both places (inside the JSani <form></form> container via <input> fields and via the config file) - the same option must NOT be specified in both places however.

Config parameter names are case insensitive (but the values are NOT).
For example,

<input type="hidden" name="filenames" value="image0.jpg, image1.jpg, image2.jpg, image3.jpg">

(or if in the config file:
filenames=image0.jpg, image1.jpg, image2.jpg, image3.jpg
)

and

<input type="hidden" name="FileNames" value="image0.jpg, image1.jpg, image2.jpg, image3.jpg">

(or if in the config file:
FileNames=image0.jpg, image1.jpg, image2.jpg, image3.jpg
)

will be treated the same. However

<input type="hidden" name="FileNames" value="IMAGE0.jpg, image1.JPG, Image2.jpg, image3.jpg">
is NOT the same.

Parameters - required (if specified inline)

  • filenames: a comma separated list of the filenames of the images comprising your animation.
    Example: "image1.jpg, image2.jpg, image3.jpg"
    or
    file_of_filenames: the URL (relative or absolute) of a text file that contains the filenames for the animation.
    Example: "file_of_filenames.txt"

    The format of the file_of_filenames should be one filename per line in the order that you want them to appear in the animation. Example:
    image1.jpg
    image2.jpg
    image3.jpg # UNIX style comments are allowed

    # FlAniS formatted file_of_filenames files are also allowed which have lines like this
    image4.jpg "Aug 3 1:15pm" overlay= TSFC2.GIF, TSTR1.GIF, TMAP.GIF
    # In the above line, only image4.jpg is read - the rest is ignored.

    FlAniS formatted file_of_filenames can also be used - overlays and frame labels, are not supported (yet) so this additional information is ignored. Note: as JSani is currently coded, this parameter may not work as intended if you are viewing your animation web page locally (i.e., file://).

  • controls: a list of the animation controls you want displayed. Example: "previous, stopplay, next"
    Required controls:
    • stopplay: the Stop/Play button - will show as "stop" when the animation is playing and when clicked on it will stop the animaiton and change to a "play" button. (Can also be called startstop for compatibility with FlAniS config files)
    Optional controls:
    • previous: a previous frame button. Clicking on it will stop the animation and advance to the previous frame of the animation. (The FlAniS control called step can used in place of this and the next control - in that case if step is used then the previous and next controls are placed side by side)
    • next: a next frame button. Clicking on it will stop the animation and advance to the next frame of the animation. (see notes on the control called: previous)
    • looprock: a button that allows the user to toggle between the default loop mode and a rock mode. The rock mode will make the animation rock back and forth between the beginning and end of the animation - when the end of the animation is reached in rock mode, the animation reverses direction until it reaches the first frame at which point it starts going forward again.
    • slowfast: two buttons, "slower" and "faster". Clicking on "slower" slows down the animation and clicking on the "faster" button will ... yep, speed up the animation. (Can also be called speed for compatibility with FlAniS config files)
    • refresh: a refresh button that when clicked on will reload the animation images from the server (useful if you are serving real-time images).
    • zoom: when clicked a zoom mode is enabled where the user can zoom in by clicking on the animation or zoom out by CTRL-clicking. Note: the zoom button will not be displayed and is disabled if a mobile browser is detected viewing the animation.

Parameters - required (if specified via config file)

  • config_file: the URL (relative, absolute ...) of an external config file that contains the required (see above) and optional (see below) config options. Example. Note: this parameter may not work as intended if you are viewing your animation web page locally (i.e., file://).

Parameters - optional

  • imgbaseurl:the URL (relative, absolute ...) of where your images are located. There should NOT be a trailing slash (/) This parameter can be specified with or without trailing slash. If this parameter is omitted then the current folder where your web page resides is assumed where your images reside. Example: "images". Note: this parameter can also be called image_base (for compabibility with FlAniS config files).
  • maxdwell: Maximum dwell rate. Clicking on the "slower" button will keep increasing the dwell rate (how many seconds to dwell on each frame/image in the animation) until the maxdwell rate is reached - this is the slowest the animation can be animated. Units are in milliseconds. Example: "1400". Note: for backwards compatibility, if this value is less than 2.0, it is assumed to be seconds and is multiplied by 1000 to be converted to milliseconds internally.
  • mindwell: Minimum dwell rate. Clicking on the "faster" button will keep decreasing the dwell rate (how many seconds to dwell on each frame/image in the animation) until the mindwell rate is reached - this is the fastest the animation can be animated. Units are in seconds. Example: "100". Note: for backwards compatibility, if this value is less than 2.0, it is assumed to be seconds and is multiplied by 1000 to be converted to milliseconds internally.
  • initdwell: Initial dwell rate. Example: "300". Note: for backwards compatibility, if this value is less than 2.0, it is assumed to be seconds and is multiplied by 1000 to be converted to milliseconds internally.
  • nsteps: How many dwell rate steps are allowed between the mindwell and maxdwell dwell rates when clicking on the "slower" and "faster" buttons. Example: "8"
  • missingimages: Specifies whether to show or hide missing images in the animation. Set either to "show" or "hide". Default: "hide"
  • last_frame_pause: Pause on last frame for N*D seconds where N is specified in the value attribute for this parameter and D is the current dwell rate as set by the user using the slowfast controls.

    Example:
    <input type="hidden" name="last_frame_pause" value="5">

    will make JSani pause on the last frame 5 times the current dwell rate. So if for example the user has set the animation speed so that each frame is shown for 1 second then the last frame would be shown for 5 seconds.
  • first_frame_pause: Pause on the first frame - works the same as last_frame_pause.
  • frame_pause: Similar to first_frame_pause and last_frame_pause, but you can specify any frame to pause on. The value is a comma separated list of values of the form n:m where n is the frame number (first frame is 0) and m is an integer specifying how much to pause that frame. Example:

    <input type="hidden" name="frame_pause" value="2:4,4:2,0:3">

    Dwell on the 2nd frame 4 times longer than the current dwell rate,
    dwell on the 4th frame 2 times longer, and
    dwell on the 0th frame (which is the first frame), 3 times as long.

    Note: first_frame_pause and last_frame_pause override this parameter - i.e., if you use this parameter to specify a dwell/pause rate for the first frame, and you use first_frame_pause to specify an different dwell/pause rate, that value will be used for the first frame.
  • overlay_filenames: list of the filenames for overlay images to overlay on top of the images specified via the filenames parameter. Example:

    <input type="hidden" name="overlay_filenames" value="
    overlay1_time1.jpg | overlay1_time2.jpg | overlay1_time3.jpg ,
    overlay2_time1.jpg | overlay2_time2.jpg | overlay2_time3.jpg
    ">

    or if specified via the config file:

    overlay_filenames = overlay1_time1.jpg | overlay1_time2.jpg | overlay1_time3.jpg , overlay2_time1.jpg | overlay2_time2.jpg | overlay2_time3.jpg

    or if specified via a file_of_filenames file (including FlAnis formatted file_of_filenames):

    # JSani file_of_filenames
    base_image_time1.gif "FlAniS Frame Label" overlay = overlay1_time1.jpg, overlay2_time1.jpg
    base_image_time2.gif "FlAniS Frame Label" overlay = overlay1_time2.jpg, overlay2_time2.jpg
    base_image_time3.gif "FlAniS Frame Label" overlay = overlay1_time3.jpg, overlay2_time3.jpg

    where "FlAniS Frame Label" is currently not implemented by JSani and can either be omitted or you can put whatever you want in that space and it will be ignored by JSani (as of the current version). Overlays are stacked in the order they are specified in overlay_filenames (which should also correspond to the order specified in overlay_labels).

    If your JSani animation that is using overlay images generates an error message (such as "unresponsive script") or takes too long to load, consider using overlay_filter=none (additional info).
  • overlay_labels: the labels to use for the overlay controls (this parameter is required if you want to use overlays). Example:

    <input type="hidden" name="overlay_labels" value="Overlay 1, Overlay 2/on">

    In the above example, the /on flag tells JSani to toggle that overlay to visible or on by default when the animation loads.
  • transparency: the color (specified in #RRGGBB hexadecimal format) of the pixels in the overlay images that you wish to make transparent (this parameter is required if you wish to use overlays). Example:

    <input type="hidden" name="transparency" value="#000000">
  • overlay_filter: tells JSani what to do with overlay images.

    Possible values:
    • default - the default value for this parameter. Tells JSani to convert all pixels of a certain color
      (as specified by transparency) to transparent pixels.
    • none - tells JSani to do nothing with the overlay images and to use them as they originally are.

      Depending on the number of overlay images in your animation (and their dimensions), the process of JSani removing background pixels may be a significantly processor and time consuming operation. You may encounter problems with your animation that is using overlay images where the animation takes a significant amount of time to load or you may even encounter an error message from the browser (such as an "unresponsive script" error message). Using this option allows you to tell JSani to skip the process of removing background pixels - this will improve the performance of the animation. If you use this option (overlay_filter=none) it's then assumed that the overlay images are PNGs or GIFs with transparent backgrounds. Programs like ImageMagick can be used in UNIX automated scripts to convert background pixels in images to transparent pixels.
  • disable_auto_start - setting this parameter (the value doesn't matter as long as it's a non-blank, valid string such as "true" or "yes") will instruct JSani to not automatically start when the web page loads. This allows JSani to be initialized / started via other JavaScript by calling the following JSani method:

    jsani.init('start');
    If this parameter is not set, then JSani will automatically call the above method once the web page is done loading. In both cases, JSani will now trigger a custom JavaScript event "jsani_is_loaded" when the JSani animation is done loading and has started (except for overlays - they are set to always start preloading and then appear after the animation has started). This new custom event can be bound to a JavaScript event handler.

Resizing JSani dynamically

A JSani animation can now be dyanimcally resized (via other mechanisms not provided) and continue to work. Whatever JavaScript code that is used to resize the JSani container (<form id="jsani"></form>) can call the following JSani method to make JSani update it's layout to fit the new size of the JSani container:

jsani.jsaniResizeHandler();

Future Improvements

  • Increased use of HTML5 Canvas
  • an API to make JSani easier to customize and integrate with other web applications
  • Frame labels and controls
  • and more ...
Contact me if you wish to be put on a mailing list for announcements regarding future improvements.

Contact info

You can contact me via email contact form.

Copyright Notice

This code is copyrighted under the Gnu General Public License. It is freely available for non-commercial use. Details:

Copyright 2010, Bill Bellon
Licensed under the GPL Version 3 licenses.
http://www.ssec.wisc.edu/~billb/jsani/license