Start · Sprachen · JavaScript · Referenz · SVGTextContentElement.getExtentOfChar()

SVGTextContentElement.getExtentOfChar()

Methode

Gibt den eng anliegenden Begrenzungsrahmen (<code>DOMRect</code>) der Glyphe zurück, die zum Zeichen an der angegebenen Position gehört. Die Werte liegen im Nutzerkoordinatensystem des Elements.

seit JavaScript Baseline: alle Browser (SVG 1.1) Kategorie: webapi

Signatur

SVGTextContentElement.prototype.getExtentOfChar(index)

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

Typ
DOMRect
Beschreibung
Ein 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)}`);
x=27.3 y=18.2 w=13.4 h=27.6 (Werte hängen von der Schrift ab)

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 eine DOMException vom Typ IndexSizeError. Prüfen Sie den Bereich daher vorher.
  • Rendering erforderlich: Das Element muss im Dokument hängen und gerendert werden. Bei display: none oder vor dem Laden von Webfonts liefern Browser Nullwerte oder falsche Werte. Warten Sie gegebenenfalls auf document.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.