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

CanvasRenderingContext2D.measureText()

Methode

Misst einen Text mit den aktuellen Schrifteinstellungen des Canvas-Kontexts und gibt ein <code>TextMetrics</code>-Objekt mit Breite und Ausdehnungen zurück.

seit JavaScript Baseline: alle Browser (erweiterte TextMetrics-Eig Kategorie: webapi

Signatur

CanvasRenderingContext2D.prototype.measureText(text)

Beschreibung

measureText() berechnet, wie viel Platz ein Text einnehmen würde, wenn er mit den aktuellen Einstellungen des Kontexts (font, textAlign, textBaseline, direction, letterSpacing usw.) gezeichnet würde. Dabei wird nichts auf das Canvas gezeichnet – die Methode liefert nur Messwerte.

Das zurückgegebene TextMetrics-Objekt enthält neben width (der Vorschubbreite) auch genauere Werte wie actualBoundingBoxLeft, actualBoundingBoxRight, actualBoundingBoxAscent und actualBoundingBoxDescent (die tatsächliche Ausdehnung der Glyphen) sowie fontBoundingBoxAscent/fontBoundingBoxDescent (die Metriken der Schriftart unabhängig vom konkreten Text).

Typische Einsatzzwecke sind das Zentrieren oder Rechtsbündig-Ausrichten von Beschriftungen, automatischer Zeilenumbruch in Diagrammen und Spielen, das Kürzen zu langer Texte mit Auslassungszeichen sowie das Zeichnen passgenauer Hintergrundboxen hinter Text.

Parameter

Name Typ Default Beschreibung
$text Pflicht string Der zu messende Text. Nicht-String-Werte werden in einen String umgewandelt.

Rückgabewert

Typ
TextMetrics
Beschreibung
Ein TextMetrics-Objekt mit schreibgeschützten Eigenschaften wie width, actualBoundingBoxLeft/Right/Ascent/Descent, fontBoundingBoxAscent/Descent sowie (je nach Browser) emHeightAscent/Descent, hangingBaseline, alphabeticBaseline und ideographicBaseline. Alle Werte in CSS-Pixeln.

Beispiele

Textbreite ermitteln

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

ctx.font = '16px sans-serif';
const metrics = ctx.measureText('Hallo Welt');
console.log(`Breite: ${metrics.width.toFixed(1)} px`);
Breite: 77.6 px (Wert abhängig von Schrift und Browser)

Passende Hintergrundbox hinter ein Label zeichnen

const ctx = document.querySelector('canvas').getContext('2d');
const label = 'Umsatz 2024';
const x = 40, y = 60, padding = 6;

ctx.font = 'bold 20px system-ui';
ctx.textBaseline = 'alphabetic';
const m = ctx.measureText(label);

const ascent = m.actualBoundingBoxAscent;
const descent = m.actualBoundingBoxDescent;

// Box exakt um die sichtbaren Glyphen
ctx.fillStyle = '#ffe08a';
ctx.fillRect(
  x - m.actualBoundingBoxLeft - padding,
  y - ascent - padding,
  m.actualBoundingBoxLeft + m.actualBoundingBoxRight + padding * 2,
  ascent + descent + padding * 2
);

ctx.fillStyle = '#222';
ctx.fillText(label, x, y);

Automatischer Zeilenumbruch

const wrapText = (ctx, text, maxWidth) => {
  const words = text.split(' ');
  const lines = [];
  let line = '';
  for (const word of words) {
    const test = line ? `${line} ${word}` : word;
    if (ctx.measureText(test).width > maxWidth && line) {
      lines.push(line);
      line = word;
    } else {
      line = test;
    }
  }
  if (line) lines.push(line);
  return lines;
};

const ctx = document.querySelector('canvas').getContext('2d');
ctx.font = '14px sans-serif';
const lines = wrapText(ctx, 'Canvas kennt keinen eingebauten Zeilenumbruch, daher messen wir selbst.', 150);
lines.forEach((l, i) => ctx.fillText(l, 10, 20 + i * 18));
console.log(lines.length);
4 (abhängig von der Schrift)

Zu langen Text mit Auslassungszeichen kürzen

const truncate = (ctx, text, maxWidth) => {
  if (ctx.measureText(text).width <= maxWidth) return text;
  let t = text;
  while (t.length && ctx.measureText(t + '…').width > maxWidth) {
    t = t.slice(0, -1);
  }
  return t + '…';
};

const ctx = document.querySelector('canvas').getContext('2d');
ctx.font = '14px sans-serif';
console.log(truncate(ctx, 'Ein sehr langer Dateiname.pdf', 100));
Ein sehr langer …

// Wichtig · Fallstricke

  • Reihenfolge beachten: ctx.font (und ggf. letterSpacing) muss vor dem Messen gesetzt werden, sonst wird mit der Standardschrift 10px sans-serif gemessen.
  • Webfonts: Ist eine Schrift noch nicht geladen, misst der Browser mit der Ersatzschrift. Vorher await document.fonts.load('16px MeineSchrift') oder document.fonts.ready abwarten.
  • width ist die Vorschubbreite, nicht die sichtbare Ausdehnung. Kursive oder überhängende Glyphen können darüber hinausragen – für exakte Boxen actualBoundingBoxLeft + actualBoundingBoxRight verwenden.
  • Die Methode berücksichtigt keine Zeilenumbrüche (\n); mehrzeiliger Text muss selbst aufgeteilt werden.
  • ctx.scale() und andere Transformationen fließen nicht in die Messwerte ein.
  • Kompatibilität: width wird überall unterstützt; die Bounding-Box-Eigenschaften sind in allen modernen Browsern verfügbar, emHeightAscent und die Baseline-Eigenschaften erst seit neueren Versionen. Auch in OffscreenCanvasRenderingContext2D (Worker) verfügbar.
  • Performance: Häufiges Messen in Schleifen (z. B. beim Kürzen Zeichen für Zeichen) kann teuer werden – Ergebnisse cachen oder binär suchen.
  • Messwerte unterscheiden sich zwischen Browsern und Betriebssystemen und werden teilweise für Fingerprinting genutzt; manche datenschutzorientierte Browser verrauschen sie leicht.