Signatur
Beschreibung
getExtentOfChar() misst ein einzelnes Zeichen innerhalb eines SVG-Textelements wie <text>, <tspan> oder <textPath>. Sie erhalten ein DOMRect mit x, y, width und height. Die Werte gelten im Nutzerkoordinatensystem des Textelements, also vor Transformationen durch Vorfahren-Elemente.
Der Rahmen reicht horizontal vom Anfangs- bis zum Endpunkt des Vorschubs der Glyphe (advance). Vertikal umfasst er die Zelle der Schrift, also Oberlänge und Unterlänge, nicht nur die tatsächlich sichtbare Tinte. Wurde das Zeichen gedreht, etwa über das Attribut rotate oder durch einen <textPath>, ergibt sich der Rahmen aus dem gedrehten Zeichen. Er bleibt dabei achsenparallel und umschließt die gedrehte Glyphe.
Typische Einsatzfälle:
- einzelne Buchstaben hervorheben (z. B. Suchtreffer oder Cursor-Position in einem SVG-Editor),
- Hintergrund-Rechtecke oder Unterstreichungen zeichnen,
- Trefferprüfung auf Zeichenebene, oft zusammen mit
getCharNumAtPosition().
Der Index zählt in UTF-16-Codeeinheiten, wie String.prototype.length, und nicht in sichtbaren Zeichen (Graphemen).
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $index Pflicht | number | Nullbasierter Index des Zeichens in UTF-16-Codeeinheiten. Muss zwischen 0 und getNumberOfChars() - 1 liegen. |
Rückgabewert
DOMRect (in älteren Implementierungen ein SVGRect) mit x, y, width und height der Glyphe im Nutzerkoordinatensystem des Elements.Beispiele
Rahmen eines einzelnen Zeichens auslesen
// <svg><text id="label" x="10" y="40" font-size="24">Hallo</text></svg>
const text = document.querySelector('#label');
const box = text.getExtentOfChar(1); // das "a"
console.log(`x=${box.x.toFixed(1)} y=${box.y.toFixed(1)} w=${box.width.toFixed(1)} h=${box.height.toFixed(1)}`);
Alle Vorkommen eines Buchstabens farbig hinterlegen
const SVG_NS = 'http://www.w3.org/2000/svg';
const highlightChar = (textEl, char) => {
const content = textEl.textContent;
for (let i = 0; i < textEl.getNumberOfChars(); i++) {
if (content[i] !== char) continue;
const { x, y, width, height } = textEl.getExtentOfChar(i);
const rect = document.createElementNS(SVG_NS, 'rect');
Object.entries({ x, y, width, height, fill: 'gold' })
.forEach(([k, v]) => rect.setAttribute(k, v));
// Rechteck hinter den Text legen
textEl.parentNode.insertBefore(rect, textEl);
}
};
highlightChar(document.querySelector('#label'), 'l');
Zeichen unter dem Mauszeiger ermitteln und markieren
const svg = document.querySelector('svg');
const text = svg.querySelector('text');
const marker = svg.querySelector('#marker'); // vorhandenes <rect>
text.addEventListener('mousemove', (event) => {
// Bildschirmkoordinaten in Nutzerkoordinaten des Textes umrechnen
const pt = new DOMPoint(event.clientX, event.clientY)
.matrixTransform(text.getScreenCTM().inverse());
const index = text.getCharNumAtPosition(pt);
if (index < 0) return;
const box = text.getExtentOfChar(index);
marker.setAttribute('x', box.x);
marker.setAttribute('y', box.y);
marker.setAttribute('width', box.width);
marker.setAttribute('height', box.height);
});
// Wichtig · Fallstricke
- Ungültiger Index: Ein negativer Index oder ein Index ≥
getNumberOfChars()wirft eineDOMExceptionvom TypIndexSizeError. Prüfen Sie den Bereich daher vorher. - Rendering erforderlich: Das Element muss im Dokument hängen und gerendert werden. Bei
display: noneoder vor dem Laden von Webfonts liefern Browser Nullwerte oder falsche Werte. Warten Sie gegebenenfalls aufdocument.fonts.ready. - Koordinatensystem: Transformationen des Elements selbst und seiner Vorfahren fließen nicht ein. Für Bildschirmkoordinaten rechnen Sie mit
getScreenCTM()um. - Unicode: Emojis und Zeichen außerhalb der Basic Multilingual Plane belegen zwei Indizes (Surrogatpaar). Ligaturen können mehrere Zeichen auf eine Glyphe abbilden. Die Ergebnisse unterscheiden sich dann je nach Browser.
- Kompatibilität: Die Methode wird in allen modernen Browsern unterstützt. Die genauen Rahmenmaße (vor allem die Höhe) können sich zwischen Chrome, Firefox und Safari leicht unterscheiden.