javascriptsvghtml5-canvaspath-2d

Recovering elements of a Javascript Path2D


I want to examine the individual path segments of a Path2D object. For example, suppose that

path = new Path2D();
path.ellipse(70,90,2,2,0,0,2*Math.PI);

I want to pass path to some other function and pull out the elements of the Path2D so that they can be translated into another format. The big picture goal is to allow the user to create a path and translate it to TikZ for inclusion in a LaTeX document.

Is there something like Java's Shape.getPathIterator(), which allows one to examine each segment along a path. Can this be done Javascript? As a template, here is an outline of the Java code that does what I'm hoping to do in Javascript.

PathIterator p = path.getPathIterator(new AffineTransform());
while (p.isDone() == false)
  {
    double c = new double[6];
    int t = p.currentSegment(c);
    if (t == PathIterator.SEG_MOVETO)
      // (c[0],c[1]) is the "move-to" point.
    else if (t == PathIterator.SEG_LINETO)
      // (c[0],c[1]) is the "line-to" point.
    else if (t == == PathIterator.SEG_CUBICTO)
      // c[0] through c[5] specify the cubic curve
    else
      // etc., etc.
  }

Editing this after seeing @Kaiido's answer. What I ended up doing was extending Path2D to a new class that is functionally identical, except that it stores each call to arc(), lineTo(), etc. to an array as the call is made. This allows me to examine the record of past calls. It may not be a sufficiently general solution for everyone, but it works for my needs.


Solution

  • No there is currently nothing in the API that allows us to do that.
    There are some discussions to extend the Path2D API so it's less "opaque", but nothing tangible yet, I don't think anyone is actively working on it, and we can't be sure what it will include.
    The current proposal reads

    Path2D Inspection. Allow inspection of Path2D objects, that are currently opaque.

    For what it's worth, I myself started working on this idea a few months ago, in the hope I could help this discussion get started somehow with a possible feature design.
    My very ambitious idea is to bring an API like SVG's SVGPathData and add methods to Path2D like getBBox, getPathData(), setPathData(), toSVGString(), getTotalLength(), or getPointAtLength().

    You can check this repository where lives my project, and below is a demo using your input.

    const path = new Path2D();
    path.ellipse(70,90,50,20,0,0,2*Math.PI);
    
    const svgString = path.toSVGString();
    document.querySelector("pre").textContent += svgString;
    document.querySelector("path").setAttribute("d", svgString);
    document.querySelector("canvas").getContext("2d").fill(path);
    <script src="https://cdn.jsdelivr.net/gh/Kaiido/path2D-inspection@master/build/path2D-inspection.min.js"></script>
    <pre>
    const path = new Path2D();
    path.ellipse(70,90,50,20,0,0,2*Math.PI);
    path.toSVGString();
    
    </pre>
    SVG:<br>
    <svg><path fill="green"></path></svg><br>
    Canvas:<br>
    <canvas></canvas>