调整SVG图形的原点

时间:2015-11-05 00:13:49

标签: android svg android-vectordrawable

tl; dr :给定任意SVG <path>如何调整路径命令以设置文件的新原点?

详细

我正在使用Adobe Illustrator创建用于Android的矢量图形。 Illustrator已a bug ,在{未​​知]的情况下,viewBox和为图形创建的所有坐标与您在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文件中所有路径的路径命令,使其偏移一定量,让我可以将原点放在我喜欢的位置?

1 个答案:

答案 0 :(得分:0)

解决方案是将明确的transform="translate(…,…)"添加到您要调整的每个路径上,在Web浏览器中查看SVG,使用this question中的代码[注意:我自己]将翻译烘焙到路径数据中,然后使用Web检查器获取更改的值。繁琐。

更好:我创建了一个小型在线工具SVG Reoriginizer [无广告,无收入],可让您将SVG代码粘贴到顶部框中,点击(或使用alt + shift +箭头键)调整原点,并查看底部显示的翻译路径命令。

核心代码是这个函数,它将viewBox和所有绝对路径命令偏移指定的数量,并将更改后的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);
}