Monthly Archives: May 2011

Sprite Sheets. Reloaded. Canvas Style

Last post I showed how to animate a sprite sheet using a jquery plugin spritely. The technique essentially moved the css background-position property to show the animation. Today we are going to show a technique that will be one step better. We are going to do the same animation using the HTML 5 canvas tag and no jquery at all! Note: If you need info on how to create a sprite sheet visit the last post for more details…

Canvas

So what is canvas? Think of canvas just like the name says. It’s a big drawing canvas that we can draw lines, shapes, images, and videos on. However remember everything is bitamp based. It is very similar to if you have used the BitmapData class within Flash. This basically means once we draw to the canvas we cannot get object information back since it is now just a drawing full of pixels. However, for our purposes this is fine since we will be clearing the canvas and redrawing each time we update our robin animation.

Let’s get it started!

First we need to add the canvas tag. The h1 message is an alternative the user will see if their browser does not support canvas. Cough. IE < 9. Fail... Anyway there is a special function we can call on canvas called drawImage. The syntax is as follows.

Let’s break down what this function does. It takes in an image, x pos, y pos, height and width and draws it to the canvas. By changing the x and y position we can move our image around on the canvas. By setting the height and width to one “frame” within the image we can make it look like an animation. Let’s see a diagram.

Changing the x and y position properties of the drawImage function we can move the window region that we want to animate. Let’s take a look at the whole draw function.

Ok let’s highlight some of the features of the draw method. You can see we are doing a clearRect() each time right before the draw image. Think of it like an etch-a-sketch. Canvas would keep the past drawings if we did not clear it each time. The rest of this method is calculating frames based on the time elapsed and the FPS to position x and y and draw. Neato! One other small note. We are using the requestAnimationFrame shim to call this draw function and NOT setInterval(). If you need more info on why go to Paul Irish’s blog post.

Let’s ACTUALLY get it started…

To start drawing to the canvas we need to call the draw method repeatedly. To do this we will create another method called tick. This method will call draw and then call the requestAnimFrame shim which will in turn call tick again when the browser is ready. The result is a solid animation loop.

Finally here is the result.

The benefits of this method may not seem immediately obvious. However, using the other method we are updating the css background property continuously which means we are touching the dom over and over. By using the drawImage method with canvas we can have an animation that will preform much better when used to create games or multiple animations.

Sprite Sheets. Return of the animated gif?

If you have visited google’s home page in a modern browser (Chrome, Firefox) lately you may have noticed some cool animations happening above the search bar. I knew this could not be flash since for google using flash on the homepage would be like the Yankees settling for farm system talent. So what is producing this crazy effect? They are called sprite sheets and are taking a page from an old technology. Animated GIFs! We have all seen the hotness of animated gif’s popularized in the early 90’s. Sprite sheets are pretty much what you would expect. A flip book of images that combined together make up an animation.

Sample sprite sheet.

Robin Sprite Sheet

Robin Sprite Sheet

Example animation

Making a sprite sheet

So how do we make a sprite sheet? There are a few different ways to accomplish this. We will be using Photoshop CS5 extended.

First things first we need an image sequence of the animation. This can be achieved by exporting from After Effects, Maya, Blender and a slew of other programs. If you don’t know how to do this consult your designer…

Ok assuming you have an image sequence we need to get that into Photoshop. File -> Open, navigating to the sequence folder and clicking “Image Sequence” checkbox will import the sequence into Photoshop. Leave the default frame rate at 30 and click ok.

Now you will only see 1 layer and go whaaa. Where’s my sequence? Relax. If you goto Window -> Animation you should see the animation appear if not already open.

So… Now that we have the sequence into Photoshop we need to transform it into a sprite sheet like our example above. To do this we are going to run a script on the sequence. But first we need each frame to be on it’s own layer. To distribute each video frame to an actual photoshop layer we need to click the context menu in the animation panel and choose “Flatten Frames to Layers”

Aight bro now we are ready for the magic. First you need to get a script to automate this task. Here In order to get this script to show up in photoshop you need to copy the layersToSprite.js file to your Presets/Scripts folder within your photoshop application directory and restart photoshop. (/Applications/Adobe Photoshop CS5 on mac).

You should now have a menu option File->Scripts->layersToSprite. Click that and you should see a sprite sheet sort of like the example above.

Animating with JQuery

The technique of animating the sheet really is setting up 1 css rule and then moving the background-position property to make a flipbook style animation. We are going to be using a modified version of the spritely JQuery plugin to handle the animation. Here

First we need to include jquery and spritely

Next we define some markup and CSS for the bird

Lastly we need to add the animation script.

Let’s break down the parameters. FPS is our frames per second that we want for this animation. The no_of_frames parameter is how many columns there are per row in our sprite sheet. Rows are the total number of rows in the sheet. lastRowCount is a parameter that defines how many columns are in our last row and is not needed if the last row is also full.

spRandom is a spritely function that randomly moves the sprite within a box defined by top, bottom, left and right properties. For more information on Spritely check out their website. Here

Conclusion

As you can see this is a pretty neat technique to create simple bitmap animations without the need of an external plugin such as Flash. I feel like this opens a great door for creative designers that have used an After Effects -> Flash workflow in the past to create cool timeline animations. I would be totally interested to see some examples of people using crazy sprite sheets to create HTML/JS/CSS animations and or games. Shoot me a comment!

Require JS – Requires an explanation…

After going to a jQuery conference out in Mountain View I was more determined than ever to understand how to use script loaders to abstract my JavaScript code into a more object oriented approach. I always loved the ability in AS3 to break code up using OOP principles. I found the process of concatenating scripts to be clumsy and cumbersome. That being said I had heard of requireJS while I was at the conference and decided to give it a go. The examples below are my attempts to just get things flowing with require. They are by no means perfect.

Step 1: Add base dependency app.js

In this first line we are requiring one file to be loaded. In this case it is in the scripts directory and is named app.js

Step 2: Adding dependencies to app.js

The code within app.js will load a dependency file based on the array parameter in the define function. app.menu.js. Pretty slick! Each file you want to make available just needs to be included in this array parameter at the top. As you can see we are leaving the extension .js off since require doesn’t want it. Since we have also included app.menu.js we can easily return Menu which is a function defined in app.menu.js. Making sense?

Step 3: Adding dependencies to dependencies – app.menu.js

In this file we are using a simple JavaScript inheritance technique that John Resig blogged about Good Read here. All that really needs to be understood here is that within app.menu.js we are loading another file called inherit.js which contains that inheritance code. So now we have a reusable menu that can be worked on within app.menu.js and it will automagically be loaded when app.js is loaded. Reusable components. Toats!

Step 4: Wait a sec…

At this point you are probably thinking ok great. I can separate my logic into multiple JavaScript files but man you are killing me with all these HTTP requests. Arn’t those supposed to be like the worst for JavaScript performance?? And the answer is yup. We are killing it. But relax… This is on a local environment. That’s ok. When we push to dev or test is when we need a method to “compile” our JS code. (For lack of a better term)

Enter ANT…

Lucky for us requireJS comes with a tool for this process. Since we namespaced using APP in beginning when defining our JS objects we should have less conflicts when using the concat and minify tools on our JS. Ok let’s get started… First, we need to setup a generic optimize target. We can then call this over and over for different require dependency traversals. We are going to be invoking the java based engine Rhino along with Uglify.js for the minification. Don’t worry the rhino.jar file comes with requireJS so you shouldn’t need to download anything else. Let’s take a look at this generic ANT target.

We first define requirejs.dir as the path to our requirejs folder. We then tell java where the rhino jar file is. Next we are invoking rhino and passing it a baseUrl argument. This will be specific to where your JavaScript code is located in your project. Ours is just in a scripts folder off the root. Next we are passing in a variable for the name of the JavaScript file to traverse called “build-in-file”. This would be our app.js from the examples above. We also have an argument for the out file “build-out-file”. The last argument “excludeShallow=jquery” is basically saying if we have a dependency that requires jquery ignore it. As you can see in app.menu.js we are saying that jquery is required as a dependency however in our strategy we are loading it from an external CDN and want the benefits of caching so we chose to leave it out.

Step 5: Minify and Concatenation

Ok at this point you are prolly saying wow this is alot of steps. Or you stopped reading. Either way here’s the big pay off.

Here is an antcall to the generic -optimize target. It is going to run requireJS on app.js, traverse through, grab namespaces.js, app.menu.js, inherit.js (nested from inside app.menu.js), exclude jquery and concatenate and minify all those files into one file called app-build.js in the scripts directory. Oh Snap! Think about that for a second. Now you have the same power you had with Flash and compiling to one swf file with one HTTP request. This can be taken one step further as well and be combined with a CI server to automate all of this so you could have one core JavaScript file that would be used on every page along with page specific scripts. Neato!

1 2