v136 · miscellaneous
Coordinate Transform Lab
The key challenge with isPointInFill, isPointInStroke, and getCharNumAtPosition accepting DOMPointInit: you must convert screen (viewport) coordinates to element-local coordinates first. This lab shows the transform math and lets you click SVG shapes to see the live conversion using plain {x, y} object literals.
checking isPointInFill(DOMPointInit)…
checking isPointInStroke(DOMPointInit)…
Before Chrome 136,
isPointInFill({x, y}) accepted an SVGPoint created via svg.createSVGPoint(). Chrome 136 upgrades to DOMPointInit, so you can pass a plain object literal {x: 50, y: 80}. The coordinates must be in the element's local coordinate system (after CTM inversion).
Click to hit-test
Click anywhere on the SVG to test hit detection.
Manual coordinate test
These are element-local coordinates (after group transform).
Hit-test results
Click on the SVG or use the manual test.
Coordinate conversion code (old vs new)
// OLD: createSVGPoint + matrix inverse
function hitTestOld(svgEl, element, screenX, screenY) {
const pt = svgEl.createSVGPoint();
pt.x = screenX;
pt.y = screenY;
const ctm = element.getScreenCTM();
const localPt = pt.matrixTransform(ctm.inverse());
return element.isPointInFill(localPt); // SVGPoint
}
// NEW (Chrome 136): DOMPointInit — plain object literal
function hitTestNew(element, screenX, screenY) {
const ctm = element.getScreenCTM();
const inv = ctm.inverse();
// Convert screen → local using DOMMatrix
const dm = new DOMMatrix([inv.a, inv.b, inv.c, inv.d, inv.e, inv.f]);
const local = dm.transformPoint({ x: screenX, y: screenY });
return element.isPointInFill({ x: local.x, y: local.y }); // DOMPointInit ✓
}
// isPointInStroke and getCharNumAtPosition work the same way:
element.isPointInStroke({ x: local.x, y: local.y });
textEl.getCharNumAtPosition({ x: local.x, y: local.y });