Signatur
Beschreibung
getStartPositionOfChar() liefert die Startposition eines typografischen Zeichens in einem SVG-Textelement wie <text>, <tspan> oder <textPath>. Die Position wird erst nach dem Layout berechnet. Deshalb sind Attribute wie x, y, dx, dy, rotate, letter-spacing, Kerning und ein Textpfad bereits eingerechnet.
Der zurückgegebene Punkt ist der Glyphen-Ursprung, also in der Regel der Punkt auf der Grundlinie an der Vorderkante des Zeichens. Bei Text von links nach rechts ist das die linke Kante, bei Text von rechts nach links die rechte. Die Koordinaten beziehen sich auf das Benutzerkoordinatensystem des Elements. Transformationen des Elements selbst sind also nicht eingerechnet.
Typische Einsatzfälle sind: Markierungen oder Cursor-Positionen über einzelnen Zeichen, eigene Textauswahl in SVG-Editoren, Animationen einzelner Buchstaben entlang eines Pfads und das Ausrichten grafischer Elemente an bestimmten Zeichen. Zusammen mit getEndPositionOfChar() und getExtentOfChar() lässt sich die Geometrie jedes Zeichens vollständig ermitteln.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $index Pflicht | number | Index des Zeichens (in UTF-16-Codeeinheiten) innerhalb des Textinhalts des Elements, beginnend bei 0. Er muss kleiner als getNumberOfChars() sein. |
Rückgabewert
DOMPoint (in älteren Implementierungen SVGPoint) mit den Eigenschaften x und y für die Startposition des Zeichens im Benutzerkoordinatensystem des Elements.Beispiele
Startposition eines Zeichens ermitteln
const svgNS = 'http://www.w3.org/2000/svg';
const svg = document.createElementNS(svgNS, 'svg');
svg.setAttribute('width', '300');
svg.setAttribute('height', '100');
const text = document.createElementNS(svgNS, 'text');
text.setAttribute('x', '10');
text.setAttribute('y', '50');
text.textContent = 'Hallo SVG';
svg.append(text);
document.body.append(svg);
// Layout ist nach dem Einfügen ins DOM verfügbar
const p = text.getStartPositionOfChar(0);
console.log(p.x, p.y);
Senkrechte Markierungen vor jedem Buchstaben zeichnen
const svgNS = 'http://www.w3.org/2000/svg';
const text = document.querySelector('svg text');
const svg = text.ownerSVGElement;
for (let i = 0; i < text.getNumberOfChars(); i++) {
const { x, y } = text.getStartPositionOfChar(i);
const line = document.createElementNS(svgNS, 'line');
line.setAttribute('x1', x);
line.setAttribute('y1', y - 20);
line.setAttribute('x2', x);
line.setAttribute('y2', y + 4);
line.setAttribute('stroke', 'tomato');
svg.append(line);
}
Zeichenbreite aus Start- und Endposition berechnen
const text = document.querySelector('svg text');
const charWidth = (el, i) => {
const start = el.getStartPositionOfChar(i);
const end = el.getEndPositionOfChar(i);
return Math.hypot(end.x - start.x, end.y - start.y);
};
console.log(`Breite von Zeichen 2: ${charWidth(text, 2).toFixed(2)} px`);
Ungültigen Index abfangen
const text = document.querySelector('svg text');
try {
text.getStartPositionOfChar(text.getNumberOfChars());
} catch (err) {
console.log(err.name);
}
// Wichtig · Fallstricke
- Ungültiger Index: Ist
indexnegativ oder größer oder gleichgetNumberOfChars(), wird einDOMExceptionvom TypIndexSizeErrorgeworfen. - Kein Layout, kein Ergebnis: Ist das Element nicht im Dokument oder nicht gerendert (z. B.
display: none), liefern Browser0/0oder werfen einen Fehler. Deshalb erst nach dem Einfügen und Rendern abfragen und nach dem Laden von Webfonts erneut messen (document.fonts.ready). - Koordinatensystem: Der Punkt liegt im lokalen Benutzerraum. Für Bildschirmkoordinaten muss er mit
getScreenCTM()transformiert werden:new DOMPoint(p.x, p.y).matrixTransform(text.getScreenCTM()). - Index in UTF-16: Zeichen außerhalb der BMP (z. B. Emoji) belegen zwei Indizes. Bei Ligaturen können mehrere Zeichen dieselbe Position haben.
- Leistung: Jeder Aufruf kann eine Layout-Berechnung erzwingen. Bei vielen Zeichen besser nicht abwechselnd lesen und das DOM verändern.
- Kompatibilität: Wird von allen modernen Browsern unterstützt. Ältere Browser geben ein
SVGPointstatt einesDOMPointzurück. Die Nutzung vonx/yfunktioniert in beiden Fällen.