将SVG多边形转换为路径

时间:2012-05-23 09:32:43

标签: svg raphael

我有一个相当大的行政细分SVG文件,我需要在Raphael.JS中使用它(它有600个多边形,重量为1.2 Mb)。

现在,我需要将这些多边形转换为路径,以便它在Raphael中工作。伟大的poly2path tool会这样做,但它不支持任何批处理命令,因此每个多边形相对于其他多边形的位置都会丢失。

您知道将SVG多边形转换为路径的任何工具吗? (我还有用于导出SVG的AI文件)。

非常感谢

4 个答案:

答案 0 :(得分:74)

  1. 在网络浏览器中打开您的SVG。
  2. 运行此代码:

    var polys = document.querySelectorAll('polygon,polyline');
    [].forEach.call(polys,convertPolyToPath);
    
    function convertPolyToPath(poly){
      var svgNS = poly.ownerSVGElement.namespaceURI;
      var path = document.createElementNS(svgNS,'path');
      var pathdata = 'M '+poly.getAttribute('points');
      if (poly.tagName=='polygon') pathdata+='z';
      path.setAttribute('d',pathdata);
      poly.parentNode.replaceChild(path,poly);
    }
    
  3. 使用浏览器的开发人员工具(或Firebug),在元素上使用“复制为HTML”(或复制SVG)将修改后的源文件放到剪贴板上。

  4. 粘贴到新文件中并享受。

  5. 我在我的网站上有上述方法的演示(稍加修改):
    http://phrogz.net/svg/convert_polys_to_paths.svg

    该页面上使用了两种方法;一个(如上所述)使用基于字符串的技术来获取和设置点;另一个使用SVG DOM来访问点和设置路径命令。


    如评论中的@Interactive所述,您可以通过以下文本进行纯文本转换:

    1. 将所有<polyline<polygon转换为<path
    2. 将所有points="更改为d="M
    3. 对于<polygon>的所有元素,您需要添加z作为d属性的最后一个字符,以将最后一个点连接到第一个。例如:

      <polygon points="1,2 3,-4 5,6"/> 
      

      变为

      <path d="M1,2 3,-4 5,6z"/> 
      
    4. 此'hack'有效,因为moveto命令(Mm)后跟多个坐标的specifications declare是合法的,所有坐标都在第一个解释后作为lineto命令。

答案 1 :(得分:4)

从开发人员工具中复制所有内容似乎非常不方便。您可以使用XSLT将多边形和折线转换为路径:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" exclude-result-prefixes="svg"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/2000/svg"
    xmlns:svg="http://www.w3.org/2000/svg">

  <!-- Identity transform: Copy everything 
       (except for polygon/polyline, handled below) -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- Turn polygons/polylines into paths, 
       copy all attributes and content 
       (except for @points: Will be matched
       by template below) -->
  <xsl:template match="svg:polygon|svg:polyline">
    <path>
      <xsl:apply-templates select="@*|node()"/>
    </path>
  </xsl:template>

  <!-- Turn the points attribute into a d attribute -->
  <xsl:template match="@points">
    <xsl:attribute name="d">
      <xsl:value-of select="concat('M',.)"/>
      <!-- If we have a polygon, we need to make 
           this a closed path by appending "z" -->
      <xsl:if test="parent::svg:polygon">
        <xsl:value-of select="'z'"/>
      </xsl:if>
    </xsl:attribute>
  </xsl:template>
</xsl:stylesheet>

多边形/折线元素的任何属性都将被转移到path元素。这也适用于批处理。您可以使用任何XSLT处理器(Saxon,Xalan,xsltproc,Altova ...)甚至在浏览器中使用XSLTProcessor对象运行它,例如:

var xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(stylesheet);
var transformedSVG = xsltProcessor.transformToFragment(svgDocument).firstChild

(类似问题:Examples of polygons drawn by path vs polygon in SVG

答案 2 :(得分:3)

对多边形id,填充和描边属性保存

的修复很少
var polys = document.querySelectorAll('polygon,polyline');
[].forEach.call(polys,convertPolyToPath);

function convertPolyToPath(poly){
  var svgNS = poly.ownerSVGElement.namespaceURI;
  var path = document.createElementNS(svgNS,'path');
  var points = poly.getAttribute('points').split(/\s+|,/);
  var x0=points.shift(), y0=points.shift();
  var pathdata = 'M'+x0+','+y0+'L'+points.join(' ');
  if (poly.tagName=='polygon') pathdata+='z';
  path.setAttribute('id',poly.getAttribute('id'));
  path.setAttribute('fill',poly.getAttribute('fill'));
  path.setAttribute('stroke',poly.getAttribute('stroke'));
  path.setAttribute('d',pathdata);

  poly.parentNode.replaceChild(path,poly);
}

答案 3 :(得分:3)

点击bu:答案:

  1. 在inkscape矢量图形编辑器中打开svg
  2. 选择所有对象(ctrl-a)
  3. 在下拉菜单中点“路径”选择第一个条目“对象到路径”(shift-ctrl-c)
  4. 保存svg并查看路径属性
  5. 可能不是一个合适的答案(因为对于大文件,程序需要一些时间)。