javascript - To rotation an image in canvas using mouse -


in code loading image in canvas. need resize, rotate , drag it. managed implement both dragging , resizing.

how can implement rotation(along center of image) using mouse on 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 canvas         ctx.clearrect(0,0,canvas.width,canvas.height);          // draw image         ctx.drawimage(img,0,0,img.width,img.height,imagex,imagey,imagewidth,imageheight);          // optionally draw draggable anchors         if(withanchors){             drawdraganchor(imagex,imagey);             drawdraganchor(imageright,imagey);             drawdraganchor(imageright,imagebottom);             drawdraganchor(imagex,imagebottom);         }          // optionally draw 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 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 image right , bottom           imageright=imagex+imagewidth;           imagebottom=imagey+imageheight;            // redraw image resizing anchors           draw(true,true);        }else if(draggingimage){            imageclick=false;            mousex=parseint(e.clientx-offsetx);           mousey=parseint(e.clienty-offsety);            // move image amount of latest drag           var dx=mousex-startx;           var dy=mousey-starty;           imagex+=dx;           imagey+=dy;           imageright+=dx;           imagebottom+=dy;           // reset startxy next time           startx=mousex;           starty=mousey;            // redraw image 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 image using 4 draggable corner anchors</p>     <p>you can drag image</p>     <canvas id="canvas" width=350 height=350></canvas> </body> </html> 

here’s how use drag-handle rotate image

enter image description hereenter image description here

the mousedown event handler hit-tests if user starting drag rotation-handle.

this hit-testing made easier context.ispointinpath(x,y) tests whether specified [x,y] coordinate inside drawn path (conveniently, rotation-handle path).

so mousedown activates drag-handle this:

  • calculate current mousex , mousey.
  • redraw rotation handle (required because ispointinpath hit-tests recent path)
  • set isdown flag if user did click in rotation handle.

the mousedown code looks this:

function handlemousedown(e){   mousex=parseint(e.clientx-offsetx);   mousey=parseint(e.clienty-offsety);   drawrotationhandle(false);   isdown=ctx.ispointinpath(mousex,mousey); } 

yes...we have hit-tested circle on end of rotation-handle, using ispointinpath allow draw whatever fancy rotation handle desire.

and ispointinpath has nice benefit. when context containing path rotated, ispointinpath hit-test rotated path you. means don't have code math unrotate mouse coordinates hit testing--it's done you!

the mousemove handler redraws rotatable image @ angle specified rotation-handle:

  • if isdown flag not set, return (the user not dragging rotation-handle).
  • calculate current mousex , mousey.
  • calculate current angle of rotation-handle.
  • redraw rotatable image @ current angle.

the mousemove code looks 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(); } 

the image drawn @ specified rotation using context's transform methods

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

finally, mouseup , mouseout handlers stop drag operation clearing isdown flag.

function handlemouseup(e){   isdown=false; }  function handlemouseout(e){   isdown=false; } 

here code , 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 dragging blue rotation handle</p>     <canvas id="canvas" width=300 height=300></canvas> </body> </html> 

Comments

Popular posts from this blog

c++ - CryptStringToBinary API behavior -

c++ - Correct method for redrawing a layered window -

java.util.scanner - How to read and add only numbers to array from a text file -