As promised, here’s the follow up on my previous post Javascript: Using Canvas to cut an area of an image where we looked at how to use Canvas to cut a mask out of an image. To quickly recap, in the last post we looked at how to crop a patterned mask out of an image using a HTML5 Canvas. Using this technique, you’d be able to provide an image that looks something like:

So how do you go about making a puzzle? You can see the end result at HTML5 Canvas Puzzle and the code is online at https://github.com/Setfive/setfive.github.com/tree/master/canvas_puzzle.

As it turns out generating an arbitrary puzzle programatically is reasonably complicated. The best explanation I could find on how to accomplish this is at https://www.allegro.cc/forums/thread/586750/603411#target. Conceptually, the process looks straightforward enough and you could probably manually do it on a whiteboard. Unfortunately, the issue I ran into with this approach is that drawing bezier curves and splines programmatically on a Canvas is a bit involved. I also don’t have a background in vector graphics so I was getting stuck in the weeds drawing lines.

Discounting generating the puzzle entirely on the fly, an alternative approach would be to use a fixed set of available pieces and then “fill in” a grid depending on how large the image area is. Conceptually, the idea is to construct a closed grid of pieces where some number of the pieces can be repeated and then repeat those pieces as needed to cover the target image. The templated pieces I used are in /puzzle_pieces/.

Technically, I decided to use fabric.js to facilitate Canvas interaction along with lodash.js and of course the ubituqous jQuery.

Walking through the code, the steps to build a puzzle are fairly straightforward:

  1. Load images: The first step is to load all the template images and target image so that they’re available to use on a Canvas. Since jQuery is available, one approach is to create a deferred for each image, resolve it as the image loads, and use $.when to wait for all of the images to load. See here for example.
  2. Build pieces grid: Next you’ll need to figure out how many repeated pieces you need to fill into the grid. One issue here is that since the puzzles need to fit snuggly the image dimensions of a given piece won’t be what you need to use to calculate the grid. Because of this, I ended up with a bit of goofy code for this.
  3. Create image masks: Once you have the number of pieces to create you’ll need to cut masks for each piece out of the source image and create fabric.js objects for them. See copyImageChunk.
  4. Place masks: Placing the “pieces” is also complicated because of the dimension issue above. See kludgy code.
  5. Shuffle and track movements: Finally, you just need to shuffle the positions of the images and then track their movement to report a “correct” position.

And that’s about it. One other “trick” is that you can use Window.requestAnimationFrame to avoid locking the UI when you’re creating the masked images since it’s a compute intensive task.

Anyway, as always questions and comments welcome.

Posted In: Javascript

Tags: , ,

Over the few weeks I’ve been working on a Canvas based side project (more on that soon) that involved cutting a mask out of a source image and placing it on a Canvas. In Photoshop parlance, this would be similar to creating a clipping mask and then using it to extract a path from the image into a new layer. So visually, we’re looking to achieve something similar to:

At face value, it looks like doing this with Canvas is pretty straightforward using the getImageData function. Unfortunately, if you look at the parameters that function accepts it’ll only support slicing out rectangular areas which isn’t what we’re looking to do. Luckily, if you look a bit further in the docs it turns out Canvas supports setting globalCompositeOperation which allows you to control how image data is drawn onto the canvas. The idea is to draw the mask on a canvas, turn on the “source-in” setting, and then draw on the image that you want to generate the slice off. The big thing to note here is that putImageData isn’t effected by the globalCompositeOperation setting so you have to use drawImage to draw the mask and image data.

So concretely how do you do this? Well check it out:

The code is running over at http://symf.setfive.com/canvas_puzzle/grass.html if you want to see it in action.

Anyway, happy canvasing!

Posted In: Javascript, Tips n' Tricks

Tags: , ,

A couple of weeks ago, we picked up a RaspberryPi for the office and started brainstorming ideas for cool hacks for it. One of the ideas that was floated was using the Pi as a server for some sort of multiplayer JavaScript game. I’ve actually never written a game before so I figured it would be an interesting project. We ended up trying to use node-qt for graphics along with ws to receive input via websockets but the refresh rate of Qt was just to low. A story for another time.

Anyway, so back to ping pong. One of the things we wanted to avoid was writing our own code to manage the game objects, we really wanted to use a game engine for this. The only caveat we had was that the engine had to be UI agnostic since we were planning to output graphics on Qt instead of a HTML5 Canvas. After looking around, most of the JavaScript game engines have strong dependencies on Canvas so we started looking at other options. The two strongest options were Box2JS and ChipmunkJS. We decided to go with ChipmunkJS in part because it was handwritten while Box2JS was automatically converted from ActionScript so the resulting code is harder to follow.

Getting ChipmunkJS setup is relatively painless, just include the file and you’re off to the races. Since we were looking to eventually use Qt, we tried our best to cleanly separate the Chipmunk code from what we’d be using to draw the objects on the screen. Because of that, it’s pretty easy to follow what’s going on with the Chipmunk code. If you take a look at cpPong.js it basically initializes the physics space and then starts the game.

With the physics space setup, the next step is setting up the drawing. Following the Chipmunk demo’s lead, I added specific “draw” methods to the Prototypes of each shape. Doing this, allows you to just iterate over each shape in the scene and call “draw” to have it appear on Canvas or Qt. Check out pong.html to see how we added the draw methods to the shapes. And that’s about it! The only other interesting part is using “requestAnimationFrame” to avoid using setTimeout to update the scene.

There’s a live demo running here and of course the code on GitHub.

Any questions or comments welcome!

Posted In: Javascript

Tags: , ,