Convert Mouse Events to SVG with Matrix Inversion

Converting client mouse events into local SVG coordinates involves mapping a point from the browser’s viewport coordinate space into an SVG element’s internal coordinate system using matrix inversion. Because SVG elements can be scaled, rotated, translated, and dynamically fitted using the viewBox attribute, raw screen coordinates (clientX, clientY) do not match local SVG units. By taking the element’s Current Transformation Matrix (CTM) and computing its mathematical inverse, you create an inverted transformation pipeline that translates raw viewport pixels directly into the element’s local coordinate space.

The Coordinate Space Mismatch

When a user interacts with a web page, the browser reports pointer coordinates relative to the visible viewport via properties like event.clientX and event.clientY. These values are measured in standard screen pixels starting from the top-left corner of the browser window.

An SVG graphic, however, exists in its own abstract coordinate space defined by the viewBox attribute, nested <g> container transforms, and CSS styling. The transformation from an SVG’s internal units to screen pixels is represented as an affine transformation matrix—specifically, the Screen Current Transformation Matrix (Screen CTM).

The Role of the Current Transformation Matrix (CTM)

The Screen CTM encapsulates every operation applied to the SVG element, including:

Mathematically, the forward transformation maps a local SVG point \((X_{svg}, Y_{svg})\) to a screen coordinate \((X_{screen}, Y_{screen})\):

\[P_{screen} = M \times P_{svg}\]

where \(M\) is the \(3 \times 3\) affine transformation matrix representing the element’s CTM.

Why Inversion is Required

To map a mouse click back into the SVG space, the process must be reversed. You start with the known screen point \(P_{screen}\) and must solve for \(P_{svg}\).

By calculating the inverse of the matrix \(M\) (denoted as \(M^{-1}\)), the equation becomes:

\[P_{svg} = M^{-1} \times P_{screen}\]

Matrix inversion mathematically undoes every transformation in reverse order: - Translations are subtracted rather than added. - Scale factors are divided rather than multiplied. - Rotations are applied in the opposite angular direction.

The Conversion Process in Practice

The browser DOM provides built-in methods to perform this transformation efficiently without requiring manual matrix math.

  1. Capture Screen Coordinates: When a mouse event occurs, extract event.clientX and event.clientY.
  2. Create an SVG Point: Instantiate a DOMPoint (or SVGPoint in older APIs) using the captured coordinates.
  3. Retrieve the Screen CTM: Call element.getScreenCTM() on the target SVG element. This returns a DOMMatrix representing the forward transformation from the element’s local space to the viewport.
  4. Invert the Matrix: Call the .inverse() method on the matrix object to obtain \(M^{-1}\).
  5. Apply the Transformation: Pass the inverted matrix to point.matrixTransform(invertedMatrix).

The resulting point object contains the exact \(x\) and \(y\) values corresponding to the target SVG element’s internal coordinate system, regardless of zoom level, viewport resizing, or complex transforms.