Created
February 27, 2011 04:28
-
-
Save Phrogz/845901 to your computer and use it in GitHub Desktop.
Convert a SVG path to a Polygon by sampling the path, but also including all control points in the result. See http://phrogz.net/SVG/convert_path_to_polygon.xhtml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// http://phrogz.net/SVG/convert_path_to_polygon.xhtml | |
function pathToPolygon(path,samples){ | |
if (!samples) samples = 0; | |
var doc = path.ownerDocument; | |
var poly = doc.createElementNS('http://www.w3.org/2000/svg','polygon'); | |
// Put all path segments in a queue | |
for (var segs=[],s=path.pathSegList,i=s.numberOfItems-1;i>=0;--i) segs[i] = s.getItem(i); | |
var segments = segs.concat(); | |
var seg,lastSeg,points=[],x,y; | |
var addSegmentPoint = function(s){ | |
if (s.pathSegType == SVGPathSeg.PATHSEG_CLOSEPATH){ | |
}else{ | |
if (s.pathSegType%2==1 && s.pathSegType>1){ | |
// All odd-numbered path types are relative, except PATHSEG_CLOSEPATH (1) | |
x+=s.x; y+=s.y; | |
}else{ | |
x=s.x; y=s.y; | |
} | |
var lastPoint = points[points.length-1]; | |
if (!lastPoint || x!=lastPoint[0] || y!=lastPoint[1]) points.push([x,y]); | |
} | |
}; | |
for (var d=0,len=path.getTotalLength(),step=len/samples;d<=len;d+=step){ | |
var seg = segments[path.getPathSegAtLength(d)]; | |
var pt = path.getPointAtLength(d); | |
if (seg != lastSeg){ | |
lastSeg = seg; | |
while (segs.length && segs[0]!=seg) addSegmentPoint( segs.shift() ); | |
} | |
var lastPoint = points[points.length-1]; | |
if (!lastPoint || pt.x!=lastPoint[0] || pt.y!=lastPoint[1]) points.push([pt.x,pt.y]); | |
} | |
for (var i=0,len=segs.length;i<len;++i) addSegmentPoint(segs[i]); | |
for (var i=0,len=points.length;i<len;++i) points[i] = points[i].join(','); | |
poly.setAttribute('points',points.join(' ')); | |
return poly; | |
} |
Great work! We've implemented it in svg.topoly.js a plugin for svg.js.
SVGPathElement.getPathSegAtLength is removed from Chrome.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This will return NaNs if you have SVGPathSegLineto(Vertical/Horizontal)(Abs/Rel) i.e. 'V/H' and 'v/h' elements. Eg. if you have a path that contains c0,2.995,2.776,5.398h85.489c3.431... it will return a 'NaN' for the y choord since there's only an x choord in the element. To fix it, change addSegmentPoint to: