将SVG对象移动至原点

2 投票
2 回答
1751 浏览
提问于 2025-04-18 02:30

我正在用Python的svgwrite模块创建一堆不同的SVG文件,之后我需要把这些图片放到网站上展示。

因为这些图片里包含了不同的数学图形,所以我在整个平面上工作,涉及到正数和负数。这就意味着我需要把所有的图形移动一下,让它们都能看得见,并且保持原来的结构。有时候移动这些图形并不难,但因为我几乎在所有的工作中都需要这样做,所以我想找一个更通用的方法。

我希望找到一种方法,可以把所有的图形都移动到合适的位置,同时保持它们的结构,这样所有的东西都能看得见,而且图片的大小(宽度和高度)会尽量小。

我查阅了官方文档,但到目前为止还没有找到合适的解决方案,可能是我没看明白。

更新 为了让问题更清楚,我添加了一个例子。

Python示例:

import svgwrite

im = svgwrite.drawing.Drawing()
im.add(im.line( start = (-10,-10),\
                end   = (20,20),\
                stroke= 'black'))
im.saveas('example.svg')

然后,当我在比如Firefox中查看example.svg时,只能看到“正”的部分,也就是从[0,0]到[20,20]的那条线。

或者是稍微不同的例子:

import svgwrite

im = svgwrite.drawing.Drawing()
im.add(im.line( start = (10,10),\
                end   = (20,20),\
                stroke= 'black'))
im.saveas('example2.svg')

现在在[0,0]和从[10,10]开始的那条线之间有一个不必要的空隙。

所以,总结一下。想象一下有一堆SVG图形,它们可以画在任何地方。我想找到所有图形中最小的x坐标和y坐标(x_min和y_min),然后:

  • 如果x_min(或者y_min)是负数,就把|x_min|(或者|y_min|)加到所有图形的x(或者y)坐标上。这里的|a|表示a的绝对值。
  • 如果x_min(或者y_min)是正数,就从所有图形的x(或者y)坐标中减去x_min(或者y_min)。

这样一来,所有的图形都会变得可见,并且它们会在零点处接触到一个或两个坐标轴。正如下面讨论的那样,通过相应地移动原点也可以达到同样的效果。

注意 顺便提一下,module Image也有类似的问题。

2 个回答

4

假设你想要移动坐标系的原点,你需要做的就是把你的图形线条放在一个组元素里面,然后对这个组应用一个变换。

我不太清楚那个库的具体语法,但根据文档,它应该类似于下面这样:

im = svgwrite.drawing.Drawing()
g = svgwrite.container.Group(transform='translate(50,50)')
im.add(g)
g.add(im.line( start = (-10,-10),\
                end   = (20,20),\
                stroke= 'black'))
im.saveas('example.svg')
2

如果我理解你的意思没错的话,你希望图表在显示时不要超出页面的范围对吧?如果是这样的话,你需要给你的SVG添加一个 viewBox 属性。

首先,你需要记录下整个图表的最小和最大x、y值。这个步骤可能需要你自己来做,或者可能使用的svgwrite库会帮你完成。

当图表完成后,给你的根SVG元素添加一个 viewBox 属性,里面包含这些值。

viewBox的格式是这样的:

minX minY width height

其中minX和minY是图表的左上角位置。所以,对于你上面的第一个例子,viewBox应该是:

<svg viewBox="-10 -10 30 30" ... >

而对于你的第二个例子,它应该是:

<svg viewBox="10 10 10 10" ... >

这样,当图像在浏览器中显示时,它会根据viewBox属性提供的尺寸来调整内容的位置和大小,以填满容器(比如浏览器窗口、<div>等)。

如果你不想让它填满容器,而是想指定图表的默认宽度和高度(比如200px x 200px),可以给SVG添加 widthheight 属性。像这样:

<svg width="200px" height="200px" viewBox="-10 -10 30 30">

    <line x1="-10" y1="-10" x2="20" y2="20" stroke="black" />

</svg>

这里有个演示

撰写回答