0

I am making a website to allow users to resize and drag their different sketches to make a final sketch. I've seen this excellent example to enable both of these functionalities, but it works only for a single image, and I couldn't understand how to integrate it for multiple images. Most of the examples I could find were only for single images, I couldn't find any for doing this for multiple images. I tried to do the following:

var canvas = document.getElementById("paint");    
var ctx = canvas.getContext("2d");
var canvasOffset=$("#paint").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;

var startX;
var startY;
var isDown=false;


var pi2=Math.PI*2;
var resizerRadius=8;
var rr=resizerRadius*resizerRadius;
var draggingResizer={x:0,y:0};
var imageX=50;
var imageY=50;
var imageWidth,imageHeight,imageRight,imageBottom;
var draggingImage=false;
var startX;
var startY;

var tx,ty,tw,th,img;



async function loadImages(data, targetX, targetY, targetWidth, targetHeight) {
    

    data = data.replace(/'/g, '"');
    targetX = targetX.replace(/'/g, '"');
    targetY = targetY.replace(/'/g, '"');
    targetWidth = targetWidth.replace(/'/g, '"');
    targetHeight = targetHeight.replace(/'/g, '"');

    data = JSON.parse(data);
    targetX = JSON.parse(targetX);
    targetY = JSON.parse(targetY);
    targetWidth = JSON.parse(targetWidth);
    targetHeight = JSON.parse(targetHeight);


    for (var i = 0; i < data.length; i++) {
        tx = parseInt(targetX[i]);
        ty = parseInt(targetY[i]);
        tw = parseInt(targetWidth[i]);
        th = parseInt(targetHeight[i]);
        img = await loadImage(data[i]);
        imageWidth=img.width;
        imageHeight=img.height;
        imageRight=imageX+imageWidth;
        imageBottom=imageY+imageHeight
        draw(true,false);
      }


}
    
function loadImage(src){
    return new Promise(done=>{
    img = new Image();
    img.src = src;
    img.onload = function() {
        done(img);
    };
    });
}
function draw(withAnchors,withBorders){

    // draw the image

    ctx.drawImage(img,0,0,img.width,img.height,tx,ty,tw,th);

    // optionally draw the draggable anchors
    if(withAnchors){
        drawDragAnchor(imageX,imageY);
        drawDragAnchor(imageRight,imageY);
        drawDragAnchor(imageRight,imageBottom);
        drawDragAnchor(imageX,imageBottom);
    }
    
    // optionally draw the connecting anchor lines
    if(withBorders){
        ctx.beginPath();
        ctx.moveTo(imageX,imageY);
        ctx.lineTo(imageRight,imageY);
        ctx.lineTo(imageRight,imageBottom);
        ctx.lineTo(imageX,imageBottom);
        ctx.closePath();
        ctx.stroke();
    }

}

function drawDragAnchor(x,y){
    ctx.beginPath();
    ctx.arc(x,y,resizerRadius,0,pi2,false);
    ctx.closePath();
    ctx.fill();
}

function anchorHitTest(x,y){

    var dx,dy;

    // top-left
    dx=x-imageX;
    dy=y-imageY;
    if(dx*dx+dy*dy<=rr){ return(0); }
    // top-right
    dx=x-imageRight;
    dy=y-imageY;
    if(dx*dx+dy*dy<=rr){ return(1); }
    // bottom-right
    dx=x-imageRight;
    dy=y-imageBottom;
    if(dx*dx+dy*dy<=rr){ return(2); }
    // bottom-left
    dx=x-imageX;
    dy=y-imageBottom;
    if(dx*dx+dy*dy<=rr){ return(3); }
    return(-1);

}


function hitImage(x,y){
    return(x>imageX && x<imageX+imageWidth && y>imageY && y<imageY+imageHeight);
}


function handleMouseDown(e){
  startX=parseInt(e.clientX-offsetX);
  startY=parseInt(e.clientY-offsetY);
  draggingResizer=anchorHitTest(startX,startY);
  draggingImage= draggingResizer<0 && hitImage(startX,startY);
}

function handleMouseUp(e){
  draggingResizer=-1;
  draggingImage=false;
  draw(true,false);
}

function handleMouseOut(e){
  handleMouseUp(e);
}

function handleMouseMove(e){
  
  if(draggingResizer>-1){
  
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);

      // resize the image
      switch(draggingResizer){
          case 0: //top-left
              imageX=mouseX;
              imageWidth=imageRight-mouseX;
              imageY=mouseY;
              imageHeight=imageBottom-mouseY;
              break;
          case 1: //top-right
              imageY=mouseY;
              imageWidth=mouseX-imageX;
              imageHeight=imageBottom-mouseY;
              break;
          case 2: //bottom-right
              imageWidth=mouseX-imageX;
              imageHeight=mouseY-imageY;
              break;
          case 3: //bottom-left
              imageX=mouseX;
              imageWidth=imageRight-mouseX;
              imageHeight=mouseY-imageY;
              break;
      }

      // enforce minimum dimensions of 25x25
      if(imageWidth<25){imageWidth=25;}
      if(imageHeight<25){imageHeight=25;}

      // set the image right and bottom
      imageRight=imageX+imageWidth;
      imageBottom=imageY+imageHeight;
      
      // redraw the image with resizing anchors
      draw(true,true);
  
  }else if(draggingImage){
  
      imageClick=false;
      
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      
      // move the image by the amount of the latest drag
      var dx=mouseX-startX;
      var dy=mouseY-startY;
      imageX+=dx;
      imageY+=dy;
      imageRight+=dx;
      imageBottom+=dy;
      // reset the startXY for next time
      startX=mouseX;
      startY=mouseY;
      
      // redraw the image with border
      draw(false,true);
      
  }
  
  
}

$("#paint").mousedown(function(e){handleMouseDown(e);});
$("#paint").mousemove(function(e){handleMouseMove(e);});
$("#paint").mouseup(function(e){handleMouseUp(e);});
$("#paint").mouseout(function(e){handleMouseOut(e);});

This resulted in the following output: enter image description here

As you can see, it has only 2 anchors (when there should be 8 for two images ideally) I figured this must be because of the img variable being used by the other functions and also being present in the for loop for loading the images, but I can't figure out how to resolve this and make anchors for all the images in the loop.

Ravish Jha
  • 359
  • 1
  • 16

0 Answers0