如果在给定弧之后有一个弯曲的文本路径,那么textpah如何在弧内居中?
请参阅this example
在其中,我在< text>上手动设置了x和dy。通过试验和错误,以便结果是我想要的(文本沿弧线居中)。
但我动态生成许多弧,需要一种动态居中文本位置的方法(取决于d)。
我认为这里的子问题是d.x和d.dx与< text>的关系。 dx和x?同样适用于y。
答案 0 :(得分:1)
为子孙后代;)
您需要dy
的原因是因为TextPath
从outerRadius
定义的路径的开头开始,并绘制文本以使其基线与路径匹配。然后它将继续到这个外部路径的末端并环绕到内部路径。我还没有找到或想出一种计算字体高度的方法,并相应地调整dy
。或者,您可以创建一个新弧来指导文本并将半径调整为合适的值。
要自动将文本置于上弧上,您需要设置两个属性。第一个是startOffset
,以抵消起点;它应该设置为25%,因为线的全长包括内半径和外半径。由于外弧比内弧长,因此可能略微偏离。或者,您可以创建第二条路径,其内半径和外半径相同,并使用该路径作为文本。然后,您需要使用text-anchor
并将其设置为middle
。
如果要防止文本从外部圆弧到内部圆弧缠绕,可以先从路径中删除内部圆弧,然后将文本偏移50%而不是25%。
function removeInnerArc(path) {
return path.replace(/(M.*A.*)(A.*Z)/, function(_, m1) {
return m1 || path;
});
}
var arc = d3.svg.arc()
.innerRadius(180)
.outerRadius(220)
.startAngle(-Math.PI / 4)
.endAngle(function(t) {
return t * 2 * Math.PI / 3;
});
// Generate a new arc to guide the text
// The radius determines the baseline for the text
var textArc = d3.svg.arc()
.innerRadius(190)
.outerRadius(190)
.startAngle(-Math.PI / 4)
.endAngle(function(t) {
return t * 2 * Math.PI / 3;
});
var svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 500)
.append("g")
.attr("transform", "translate(250,250)");
svg.append("defs").append("path")
.attr("id", "text-path")
.attr("d", removeInnerArc(textArc(1)));
svg.append("path")
.attr("id", "path")
.attr("d", arc(1));
svg.append("clipPath")
.attr("id", "text-clip")
.append("use")
.attr("xlink:href", "#path");
svg.append("text")
.attr("clip-path", "url(#text-clip)")
.append("textPath")
.attr("xlink:href", "#text-path")
.text("Hello, curved textPath!")
// You need the following two lines to position the text correctly
.attr("text-anchor", "middle")
.attr("startOffset", "50%");

path {
fill: #3182bd;
}
text {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 24px;
}

<html>
<head>
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Open+Sans:400,600">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
</body>
</html>
&#13;
答案 1 :(得分:0)
使用SVG Path的getPointAtLength方法。希望这会有所帮助。
var path = svg.append("path")
.attr("id", "path")
.attr("d", arc(1));
var text = "Hello, curved textPath!";
var pt = path.node().getPointAtLength(path.node().getTotalLength()/2-text.length);
svg.append("text")
.attr("clip-path", "url(#text-clip)")
.attr("x", pt.x)
.attr("dy", 28)
.append("textPath")
.attr("xlink:href", "#text-path")
.text("Hello, curved textPath!");