基于SVG中的路径元素计算viewBox参数

8
我得到一个只有路径的XML或JSON文件,并需要重新创建SVG图像。
我创建了一个空的<svg xmlns='http://www.w3.org/2000/svg' version='1.1'></svg>元素,
在其中添加一个<g transform="scale(1 -1)" fill='#aaa' stroke='black' stroke-width='5' ></g>,然后将所有路径都添加进来(例如 <path d= ... />)。
最后得到了一个SVG图像,但由于我没有在SVG元素中设置viewBox属性,因此图像无法正常显示-当我在浏览器中打开它时,其中一部分会以全尺寸显示。
可以从路径的值计算出viewBox吗?
谢谢!

“a part of it is displayed full size” 是什么意思? - mihai
例如,如果我有一个400x400像素的SVG,其中一部分 - 例如从左下角开始的50x50 - 我会将其完整显示。 - Martin Spa
2个回答

18

与Martin Spa的答案类似,但更好的获取最大视口面积的方法是使用getBBox函数:

var clientrect = path.getBBox();
var viewBox = clientrect.x+' '+clientrect.y+' '+clientrect.width+' '+clientrect.height;

您可以将视口设置为这些坐标。

n.b. 我认为您可以在呈现后更改SVG的视口,因此您可能需要重新呈现SVG。


完美,正是我所需要的。 - Martijn B

4

好的,我用以下方法解决了它:

  1. 从路径字符串中删除所有字母,并将其制成一个数组

    var values = pathValue.split('L').join(' ').split('M').join(' ').split('z').join('').split(' ');

  2. 在这些值中找到最大值和最小值:

    var max = Math.max.apply( Math, values );

    var min = Math.min.apply( Math, values );

  3. 设置viewBox:

    viewBox = max min max max

在我的情况下,这个方法非常有效。希望对其他人也有所帮助。


听起来不错。我现在理解问题了。最初,我认为你可以将viewBox设置为固定值,但我猜这样行不通,因为如果图像太大,一部分将无法显示。 - mihai
2
顺便说一句,更简单的方法是使用 path.match(/(-?\d+(.\d+)?)/gi) 来处理值部分。这种方法也适用于路径中可能包含的其他字符,如 q 和 t。 - alzclarke
1
请注意,仅当路径为多边形时,通过这种方式拆分路径以查找范围才有效;任何圆弧或三次/二次样条线,或位于SVG中的定位文本元素可能会超出以此方式计算的bbox。对于弧和样条线有解决方案,但需要将它们转换为多边形线,直到某个精度级别,您可以确信它不会逃脱边界框;对于文本而言,它更加复杂,因为它需要计算字体样式并提取字形。此外,笔画具有宽度,您需要考虑斜接/圆形/平头连接类型。 - verdy_p
最后,SVG中的动画可以将元素移动到它们的初始位置之外。在SVG中包含一些虚拟矩形(未填充且没有描边边框)来定义其余部分将被绘制的预期区域始终是一个好的解决方案。 - verdy_p
对于具有外曲线(凹面)的弧和贝塞尔曲线,它将如何工作? - Mark Vital

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接