0

I have a canvas area and I'm adding some images into and I would love to make my canvas images draggable. I've created mouse events via addEventListener to handle mouse clicks.
But my problem is that I'm able to make draggable all canvas context and not just only my images.

html code:

<canvas></canvas>

part of JS code:

var canvas = document.getElementsByTagName('canvas')[0];
var gkhead = new Image;
var ball   = new Image;
ctx.drawImage(gkhead,0,0,1000, 200);
ctx.drawImage(ball,0,0,100,100);

canvas.addEventListener('mousedown',function(evt){
        document.body.style.mozUserSelect = document.body.style.webkitUserSelect = document.body.style.userSelect = 'none';
        lastX = evt.offsetX || (evt.pageX - canvas.offsetLeft);
        lastY = evt.offsetY || (evt.pageY - canvas.offsetTop);
        dragStart = ctx.transformedPoint(lastX,lastY);
        dragged = false;
    },false);

canvas.addEventListener('mousemove',function(evt){
        lastX = evt.offsetX || (evt.pageX - canvas.offsetLeft);
        lastY = evt.offsetY || (evt.pageY - canvas.offsetTop);
        dragged = true;
        if (dragStart){
            var pt = ctx.transformedPoint(lastX,lastY);
            ctx.translate(pt.x-dragStart.x,pt.y-dragStart.y);
            redraw();
        }
    },false);

canvas.addEventListener('mouseup',function(evt){
        dragStart = null;
        if (!dragged) zoom(evt.shiftKey ? -1 : 1 );
    },false);

And is it event possible to make the first image( gkhead ) graggable just in canvas area and the second( ball ) image moveable just in the area of the first ( gkhead ) image?
HERE is my fiddle
Thank you all in advice.

Petr Bečka
  • 774
  • 3
  • 16
  • 39

1 Answers1

0

For efficiency, you might set up two separate canvas layers of the same size. One that has all the canvas objects drawn on it, and another that is a blank temporary canvas where you'll do the actual moving of the objects.

You'll also need to store the images in some kind of container, like a JSON-y object. So you'll have some reference, like an x- and y-coordinate, the image source, the width of the image, the height of the image, and possibly the image's z-index. You'll create some kind of hit detection that checks through all the images and, if the user clicks on an image, erase that image from your main canvas. Draw the image in the exact same place on the temporary canvas. Do all the dragging on the temporary canvas (to save on paint times and processing required). Then, on drop, erase the temporary canvas and draw it on the main canvas again.

Here's an example I made a long time ago (just code, sorry). Trying to find some online tutorial about it now.

Justin McCraw
  • 540
  • 9
  • 22
  • *" One that has all the canvas objects drawn on it, and another that is a blank temporary canvas where you'll do the actual moving of the objects"* - what sort of efficiency is achieved by this..? As far as I can see that gives the overhead of having to create and draw things on a different canvas as well – T J Jan 11 '16 at 07:14
  • It would only perhaps become more efficient if you have a lot of objects on your canvas. So instead of redrawing 100 objects every refresh, it would only redraw the main canvas once, to remove the object you're moving, and then it would redraw the temporary canvas during the move, saving on redrawing those other hundred objects during move. – Justin McCraw Jan 12 '16 at 21:54