Javascript programming has become more and more interesting since modern browsers started implementing HTML5 and CSS3 specifications.
Some people have been hoping for the trio javascript/html5/css3 to free web development from plug-ins such as Flash and Silverlight. So far we've
seen noticing a myriad of Html5 development tools and frameworks popping up here and there all the time, trying to catch up with the maturity and
user experience of established Flash and Silverlight frameworks and tools.

This time I became particularly well impressed by the Paper.js framework. It's easy to use, very clean
and intuitive to work with, and provides powerful and flexible set of classes and events. This, in addition to the flexibility of javascript language, enables a
fast and productive development environment.

After some time playing with Paper.js, I decided to create a jigsaw puzzle game with that tool, and only then the real learning began.
The results of hours of trial-and-error are in this article, and I hope to explain Paper.js by explaining the game development itself. And if you're
not interested in the article nor in the javascript, at least you might end up playing with the puzzle game.

To use HTML5 Snooker Club application provided with this article, all you have to do is install or have a modern web browser:
Chrome, Fire Fox, Maxthon, Opera, Safari or Internet Explorer (9 or superior).

"... an open source vector graphics
scripting framework that runs on top of the HTML5
Canvas. It offers a clean Scene Graph / Document
Object Model and a lot of powerful functionality to
create and work with vector graphics and bezier
curves, all neatly wrapped up in a well designed,
consistent and clean programming interface."

So what's really behind that beautiful description? Let's say you want to user Paper.js to perform a simple task of displaying a simple image
in the center of your browser. The next short segment shows the entire html needed for the task:

Quite simple, isn't it? Now let's get back to the Paper.js description:

"... an open source vector graphics
scripting framework that runs on top of the HTML5
Canvas..."

Paper.js only targets the canvas, so the canvas element is a requirement:

<canvas id="canvas"class="canvas" resize></canvas>

Notice the special element attribute, <class>resize. It tells the Paper.js to resize the canvas to fit the size
of the parent html element (in our case, the body element).

"... It offers a clean Scene Graph / Document
Object Model and a lot of powerful functionality to
create and work with vector graphics and bezier
curves, all neatly wrapped up in a well designed,
consistent and clean programming interface..."

So true. You can see this cleanness in these 2 lines of javascript code:

The first line instantiates a <class>Raster, which in Paper.js framework is an item that represents an image in a project. So
there you have a paramenter, "Bob", which is simply the id of the <img> tag from which the image source for the Raster object is taken.

So, since we're already using the <img> element, why not use it right away instead of the <class>Raster? The answer is, as explained
before, the Paper.js renders graphics only in the context of a <class>Canvas element, so the <img> is outside the scope of it.

Another fact worth noticing is that strange script tag:

<scripttype="text/paperscript"canvas="canvas">

What is that "text/paperscript"? What does it do? Well, it is the good old javascript we are used to, but the difference is that, behind the
scenes, it takes care of all that boring, plumbing job we would otherwise have to do by ourselves (such as creation of the basic objects of the framework,
such as Project, View and Tool, and event handler attachments) and also provides support for overloading operators for vector operations (such as +, - and *)
which we would have to implement by means of method calls, thus polluting the code. Also, all global browser objects (such as document and window) are
still accessible within the <class>paperscript code.

If your project gets bigger, it is preferrable that you use javascript directly, instead of paperscript. In our sample jigsaw puzzle application,
though, I used only paperscript. One clear disadvantage of paperscript is that when you set the script tag to type="text/paperscript"
you automatically loose javascript intellisense. One workaround for this is to change the script type to "text/paperscript", do the code modifications you
need and then change it back to "text/paperscript" once again.

Obviously, there is much more to Paper.js than just the <class>Raster objets. We will learn about other classes in the following sections.

A jigsaw puzzle is a puzzle where the goal is to position correctly a set of interlocking, oddly shaped pieces. Each piece has part of the original picture, and
when you finish the puzzle you can see the whole picture.

A simple game like that may look simple at first, but can easily takes you many hours of work if you don't have a clear plan and you don't know how to begin with.
Fortunately, I had a previous experience with creating this kind of puzzle, so this time I
was able to avoid many of the pitfalls I fell into when developing the app for my first puzzle article.

Below there is a series of solutions for the most common problems found in a jigsaw puzzle application:

When you first notice that you have to create all these oddly shaped tiles, like in the image below, you may find the task intimidating:

In fact you should for now forget those curvy lines, and focus on the most basic tasks first, like dividing the source image into perfect little squares.
Each piece in the puzzle will have a distinct part of the image, so that they all positioned together can make the whole image. So let's divide this image in squares:

Now let's take a particular square tile and use it as a background for a puzzle piece. Here is the piece separated from the whole:

And here is the piece with its image background:

Now, do you see the problem? The image doesn't fit into the piece! There are areas near the borders of the piece where the background is empty.
This happens because we haven't predicted that in a jigsaw puzzle the interlocking pieces "invade" spaces which should otherwise be preserved in a square
puzzle.

By the picture above, it becomes clear that each piece should have a slightly larger background image, so that the image portion could fit in. We do this by expanding the tile image
for each piece:

The clipping part is a vital one in our application. We must take each piece and cut out the corresponding shape, so that each piece appears nice and curvy.

We draw the shapes by creating a set of bezier curves. Bezier curves are sexy and fit well in our application. Fortunately, I used these curves in my
previous WPF article, and since the basic premises are the same, I reused the same logic for constructing the curves.

Each piece has 4 sides (top, bottom, left, right) and each side can have one of 3 forms: flat, a mountain or a valley. All these forms are constructed basically
by the same function. The only difference is the factor applied to the calculation: 0 for flat sides, 1 for mountain and -1 for valley.

The code below shows that each piece is a <class>Group object (this is from Paper.js framework). A Group object
is a composition of two or more items. The first item (mask) define the shape of the clipping, while the img item define the
image background. In short, the tile image is cut out according to the shape of the mask of each piece.

Each of the 4 sides of the piece is given a random number between a range of values (-1, 0, 1), that defines the curve of that side.

It's important to notice that inside the loop that generates the random shapes, for each piece iteration only the right and bottom sides are given values.
When we define the right side value, we also have to define the opposite value for the left side of the piece at the right of that piece. The same occurs for the
bottom side: if the bottom side of a piece is given a value of 1, then the top side of the piece at the bottom of that piece must be given a value of -1.
In short, the neighboring sides must always have complimentary values.

The pieces are initially positioned in a retangular central area, but with blank spots separating them. They are arranged
by a function that picks a piece randomly from the array of pieces, place it into the board, and then picks another piece from
the remaining pieces and places it in the square area, until no more pieces are left.

Each time the left mouse button is down over a selected piece, it is "taken" from the board and is brought to front (by enlarging its size) and you can
drag it all over the board, until you release the mouse button to drop the piece in a suitable location.

That's it. As you can see, there is a lot of room for enhancement in the application. The Paper.js framework proved itself up to the
task of handling complex graphic scripting and event handling, while providing a clean and simplified set of classes and events.

If you have any comments, complaints or suggestions, please leave a comment below. I'd like to hear from you and I'm willing to improve the app
as new ideas arrive.

Share

About the Author

Marcelo Ricardo de Oliveira is a senior freelance software developer who lives with his lovely wife Luciana and his little buddy and stepson Kauê in Guarulhos, Brazil, is co-founder of the Brazilian TV Guide TV Map and currently works for Alura Cursos Online.

I read your article regarding the Jigsaw puzzle.Its absolutely fantastic!.I got a requirement where i need to customize the number of tiles.Ex:User can select 10 tile,15 tiles etc(Based on the difficulty level).
When i changed the tiles per row and tiles per column while generating the tiles.I was able to see only few blocks of a image.
I should be able to see the complete image with tiles increased in size when i select the less number of tiles.
Please help me over this ASAP.
Thanks.

Hi Franco, I recommend extracting the zip file and opening Visual Studio or other dev tool, then opening via "Open Web Site" menu item at the directory: \Downloads\HTML5Puzzle. Then execute it at Paper.htm file.

You probably wouldn't know the impact you are creating abroad. it really is one of the very few articles with perfectly working codes contributed. we use it as a teaching tool here and no doubt it changes minds of our students.
Here is what we faced : some genius students catch up fast and I couldn't change the difficulty with more number of pieces (what I meant is change the number of pieces for students with different level of capacity). Please please help me get a hint to make this possible. I surely don't want to west your time except giving me the idea with a couple of lines of guide here or at my email mikemexi@gmail.com
will be looking forward to hear from you.

You are one great man no matter my issue. god bless you and all your loved ones
Regards
Mike from Ethiopia