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?
1 Answers
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
anddrawHeight==clipHeight
, the sub-image will be drawn at the same size clipped from the original.If
drawWidth!==clipWidth
anddrawHeight!==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>

- 102,905
- 11
- 164
- 176
-
1This is a sick response. Never got an answer as elaborated as this one. If possible, I would give all my points to you now. Thank you very much!!!! – WJA Nov 24 '14 at 13:10
-
quick question, is it possible to split the canvas up in pieces, instead of the img? Thank you. – AMG Jan 19 '15 at 13:12