Search code examples
svgcrop

Proper way to crop an SVG?


I'm totally baffled by SVG images. I want to crop the image to its core content. I want to crop it by specifying its viewbox and/or viewport and/or anything else EXCEPT I do NOT want to change any of the points in the polyline elements. The image as-is renders something like this. (NOTE the border is only for illustration purposes. The border is not actually part of the SVG.)

original

and I want to crop it so it looks something like this. (NOTE the border again is for illustration purposes only)

cropped

Given this SVG XML how do I crop it?

<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" >
    <polyline points="39,340  42,338  47,333  54,322  68,308  83,292  91,277  100,259  106" style="fill:none;stroke:black;stroke-width:3"/>
    <polyline points="71,299  82,303  95,304  109,302  120,301" style="fill:none;stroke:black;stroke-width:3"/>
    <polyline points="212,275  228,254  233,233  240,208  239,246  188,278  174,306  158,334  149,351  144,358  140,362  139,362  139,340  179,313  186" style="fill:none;stroke:black;stroke-width:3"/>
    <polyline points="169,345  174,347  227,333  231,330  330,371  328,374  414,209  410,192  404,183  401,177  398,177  395,179   379,340  385,384  397,414" style="fill:none;stroke:black;stroke-width:3"/>
</svg>

Solution

  • When the svg is inline, you can compute its viewBox by using getBBox() for the root svg.

    Below is an example for your polylines:

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>Compute viewBox</title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    </head>
    <body>
    <center>
    <h3>Compute viewBox</h3>
    <div id=svgDiv style='background-color:lightgreen'>
    <svg id=mySVG>
        <polyline points="39,340  42,338  47,333  54,322  68,308  83,292  91,277  100,259" style="fill:none;stroke:black;stroke-width:3"/>
        <polyline points="71,299  82,303  95,304  109,302  120,301" style="fill:none;stroke:black;stroke-width:3"/>
        <polyline points="212,275  228,254  233,233  240,208  239,246  188,278  174,306  158,334  149,351  144,358  140,362  139,362  139,340  179,313  " style="fill:none;stroke:black;stroke-width:3"/>
        <polyline points="169,345  174,347  227,333  231,330  330,371  328,374  414,209  410,192  404,183  401,177  398,177  395,179   379,340  385,384  397,414" style="fill:none;stroke:black;stroke-width:3"/>
    </svg>
    </div>
    <button onClick=fit()>fit</button>
    viewVox:<input type=text size=20 id=vbValue />
    </center>
    </body>
    <script>
     //---button--
    function fit()
    {
        var bb=mySVG.getBBox()
        var bbx=bb.x
        var bby=bb.y
        var bbw=bb.width
        var bbh=bb.height
        var vb=[bbx,bby,bbw,bbh]
        mySVG.setAttribute("viewBox", vb.join(" ") )
        vbValue.value=vb.join(" ")
        svgDiv.style.width=bbw+"px"
        svgDiv.style.height=bbh+"px"
    }
    </script>
    </html>