Placing a text label along a line on a canvas

I managed to draw a line on the canvas using html5:

ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();

It works. Now I want to "annotate" the string with text. Therefore, basically, I want the text to appear on your sheet (for example, no matter what I go through). The difficulty is that the line can be displayed in any orientation (for example, have any slope), so the text should be oriented accordingly. Any ideas how to get started?

+3
source share
2 answers

I created an example of this on my website . In general, you want:

  • translate context with the text anchor point and then
  • rotate context for the amount (in radians) you want, and then
  • fillText normally.

; , , . : , , .

function drawLabel( ctx, text, p1, p2, alignment, padding ){
  if (!alignment) alignment = 'center';
  if (!padding) padding = 0;

  var dx = p2.x - p1.x;
  var dy = p2.y - p1.y;   
  var p, pad;
  if (alignment=='center'){
    p = p1;
    pad = 1/2;
  } else {
    var left = alignment=='left';
    p = left ? p1 : p2;
    pad = padding / Math.sqrt(dx*dx+dy*dy) * (left ? 1 : -1);
  }

  ctx.save();
  ctx.textAlign = alignment;
  ctx.translate(p.x+dx*pad,p.y+dy*pad);
  ctx.rotate(Math.atan2(dy,dx));
  ctx.fillText(text,0,0);
  ctx.restore();
}

Firefox mozTextAlongPath.

+9

, =) - , , node, :

- :

particleSystem.eachEdge(function(edge, pt1, pt2){
      // edge: {source:Node, target:Node, length:#, data:{}}
      // pt1:  {x:#, y:#}  source position in screen coords
      // pt2:  {x:#, y:#}  target position in screen coords
      // draw a line from pt1 to pt2

     var dx = (pt2.x - pt1.x);
     var dy = (pt2.y - pt1.y);
     var p, pad;
     var alignment = "center";


      //ctx.label(edge.data.role,dx,dy,5,90,14);
      ctx.strokeStyle = "rgba(0,0,0, .333)";
      ctx.lineWidth = 1;
      ctx.beginPath();
      ctx.moveTo(pt1.x, pt1.y);
      ctx.lineTo(pt2.x, pt2.y);
      ctx.stroke();


     p = pt1;
     pad = 1/2;
     ctx.save();
 ctx.textAlign = alignment;
 ctx.translate(p.x+dx*pad,p.y+dy*pad);
     if(dx < 0)
     {
     ctx.rotate(Math.atan2(dy,dx) - Math.PI);  //to avoid label upside down
     }
     else
     {
     ctx.rotate(Math.atan2(dy,dx));

 }
     ctx.fillStyle = "black"
     ctx.fillText(edge.data.role,0,0);

 ctx.restore();
    })          

,

.

0

Source: https://habr.com/ru/post/1793633/


All Articles