如何限制或剪切 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标签的xy指的是嵌套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,如果每个元素都有不同的大小可能会很痛苦,那么您还可以使用嵌套的&lt;svg&gt; 元素进行剪辑。只需确保 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 中的文本?的主要内容,如果未能解决你的问题,请参考以下文章

C#限制文本框输入

如何在ios中限制UITextView中的内容

Swift 4 或 Swift 5 中的 UITextView 用户输入文本验证:限制 Swift 中的特定字符

如何按行数限制(或截断)文本文件?

如何在 VS Code 中添加文本限制行?

如何为css中的文本设置特定的像素或字符宽度限制