Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Placing text label along a line on a canvas

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

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

This works. I now want to "annotate" the line with text. So basically, I want there to be custom (e.g. whatever I pass in) text appearing along the length of the line. The difficulty is that the line can appear in any orientation (e.g. have any slope) so the text needs to be oriented accordingly. Any ideas how to start?

like image 479
john Avatar asked Dec 07 '22 23:12

john


1 Answers

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

  1. translate the context to the anchor point of the text, then
  2. rotate the context by the amount (in radians) you desire, and then
  3. fillText as normal.

I have included the relevant portion of my example below; I leave it as an exercise to the reader to detect when the text is upside down and handle it as desired. Edit: view the source on my site for additional code that keeps the text upright and also auto-truncates it.

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();
}

For Firefox only you also have the option of using mozTextAlongPath. (Deprecated)

like image 87
Phrogz Avatar answered Dec 17 '22 10:12

Phrogz