score:7

Accepted answer

think of a svg as a tree of nested coordinate systems. every element has its own coordinates, and is fitted into its parent with a rule how to re-calculate them. these rules can be explicit transform attributes, but also implicit combinations of width, height and viewbox ("fit box a in size b").

a transform attribute is considered to be the link to the parent element. that means, if you ask for a geometric property of an element, most of the times you get the value before the transform is applied. after it is applied would be asking for geometric values in the coordinate system of the parent.

because of this complexity there are several svg api functions to find out how these coordinate systems fit together. getpointatlength() gets you coordinates before applying the transform attribute.

var localpoint = path.node().getpointatlength(0)

first, you have to find out what the transform attribute does. this looks a bit complicated, partly because the attribute can be animated and can contain a list of functions, partly because the api is...well...:

// construct a neutral matrix
var localmatrix = path.node().viewportelement.createsvgmatrix()
var localtransformlist = path.node().transform.baseval
 // is there at least one entry?
if (localtransformlist.length) {
    // consolidate multiple entries into one
    localmatrix = localtransformlist.consolidate().matrix
}

you can then apply the found transformation to the point with

var transformedpoint = localpoint.matrixtransform(localmatrix)

there are several functions hat will return a svgmatrix to transform data from the coordinate system after application of the transform attribute (i. e. after the step above):

  • to ask for the transformation to the nearest viewport (in most cases the nearest parent <svg>) element: element.getctm()

  • to ask for the transformation to screen pixels: element.getscreenctm()

  • to ask for the transformation to an arbitrary element: element.gettransformtoelement(...)


Related Query