svg - 如何沿着文本段的边界框画一条线?
问题描述
Gnuplot 支持“盒装文本”属性,该属性在文本标签周围绘制一个带有可选填充的框。由于 gnuplot 基本上对字体一无所知,因此它依赖于特定于设备的代码来生成适当的框。这是为大多数 gnuplot 输出设备实现的,但我不知道如何支持 svg 输出。特别是我知道如何使用过滤器在文本周围生成一个实心填充框(参见下面的示例),但我不知道如何在同一个框周围画一条线。
这是 gnuplot 输出的 svg 片段,以及生成的渲染 svg 图像的屏幕截图以及不同 gnuplot 输出设备输出的所需结果。
请注意,我不是在问如何在 javascript 中获取和修改边界框。我要求生成本机 svg 文档。
<svg
width="600" height="480"
viewBox="0 0 600 480"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<rect x="0" y="0" width="600" height="480" fill="none"/>
<defs>
<filter id='textbox' filterUnits='objectBoundingBox' x='0' y='0' height='1' width='1'>
<feFlood flood-color='cyan' flood-opacity='1' result='bgnd'/>
<feComposite in='SourceGraphic' in2='bgnd' operator='atop'/>
</filter>
</defs>
<g id="textbox 1">
<g transform="translate(297.9,244.6)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="start" style='filter:url(#textbox)'>
<text><tspan font-family="Arial" >A two-line label</tspan>
<tspan x="0" dy="12" font-family="Arial" > in a box </tspan></text>
</g>
</g>
</svg>
更新:
到目前为止提出的三个答案是基于使用过滤器+填充操作,基本上是在一个稍小的矩形周围放置一个稍大的矩形。这与画线不同。它不容易缩放,并且生成的外观与同一图中的其他线条不匹配。我真的想要某种方式来为组或文本边界框发出“笔画”而不是“填充”操作。这将允许匹配图中其他线的连接、粗细和其他属性。
边界框坐标显然隐含在 svg 上下文中,这既是因为它们被 filter+fill 使用,又因为它们可以被 javascript 查询。真的不能用于“中风”吗?
解决方案
我不是 SVG 专家,而是使用 Inkscape 和您的 SVG。看起来没有简单的框架命令(至少我还没有找到),但是您可以将一些高斯模糊滤镜效果应用于文本框。我假设您可以重命名id="filter1780"
为其他名称。
我还更改了行以在文本周围留出一些边距:
<filter id='textbox' filterUnits='objectBoundingBox' x='-0.1' y='-0.1' height='1.2' width='1.2'>
如果您调整数字,您最终可能会在文本周围出现清晰的框架。不能保证这是有效的 SVG,它看起来像一个丑陋而冗长的解决方法,但至少它看起来像你的目标。
SVG代码:
<svg
width="600" height="480"
viewBox="0 0 600 480"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<rect x="0" y="0" width="600" height="480" fill="none"/>
<defs>
<filter id='textbox' filterUnits='objectBoundingBox' x='-0.1' y='-0.1' height='1.2' width='1.2'>
<feFlood flood-color='cyan' flood-opacity='1' result='bgnd'/>
<feComposite in='SourceGraphic' in2='bgnd' operator='atop'/>
</filter>
<filter id="filter1780" x="-.2" y="-.2" width="1.4" height="1.4" color-interpolation-filters="sRGB">
<feGaussianBlur in="SourceAlpha" result="blur1" stdDeviation="0.33"/>
<feComposite in="SourceGraphic" in2="blur1" operator="out" result="composite1"/>
<feColorMatrix result="colormatrix1" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 100 -0 "/>
<feGaussianBlur result="blur2" stdDeviation="0.01"/>
<feComposite in="blur2" in2="blur2" result="composite2"/>
<feColorMatrix result="colormatrix2" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 100 -0 "/>
<feGaussianBlur result="blur3" stdDeviation="0.01"/>
<feColorMatrix result="colormatrix3" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 5 -1 "/>
<feFlood flood-color="rgb(0,0,0)" result="flood"/>
<feComposite in="flood" in2="colormatrix3" k2="1" operator="in" result="composite3"/>
<feComposite in="SourceGraphic" in2="colormatrix3" operator="out" result="composite4"/>
<feComposite in="composite4" in2="composite3" k2="1" k3="1" operator="arithmetic" result="composite5"/>
</filter>
</defs>
<g id="textbox 1">
<g filter="url(#filter1780)">
<g transform="translate(297.9,244.6)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="start" style='filter:url(#textbox)'>
<text><tspan font-family="Arial" >A two-line label</tspan>
<tspan x="0" dy="12" font-family="Arial" > in a box </tspan></text>
</g>
</g>
</g>
</svg>
结果:
推荐阅读
- c# - WPF - 设置 DataContext 极大地增加了计算时间
- javascript - 检查用户是否对 Google Drive URL 具有“编辑权限”
- python - 如何将一个数字作为输入并在 Python 中打印一个浮点数直到该小数点
- java - iText7 LtvVerification.addVerification 未启用 LTV
- vector - openlayers 5中矢量图层的交互功能
- c# - C# 将两种不同类型的属性序列化为 JSON
- javascript - 为什么在 vuex 存储中推送到数组后未定义数组?
- c - 有效地将可被 3 或 5 整除的数字相加
- python - django 如何显示新添加产品的详细信息页面
- python - 在 Seaborn / Matplotlib 的小提琴图上指定高于和低于中位数的颜色