简体   繁体   中英

How to rotate and translate html5 canvas path so the last point will be at center

Here I have Demo and Code : http://jsbin.com/wuhuro/1/edit?js,output

First I have coordinates here:

var pts = [[{"X":"52.724649013065175","Y":"8.245410919189453"},{"X":"52.65681045479847","Y":"8.245067596435547"},{"X":"52.65056234595389","Y":"8.255367279052734"},{"X":"52.648271148983376","Y":"8.26772689819336"},{"X":"52.65035406028101","Y":"8.27768325805664"},{"X":"52.654519585231995","Y":"8.284549713134766"},{"X":"52.718826525722605","Y":"8.283863067626953"},{"X":"52.7250648752743","Y":"8.292789459228516"},{"X":"52.7283916301808","Y":"8.30514907836914"},{"X":"52.72402521231565","Y":"8.320941925048828"},{"X":"52.717162815135964","Y":"8.328838348388672"},{"X":"52.657851719462975","Y":"8.327465057373047"},{"X":"52.652853422873996","Y":"8.332958221435547"},{"X":"52.6480628523967","Y":"8.345661163330078"},{"X":"52.6509789143232","Y":"8.36111068725586"},{"X":"52.65639394198803","Y":"8.36832046508789"},{"X":"52.71820264168893","Y":"8.369007110595703"},{"X":"52.72423314689028","Y":"8.377933502197266"},{"X":"52.727975799697404","Y":"8.389263153076172"},{"X":"52.7281837154348","Y":"8.402652740478516"},{"X":"52.649520907667934","Y":"8.400249481201172"},{"X":"52.649312617034255","Y":"8.43149185180664"},{"X":"52.73317339571309","Y":"8.433551788330078"},{"X":"52.73317339571309","Y":"8.448314666748047"},{"X":"52.688245712958974","Y":"8.472347259521484"},{"X":"52.724649013065175","Y":"8.245410919189453"}]]; 

this coordinates I cant show on canvas becouse its to small points so I write:

function drawPolyline(pts){
  ctx.beginPath();

  function endProp( mathFunc, array, property ) {
    return Math[ mathFunc ].apply(array, array.map(function ( item ) {
        return item[ property ];
    }));
}

var maxY = endProp( "max", pts[0], "Y" ), // 8.389
    minY = endProp( "min", pts[0], "Y" );

var maxX = endProp( "max", pts[0], "X" ), // 8.389
    minX = endProp( "min", pts[0], "X" );

  for(var i=1;i<pts[0].length;i++){
    var a = (((pts[0][i].X - minX) * (1000 - 100)) / (maxX - minX)) + 0;
    var b = (((pts[0][i].Y - minY) * (600 - 0)) / (maxY - minY)) + 0;
    ctx.lineTo(a,b);
  }
  ctx.stroke();


}

With this function I get minimal and maximal values from pts for X and Y. Then I make transformation of coordinates like this:

NewValue = (((OldValue - OldMin) * (NewMax - NewMin)) / (OldMax - OldMin)) + NewMin

so this is the same:

for(var i=1;i<pts[0].length;i++){
        var a = (((pts[0][i].X - minX) * (1000 - 100)) / (maxX - minX)) + 0;
        var b = (((pts[0][i].Y - minY) * (600 - 0)) / (maxY - minY)) + 0;
        ctx.lineTo(a,b);
      }

With this code I transform coordinates and I easily show them on CANVAS.

After that I have:

ctx.beginPath();
      ctx.moveTo(470, 300);
      ctx.lineTo(530, 300);
ctx.lineWidth = 5;
ctx.strokeStyle = 'red';
ctx.stroke();

ctx.fillStyle="blue";
ctx.beginPath();
ctx.moveTo(500,260);
ctx.lineTo(530,280);
ctx.lineTo(470,280);
ctx.closePath();
ctx.fill();

With this code I draw triangle on center on canvas as you can see from demo link on the top.

Now, I need to transform and rotate path that I create from pts, so I need the last point to be at center to incorporate my path with triangle on center like this:

在此处输入图片说明

So I need to rotate full path to incorporate it with triangle on center. Please help.

Somebody have idea?

在此处输入图片说明

Here's one way:

  • Adjust all the points in your path so that the endpoint is at [0,0]. You can do this by subtracting the ending x,y from every point in the path.

  • context.translate to the center of your canvas. This will pull the endpoint of your path the the center of your canvas.

  • context.rotate by the angle that will rotate your path's last line segment to approach the endpoint from the bottom. You can get the angle of the last line segment using Math.atan2 and then calculate the required rotation angle as: -segmentAngle-PI/2

Here's example code and a Demo:

 var canvas=document.getElementById("canvas"); var ctx=canvas.getContext("2d"); var canvas1=document.getElementById("canvas1"); var ctx1=canvas1.getContext("2d"); var cw=canvas.width; var ch=canvas.height; var cx=cw/2; var cy=ch/2; var pts=[]; for(var i=0;i<10;i++){ var x=Math.random()*100-50+100; var y=Math.random()*100-50+100; pts.push({x:x,y:y}); } drawPts(pts); drawPts1(pts); function drawPts(pts){ var lastPt=pts[pts.length-1]; var nextToLastPt=pts[pts.length-2]; var dx=lastPt.x-nextToLastPt.x; var dy=lastPt.y-nextToLastPt.y; var angle=Math.atan2(dy,dx); var rotation=-angle-Math.PI/2; ctx.beginPath(); ctx.arc(cx,cy,5,0,Math.PI*2); ctx.closePath(); ctx.fillStyle='red'; ctx.fill(); var pts1=[]; var lp=pts[pts.length-1]; for(var i=0;i<pts.length;i++){ pts1.push({x:pts[i].x-lp.x,y:pts[i].y-lp.y}); } ctx.save(); ctx.translate(cx,cy); ctx.rotate(rotation); ctx.beginPath(); ctx.moveTo(pts1[0].x,pts1[0].y); for(var i=1;i<pts1.length;i++){ ctx.lineTo(pts1[i].x,pts1[i].y); } ctx.stroke(); ctx.beginPath(); ctx.arc(pts1[pts1.length-1].x,pts1[pts1.length-1].y,2,0,Math.PI*2); ctx.closePath(); ctx.fillStyle='blue'; ctx.fill(); ctx.restore(); } function drawPts1(pts){ var lastPt=pts[pts.length-1]; ctx1.beginPath(); ctx1.arc(cw/2,ch/2,5,0,Math.PI*2); ctx1.closePath(); ctx1.fillStyle='red'; ctx1.fill(); ctx1.save(); ctx1.beginPath(); ctx1.moveTo(pts[0].x,pts[0].y); for(var i=1;i<pts.length;i++){ ctx1.lineTo(pts[i].x,pts[i].y); } ctx1.stroke(); ctx1.beginPath(); ctx1.arc(lastPt.x,lastPt.y,2,0,Math.PI*2); ctx1.closePath(); ctx1.fillStyle='blue'; ctx1.fill(); ctx1.restore(); } 
 body{ background-color: ivory; padding:10px; } canvas{border:1px solid red;} 
 <h4>Left: original path.<br>Right: path endpoint moved to canvas centerpoint and approaching from bottom.<br>Red dot is canvas centerpoint<br>Blue dot is path endpoint</h4> <canvas id="canvas1" width=350 height=350></canvas> <canvas id="canvas" width=350 height=350></canvas> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM