dragging and resizing an image on html5 canvas

I am building a HTML5 canvas image editor. After uploading an image in to the canvas i need to Dragg and resize it over the canvas. I managed to upload an image and make it draggable on the canvas. But i need to make it resizable also along the canvas. Thanks in advance.

var Img = new Image();
Img.src = file;
Img.onload = function () {
  context.drawImage(Img, 50, 0, 200, 200); 
}
mouseMove = function (event){
if (down) 
{
 context.clearRect(0,0,800,500);
 context.translate(0, -50); 
 context.drawImage(Img, (event.clientX - offsetX),
 (event.clientY - offsetY), 200, 200);
 context.translate(0, 50);
}
}
mouseUp = function () {
  down = false;
}
mouseDown = function () {
  down = true;
}
canvas.addEventListener('mousedown', mouseDown, false);
canvas.addEventListener('mouseup', mouseUp, false);
canvas.addEventListener('mousemove',mouseMove, false);

I tried with kinetics js but it is not suitable with canvas.

Answers:

Answer

Here's example code to allow you to drag and resize an image using Canvas.

Resizing

enter image description hereenter image description here

How to resize an image with 4 draggable anchors

  • Draw a draggable anchor on each corner of an image.
  • If the user mousedown’s one if the anchors, start dragging that anchor.
  • In the mousemove handler, resize the image using the dragging anchor’s position(Note below).
  • As the last act in mousemove, redraw the resized image and 4 new anchors.
  • On mouseup, stop the anchor’s drag.

Note on the math used to resize the image:

  • The resized width is the difference between the mouseX position and the opposite corner’s X.
  • The resized height is the difference between the mouseY position and the opposite corner’s Y.

Dragging

enter image description hereenter image description here

How to drag an image

  • If the user mousedown’s inside the image, save the mouses starting XY to begin dragging.
  • In the mousemove handler, move the image by the current mouseXY minus the startingXY.
  • Also in mousemove, reset the startingXY to the current mouseXY in preparation for continued dragging.
  • On mouseup, stop the image’s drag.

Here is code and a Fiddle: http://jsfiddle.net/m1erickson/LAS8L/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; padding:10px;}
    #canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    var canvasOffset=$("#canvas").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 img=new Image();
    img.onload=function(){
        imageWidth=img.width;
        imageHeight=img.height;
        imageRight=imageX+imageWidth;
        imageBottom=imageY+imageHeight
        draw(true,false);
    }
    img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/facesSmall.png";


    function draw(withAnchors,withBorders){

        // clear the canvas
        ctx.clearRect(0,0,canvas.width,canvas.height);

        // draw the image
        ctx.drawImage(img,0,0,img.width,img.height,imageX,imageY,imageWidth,imageHeight);

        // 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);

      }


    }


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


}); // end $(function(){});
</script>

</head>

<body>
    <p>Resize the image using the 4 draggable corner anchors</p>
    <p>You can also drag the image</p>
    <canvas id="canvas" width=350 height=350></canvas>
</body>
</html>

Also:

Simon Sarris has done a nice tutorial on how to drag and resize "elements" on html canvas.

http://simonsarris.com/blog/225-canvas-selecting-resizing-shape

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.