Start · Sprachen · JavaScript · Referenz · SVGPathElement.getPointAtLength()

SVGPathElement.getPointAtLength()

Methode

Gibt die Koordinaten des Punktes zurück, der in einer bestimmten Entfernung (in Benutzereinheiten) vom Startpunkt entlang eines SVG-Pfades liegt.

seit JavaScript Baseline: alle Browser (seit SVG 1.1; in SVG 2 auf Kategorie: webapi

Signatur

SVGPathElement.prototype.getPointAtLength(distance)

Beschreibung

getPointAtLength() berechnet, wo genau auf einem <path> man landet, wenn man vom Startpunkt aus eine bestimmte Strecke entlang der Pfadgeometrie geht. Das Ergebnis ist ein DOMPoint mit den Eigenschaften x und y im lokalen Benutzerkoordinatensystem des Elements.

Typische Einsatzzwecke sind Animationen entlang eines Pfades (z. B. ein Icon, das einer Kurve folgt), das gleichmäßige Verteilen von Markierungen auf einer Linie, das Abtasten (Sampling) komplexer Bézier-Kurven zu Polygonen sowie Kollisions- oder Nähe-Berechnungen. Zusammen mit getTotalLength() lässt sich die Position auch relativ angeben (z. B. „bei 30 % des Weges“).

Seit SVG 2 ist die Methode eigentlich auf SVGGeometryElement definiert, sodass sie auch für <circle>, <rect>, <line> usw. verfügbar ist. SVGPathElement erbt sie von dort.

Die Entfernung wird auf den Bereich 0 bis getTotalLength() begrenzt: Negative Werte liefern den Startpunkt, zu große Werte den Endpunkt. Transformationen (transform-Attribut, CSS-Transforms, viewBox) werden nicht eingerechnet.

Parameter

Name Typ Default Beschreibung
$distance Pflicht number Entfernung vom Startpunkt des Pfades in Benutzereinheiten. Werte kleiner 0 werden als 0, Werte größer als getTotalLength() als Gesamtlänge behandelt.

Rückgabewert

Typ
DOMPoint
Beschreibung
Ein DOMPoint (in älteren Implementierungen SVGPoint) mit den Koordinaten x und y des Punktes im lokalen Koordinatensystem des Pfades.

Beispiele

Mittelpunkt eines Pfades bestimmen

const ns = 'http://www.w3.org/2000/svg';
const svg = document.createElementNS(ns, 'svg');
const path = document.createElementNS(ns, 'path');
path.setAttribute('d', 'M 0 0 L 100 0 L 100 100');
svg.append(path);
document.body.append(svg);

const total = path.getTotalLength(); // 200
const mitte = path.getPointAtLength(total / 2);
console.log(total, mitte.x, mitte.y);

// Werte außerhalb des Bereichs werden begrenzt
const ende = path.getPointAtLength(9999);
console.log(ende.x, ende.y);
200 100 0 100 100

Kreis entlang eines Pfades animieren

// Annahme: <svg><path id="bahn" d="M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80" fill="none" stroke="#999"/>
//          <circle id="ball" r="5" fill="crimson"/></svg>
const bahn = document.getElementById('bahn');
const ball = document.getElementById('ball');
const laenge = bahn.getTotalLength();
const dauer = 3000; // ms

const schritt = (zeit) => {
  const fortschritt = (zeit % dauer) / dauer; // 0..1
  const { x, y } = bahn.getPointAtLength(fortschritt * laenge);
  ball.setAttribute('cx', x);
  ball.setAttribute('cy', y);
  requestAnimationFrame(schritt);
};
requestAnimationFrame(schritt);

Pfad abtasten und Tangentenwinkel berechnen

const samplePath = (path, anzahl) => {
  const laenge = path.getTotalLength();
  return Array.from({ length: anzahl }, (_, i) => {
    const d = (i / (anzahl - 1)) * laenge;
    const p = path.getPointAtLength(d);
    // Nachbarpunkt für die Richtung (Tangente)
    const q = path.getPointAtLength(Math.min(d + 0.5, laenge));
    const r = path.getPointAtLength(Math.max(d - 0.5, 0));
    const winkel = Math.atan2(q.y - r.y, q.x - r.x) * 180 / Math.PI;
    return { x: +p.x.toFixed(1), y: +p.y.toFixed(1), winkel: Math.round(winkel) };
  });
};

const ns = 'http://www.w3.org/2000/svg';
const path = document.createElementNS(ns, 'path');
path.setAttribute('d', 'M 0 0 L 100 0 L 100 100');
const svg = document.createElementNS(ns, 'svg');
svg.append(path);
document.body.append(svg);

console.log(samplePath(path, 3));
[{x: 0, y: 0, winkel: 0}, {x: 100, y: 0, winkel: 45}, {x: 100, y: 100, winkel: 90}]

// Wichtig · Fallstricke

  • Keine Transformationen: Der Punkt liegt im lokalen Koordinatensystem des Pfades. Liegt ein transform auf dem Pfad oder einem Elternelement, rechnet man mit point.matrixTransform(path.getCTM()) bzw. getScreenCTM() in SVG- oder Bildschirmkoordinaten um.
  • pathLength-Attribut: Die Entfernung wird in echten Benutzereinheiten angegeben. Ein gesetztes pathLength wird von aktuellen Browsern hier nicht berücksichtigt; es wirkt sich nur auf Strich-Berechnungen wie stroke-dasharray aus.
  • Leere oder ungültige Pfade: Ohne gültiges d-Attribut können manche Browser eine InvalidStateError-Ausnahme werfen oder (0, 0) zurückgeben. Vorher getTotalLength() > 0 prüfen.
  • Performance: Jeder Aufruf kostet bei komplexen Bézier-Kurven Rechenzeit. Für viele Aufrufe pro Frame die Gesamtlänge und abgetastete Punkte zwischenspeichern.
  • Kompatibilität: Wird von allen modernen Browsern unterstützt. Ältere Browser liefern ein SVGPoint statt eines DOMPoint – der Zugriff über x/y funktioniert in beiden Fällen. Für andere Formen als <path> (über SVGGeometryElement) ist die Unterstützung in älteren Versionen lückenhaft.