调整 SVG 图形的原点
Adjust origin of SVG graphic
tl;dr:给定任意 SVG <path>
如何调整路径命令以设置文件的新原点?
详情
我正在使用 Adobe Illustrator 创建用于 Android 的矢量图形。 Illustrator 有 a bug 在(未知)情况下 viewBox
和为您的图形创建的所有坐标与您为 canvas 设置的坐标不匹配和 Illustrator 中的对象。而不是(例如)viewBox="-7 0 14 20"
你可能会得到 viewBox="-53 75 14 20"
。通常,路径命令将被翻译以适应该 viewBox。有时甚至会失败。
在普通的 SVG 文件中 (a) 这几乎不会被注意到,并且 (b) 通过将所有内容包装在根级别 <g transform="translate(46,-75)">
中很容易修复。在 Android VectorDrawable
中,这需要一个我不想添加的额外 <group>
,并且(与 SVG 不同)我无法向 <path>
本身添加翻译.在我的代码中,来源很重要。
如何调整 SVG 文件中所有路径的路径命令以将它们偏移固定量,从而允许我将原点放在我想要的位置?
A 解决方案是在每个要调整的路径上显式添加 transform="translate(…,…)"
,在网络浏览器中查看 SVG,使用 [=12 中的代码=] [注:我自己的]将translate烘焙成路径数据,然后使用Web inspector获取变化后的值。很麻烦。
更好:我创建了一个在线小工具SVG Reoriginizer[没有广告,没有收入],可以让您将 SVG 代码粘贴到顶部框中,点击 (或使用alt+shift+箭头键)调整原点,看到底部显示的翻译路径命令。
核心代码是这个函数,它将viewBox和所有绝对路径命令偏移指定的量,并且returns改变后的SVG作为字符串:
function offsetOrigin(svg,dx,dy){
svg.viewBox.baseVal.x -= dx;
svg.viewBox.baseVal.y -= dy;
[].forEach.call(svg.querySelectorAll('path'),function(path){
var segs = path.pathSegList;
for (var i=segs.numberOfItems;i--;){
var seg=segs.getItem(i), c=seg.pathSegTypeAsLetter;
if (/[MLHVCSQTA]/.test(c)){
if ('x' in seg) seg.x -=dx;
if ('y' in seg) seg.y -=dy;
if ('x1' in seg) seg.x1-=dx;
if ('x2' in seg) seg.x2-=dx;
if ('y1' in seg) seg.y1-=dy;
if ('y2' in seg) seg.y2-=dy;
}
}
});
return (new XMLSerializer).serializeToString(svg);
}
tl;dr:给定任意 SVG <path>
如何调整路径命令以设置文件的新原点?
详情
我正在使用 Adobe Illustrator 创建用于 Android 的矢量图形。 Illustrator 有 a bug 在(未知)情况下 viewBox
和为您的图形创建的所有坐标与您为 canvas 设置的坐标不匹配和 Illustrator 中的对象。而不是(例如)viewBox="-7 0 14 20"
你可能会得到 viewBox="-53 75 14 20"
。通常,路径命令将被翻译以适应该 viewBox。有时甚至会失败。
在普通的 SVG 文件中 (a) 这几乎不会被注意到,并且 (b) 通过将所有内容包装在根级别 <g transform="translate(46,-75)">
中很容易修复。在 Android VectorDrawable
中,这需要一个我不想添加的额外 <group>
,并且(与 SVG 不同)我无法向 <path>
本身添加翻译.在我的代码中,来源很重要。
如何调整 SVG 文件中所有路径的路径命令以将它们偏移固定量,从而允许我将原点放在我想要的位置?
A 解决方案是在每个要调整的路径上显式添加 transform="translate(…,…)"
,在网络浏览器中查看 SVG,使用 [=12 中的代码=] [注:我自己的]将translate烘焙成路径数据,然后使用Web inspector获取变化后的值。很麻烦。
更好:我创建了一个在线小工具SVG Reoriginizer[没有广告,没有收入],可以让您将 SVG 代码粘贴到顶部框中,点击 (或使用alt+shift+箭头键)调整原点,看到底部显示的翻译路径命令。
核心代码是这个函数,它将viewBox和所有绝对路径命令偏移指定的量,并且returns改变后的SVG作为字符串:
function offsetOrigin(svg,dx,dy){
svg.viewBox.baseVal.x -= dx;
svg.viewBox.baseVal.y -= dy;
[].forEach.call(svg.querySelectorAll('path'),function(path){
var segs = path.pathSegList;
for (var i=segs.numberOfItems;i--;){
var seg=segs.getItem(i), c=seg.pathSegTypeAsLetter;
if (/[MLHVCSQTA]/.test(c)){
if ('x' in seg) seg.x -=dx;
if ('y' in seg) seg.y -=dy;
if ('x1' in seg) seg.x1-=dx;
if ('x2' in seg) seg.x2-=dx;
if ('y1' in seg) seg.y1-=dy;
if ('y2' in seg) seg.y2-=dy;
}
}
});
return (new XMLSerializer).serializeToString(svg);
}