Signatur
Beschreibung
isPointInStroke() ist auf allen SVG-Geometrie-Elementen verfügbar, also z. B. <path>, <circle>, <rect>, <line>, <polyline> und <polygon>. Die Methode gibt true zurück, wenn der übergebene Punkt auf dem gezeichneten Umriss liegt. Dabei berücksichtigt der Browser die Umriss-Eigenschaften wie stroke-width, stroke-linecap, stroke-linejoin und stroke-miterlimit.
Typische Einsatzfälle sind eine präzise Trefferprüfung für dünne Linien und Pfade (z. B. in Diagramm-Editoren, Zeichenwerkzeugen oder Karten), eine eigene Kollisionserkennung oder die Frage, ob ein Klick eine Kante und nicht die Fläche getroffen hat. Für die Füllfläche gibt es die Schwestermethode isPointInFill().
Wichtig: Der Punkt wird im lokalen Benutzerkoordinatensystem des Elements angegeben, nicht in Bildschirm- oder Seitenkoordinaten. Mauskoordinaten wie clientX/clientY musst du deshalb vorher mit der inversen Matrix aus getScreenCTM() umrechnen. Eigenschaften wie pointer-events, visibility oder display haben auf das Ergebnis keinen Einfluss – es wird rein geometrisch gerechnet.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $point Pflicht | DOMPointInit | DOMPoint | SVGPoint | Der zu prüfende Punkt mit x- und y-Koordinate im lokalen Koordinatensystem des Elements. Ein einfaches Objekt wie { x: 10, y: 20 } genügt in modernen Browsern; fehlende Werte gelten als 0. |
Rückgabewert
true, wenn der Punkt innerhalb der Umrissform liegt, sonst false.Beispiele
Einfache Prüfung an einem Kreis
const svgNS = 'http://www.w3.org/2000/svg';
const svg = document.createElementNS(svgNS, 'svg');
svg.setAttribute('width', '200');
svg.setAttribute('height', '200');
const circle = document.createElementNS(svgNS, 'circle');
circle.setAttribute('cx', '100');
circle.setAttribute('cy', '100');
circle.setAttribute('r', '50');
circle.setAttribute('fill', 'none');
circle.setAttribute('stroke', 'black');
circle.setAttribute('stroke-width', '10');
svg.append(circle);
document.body.append(svg);
// Umriss reicht von Radius 45 bis 55
console.log(circle.isPointInStroke({ x: 100, y: 100 })); // Mittelpunkt
console.log(circle.isPointInStroke({ x: 150, y: 100 })); // genau auf der Linie
console.log(circle.isPointInStroke({ x: 154, y: 100 })); // noch im 10px-Umriss
console.log(circle.isPointInStroke({ x: 160, y: 100 })); // außerhalb
Mausposition auf einem Pfad erkennen (mit Koordinatenumrechnung)
// HTML: <svg id="chart" viewBox="0 0 400 200"><path id="kurve" d="M10 150 Q 200 0 390 150" fill="none" stroke="steelblue" stroke-width="8"/></svg>
const svg = document.querySelector('#chart');
const path = document.querySelector('#kurve');
const toLocal = (element, clientX, clientY) => {
const matrix = element.getScreenCTM()?.inverse();
if (!matrix) return null;
return new DOMPoint(clientX, clientY).matrixTransform(matrix);
};
svg.addEventListener('pointermove', (event) => {
const point = toLocal(path, event.clientX, event.clientY);
const hit = point !== null && path.isPointInStroke(point);
path.setAttribute('stroke', hit ? 'tomato' : 'steelblue');
svg.style.cursor = hit ? 'pointer' : 'default';
});
Kanten- oder Flächentreffer unterscheiden
const rect = document.querySelector('rect'); // z. B. fill="#eee" stroke="#333" stroke-width="6"
const classifyHit = (element, point) => {
if (element.isPointInStroke(point)) return 'Kante';
if (element.isPointInFill(point)) return 'Fläche';
return 'daneben';
};
rect.ownerSVGElement.addEventListener('click', (event) => {
const matrix = rect.getScreenCTM().inverse();
const point = new DOMPoint(event.clientX, event.clientY).matrixTransform(matrix);
console.log(`Treffer: ${classifyHit(rect, point)}`);
});
Kompatibler Aufruf für ältere Browser mit SVGPoint
const isOnStroke = (element, x, y) => {
try {
// Moderne Browser: einfaches Objekt reicht
return element.isPointInStroke({ x, y });
} catch {
// Ältere Engines verlangen ein echtes SVGPoint
const pt = element.ownerSVGElement.createSVGPoint();
pt.x = x;
pt.y = y;
return element.isPointInStroke(pt);
}
};
const line = document.querySelector('line');
console.log(isOnStroke(line, 50, 50));
// Wichtig · Fallstricke
- Koordinatensystem: Der Punkt muss in lokalen Benutzerkoordinaten des Elements angegeben werden. Wer direkt
clientX/clientYübergibt, bekommt beiviewBox, Skalierung,transformoder Scrollen falsche Ergebnisse. Rechne deshalb mitgetScreenCTM().inverse()undDOMPoint.matrixTransform()um. - Kein Umriss nötig: Die Methode wertet die berechneten Umriss-Eigenschaften aus. Bei
stroke-width: 0ist das Ergebnis immerfalse. Obstrokegesetzt ist (none) odervisibility/pointer-eventsgesetzt sind, spielt dagegen keine Rolle. - Gestrichelte Linien: Wie
stroke-dasharraybehandelt wird, war lange uneinheitlich zwischen den Browsern. Verlasse dich bei gestrichelten Linien nicht auf pixelgenaue Treffer in den Lücken. - Nicht gerenderte Elemente: Elemente mit
display: noneoder außerhalb des Dokuments können je nach Browserfalseliefern, weil keine Layoutdaten vorhanden sind. - Kompatibilität: Ältere Firefox- (vor Version 69) und Safari-Versionen verlangen ein
SVGPointauscreateSVGPoint()statt eines einfachen Objekts. Moderne Browser akzeptierenDOMPointInit. Der Internet Explorer unterstützt die Methode nicht. - Leistung: Bei sehr vielen Elementen und häufigen
pointermove-Ereignissen kann die Prüfung teuer werden. Grenze die Kandidaten vorher übergetBBox()ein oder drossle die Abfrage mitrequestAnimationFrame.