Animation is just moving something over time. The rate at which the something moves is defined by a function called an easing equation or interpolation function. It is these equations which make something move slowly at the start and speed up, or slow down near the end. These equations give animation a more life like feel. The most common set of easing equations come from Robert Penner's book and webpage.

Penner created a very complete set of equations, including some fun ones like 'spring' and 'bounce'. Unfortunately their formulation isn't the best. Here is one of them in JavaScript


easeInCubic:function(x,t,b,c,d){
returnc*(t/=d)*t*t+b;
},
easeOutCubic:function(x,t,b,c,d){
returnc*((t=t/d-1)*t*t+1)+b;
},

They really obscure the meaning of the equations, making them hard to understand. I think they were designed this way for efficiency reasons since they were first implemented in Flash ActionScript, where speed would be important on the in-efficient. It makes them much harder to understand and extend, however. Fortunately, we can refactor it to be a lot clearer.

Let's start with the easeInCubic equation. Ignore the x parameter (I'm not sure why it's there since it's not used). t is the current time, starting at zero. d is the duration in time. b and c are the starting and ending values.

easeInCubic:function(x,t,b,c,d){
returnc*(t/=d)*t*t+b;
},

If we divide t by d before calling this function, then t will always be in the range of 0 to 1, and d can be left out of the function. If we define the returned version of t to also be from 0 to 1, then the actual interpolation of b to c can also be done outside of the function. Here is some code which will call the easing equation then interpolate the results:


                var t = t/d;
                t = easeInCubic(t);
                var val = b + t*(c-b);

We have moved all of the common code outside the actual easing equation. What that leaves is a value t from 0 to 1 which we must transform into a different t. Here's the new easeInCubic function.


        function easeInCubic(t) {
            return Math.pow(t,3);
        }

That is the essence of the equation. Simply raising t to the power of three. The other formulation might be slightly faster, but it's very confusing, and the speed difference today is largely irrelevant since modern VMs can easily optimize the cleaner form.

Now let's try to transform the second one. An ease out is the same as an ease in except in reverse. If t when from 0 to 1 then the out version will go from 1 - 0. To get this we subtract t from 1 as shown:

        function cubicOut(t) {
            return 1-Math.pow(1-t,3);
        }

However, this looks awfully close to the easeIn version. Rather than writing a new equation we can factor out the differences. Subtract t from 1 before passing it in, then subtract the result from one after getting the return value. The out form just invokes the in form:

function easeOutCubic(t) {
     return 1 - easeInCubic(1-t);
}

Now we can write other equations in a similarly compact form. easeInQuad and easeOutQuad go from:

easeInQuad:function(x,t,b,c,d){
returnc*(t/=d)*t+b;
},
easeOutQuad:function(x,t,b,c,d){
return-c*(t/=d)*(t-2)+b;
},

to

function easeInQuad(t) {  return t*t; }
function easeOutQuad(t) { return 1-easeInQuad(1-t); }

Now let's consider the easeInOutCubic. This one smooths both ends of the equation. In reality it's just scaling the easeIn to the first half of the t, from 0 to 0.5. Then it applies an easeOut to the second half, from 0.5 to 1. Rather than this complex form:

easeInOutQuad:function(x,t,b,c,d){
if((t/=d/2)<1)returnc/2*t*t+b;
return-c/2*((--t)*(t-2)-1)+b;
},

We can compose our previous functions to define it like so:

        function cubicInOut(t) {
            if(t < 0.5) return cubicIn(t*2.0)/2.0;
            return 1-cubicIn((1-t)*2)/2;                
        }

Much cleaner.

Here is the original form of elastic out, which gives you a cartoon like bouncing effect:

easeOutElastic:function(x,t,b,c,d){
vars=1.70158;varp=0;vara=c;
if(t==0)returnb;if((t/=d)==1)returnb+c;if(!p)p=d*.3;
if(a<Math.abs(c)){a=c;vars=p/4;}
elsevars=p/(2*Math.PI)*Math.asin(c/a);
returna*Math.pow(2,-10*t)*Math.sin((t*d-s)*(2*Math.PI)/p)+c+b;
},

and here is the reduced form:


        function easeOutElastic(t) {
            var p = 0.3;
            return Math.pow(2,-10*t) * Math.sin((t-p/4)*(2*Math.PI)/p) + 1;
        }

Moral of the story: "Math is your friend" and "always refactor".

These new equations will be included in a future release of Amino, my cross platform graphics library.

This week at OSCON gave an updated version of my 3 hour Canvas tutorial. I think the session was well received. It was one of only a few tutorials that was completely sold out, 200 seats taken. But if you couldn't be one of those two hundred I don't want you to miss out.

I turned the content from last year's tutorial into an interactive eBook for the iPad and TouchPad. I did this partly to experiment with ebooks and partly to learn how to publish an app in the various stores. In thanks to my webOS fans I sold the TouchPad version for 99c while the iPad app costs 4.99$. It was a fun experiment but I have decided my real goal is not to make money, but rather to spread knowledge as widely as possible. So I have decided to make it all free as in beer and speech.

Yes, HTML Canvas Deep Dive is now 100% free

I have dropped the price of the existing apps to 0 (the TouchPad store may not yet reflect this). I have also published the book as a set of pages on the web so you can easily read and link to the book without installing an app. Note that the apps don't yet have the new content, just the webpage.

read it now

Even better, there is a bunch of new content I created for this year's OSCON. We now have new chapters on WebGL, WebAudio, and getUserMedia (webcam), as well as fixes for various existing chapters. Deep Dive is now over 20k word!

But, I need your help.

First, please spread the word about my book. I want it to be the definitive introduction to Canvas.

Second, I would love some help both with programming and design. I have created iOS and webOS versions of the book, but I need some help supporting Android, WinPhone / Win8RT, and PlayBook 2.0. I would also like some help from a web designer to improve the layout and font selection, especially on mobile devices.

Finally, please read the book and give me feedback. If you find spelling errors, code bugs, or an unclear description, please let me know. If you are interested in contributing new chapters I'd love that as well.

Working on this project has really been a labor of love. Thank you for your support.

Thanks to my HTML Canvas Deep Dive at OSCON, .net Magazine asked me to write a tutorial for them. The topic was just something interesting with Canvas. I'm a huge fan of infographics, as well as .net Magazine, so I jumped at the chance to write for them. I recently discovered an amazing treasure trove of data at the World dataBank, so that formed the core of the article.

My tutorial will take you from drawing a few shapes using canvas to processing real data from CSV files, then finally adding some interactivity and sprucing up the graphics. It should take you about one hour to complete, and if you know basic JavaScript then you're all set. It was a lot of fun to write. I hope you enjoy it.

Read it now

Mmmwaa haa haa. It lives! I've gotten Java to run on webOS natively with a new set of Java SDL bindings. That means it just *might* time to start a new project. Read on for how it works and how you could help.

 

For a while I've been following an open source project called Avian. It's a very lightweight and highly portable JVM that can run almost anywhere. Recently I tried a new build and was able to get the ARM port running on webOS!  This is good news because Avian can run pretty much any Java code if you supply it with the right runtime (it can optionally work with the OpenJDK libs).

Now, of course getting a command line app it run is not very interesting. Really we want to talk to the screen to make some real graphical applications. So that brings us to part two: SDL.

If you've been doing desktop programming for a while you've probably heard of SDL, the Simple DirectMedia Library. It's a fairly low level graphics and audio API that runs pretty much everywhere, including on webOS.   But, of course, like many low level APIs it's built in C. So if I want to use Java I need to some wrapper to call it.  The existing wrappers out there are very old and didn't work well on Mac, so it was time to build my own.

Over the weekend I learned how to use Swig, a JNI wrapper generator and successfully ran my new SDL wrappers on Mac, Linux, and webOS.  Here's a quick screenshot:

 

Screen Shot 2011 08 31 at 3 28 52 PM

it's not much but it proves that everything is working.

So what's the next step?  Honestly... I don't know. I created this specifically to let me code Java on webOS, but the SDL bindings would probably be useful for cross platform desktop applications as well.  We could port Amino to it, or do some funky multitouch stuff. It would certainly be great for people creating games. I need your advice.

What would you like to do with this library? What higher level APIs would you like? If you have any ideas of what you'd do with this lib, or would like to contribute to the project (help on Windows compilation would be greatly appreciated), then please message me on twitter: @joshmarinacci.

Thanks!

- Josh

While I have many projects in progress right now, including Amino, Leonardo, getting the TouchPad out the door, and having my first baby (only a few weeks left!); every now and then I just get something into my head and have to code it out. Last night it was noise functions.

Since I've been using little bits of noise in my designs I thought it was high time to really learn how it works. Following code & articles from here and here I've managed to create a simple noise and turbulence generator in Java. With a few different settings you can get textures that range from completely random to something that looks like marble.

com.joshondesign.texgen.Test1ScreenSnapz004.png
pure random grayscale noise

com.joshondesign.texgen.Test1ScreenSnapz002.png
high turblence

com.joshondesign.texgen.Test1ScreenSnapz001.png
medium turbulence + one sinewave

com.joshondesign.texgen.Test1ScreenSnapz003.png
medium turbulence + three sinewaves

It's actually simpler than I thought. Noise is just a bitmap filled with random values from 0 to 1 (or a grayscale value between black and white). Turbulence is created by stacking multiple layers of noise, each stretched to different amounts. Add in a bit of linear smoothing and you get some quality texture. The marble effect is just a turblence texture merged with a sine wave.

Next up, making the noise repeat so we can have tileable textures. Then I might make a simple app to generate noise with various colors. If it all turns out okay I might make a plugin for Leonardo to create your own textures.