Start · Sprachen · JavaScript · Referenz · CanvasRenderingContext2D.isPointInStroke()

CanvasRenderingContext2D.isPointInStroke()

Methode

Prüft, ob ein Punkt auf der Kontur (Linie) des aktuellen oder eines übergebenen <code>Path2D</code>-Pfads liegt – unter Berücksichtigung von Linienbreite, Linienenden und Verbindungen.

seit JavaScript Baseline: alle modernen Browser (Path2D-Variante s Kategorie: webapi

Signatur

CanvasRenderingContext2D.prototype.isPointInStroke(path?, x, y)

Beschreibung

isPointInStroke() beantwortet die Frage, ob ein Punkt auf der gezeichneten Linie eines Pfads liegt, also in der Fläche, die ein stroke() einfärben würde. Maßgeblich sind dabei die aktuellen Linieneinstellungen des Kontexts: lineWidth, lineCap, lineJoin, miterLimit und das mit setLineDash() gesetzte Strichmuster.

Typische Einsatzgebiete sind Treffertests (Hit-Testing) in interaktiven Zeichnungen: Linien, Kurven, Diagrammlinien oder Umrisse per Maus anklicken oder hervorheben, ohne die Geometrie selbst berechnen zu müssen. Im Gegensatz zu isPointInPath(), das die gefüllte Innenfläche prüft, betrachtet isPointInStroke() nur den Randstrich.

Ohne path-Argument wird der aktuelle Pfad des Kontexts geprüft (der mit beginPath(), moveTo(), lineTo() usw. aufgebaut wurde). Wird ein Path2D-Objekt übergeben, prüft die Methode dieses – ideal, wenn mehrere Formen gespeichert und unabhängig voneinander getestet werden sollen.

Die Koordinaten x und y werden im unveränderten Canvas-Koordinatensystem (Pixel des Canvas-Bitmaps) angegeben; die aktuelle Transformation wird auf den Pfad angewendet, nicht auf den Punkt.

Parameter

Name Typ Default Beschreibung
$path Path2D aktueller Pfad Optionaler Path2D-Pfad, der geprüft werden soll. Fehlt er, wird der aktuelle Pfad des Kontexts verwendet.
$x Pflicht number Horizontale Koordinate des zu prüfenden Punkts im Canvas-Bitmap (nicht transformiert).
$y Pflicht number Vertikale Koordinate des zu prüfenden Punkts im Canvas-Bitmap (nicht transformiert).

Rückgabewert

Typ
boolean
Beschreibung
true, wenn der Punkt innerhalb der Konturfläche des Pfads liegt, sonst false. Bei nicht-endlichen Koordinaten (NaN, Infinity) immer false.

Beispiele

Einfacher Test am aktuellen Pfad

const canvas = document.createElement('canvas');
canvas.width = 200;
canvas.height = 100;
const ctx = canvas.getContext('2d');

ctx.beginPath();
ctx.rect(20, 20, 150, 60);
ctx.lineWidth = 10;
ctx.stroke();

// Punkt direkt auf dem Rand (x = 20 ± 5)
console.log(ctx.isPointInStroke(22, 50));
// Punkt in der Mitte – innen, aber nicht auf der Linie
console.log(ctx.isPointInStroke(90, 50));
true false

Linie per Mausklick auswählen (Path2D + Mauskoordinaten)

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

const curve = new Path2D();
curve.moveTo(30, 150);
curve.bezierCurveTo(100, 20, 200, 280, 300, 60);

const draw = (highlight = false) => {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.lineWidth = 12; // großzügige Trefferfläche
  ctx.strokeStyle = highlight ? 'crimson' : 'steelblue';
  ctx.stroke(curve);
};

canvas.addEventListener('mousemove', (event) => {
  const rect = canvas.getBoundingClientRect();
  // CSS-Pixel in Canvas-Pixel umrechnen
  const x = (event.clientX - rect.left) * (canvas.width / rect.width);
  const y = (event.clientY - rect.top) * (canvas.height / rect.height);
  draw(ctx.isPointInStroke(curve, x, y));
});

draw();

Unsichtbar breitere Trefferzone für dünne Linien

const ctx = document.createElement('canvas').getContext('2d');
const line = new Path2D('M 10 10 L 190 10');

const hitTest = (x, y, tolerance = 8) => {
  ctx.save();
  ctx.lineWidth = tolerance * 2; // nur für den Test, nicht zum Zeichnen
  const hit = ctx.isPointInStroke(line, x, y);
  ctx.restore();
  return hit;
};

console.log(hitTest(100, 15)); // 5 px daneben
console.log(hitTest(100, 30)); // 20 px daneben
true false

// Wichtig · Fallstricke

  • Linieneinstellungen zählen: Das Ergebnis hängt vom aktuellen Zustand ab (lineWidth, lineCap, lineJoin, setLineDash()). Wurden sie nach dem Zeichnen geändert, stimmt der Test nicht mehr mit der sichtbaren Linie überein – ggf. mit save()/restore() arbeiten.
  • Koordinatensystem: Mausereignisse liefern CSS-Pixel. Bei skalierten Canvas-Elementen oder HiDPI (devicePixelRatio) müssen die Koordinaten auf die Bitmap-Größe umgerechnet werden, sonst liegen Treffer daneben.
  • Transformationen: Die Transformation (translate(), scale() …) gilt für den Pfad zum Prüfzeitpunkt – nicht für den Punkt. Der Punkt wird immer in unveränderten Canvas-Koordinaten angegeben.
  • Sehr dünne Linien (1 px) sind schwer zu treffen; für bessere Bedienbarkeit eine größere lineWidth nur für den Test verwenden.
  • Kompatibilität: In allen modernen Browsern verfügbar, auch in OffscreenCanvasRenderingContext2D (Worker). Die Variante mit Path2D-Argument fehlt in sehr alten Browsern und im Internet Explorer.
  • Performance: Bei vielen Formen pro mousemove vorab per Bounding-Box filtern, bevor isPointInStroke() aufgerufen wird.