Skip to content Skip to sidebar Skip to footer

Resize Rectangle Html5 Canvas

I have some functions to draw rectangles on a canvas element. When the element is drawn, I want to be able to resize it by dragging its corners.

Solution 1:

Make sure to use some kind of threshold value to check for dragging on corners, use a closeEnough variable to hold this threshold then check corners by seeing if the absolute value of the difference between corner point and mouse point is less than the threshold. Apart from that, it is just a lot of cases to go through. Here is a jsFiddle of it

var canvas = document.getElementById('canvas'),
    ctx = canvas.getContext('2d'),
    rect = {},
    drag = false,
    mouseX, 
    mouseY,
    closeEnough = 10,
    dragTL=dragBL=dragTR=dragBR=false;

functioninit() {
  canvas.addEventListener('mousedown', mouseDown, false);
  canvas.addEventListener('mouseup', mouseUp, false);
  canvas.addEventListener('mousemove', mouseMove, false);
}

functionmouseDown(e) {
  mouseX = e.pageX - this.offsetLeft;
  mouseY = e.pageY - this.offsetTop;

  // if there isn't a rect yetif(rect.w === undefined){
    rect.startX = mouseY;
    rect.startY = mouseX;
    dragBR = true;
  }

  // if there is, check which corner//   (if any) was clicked//// 4 cases:// 1. top leftelseif( checkCloseEnough(mouseX, rect.startX) && checkCloseEnough(mouseY, rect.startY) ){
    dragTL = true;
  }
  // 2. top rightelseif( checkCloseEnough(mouseX, rect.startX+rect.w) && checkCloseEnough(mouseY, rect.startY) ){
    dragTR = true;

  }
  // 3. bottom leftelseif( checkCloseEnough(mouseX, rect.startX) && checkCloseEnough(mouseY, rect.startY+rect.h) ){
    dragBL = true;

  }
  // 4. bottom rightelseif( checkCloseEnough(mouseX, rect.startX+rect.w) && checkCloseEnough(mouseY, rect.startY+rect.h) ){
    dragBR = true;

  }
  // (5.) none of themelse {
    // handle not resizing
  }

  ctx.clearRect(0,0,canvas.width,canvas.height);
  draw();

}

functioncheckCloseEnough(p1, p2){
  returnMath.abs(p1-p2)<closeEnough;
}
functionmouseUp() {
  dragTL = dragTR = dragBL = dragBR = false;
}

functionmouseMove(e) {
  mouseX = e.pageX - this.offsetLeft;
  mouseY = e.pageY - this.offsetTop;
  if(dragTL){
    rect.w += rect.startX-mouseX;
    rect.h += rect.startY-mouseY;
    rect.startX = mouseX;
    rect.startY = mouseY;
  } elseif(dragTR) {
    rect.w = Math.abs(rect.startX-mouseX);
    rect.h += rect.startY-mouseY;
    rect.startY = mouseY;
  } elseif(dragBL) {
    rect.w += rect.startX-mouseX;
    rect.h = Math.abs(rect.startY-mouseY);
    rect.startX = mouseX;  
  } elseif(dragBR) {
    rect.w = Math.abs(rect.startX-mouseX);
    rect.h = Math.abs(rect.startY-mouseY);
  }
    ctx.clearRect(0,0,canvas.width,canvas.height);
    draw();
}

functiondraw() {
  ctx.fillRect(rect.startX, rect.startY, rect.w, rect.h);
}

init();

Solution 2:

Do a handle system: when the mouse move, get the distance to each corner to get the first one that is near the cursor then save it and resize your rectangle according to it.

Here is a JSfiddle illustrating it: http://jsfiddle.net/BaliBalo/9HXMG/

function getHandle(mouse) {
    if (dist(mouse, point(rect.x, rect.y)) <= handlesSize) return'topleft';
    if (dist(mouse, point(rect.x + rect.w, rect.y)) <= handlesSize) return'topright';
    if (dist(mouse, point(rect.x, rect.y + rect.h)) <= handlesSize) return'bottomleft';
    if (dist(mouse, point(rect.x + rect.w, rect.y + rect.h)) <= handlesSize) return'bottomright';
    if (dist(mouse, point(rect.x + rect.w / 2, rect.y)) <= handlesSize) return'top';
    if (dist(mouse, point(rect.x, rect.y + rect.h / 2)) <= handlesSize) return'left';
    if (dist(mouse, point(rect.x + rect.w / 2, rect.y + rect.h)) <= handlesSize) return'bottom';
    if (dist(mouse, point(rect.x + rect.w, rect.y + rect.h / 2)) <= handlesSize) return'right';
    returnfalse;
}

Post a Comment for "Resize Rectangle Html5 Canvas"