Convertir SVG polygon en chemin
j'ai un assez grand fichier SVG de subdivisions administratives avec lesquelles je dois travailler dans Raphael.JS (il a 600 polygones et Poids 1,2 Mb).
maintenant, je dois convertir ces polygones en chemins pour qu'ils fonctionnent en Raphaël. Le grand poly2path tool fait cela, mais il ne supporte aucune commande batch, de sorte que la position de chaque polygone par rapport aux autres est perdue.
connaissez-vous un outil pour convertir SVG les polygones tracés? (J'ai aussi le fichier AI qui a été utilisé pour exporter la SVG).
merci Beaucoup
4 réponses
- ouvrez votre SVG dans un navigateur web.
-
Exécuter ce code:
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); }
-
à l'aide des outils de développement (ou Firebug) du navigateur, utilisez" copier en HTML " (ou copier SVG) sur l'élément pour obtenir la source modifiée sur le bloc-notes.
-
Coller dans un nouveau fichier et d'en profiter.
j'ai une démo de la méthode ci-dessus (légèrement modifiée) sur mon site web:
http://phrogz.net/svg/convert_polys_to_paths.svg
il y a deux méthodes utilisées sur cette page; l'une (comme ci-dessus) utilise des techniques basées sur les chaînes de caractères pour obtenir et définir les points; l'autre utilise le DOM SVG pour accéder aux points et définir les commandes path.
comme noté par @Interactive en les commentaires, vous pouvez le faire via des transformations texte seulement par:
- Convertir tous les
<polyline
et<polygon
à<path
- changer toutes
points="
end="M
-
pour tous les éléments qui étaient
<polygon>
, vous devez ajouterz
comme dernier caractère de l'attributd
pour relier le dernier point au premier. Par exemple:<polygon points="1,2 3,-4 5,6"/>
devient
<path d="M1,2 3,-4 5,6z"/>
ce "hack" fonctionne parce que les spécifications déclarent qu'une commande moveto
( M
ou m
) suivie de coordonnées multiples est légale, avec toutes les coordonnées après la première interprété comme lineto
commandes.
copier tout des outils de développement semble assez incommode. Vous pouvez utiliser un XSLT pour transformer les polygones et les polylines en chemins:
<?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>
tout attribut des éléments polygones/polylignes sera transféré à l'élément path. C'est également adapté pour le traitement par lot. Vous pouvez l'exécuter avec n'importe quel processeur XSLT (Saxon, Xalan, xsltproc, Altova...) ou même dans le navigateur, en utilisant l'objet XSLTProcessor
, comme:
var xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(stylesheet);
var transformedSVG = xsltProcessor.transformToFragment(svgDocument).firstChild
(question similaire: exemples de polygones dessinés par chemin vs polygone dans SVG )
petit correctif pour les attributs polygon id, fill et stroke save
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);
}
clicky-bunty réponse:
- ouvrir le svg inkscape éditeur de graphiques vectoriels
- sélectionner tous les objets (ctrl-A)
- au point de menu déroulant" chemin "sélectionner la première entrée " objet vers le chemin" (shift-ctrl-c)
- enregistrer le svg et de vérifier les propriétés du chemin
pourrait ne pas être une réponse appropriée (parce qu'avec de grands fichiers le le programme a besoin d'un certain temps).