27

I am creating a simple Jigsaw puzzle. In order to do this, I need to cut the picture I am using into 20 pieces. Is there a way in Javascript to cut a picture into 20 equal pieces and save them as 20 different objects within the webpage? Or do I just have to go into photoshop and cut each picture out myself and call it in?

TheChes44
  • 648
  • 1
  • 10
  • 21
  • A canvas element would let you "cut out" pieces, but exactly how to do it would depend on your exact requirements around what you want to *do* with the pieces. – Pointy Jan 18 '12 at 15:42
  • I want the pieces to be able to be draggable and droppable. I am currently using Jquery for this task, but as this feature is not supported, and the third party add-ons aren't working, I am shirking away from using Jquery. I might change over to HTML5 if it can drag and drop. Anyways, I basically want 20 different images that I can drag and drop onto a frame so they can "solve" the puzzle. – TheChes44 Jan 18 '12 at 15:45

3 Answers3

33

This is easy to do with Canvas. The general idea is:

var image = new Image();
image.onload = cutImageUp;
image.src = 'myimage.png';

function cutImageUp() {
    var imagePieces = [];
    for(var x = 0; x < numColsToCut; ++x) {
        for(var y = 0; y < numRowsToCut; ++y) {
            var canvas = document.createElement('canvas');
            canvas.width = widthOfOnePiece;
            canvas.height = heightOfOnePiece;
            var context = canvas.getContext('2d');
            context.drawImage(image, x * widthOfOnePiece, y * heightOfOnePiece, widthOfOnePiece, heightOfOnePiece, 0, 0, canvas.width, canvas.height);
            imagePieces.push(canvas.toDataURL());
        }
    }

    // imagePieces now contains data urls of all the pieces of the image

    // load one piece onto the page
    var anImageElement = document.getElementById('myImageElementInTheDom');
    anImageElement.src = imagePieces[0];
}
Matt Greer
  • 60,826
  • 17
  • 123
  • 123
  • 2
    This might give SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. – Mert Mertce Apr 04 '14 at 16:42
  • 2
    @MertKoksal Its because of CORS You can set: img.setAttribute('crossOrigin', 'anonymous'); refer: https://stackoverflow.com/a/20424457/7121889 – Sarat Chandra Jul 06 '17 at 05:11
27

You can do this by setting the image as a background on a div, then setting its background-position. This is basically the same as using CSS Sprites.

(assume pieces are 100 x 100px)

<div class="puzzle piece1"></div>
<div class="puzzle piece2"></div>

CSS:

.puzzle {
   background-image:url(/images/puzzle.jpg);
   width:100px;
   height:100px;
}

.piece1 {
   background-position:0 0
}

.piece2 {
   background-position:-100px -100px
}
Diodeus - James MacFarlane
  • 112,730
  • 33
  • 157
  • 176
1

you can use the drawImage method to slice parts of a source image and draw them to a canvas:

drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) 

https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Using_images

something like :

  document.getElementById("vangogh").onclick=function()
    {
    draw();
    }; 

 function draw() {
    var ctx = document.getElementById('canvas').getContext('2d');
    ctx.drawImage(document.getElementById('source'),33,45);
                 }

then create draggable content for your new entities :

<div id="columns">
   <div class="column" draggable="true"><header>A</header></div>
   <div class="column" draggable="true"><header>B</header></div>
   <div class="column" draggable="true"><header>C</header></div>
</div>

http://www.html5rocks.com/en/tutorials/dnd/basics/

Wesley Bland
  • 8,816
  • 3
  • 44
  • 59
Matoeil
  • 6,851
  • 11
  • 54
  • 77