如何限制或剪切 SVG 中的文本?
Posted
技术标签:
【中文标题】如何限制或剪切 SVG 中的文本?【英文标题】:How can I limit or clip text in SVG? 【发布时间】:2011-10-05 05:19:05 【问题描述】:我在 SVG 中做了一个表格,我想用数据动态填充它。这意味着我不知道文本占用了多少空间,并且我想剪辑或隐藏重叠的文本。如何在 SVG 中做到这一点?
我的带有 SVG 的 html 文档如下所示:
<!DOCTYPE html>
<html>
<body>
<svg>
<text x="100" y="100">Orange</text> <text x="160" y="100">12</text>
<text x="100" y="115">Pear</text> <text x="160" y="115">7</text>
<text x="100" y="130">Banana</text> <text x="160" y="130">9</text>
<text x="100" y="145">Pomegranate</text><text x="160" y="145">2</text>
<line x1="157" y1="85" x2="157" y2="155" style="stroke:rgb(100,100,100)"/>
</svg>
</body>
</html>
这将呈现到:
有什么方法可以在我的 SVG-“表格”中剪辑文本吗?
实施的解决方案来自 Erik 的回答:
<!DOCTYPE html>
<html>
<body>
<svg>
<text x="10" y="20" clip-path="url(#clip1)">Orange</text>
<text x="10" y="35" clip-path="url(#clip1)">Pear</text>
<text x="10" y="50" clip-path="url(#clip1)">Banana</text>
<text x="10" y="65" clip-path="url(#clip1)">Pomegranate</text>
<text x="70" y="20">12</text>
<text x="70" y="35">7</text>
<text x="70" y="50">9</text>
<text x="70" y="65">2</text>
<line x1="67" y1="5" x2="67" y2="75" style="stroke:rgb(100,100,100)"/>
<clipPath id="clip1">
<rect x="5" y="5" />
</clipPath>
</svg>
</body>
</html>
【问题讨论】:
你可以在上面的图片中看到它夹在字母a
的中间。更喜欢 textPath 而不是 ***.com/a/9249966/592792
【参考方案1】:
您可以使用 clip-path 剪辑成您想要的任何形状,例如,请参阅 svg 测试套件中的 masking-path-01。
相关部分,定义剪辑路径:
<clipPath id="clip1">
<rect x="200" y="10" />
... you can have any shapes you want here ...
</clipPath>
然后像这样应用剪辑路径:
<g clip-path="url(#clip1)">
... your text elements here ...
</g>
【讨论】:
有没有办法做到这一点?喜欢直接在 clip-path 属性中包含所有信息? @Matthias 可能可以使用数据 URI,但这会相当难看,而且我不确定所有浏览器都支持它。但是,将来可能会直接在clip-path
属性中使用一些简单的形状,请参阅dvcs.w3.org/hg/FXTF/raw-file/default/masking/…。
感谢您的回复。我对这种丑陋的 data-uri 方法很感兴趣;)你能给我举个例子吗?
正如我所怀疑的,这里有一个例子:xn--dahlstrm-t4a.net/svg/clippath/clip-data-uri.svg
@Matthias 现在你只需要使用 CSS 的 clip-path: polygon(...)
【参考方案2】:
如果由于某种原因你不想使用剪辑,你也可以使用嵌套的 SVG 标签:
<svg>
<svg x="10" y="10" >
<text x="0" y="0">Your text</text>
</svg>
</svg>
这样,您的文本在嵌套 SVG 视口之外时将被截断。注意text
标签的x
和y
指的是嵌套SVG的坐标系,对应外层SVG坐标系中的10。
【讨论】:
【参考方案3】:正如 Marcin 在他的回答的第 (2) 点中所说的那样(不幸的是,这一点被否决了,但实际上这是一个好点)实现效果的另一种方法是用白色矩形覆盖不需要的部分。
<!DOCTYPE html>
<html>
<body>
<svg>
<text x="100" y="100">Orange</text>
<text x="100" y="115">Pear</text>
<text x="100" y="130">Banana</text>
<text x="100" y="145">Pomegranate</text>
<!-- Overpaint the overflowing text -->
<rect x="155" y="85" fill="white" />
<line x1="157" y1="85" x2="157" y2="155" style="stroke:rgb(100,100,100)"/>
<text x="160" y="100">12</text>
<text x="160" y="115">7</text>
<text x="160" y="130">9</text>
<text x="160" y="145">2</text>
</svg>
</body>
</html>
参考 SVG 规范:SVG 2.0 Rendering Order
【讨论】:
【参考方案4】:(1) 没有理由将 SVG 用于表格。使用 HTML 表格。
(2) “剪裁”我理解你的意思是多余的文字会被遮住。 SVG 使用“画家模型”,即在文档后面指定的元素绘制在前面指定的元素之上。这将允许您剪辑区域。
(3) 如果您确实需要在 SVG 文档中执行此操作,您可以使用外部对象并嵌入 HTML。
【讨论】:
HTML 只是一个预览,我也会在 Java Swing 桌面应用程序中渲染我的 SVG,所以我不能使用 HTML。 Jonas,你确定 Swing 不会渲染嵌入的 HTML 吗?无论如何,我相信我已经回答了您关于剪辑的问题。 Swing 对 HTML 的支持非常有限,例如桌子上没有圆角。我无法让foreignObject
在 IE9 中工作。我会尝试更多关于裁剪区域的方法,但是太胖了,没有运气。有示例代码吗?
@Jacek 谢谢。我只能想象这是对 SVG 工作原理的无知。
同意。这里的社区有点奇怪。有时乐于助人,有时无脑。这是彩票;)。最好的问候!【参考方案5】:
如果您不想使用clip-path
,如果每个元素都有不同的大小可能会很痛苦,那么您还可以使用嵌套的<svg>
元素进行剪辑。只需确保 svg
元素具有 CSS 样式 overflow:hidden
。
<!DOCTYPE html>
<html>
<body>
<svg>
<svg x="10" y="5"><text y="15">Orange</text></svg>
<svg x="10" y="20"><text y="15">Pear</text></svg>
<svg x="10" y="35"><text y="15">Banana</text></svg>
<svg x="10" y="50"><text y="15">Pomegranate</text></svg>
<text x="70" y="20">12</text>
<text x="70" y="35">7</text>
<text x="70" y="50">9</text>
<text x="70" y="65">2</text>
<line x1="67" y1="5" x2="67" y2="75" style="stroke:rgb(100,100,100)"/>
</svg>
</body>
</html>
【讨论】:
以上是关于如何限制或剪切 SVG 中的文本?的主要内容,如果未能解决你的问题,请参考以下文章