沿着画布上的一行放置文本标签

时间:2011-02-21 16:06:38

标签: javascript html5 canvas

我设法使用html5在画布上绘制一条线:

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

这很有效。我现在想用文本“注释”该行。所以基本上,我希望在线的长度上出现自定义(例如,我传入的任何内容)文本。难点在于线可以以任何方向出现(例如,具有任何斜率),因此文本需要相应地定向。任何想法如何开始?

2 个答案:

答案 0 :(得分:10)

我已经创建了这个on my website的示例。通常,您希望:

  1. translate上下文到文本的锚点,然后
  2. rotate上下文所需的金额(以弧度表示),然后
  3. fillText正常。
  4. 我已将我的示例的相关部分包括在内; 我将它作为练习留给读者,以检测文本何时颠倒并按需要处理修改:查看我网站上的源代码,了解保持文字直立的其他代码,并自动将其截断。

    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

答案 1 :(得分:0)

我使用它并且它起作用=)我只是改变了一些东西,这样当我使节点旋转时,标签总是处于一个很好的位置可以读取:

在我的重绘功能中,我放了这样的东西:

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

谢谢,

达玛里斯。