Life is Beautiful

User Interface is an Art

Wicket animation using iAnime.js

I found a good blog entry comparing various animation libraries, which has implemented Wicket homepage in two different animation libraries. As a comparison, I have implemented the same animaition using iAnime.js.

  • Wicket home page using iAnime.js

Because of iAnime's powerful JSON-based asynchronous animation sequencing language (JAASL?), it is a lot easier to implement it in iAnime.js. Essentially, the following nested array of JSON object describes the entire sequence of animation.

        anime.addSequence([
                [{ id:'top', effect:'bounce', y:top, duration:2000 }],
                { id:'logo', effect:'easeout', duration:2000,
                  x:300+(iBrowse.getWindowWidth()/2-120) },
                [{id:'apache', effect:'fadein', duration:1500}],
                [{id:'wicket', effect:'fadein', duration:1500}],
                [{id:'introduction', effect:'fadein', duration:2000}],
                {id:'download', effect:'fadein', duration:2000}
            ]);

 

December 11, 2007 in ianime.js | Permalink | Comments (2)

ianime.js v0.26: n-dimentional Bezier-tween support

I have managed to add the Bezier curve capability to ianime.js. Click the icon below to see the demo (by the way, this animation was all done in HTML+Javascript, not Flash).

 

The syntax is quite straightfoward. You just need to give a set of control points as a property "cp" just like the example below.

    anime.add({
        element: obj,
        cp: [{x:50, y:0}, {x:0, y:50}],
        x: 100,
        y: 100,
        duration: 1000,
    });

This means "move the specified DOM object along the bezier curve specified by two control points, (50,0) and (0,50), from the current location to the specified end point (100,100) in 1 second".

December 03, 2007 in ianime.js | Permalink | Comments (0)

ianime.js v0.22 - ligh-weight Javascript animation library

ianime.js is an open-source Javascript library that enables interactive animations on web pages. The key design goal of ianime.js is its efficiency - it has to be efficient enough to implement "interactive games" with HTML+Javascript that run efficiently on Apple iPhone.

During the development of ianime.js, I have implemented an iteractive puzzle game, "iFreecell 1.2" to verify that it's efficient enough to run such a game on iPhone. If you have iPhone (or iPod touch), please run this game on it and see ianime.js in action (this game also runs on PC/Mac browsers, of course).

1. Basic

In order to use ianime.js, first you need to import it, of course.

<script src="ianime022.js"></script>

Notice that "022" is the version number (v0.22). Then, you need to create an iAnime object.

var anime = new iAnime();

While it is possible to create multiple iAnime objects, there is no advantage in doing so because single iAnime object is able to run multiple animations concurrently.

An animation can be achieved by calling its "add" method with appropriate parameters. For example,

anime.add( { id:'foo', x:100, y:150, duration:500 } );

will animate the DOM element with id='foo' from the current location to position (100, 150) in 500ms.

Passing "id" is actually a shortcut. If you already have the reference to DOM element, you can just pass it via "element" property. Therefore, the code below has the same effect as the code above.

var obj = document.getElementById('foo');
anime.add( { element:obj, x:100, y:150, duration:500 } );

While the DOM object identification property (either "id" or "element") and "duration" property are "required" parameters, other parameters are optional.

anime.add( { id:'foo', x:100, duration:500 } );

will animate the object horizontally, while

anime.add( { id:'foo', y:150, duration:500 } );

will animate the object vertically. For this reason,

anime.add( { id:'foo', duration:500 } );

is a valid code, although it does nothing (but burning CPU cycle^^). To see the actual example, see ianime1.html, which is the "Hello World" of ianime.js.

2. Concurrency and Synchronization

As I have mentioned above, a single iAnime object is able to animate multiple objects concurrently. In order to achieve it, you just need to call its "add" function mutiple times.

anime.add( { id:'turtle', x:300, duration:5000 } );
anime.add( { id:'rabbit', x:300, duration:1000 } );
anime.add( { id:'cheeta', x:300, duration:250 } );

The code above will animate three DOM objects concurrently.

By the way, while iAnime object maintains a single timer event (setInterval) for efficiency, it maintains different clock for each object. The clock starts when the "add" function is called. Therefore, the start time of each animation above will be slightly different (because of the execution of javascript code).

While it is not an issue if you are animating a few objects concurrently, it will become an issue if you animate a large number of objects.  In order to precisely synchronize multiple animations, you need to 'pause' animation while you are adding new animations.

anime.pause(true);
anime.add( { id:'turtle', x:300, duration:5000 } );
anime.add( { id:'rabbit', x:300, duration:1000 } );
anime.add( { id:'cheeta', x:300, duration:250 } );
anime.pause(false);

The pause function will stop the internal clock of iAnime object, so that those animations added while it's paused will be treated as if they are added at the same time.

3. Effect

While the feature described above is simple and easy to use, those animations are not interesting - all straigt-line animaition with constant speed. In order to achieve more interesting effects, such as ease-in/out, and fade-in/out, ianime.js allows developers to extend the capability of ianime.js by providing extensions.

The default extension is ianime-ex.js, which is always distributed along with ianime.js. It offers a standard set of effects - 'easein', 'easeout', 'fadeout', 'fadein' and 'bounce'.

In order to use this standard extension, you need to import ianime-ex.js and ibrowse.js (ibrowse.js is a cross-browser helper library, which ianime-ex.js uses) like this:

<script src="ibrowse010.js"></script>
<script src="ianime022ex.js"></script>

Notice that ibrowse.js has different version numbers, while ianime.js and ianime-ex.js always have the same version number. The effect needs to be speified via 'effect' property. The code below will fade out the DOM object (specified by id='foo') in 500ms.

anime.add( { id:'foo', effect:'fadeout', duration:500 } );

Notice that the name of the effect needs to be specified in string. See ianime2.html and ianime3.html for actual samples (click the "Click me" on ianime3.html multiple times to see what happens).

November 26, 2007 in ianime.js | Permalink | Comments (0)

ianime.js v0.12 - Vector graphics example

I have added the capability to draw arbitraty canvas graphics in ianime.js. Instead of giving the reference to the image object to be animated (via "element" property), the caller needs to provide a callback function "drawImage". Here is a sample code.

function click1(obj)
{
    var param = { sx:obj.offsetLeft, sy:obj.offsetTop,      
    x:(500-obj.offsetLeft), y:obj.offsetTop, msec:3000 }
    param.drawImage = function(ctx,element,r,x,y) {
          ctx.save();
          ctx.translate(x,y);
          ctx.fillStyle='#dd3300';
          ctx.beginPath();
          var tail = Math.sin(r*26)*5;
          ctx.moveTo(-60,tail);
          ctx.bezierCurveTo(-35,-2,0,-10,0,0);
          ctx.bezierCurveTo(0,10,-35,2,-60,tail);
          ctx.closePath();
          ctx.fill();
          ctx.restore();
    };
    anime.add(param);
}

Notice that the caller also needs to specify the starting point with "sx" and "sy" property when it eliminated the  "element" property.

Here is the actual example (runs on Safari and Firefox, and probably Opera, but not IE).


If you want to try this on your iPhone or iPod touch, try this URL.

http://satoshi.blogs.com/ianime/test23.html

As I have indicated earlier, while iPhone's Javascript is quite slow, the graphics APIs are very fast. iPhone has no problem letting a dozen of fish swim.

November 13, 2007 in ianime.js | Permalink | Comments (0)

ianime.js - Animation Javascript Library for iPhone and iPod touch

I finally found a time to play with the canvas capability of iPhone's browser. I have started with a set of simple benchmark programs to see the animation capability of iPhone, but I eventually came up with a javascript library, ianime.js, which allows me to add wide ranges of animations to my web pages easily.

Note on cross-browser comaptibility: Because this is a javascript library for iPhone, making it compatible with other browsers is not important - I rather optimize it for iPhone. At this moment, it does not run on IE because it heavily relies on <canvas> tag, and runs well on latest version of Firefox and Safari (I am testing them only on Mac). I would like to keep the compatibility with those two browsers as much as possible, as long as I don't need to sacrifice the performance under iPhone browser.

If you wants to see the actual demos on your iPhone or iPod touch first, go to the following URL, and click links to sample pages.

http://satoshi.blogs.com/ianime/

Animating an image from one location to another is quite straightforward. You need to place an image tag with "position:absolute" style, create an iAnime object when the page is loaded, then call "iAnime::add" function with appropriate parameters (image, new location, and duration) when you want to start the animation. Here is an example.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=320; user-scalable=0;"/>
  <script src="ianime010.js"></script>
  <script type="text/javascript">
var anime;

function init() {
  anime = new iAnime();
}

function click(obj) {
    param = { element:obj, x:(300-obj.offsetLeft), y:obj.offsetTop, msec:1000 };
    anime.add(param);
}
  </script>
</head>
<body onload="init()" style="margin:0">
  <img src="images/feed-icon-28x28.png" onclick="click(this)"
       style="position:absolute; left:20px; top:20px" />
</body>
</html>

Note that you need to package parameters into a hash object. The "element" specifies the image object to be animated, "x" and "y" specifies the new location, and the "msec" specifies the duration. Those four parameters are required.

I pasted this sample in <iframe>, which is supposed to run if you are running latest version of Safari or Firefox. Click the feed icon to see how it works. After the animation, you may click it again to animate it back to the original location.



The example above moves the specified image at a constant speed. You can control the speed by providing a callback function, which maps value between 0.0 and 1.0 to another value between 0.0 and 1.0.

Here is an example that demonstrate three different formulas.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=320; user-scalable=0;"/>
  <script src="ianime010.js"></script>
  <script type="text/javascript">
var anime;

function init() {
  anime = new iAnime();
}

function click1(obj) {
    param = { element:obj, x:(300-obj.offsetLeft), y:obj.offsetTop, msec:1000 };
    param.callback = function(r) { return r*r; };
    anime.add(param);
}

function click2(obj) {
    param = { element:obj, x:(300-obj.offsetLeft), y:obj.offsetTop, msec:1000 };
    param.callback = function(r) { return 1-(1-r)*(1-r); };
    anime.add(param);
}

function click3(obj) {
    param = { element:obj, x:(300-obj.offsetLeft), y:obj.offsetTop, msec:600 };
    param.callback = function(r) {
        return (r < 0.8) ? (r / 0.8) : (1.04 - 4 * (r-0.9) * (r-0.9));
    };
    anime.add(param);
}
  </script>
</head>
<body onload="init()" style="margin:0">
  <img src="images/feed-icon-28x28.png" onclick="click1(this)"
       style="position:absolute; left:20px; top:20px" />
  <img src="images/feed-icon-28x28.png" onclick="click2(this)"
       style="position:absolute; left:20px; top:60px" />
  <img src="images/feed-icon-28x28.png" onclick="click3(this)"
       style="position:absolute; left:20px; top:100px" />
</body>
</html>

And here is the actual page. Click each icon and see how the speed changes during the animation.


By the way, click an icon while another icon is animating. You can animate multiple images concurrently, by simply adding iAnime::add function.

It is also possible to animate images along non-linear path. You can achieve it by providing optional parameter, adjustX and adjustY as functions, which alters the position during the animation. Here is a simple example, that emulates a thrown object in vacume.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=320; user-scalable=0;"/>
  <script src="ianime010.js"></script>
  <script type="text/javascript">
var anime;

function init() {
  anime = new iAnime();
}

function click(obj) {
    param = { element:obj, x:(300-obj.offsetLeft), y:obj.offsetTop, msec:600 };
    param.adjustY = function(y,r) {
        return y - 60 * 4 * (0.25 - (r-0.5) * (r-0.5));
    };
    anime.add(param);
}
  </script>
</head>
<body onload="init()" style="margin:0">
  <img src="images/feed-icon-28x28.png" onclick="click(this)"
       style="position:absolute; left:20px; top:80px" />
</body>
</html>

And here is the actual demo.


The next example involves the rotation. Just like other callback functions, you just need to provide an optional parameter "rotate" to specify the orientation of the image during the animation. The example below shows you how to rotate the icon 360 degree during the animation.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=320; user-scalable=0;"/>
  <script src="ianime010.js"></script>
  <script type="text/javascript">
var anime;

function init()
{
  anime = new iAnime();
}

function click(obj)
{
    param = { element:obj, x:(300-obj.offsetLeft), y:obj.offsetTop, msec:600 };
    param.adjustY = function(y,r) {
        return y - 60 * 4 * (0.25 - (r-0.5) * (r-0.5));
    };
    if (obj.offsetLeft < 150) {
        param.rotate = function(r) { return Math.PI * 2 * r; };
    } else {
        param.rotate = function(r) { return -Math.PI * 2 * r; };
    }
    anime.add(param);
}
  </script>
</head>
<body onload="init()" style="margin:0">
  <img src="images/feed-icon-28x28.png" onclick="click(this)"
       style="position:absolute; left:20px; top:80px" />
</body>
</html>

Notice that I am changing the direction of the rotation based on the starting point, so that it rotates into a natural direction. Here is the actual demo.


There are a few more features I would like to explain (such as custom canvas, and multiple animation contexts), but I think this is enough for a single blog entry.

Please try those sample on your iPhone or iPod touch to see the actual performance (which is not bad at all), and create your own sample pages. I appreciate feedback, including feature requests, bug reports, and idea to optimize the code further via comments or trackbacks (I am going to post another entry for Japanese readers to accepts comments in Japanese).

Enjoy!

November 03, 2007 in ianime.js | Permalink | Comments (2)

My Photo

Recent Posts

  • Who killed Windows?
  • Tokyo life-style vs. Fukushima life-style
  • Amazon's Cloud Reader vs. my CloudReaders (TM)
  • Facebook API on Google App Engine: JavaScript SDK vs. Python SDK
  • Debugging Facebook AppEngine application locally
  • Google App Engine: Updating Your Model's Schema (schema-versioning)
  • Handing and Testing DeadlineExceededError
  • Dear users of CloudReaders(TM)
  • Why HTML5 is a big threat to Adobe
  • Sticker shock of iLike acquisition
Subscribe to this blog's feed

Archives

  • January 2014
  • June 2012
  • August 2011
  • January 2011
  • December 2010
  • April 2010
  • October 2009
  • August 2009
  • March 2009
  • February 2009

More...

Categories

  • Business and Marketing
  • Entertainment
  • ianime.js
  • iPhone
  • News Clip
  • Technology and Business
  • Telco/Wireless Industry
  • UIE Vision
  • User Experience
  • Web/Tech