Polyfill SVGPathElement.getPathSegAtLength
masterSVGPathElement.getPathSegAtLength, this library includes a polyfill for this method to ensure compatibility with existing codebases that rely on retrieving path segments at specific lengths.repository·master·Indexed 41 days ago
https://github.com/progers/pathsegA polyfill for SVGPathSeg, SVGPathSegList, and getPathSegAtLength APIs that were removed from the SVG2 specification. It allows legacy code to continue working in modern browsers by restoring the ability to programmatically create, manipulate, and retrieve path segments on an SVGPathElement.
SVGPathElement.getPathSegAtLength, this library includes a polyfill for this method to ensure compatibility with existing codebases that rely on retrieving path segments at specific lengths.To use the polyfill, add pathseg.js to your server and include it in your HTML or SVG files using a <script> tag. This provides a drop-in replacement for the removed SVGPathSeg, SVGPathSegList, and getPathSegAtLength APIs.
<script src="pathseg.js"></script>SVGPathSegList interface provides a way to interact with the collection of segments that make up an SVG path. The polyfill implements this to ensure compatibility with browsers where the API was removed. It uses a MutationObserver to watch for changes to the path's d attribute and keep the list synchronized.The SVGPathSegList maintains a live connection to the SVGPathElement it belongs to.
MutationObserver to watch for changes to the element's d attribute. When the attribute changes, the list internalizes the new segments via _checkPathSynchronizedToList.appendItem, removeItem, or replaceItem), the list serializes its internal segments back into a path string and updates the element's d attribute using _writeListToPath.The polyfill restores the ability to create and manipulate path segments directly on an SVG path element. You can create relative or absolute segments (like createSVGPathSegMovetoRel) and append them to the pathSegList. Modifying the properties of a segment (e.g., x or y) will automatically update the path's d attribute.
var path = document.createElementNS("http://www.w3.org/2000/svg", "path");
var moveToSeg = path.createSVGPathSegMovetoRel(10, 10);
var lineToSeg = path.createSVGPathSegLinetoRel(100, 100);
path.pathSegList.appendItem(moveToSeg);
path.pathSegList.appendItem(lineToSeg);
console.log(path.getAttribute('d')); // m 10 10 l 100 100
// Mutating the segment updates the path attribute
moveToSeg.x += 200;
moveToSeg.y += 200;
console.log(path.getAttribute('d')); // m 210 210 l 100 100To determine how many segments are in an SVGPathSegList, use the numberOfItems property or the length property. Both properties are synchronized with the actual path data.
Note: The length property is provided for compatibility with Firefox 58 behavior.
const list = document.querySelector('path').pathSegList;
console.log(list.numberOfItems); // or list.lengthThe getPathSegAtLength(distance) method is added to SVGPathElement.prototype. It returns the index of the path segment that contains the specified distance along the path.
Parameters:
distance: A finite number representing the distance along the path.Throws:
distance is undefined or not finite.const path = document.querySelector('path');
const segmentIndex = path.getPathSegAtLength(50.5);You can access the list of path segments for an <svg> path element via the pathSegList property on the SVGPathElement prototype. This property returns an SVGPathSegList object representing the segments defined in the element's d attribute.
Note: The following properties are currently implemented as aliases to pathSegList and do not provide distinct functionality:
normalizedPathSegListanimatedPathSegListanimatedNormalizedPathSegListconst pathElement = document.querySelector('path');
const segments = pathElement.pathSegList;
console.log(segments.numberOfItems);The SVGPathSegList object allows you to programmatically modify the segments of an SVG path. Changes made to the list are automatically synchronized back to the element's d attribute.
| Method | Description |
|---|---|
getItem(index) | Returns the segment at the specified index. Throws INDEX_SIZE_ERR if the index is invalid. |
insertItemBefore(newItem, index) | Inserts a new segment before the specified index. If index is greater than numberOfItems, the item is appended to the end. |
replaceItem(newItem, index) | Replaces the segment at the specified index with newItem. |
removeItem(index) | Removes the segment at the specified index and returns it. |
appendItem(newItem) | Appends a new segment to the end of the list. |
clear() | Removes all segments from the list. |
initialize(newItem) | Clears the list and initializes it with a single newItem. |
const path = document.querySelector('path');
const list = path.pathSegList;
// Append a new segment
list.appendItem(new window.SVGPathSegLinetoAbs(list, 10, 10));
// Remove a segment
list.removeItem(0);
// Clear all segments
list.clear();The polyfill adds several createSVGPathSeg* methods to the SVGPathElement.prototype. These methods allow you to programmatically create new path segment objects that can be used to manipulate SVG paths.
Note: The polyfill implementation of these methods currently passes undefined as the owningPathSegList, which may affect synchronization with the parent path element depending on how you use them.
// Example of creating different segment types on an SVG path element
const path = document.querySelector('path');
const moveAbs = path.createSVGPathSegMovetoAbs(10, 20);
const lineAbs = path.createSVGPathSegLinetoAbs(50, 50);
const curveCubicAbs = path.createSVGPathSegCurvetoCubicAbs(100, 100, 120, 120, 150, 150);
const arcAbs = path.createSVGPathSegArcAbs(200, 200, 10, 10, 0, false, true);
const closePath = path.createSVGPathSegClosePath();The SVGPathSeg constructor provides several static constants used to identify the type of a path segment. These constants correspond to the different types of commands available in an SVG path data string.
window.SVGPathSeg.PATHSEG_UNKNOWN = 0;
window.SVGPathSeg.PATHSEG_CLOSEPATH = 1;
window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2;
window.SVGPathSeg.PATHSEG_MOVETO_REL = 3;
window.SVGPathSeg.PATHSEG_LINETO_ABS = 4;
window.SVGPathSeg.PATHSEG_LINETO_REL = 5;
window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6;
window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7;
window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8;
window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9;
window.SVGPathSeg.PATHSEG_ARC_ABS = 10;
window.SVGPathSeg.PATHSEG_ARC_REL = 11;
window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12;
window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13;
window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14;
window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15;
window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16;
window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17;
window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18;
window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19;The SVGPathSeg object defines constants used to identify the type of each segment. These are used during parsing and can be checked against segment types.
// Example constants used by the parser
window.SVGPathSeg.PATHSEG_MOVETO_ABS
window.SVGPathSeg.PATHSEG_MOVETO_REL
window.SVGPathSeg.PATHSEG_LINETO_ABS
window.SVGPathSeg.PATHSEG_LINETO_REL
window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS
window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL
window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS
window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL
window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS
window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL
window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS
window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL
window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS
window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL
window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS
window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL
window.SVGPathSeg.PATHSEG_ARC_ABS
window.SVGPathSeg.PATHSEG_ARC_REL
window.SVGPathSeg.PATHSEG_CLOSEPATH
window.SVGPathSeg.PATHSEG_UNKNOWN