pathseg

repository·master·Indexed 41 days ago

https://github.com/progers/pathseg

A 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.

Tokens
2.9K
Snippets
9
Records
12
Agent score
1%

What's inside pathseg

  1. Polyfill SVGPathElement.getPathSegAtLength

    master
    Because Blink (Chrome) is deprecating 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.
  2. Install the SVGPathSeg polyfill

    master

    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>
  3. SVGPathSegList Overview

    master
    The 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.
  4. How SVGPathSegList synchronizes with the DOM

    master

    The SVGPathSegList maintains a live connection to the SVGPathElement it belongs to.

    1. From DOM to List: The list uses a MutationObserver to watch for changes to the element's d attribute. When the attribute changes, the list internalizes the new segments via _checkPathSynchronizedToList.
    2. From List to DOM: Whenever a mutation method is called on the list (like appendItem, removeItem, or replaceItem), the list serializes its internal segments back into a path string and updates the element's d attribute using _writeListToPath.
  5. Use the SVGPathSeg and SVGPathSegList APIs

    master

    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 100
  6. Get the number of items in an SVGPathSegList

    master

    To 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.length
  7. Get path segment at a specific length

    master

    The 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:

    • Throws an error if distance is undefined or not finite.
    const path = document.querySelector('path');
    const segmentIndex = path.getPathSegAtLength(50.5);
  8. Access the pathSegList of an SVGPathElement

    master

    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:

    • normalizedPathSegList
    • animatedPathSegList
    • animatedNormalizedPathSegList
    const pathElement = document.querySelector('path');
    const segments = pathElement.pathSegList;
    console.log(segments.numberOfItems);
  9. Manipulate segments using SVGPathSegList

    master

    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.

    Available Methods

    MethodDescription
    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();
  10. Create SVG path segments via SVGPathElement

    master

    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();
  11. SVGPathSeg Constants

    master

    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;
  12. Reference: SVGPathSeg segment types

    master

    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