来自嵌套svg的SVG-bbox为大组

时间:2014-04-14 17:17:02

标签: svg bounding-box

我正在构建一个基于svg的应用程序,它使用一个“root”svg作为Viewport / Canvas。在这一个中我加载了一个SVG,它设置了所有图形,一个是安静的大(~18.000px * 800px,4MB)。我正在尝试创建一个视差效果,它适用于像<rect>这样的原始图形元素。但它对<g>元素不起作用。

很难发布相关代码,因为图形已经变得非常大,所以下面你可以看到一个基本设置的例子:

<svg class="root" width="1000" height="800">
    <g class="container" transform="matrix(1,0,0,1,<dx>,<dy>)">
        <svg width="16000" height="800">

        <!-- a lot of graphics here -->

        <g>
            <!-- the group with all the graphics for the parallax  -->
            <g class="parallax" transform="matrix(<crazy inkscape values here>);">
            </g>
        </g>

        <!-- a lot of graphics here -->

        </svg>
    </g>
</svg>

总而言之,我需要访问整个组的宽度来计算视差偏移,因此我正在使用:

<g>.getBBox();

什么返回宽度约为2.5倍的值。我在DOM中的相同位置使用相同尺寸的<Rect>替换了组,一切正常。

什么可能导致返回的边界边界框增长,可能是<gradient>-<symbol>-<use>-元素?

我很欣赏任何想法。

顺便说一句:这里已经考虑了坐标的转换,至少在可能的情况下。我在FF和Chromium中对此进行了测试 - 到处都是一样的......

提前致谢!

修改

我想我找到了错误的原因。这次不是我的。图形由Illustrator提供,使用Illustrator,在原始文件中我发现了几条空路径。他们将bbox扩展到0/0,即使没有真正的点......

1 个答案:

答案 0 :(得分:0)

我不认为以下是完整的解决方案,但让我们从这里开始讨论。

以下是宽度= 400高度= 400的内联svg,但包含<g>元素,其中一些元素超出了这些大小。我想将<g>中的元素与我的400x400内联svg相匹配。

试试这个:

<!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
        <title></title>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
        </head>
        <body style='font-family:arial'>
            <center>
            <div id="svgDiv" style='background-color:lightgreen;width:400px;height:400px;'>
<svg id="mySVG" width="400" height="400"  xmlns="http://www.w3.org/2000/svg" >
    <g id="myG">
    <circle cx=1000 cy=500 r=300 fill="red" />
    <rect x=300 y=200 width=500 height=300 fill="blue" />
    </g>
</svg>
</div>
<button onClick=fitG() >fit G</button>

            <br />SVG Source:<br />
            <textarea id=svgSourceValue style='font-size:110%;font-family:lucida console;width:90%;height:200px'></textarea>
            <br />Javascript:<br />
            <textarea id=jsValue style='border-radius:26px;font-size:110%;font-weight:bold;color:midnightblue;padding:16px;background-color:beige;border-width:0px;font-size:100%;font-family:lucida console;width:90%;height:400px'></textarea>
            </center>
            <div id='browserDiv' style='padding:5px;position:absolute;top:5px;left:5px;background-color:gainsboro;'>OK in:IE11/CH32/FF28<br /></div>
<script id=myScript>
//---button--
function fitG()
{
    var bb=myG.getBBox()
    var bbx=bb.x
    var bby=bb.y
    var bbw=bb.width
    var bbh=bb.height
    //---center of import---
    var cx=bbx+.5*bbw
    var cy=bby+.5*bbh
    //---create scale: ratio of desired width vs current width--
    var width=390
    var scale=width/bbw
    //---where to move it---
    var targetX=200
    var targetY=200
    //---move its center to target x,y ---
    var transX=(-cx)*scale + targetX
    var transY=(-cy)*scale + targetY
    myG.setAttribute("transform","translate("+transX+" "+transY+")scale("+scale+" "+scale+")")

    svgSourceValue.value=svgDiv.innerHTML
}
</script>
            <script>
            document.addEventListener("onload",init(),false)
            function init()
            {
                svgSourceValue.value=svgDiv.innerHTML
                jsValue.value=myScript.text
            }
            </script>
        </body>
    </html>