我使用HTML5成功在画布上绘制了一条线:
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
这个可以工作。我现在想要在这条线上“注释”文本。所以基本上,我希望自定义(例如我传递的任何内容)文本沿着线的长度出现。困难在于,该线可以以任何方向出现(例如具有任何斜率),因此文本需要相应地定位。有什么想法如何开始吗?
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
这个可以工作。我现在想要在这条线上“注释”文本。所以基本上,我希望自定义(例如我传递的任何内容)文本沿着线的长度出现。困难在于,该线可以以任何方向出现(例如具有任何斜率),因此文本需要相应地定位。有什么想法如何开始吗?
我在我的网站上创建了一个示例。一般来说,您需要:
将上下文平移
到文本的锚点处,然后按所需角度(弧度制)旋转
上下文,然后fillText
。我在下面包含了我示例的相关部分;检测文本何时上下颠倒并进行相应处理是读者的练习任务。编辑:在我的网站上查看源代码,获取保持文本直立且自动截断的其他代码。
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
选项。
我用过它并且它工作了 =) 我只是更改了一些东西,当我让节点旋转时,标签始终处于良好位置以便阅读:
在我的重绘函数中,我加入了类似以下的内容:
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();
})
谢谢,
达玛丽丝。