我有一个相当大的行政区划SVG文件,其中包含600个多边形,大小为1.2 Mb。现在,我需要将这些多边形转换为path,以便在Raphael.JS中使用。有一个非常好用的poly2path工具可以做到这一点,但它不支持任何批量命令,因此每个多边形相对于其他多边形的位置都会丢失。
你知道有没有工具可以将SVG多边形转换为路径?(我还有用于导出SVG的AI文件)。
非常感谢。
我有一个相当大的行政区划SVG文件,其中包含600个多边形,大小为1.2 Mb。现在,我需要将这些多边形转换为path,以便在Raphael.JS中使用。有一个非常好用的poly2path工具可以做到这一点,但它不支持任何批量命令,因此每个多边形相对于其他多边形的位置都会丢失。
你知道有没有工具可以将SVG多边形转换为路径?(我还有用于导出SVG的AI文件)。
非常感谢。
在网页浏览器中打开你的SVG文件。
运行以下代码:
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.getAttributeNames().forEach(function(name){
if(name !== 'points')
path.setAttribute(name, poly.getAttribute(name))
})
poly.parentNode.replaceChild(path,poly);
}
使用浏览器的开发工具(或者Firebug),在元素上使用“复制为HTML”(或者复制SVG)来将修改后的源代码复制到剪贴板中。
将其粘贴到一个新文件中,然后享受它。
我在我的网站上演示了上述方法(稍作修改):
http://phrogz.net/svg/convert_polys_to_paths.svg
该页面上有两种方法;一种(像上面的方法)使用基于字符串的技术来获取和设置点;另一种使用SVG DOM来访问点并设置路径命令。
正如@Interactive在评论中指出的那样,您可以通过纯文本转换来完成以下操作:
将所有的<polyline
和<polygon
转换为<path
将所有的points="
改为d="M
对于任何被<polygon>
包含的元素,你需要在d
属性的最后一个字符添加z
以将最后一个点连接到第一个点。例如:
<polygon points="1,2 3,-4 5,6"/>
变成
<path d="M1,2 3,-4 5,6z"/>
这种“技巧”之所以有效,是因为规范声明,一个使用多个坐标的moveto
命令(M
或m
)是合法的,除第一个坐标外后面所有的坐标都会被解释为lineto
命令。
<script>
块中,或者打开开发者工具并将其粘贴到控制台中。 - Phrogz<polyline
替换为<path
,并将points="
替换为d="M
。具体内容可以在此链接中找到:https://gist.github.com/andytlr/9283541 - Interactivemoveto
命令的规范明确指出,除第一对坐标外的其他坐标将被视为隐式的 lineto
命令。我会编辑我的答案并添加上述内容。 - Phrogz对多边形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);
}
从开发者工具中复制所有内容似乎非常不方便。您可以使用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>
多边形/折线元素的任何属性都将传递到路径元素。这也适用于批处理。您可以使用任何XSLT处理器(Saxon、Xalan、xsltproc、Altova...)运行此操作,甚至可以在浏览器中使用XSLTProcessor
对象,例如:
var xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(stylesheet);
var transformedSVG = xsltProcessor.transformToFragment(svgDocument).firstChild
(类似的问题:SVG中通过路径和多边形绘制的多边形示例)
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 pathClass = poly.getAttribute('class');
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('class', pathClass);
path.setAttribute('d',pathdata);
poly.parentNode.replaceChild(path,poly);
}