How can I limit or clip text in SVG?

2019-03-22 14:35发布

I have done a table in SVG, and I want to fill it with data dynamically. That means that I don't know how much space the text takes, and I want to clip or hide the overlapping text. How can I do that in SVG?

My HTML document with SVG looks like:

<!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>

And this will render to:

enter image description here

Is there any way I can clip the text i my SVG-"table"?


Implemented solution from Erik's answer:

<!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" width="57" height="90"/>
    </clipPath>
</svg>
</body>
</html>

enter image description here

标签: html5 text svg
5条回答
叼着烟拽天下
2楼-- · 2019-03-22 14:43

As Marcin said in point (2) of his answer (unfortunately downvoted but actually this is a good point) an alternative way to achieve the effect is to overpaint the part not wanted with a white rectangle.

<!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" width="100" height="100" 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 overlay sample

Reference to the SVG specification: SVG 2.0 Rendering Order

查看更多
Evening l夕情丶
3楼-- · 2019-03-22 14:49

You can use clip-path to clip to whatever shape you want, see e.g masking-path-01 from the svg testsuite.

Relevant parts, defining the clip path:

<clipPath id="clip1">
  <rect x="200" y="10" width="60" height="100"/>
  ... you can have any shapes you want here ...
</clipPath>

and then apply the clip path like this:

<g clip-path="url(#clip1)">
  ... your text elements here ...
</g>
查看更多
Summer. ? 凉城
4楼-- · 2019-03-22 14:52

If for some reason you don't want to use clipping, you can also use a nested SVG tag:

<svg>
  <svg x="10" y"10" width"10" height="10">
    <text x="0" y="0">Your text</text>
  </svg>
</svg>

This way, your text will be cut off when it's outside the nested SVG viewport. Note that the x and y of the text tag refer to the coordinate system of the nested SVG, and correspond to 10 in the coordinate system of the outer SVG.

查看更多
ら.Afraid
5楼-- · 2019-03-22 14:55

If you don't want to use a clip-path, which can be a pain if each element has a different size, then you can also use nested <svg> elements for clipping. Just make sure the svg elements have the CSS style overflow:hidden.

<!DOCTYPE html>
<html>
<body>
<svg>
    <svg width="57" height="15" x="10" y="5"><text y="15">Orange</text></svg>       
    <svg width="57" height="15" x="10" y="20"><text y="15">Pear</text></svg>
    <svg width="57" height="15" x="10" y="35"><text y="15">Banana</text></svg>   
    <svg width="57" height="15" 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>
查看更多
放我归山
6楼-- · 2019-03-22 14:55

(1) There is no reason to use SVG for tables. Use HTML tables.

(2) By "clipping" I understand you to mean that the excess text will be obscured. SVG uses a "painter's model" whereby elements specified later in the document are drawn above elements specified earlier. This will allow you to clip regions.

(3) If you really needed to do this in an SVG document you could use a foreign object, and embed HTML.

查看更多
登录 后发表回答