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


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
Post a Comment