Rotate the image in the canvas using the mouse


Deepu SA

In my code I am loading the image into the canvas. Then I need to resize, rotate and drag it. I managed to achieve dragging and resizing.

How can I achieve rotation (along the center of the image) using the mouse on this code.

my html page:

<!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>
brand

Here's how to rotate the image using the drag handle

enter image description hereenter image description here

The mousedown event handler tests whether the user started dragging the rotation handle.

In-process testing is made easier by using context.isPointInPath(x, y), which tests whether the specified [x, y] coordinates are within the most recently drawn path (conveniently, the rotation handle is actually the path).

So mousedown can activate the drag handle like this:

  • Calculate the current mouseX and mouseY.
  • Redraw the rotation handle (required because isPointInPath can only test the latest path)
  • If the user did click the spin handle, the isDown flag is set.

The mousedown code looks like this:

function handleMouseDown(e){
  mouseX=parseInt(e.clientX-offsetX);
  mouseY=parseInt(e.clientY-offsetY);
  drawRotationHandle(false);
  isDown=ctx.isPointInPath(mouseX,mouseY);
}

Yes... we could simply hit test the circle at the end of the rotation handle, but using isPointInPath will allow you to draw any fancy rotation handle you want.

isPointInPath has another nice benefit. When the context containing the path is rotated, isPointInPath will hit the rotated path for you . This means you don't need to write math code to unravel mouse coordinates for hit testing, it's done for you!

The mousemove handler redraws the rotatable image at the angle specified by the rotation handle:

  • Only returns if the isDown flag is not set (the user did not drag the rotation handle).
  • Calculate the current mouseX and mouseY.
  • Calculates the current angle of the rotation handle.
  • Redraws the rotatable image at the current angle.

The mousemove code looks like this:

function handleMouseMove(e){
  if(!isDown){return;}

  mouseX=parseInt(e.clientX-offsetX);
  mouseY=parseInt(e.clientY-offsetY);
  var dx=mouseX-cx;
  var dy=mouseY-cy;
  r=Math.atan2(dy,dx);
  draw();
}

draws the image with the specified rotation using the context's transform methods

function drawRect(){
    ctx.save();
    ctx.translate(cx,cy);
    ctx.rotate(r);
    ctx.drawImage(img,0,0);
    ctx.restore();
}

Finally, the mouseup and mouseout handlers stop the drag operation by clearing the isDown flag.

function handleMouseUp(e){
  isDown=false;
}

function handleMouseOut(e){
  isDown=false;
}

Here is the code and fiddle : http://jsfiddle.net/m1erickson/QqwKR/

<!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; }
    #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 isDown=false;

    var cx=canvas.width/2;
    var cy=canvas.height/2;
    var w;
    var h;
    var r=0;

    var img=new Image();
    img.onload=function(){
        w=img.width/2;
        h=img.height/2;
        draw();
    }
    img.src="facesSmall.png";


    function draw(){
        ctx.clearRect(0,0,canvas.width,canvas.height);
        drawRotationHandle(true);
        drawRect();
    }

    function drawRect(){
        ctx.save();
        ctx.translate(cx,cy);
        ctx.rotate(r);
        ctx.drawImage(img,0,0,img.width,img.height,-w/2,-h/2,w,h);
        ctx.restore();
    }

    function drawRotationHandle(withFill){
        ctx.save();
        ctx.translate(cx,cy);
        ctx.rotate(r);
        ctx.beginPath();
        ctx.moveTo(0,-1);
        ctx.lineTo(w/2+20,-1);
        ctx.lineTo(w/2+20,-7);
        ctx.lineTo(w/2+30,-7);
        ctx.lineTo(w/2+30,7);
        ctx.lineTo(w/2+20,7);
        ctx.lineTo(w/2+20,1);
        ctx.lineTo(0,1);
        ctx.closePath();
        if(withFill){
            ctx.fillStyle="blue";
            ctx.fill();
        }
        ctx.restore();
    }

    function handleMouseDown(e){
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      drawRotationHandle(false);
      isDown=ctx.isPointInPath(mouseX,mouseY);
      console.log(isDown);
    }

    function handleMouseUp(e){
      isDown=false;
    }

    function handleMouseOut(e){
      isDown=false;
    }

    function handleMouseMove(e){
      if(!isDown){return;}

      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      var dx=mouseX-cx;
      var dy=mouseY-cy;
      r=Math.atan2(dy,dx);
      draw();
    }

    $("#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>Rotate by dragging blue rotation handle</p>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

Related


Rotate the image in the canvas using the mouse

Deepu SA In my code I am loading the image into the canvas. Then I need to resize, rotate and drag it. I managed to achieve dragging and resizing. How can I achieve rotation (along the center of the image) using the mouse on this code. my html page: <!doctype

Rotate the image in the canvas using the mouse

Deepu SA In my code I am loading the image into the canvas. Then I need to resize, rotate and drag it. I managed to achieve dragging and resizing. How can I achieve rotation (along the center of the image) using the mouse on this code. my html page: <!doctype

How to rotate an image using the mouse Python

window man So I've been trying to get the cannon image to rotate to where the mouse is, but the code I'm trying has an error. My cannon doesn't follow my mouse and when I place the rotation code I lose another sprite, I tried the code that will be shown below,

How to rotate an image using the mouse Python

window man So I've been trying to get the cannon image to rotate to where the mouse is, but the code I'm trying has an error. My cannon doesn't follow my mouse and when I place the rotation code I lose another sprite, I tried the code that will be shown below,

How to rotate an image using the mouse Python

window man So I've been trying to get the cannon image to rotate to where the mouse is, but the code I'm trying has an error. My cannon doesn't follow my mouse and when I place the rotation code I lose another sprite, I tried the code that will be shown below,

How to rotate an image using the mouse Python

window man So I've been trying to get the cannon image to rotate to where the mouse is, but the code I'm trying has an error. My cannon doesn't follow my mouse and when I place the rotation code I lose another sprite, I tried the code that will be shown below,

Rotate the image but not the canvas

Pujan Srivastava I am using a background image on the canvas. I just want to rotate the background image by 90 degrees, but the context should not be rotated. If I use CSS transitions then the whole canvas rotates. What can I do? var can = document.getElementB

Rotate an existing image on the canvas

Alex Saidani I am trying to rotate an image already drawn on an HTML canvas like this: var canvas = document.getElementById("editorCanvas"); var ctx = canvas.getContext("2d"); var canvasOffset = $("#editorCanvas").offset(); var offsetX = canvasOffset.left; va

Rotate an image in the canvas

Yaroslav Shabanov I am trying to create some rotated images. So I created an array of canvases and put in each picture. But for some reason they don't show up. please help me. var canvas = [], ctx = [], particles = []; for (var i = 0; i < 10; i++){ sym.$( sy

Rotate the image but not the canvas

Pujan Srivastava I am using a background image on the canvas. I just want to rotate the background image by 90 degrees, but the context should not be rotated. If I use CSS transitions then the whole canvas rotates. What can I do? var can = document.getElementB

Rotate an image in the canvas

Yaroslav Shabanov I am trying to create some rotated images. So I created an array of canvases and put in each picture. But for some reason they don't show up. please help me. var canvas = [], ctx = [], particles = []; for (var i = 0; i < 10; i++){ sym.$( sy

Rotate an existing image on the canvas

Alex Saidani I am trying to rotate an image already drawn on an HTML canvas like this: var canvas = document.getElementById("editorCanvas"); var ctx = canvas.getContext("2d"); var canvasOffset = $("#editorCanvas").offset(); var offsetX = canvasOffset.left; va

Rotate the image but not the canvas

Pujan Srivastava I am using a background image on the canvas. I just want to rotate the background image by 90 degrees, but the context should not be rotated. If I use CSS transitions then the whole canvas rotates. What can I do? var can = document.getElementB

Rotate an image in the canvas

Yaroslav Shabanov I am trying to create some rotated images. So I created an array of canvases and put in each image. But for some reason they don't show up. please help me. var canvas = [], ctx = [], particles = []; for (var i = 0; i < 10; i++){ sym.$( sym.

Rotate an existing image on the canvas

Alex Sadani I'm trying to rotate an image already drawn on an HTML canvas like this: var canvas = document.getElementById("editorCanvas"); var ctx = canvas.getContext("2d"); var canvasOffset = $("#editorCanvas").offset(); var offsetX = canvasOffset.left; var

Flutter - How to rotate image around center using canvas

Natwar Singh I'm trying to implement a custom painter that draws an image (minified version) on a canvas, and can rotate and scale the drawn image. I know that to scale the image, I have to use the scale method to scale the canvas. Now the question is how to r

How to resize and rotate an image at the same time using canvas

dd Before uploading, I have to resize and rotate the image, the resize is to reduce the picture size and the rotation is to correct the image captured by the iPhone. Here is the code I am using, for resize, I am using a smaller canvas to redraw the image for r

Flutter - How to rotate image around center using canvas

Natwar Singh I'm trying to implement a custom painter that draws an image (minified version) on a canvas, and can rotate and scale the drawn image. I know that to scale the image, I have to use the scale method to scale the canvas. Now the question is how to r

Flutter - How to rotate image around center using canvas

Natwar Singh I'm trying to implement a custom painter that draws an image (minified version) on a canvas, and can rotate and scale the drawn image. I know that to scale the image, I have to use the scale method to scale the canvas. Now the question is how to r

Flutter - How to rotate image around center using canvas

Natwar Singh I'm trying to implement a custom painter that draws an image (minified version) on a canvas, and can rotate and scale the drawn image. I know that to scale the image, I have to use the scale method to scale the canvas. Now the question is how to r

How to resize and rotate an image at the same time using canvas

dd Before uploading, I have to resize and rotate the image, the resize is to reduce the picture size and the rotation is to correct the image captured by the iPhone. Here is the code I'm using, for resize, I'm using a smaller canvas to redraw the image for rot

Image not following mouse on canvas

username I have a problem creating a game on html canvas. The premise of the game is that you have to catch the balloons before they fall. I have a problem with the canvas background, the basket is not moving with the mouse. The background should be black and

Image not following mouse on canvas

username I have a problem creating a game on html canvas. The premise of the game is that you have to catch the balloons before they fall. I have a problem with the canvas background, the basket is not moving with the mouse. The background should be black and

Rotate the image following the mouse pointer

Nilzone- Code: $(document).ready(function(){ var player = $('#player'); //Checks to see which key is pressed down $(window).on('mousemove', function (e) { //Current position var p1 = { x: player.offsetLeft, y: player.o

Java: Rotate image to mouse position?

Crazy Bacon So I have this person: We call him Bob. I want him to rotate to my mouse position. I've figured it out, by drawing a line between Bob and the mouse and finding the angle of that line, I can figure out what angle Bob needs to face in order to "point

Rotate animated image in gnuplot with mouse

maximum I created some 3D animated gifs using gnuplot . I can't see all the scattered data in the gif file. Using the "set view" command is not the best approach because plotting is done automatically and the data varies from plot to plot, so where one view mi