I want to create puzzle images out of original images, meaning that an image is cut into 9 pieces (3x3) and then shuffled and stored as a new image. Does anyone know which method is the best to do so and how to achieve it? Perhaps with CamanJS? Does anyone have an example code?
Canvas can do this using the clipping version of context.drawImage
.
context.drawImage
allows you to clip your 9 sub-pieces from the original image and then draw them anywhere on the canvas.
The clipping version of drawImage takes these arguments:
the image to be clipped: img
the [clipLeft, clipTop] in the original image where clipping starts
the [clipWidth, clipHeight] size of the sub-image to be clipped from the original image
the [drawLeft, drawTop] on the Canvas where the clipped sub-image will start drawing
the [drawWidth, drawHeight] is scaled size of the sub-image to be drawn on the canvas
If drawWidth==clipWidth
and drawHeight==clipHeight
, the sub-image will be drawn at the same size clipped from the original.
If drawWidth!==clipWidth
and drawHeight!==clipHeight
, the sub-image will be scaled and then drawn.
Here's example code and a Demo that randomly draws the clipped pieces onto the canvas. It shuffles an array to define random positions for the pieces and then draws those pieces using drawImage
.
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var rows=3;
var cols=3;
var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/sailboat.png";
function start(){
var iw=canvas.width=img.width;
var ih=canvas.height=img.height;
var pieceWidth=iw/cols;
var pieceHeight=ih/rows;
var pieces = [
{col:0,row:0},
{col:1,row:0},
{col:2,row:0},
{col:0,row:1},
{col:1,row:1},
{col:2,row:1},
{col:0,row:2},
{col:1,row:2},
{col:2,row:2},
]
shuffle(pieces);
var i=0;
for(var y=0;y<rows;y++){
for(var x=0;x<cols;x++){
var p=pieces[i++];
ctx.drawImage(
// from the original image
img,
// take the next x,y piece
x*pieceWidth, y*pieceHeight, pieceWidth, pieceHeight,
// draw it on canvas based on the shuffled pieces[] array
p.col*pieceWidth, p.row*pieceHeight, pieceWidth, pieceHeight
);
}}
}
function shuffle(a){
for(var j, x, i = a.length; i; j = Math.floor(Math.random() * i), x = a[--i], a[i] = a[j], a[j] = x);
return a;
};
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>