我正在尝试让文字显示在线条内部,以便与线路相连接,如下图所示。
使用该行作为图像的textPath不起作用,因为当我将文本内联时,该行继续通过文本。
我有一个适用于直路径的解决方案。我测量文本长度和完整路径长度,然后将其分成3个单独的路径。我在第1和第3条路径上绘制了一个笔划,中间路径用于textPath。
我无法将此工作用于除直线路径以外的任何其他工作,因为我无法测量文本或计算出每个部分的长度。
我正在使用JointJS,但纯粹的伪代码/ SVG答案也同样有帮助。
答案 0 :(得分:1)
解决此问题的一种方法是创建一个文本块,其长度与文本相同,只是Unicode块字符的填充等于您的背景颜色,并在绘制之前绘制实际文本路径。 (您需要将扩张滤镜添加到纸上,以消除由弧/曲线引起的伪影 - 您可能需要根据需要调整半径。)
<svg width="12cm" height="3.6cm" viewBox="0 0 1000 300" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<path id="MyPath"
d="M 100 200
C 200 100 300 0 400 100
C 500 200 600 300 700 200
C 800 100 900 100 900 100" />
<filter id="dilatethis">
<feMorphology operator="dilate" radius="4"/>
</filter>
</defs>
<use xlink:href="#MyPath" fill="none" stroke="red" stroke-width="5" y="-15" />
<text font-family="monospace" font-size="42.5" fill="white" filter="url(#dilatethis)" >
<textPath xlink:href="#MyPath" startOffset="155" >
████████████████████
</textPath>
</text>
<text font-family="Verdana" font-size="42.5" fill="blue">
<textPath xlink:href="#MyPath" startOffset="155" >
Just imagine that this
</textPath>
</text>
</svg>
&#13;
答案 1 :(得分:1)
最简单的解决方案就是在行的顶部和文本下方放置一个白色(或任何背景颜色)矩形。
<svg width="400px" height="100px">
<line x1="50" y1="50" x2="350" y2="50" stroke="blue" stroke-width="2"/>
<rect x="125" y="40" width="150" height="20" fill="white"/>
<text x="200" y="54" text-anchor="middle" fill="blue">Text inline with arrow</text>
</svg>
或者,不是矩形,而是放置文本的副本,但将其设为白色并给它一个粗的笔划。这种方法的优点是你不必为尝试找出矩形的正确尺寸而烦恼。
<svg width="400px" height="100px">
<line x1="50" y1="50" x2="350" y2="50" stroke="blue" stroke-width="2"/>
<text x="200" y="54" text-anchor="middle" fill="white" stroke="white" stroke-width="5">Text inline with arrow</text>
<text x="200" y="54" text-anchor="middle" fill="blue">Text inline with arrow</text>
</svg>
这种方法的一个方面是,如果字母中的间隙或单词之间的间隙足够大,则显示该行。您可能会或可能不会找到理想的。
这只是两种可能的方法。我可以想到更多,但他们更多参与。
答案 2 :(得分:0)
使用Michael Mullany和Paul LeBeau的答案,我已经在JointJS中实现了这一点,所以我发布了所需的更改。
定义一个扩展joint.dia.Link
的新形状模型,例如:joint.shapes.gary.InlineLabelLink
使用两个新文本字段扩展形状模型中的标记。一个用于标签(inlineText),一个用于位于标签后面的掩码(inlineTextMask)。
添加一些属性以确保文本在需要的位置。
添加一个名为&#34; caption&#34;的新属性它将保存内联标签文本。
例如:
joint.shapes.gary.InlineLabelLink = joint.dia.Link.extend({
defaults: joint.util.deepSupplement({
markup: [
'<path class="connection" stroke="black" d="M 0 0 0 0"/>',
'<path class="marker-source" fill="black" stroke="black" d="M 0 0 0 0"/>',
'<path class="marker-target" fill="black" stroke="black" d="M 0 0 0 0"/>',
'<path class="connection-wrap" d="M 0 0 0 0"/>',
'<text class="inlineTextMask" />',
'<text class="inlineText" />',
'<g class="labels"/>',
'<g class="marker-vertices"/>',
'<g class="marker-arrowheads"/>',
'<g class="link-tools"/>'
].join(''),
attrs: {
'.inlineText': {
'dominant-baseline': 'central',
'text-anchor': 'middle',
'pointer-events': 'none',
'font-size': 10
},
'.inlineTextMask': {
'dominant-baseline': 'central',
'text-anchor': 'middle',
'pointer-events': 'none',
'fill':'#ffffff',
'stroke':'#ffffff',
'stroke-linejoin':'smooth',
'stroke-linecap':'round',
'stroke-width': 8,
'font-size': 10
}
},
caption: 'TBD'
}, joint.dia.Link.prototype.defaults)});
然后创建一个从joint.dia.LinkView
在该课程中,我们覆盖update
函数,以便它可以在正确的位置绘制内联标签。
joint.shapes.gary.InlineLabelLinkView = joint.dia.LinkView.extend({
update: function() {
joint.dia.LinkView.prototype.update.apply(this, arguments);
var inlinePath = this._V.connection.node.getAttribute('d');
this._V.inlineText.text(this.model.get('caption'),
{textPath: { d: inlinePath, startOffset:"50%" } });
this._V.inlineTextMask.text(this.model.get('caption').replace(' ','\u9608'),
{textPath: { d: inlinePath, startOffset:"50%" } });
return this;
}
});
更新的View类从链接获取路径,然后将此路径应用于文本掩码和文本属性。它使用Vectorizer的文本方法创建适当的defs,textPath和tspan条目。
这确实存在这样的问题:有时文本可能会颠倒,具体取决于链接的方向。这可以通过反转路径的方向来解决。
我已经为此使用了定制功能(未显示),但有像https://github.com/SmartArtsStudio/smart-svg-path和https://www.npmjs.com/package/svg-path-reverse这样的库
if (this.sourcePoint.x > this.targetPoint.x) {
inlinePath = reversePath(inlinePath);
}