Start · Sprachen · JavaScript · Referenz · HTMLCanvasElement

HTMLCanvasElement

Schnittstelle

Stellt ein <code>&lt;canvas&gt;</code>-Element dar und liefert Eigenschaften und Methoden, um Zeichenkontexte (2D, WebGL, WebGPU) zu erhalten und den Inhalt zu exportieren.

seit JavaScript Baseline: alle Browser (seit HTML5) Kategorie: webapi

Signatur

interface HTMLCanvasElement extends HTMLElement

Beschreibung

HTMLCanvasElement ist die DOM-Schnittstelle des <canvas>-Elements. Sie erbt von HTMLElement und ist die Grundlage für pixelbasiertes Zeichnen im Browser: Diagramme, Spiele, Bildbearbeitung, Visualisierungen oder das Erzeugen von Vorschaubildern. Gezeichnet wird nicht direkt auf dem Element, sondern über einen Rendering-Kontext, den man mit getContext() anfordert.

Wichtige Mitglieder:

  • width / height – die interne Auflösung der Zeichenfläche in Pixeln (Standard: 300 × 150). Jede Zuweisung leert die Fläche und setzt den Kontextzustand zurück.
  • getContext(contextId, options) – liefert einen Kontext wie "2d", "webgl", "webgl2", "webgpu" oder "bitmaprenderer".
  • toDataURL(type, quality) – exportiert den Inhalt synchron als Data-URL (Base64).
  • toBlob(callback, type, quality) – exportiert asynchron als Blob; speichereffizienter als toDataURL().
  • captureStream(frameRate) – erzeugt einen MediaStream aus dem Canvas-Inhalt (z. B. für Aufnahmen oder WebRTC).
  • transferControlToOffscreen() – übergibt die Zeichenkontrolle an ein OffscreenCanvas, das in einem Web Worker gerendert werden kann.

Man verwendet HTMLCanvasElement immer dann, wenn Inhalte dynamisch pixelgenau erzeugt werden sollen und SVG bzw. DOM-Elemente zu langsam oder unpassend wären – etwa bei vielen tausend Objekten oder Echtzeit-Animationen. Da Canvas-Inhalte reine Pixel sind, sind sie für Screenreader unsichtbar; barrierefreie Alternativen (Fallback-Inhalt, aria-label) sollten mitgeliefert werden.

Parameter

Name Typ Default Beschreibung
$width number 300 Eigenschaft: interne Breite der Zeichenfläche in Pixeln (entspricht dem HTML-Attribut width).
$height number 150 Eigenschaft: interne Höhe der Zeichenfläche in Pixeln (entspricht dem HTML-Attribut height).
$contextId Pflicht "2d" | "webgl" | "webgl2" | "webgpu" | "bitmaprenderer" Parameter von getContext(): Art des gewünschten Rendering-Kontexts.
$options object {} Parameter von getContext(): Kontextattribute, z. B. { alpha: false }, { willReadFrequently: true } oder { antialias: true } bei WebGL.
$type string "image/png" Parameter von toDataURL()/toBlob(): MIME-Typ des Exports, z. B. "image/jpeg" oder "image/webp".
$quality number ca. 0.92 Parameter von toDataURL()/toBlob(): Qualität zwischen 0 und 1 für verlustbehaftete Formate.

Beispiele

Canvas erzeugen und mit 2D-Kontext zeichnen

const canvas = document.createElement('canvas');
canvas.width = 400;
canvas.height = 200;
document.body.append(canvas);

const ctx = canvas.getContext('2d');
ctx.fillStyle = '#1e88e5';
ctx.fillRect(20, 20, 160, 100);
ctx.font = '20px sans-serif';
ctx.fillStyle = '#000';
ctx.fillText('Hallo Canvas', 200, 80);

console.log(canvas instanceof HTMLCanvasElement, canvas.width, canvas.height);
true 400 200

Scharfe Darstellung auf HiDPI-Displays

const canvas = document.querySelector('#chart');
const dpr = window.devicePixelRatio || 1;
const { width, height } = canvas.getBoundingClientRect();

// Interne Auflösung an Pixeldichte anpassen, CSS-Größe beibehalten
canvas.width = Math.round(width * dpr);
canvas.height = Math.round(height * dpr);

const ctx = canvas.getContext('2d');
ctx.scale(dpr, dpr); // ab jetzt in CSS-Pixeln zeichnen
ctx.beginPath();
ctx.arc(width / 2, height / 2, 40, 0, Math.PI * 2);
ctx.stroke();

Inhalt als Bild herunterladen mit toBlob()

const canvas = document.querySelector('canvas');

const canvasToBlob = (cnv, type = 'image/png', quality) =>
  new Promise((resolve) => cnv.toBlob(resolve, type, quality));

const download = async () => {
  const blob = await canvasToBlob(canvas, 'image/jpeg', 0.85);
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = 'zeichnung.jpg';
  a.click();
  URL.revokeObjectURL(url);
  console.log(`Exportiert: ${blob.size} Bytes, ${blob.type}`);
};

document.querySelector('#save').addEventListener('click', download);
Exportiert: 48213 Bytes, image/jpeg

Rendering in einen Worker auslagern

// main.js
const canvas = document.querySelector('#game');
const offscreen = canvas.transferControlToOffscreen();
const worker = new Worker('render-worker.js');
worker.postMessage({ canvas: offscreen }, [offscreen]);

// render-worker.js
self.onmessage = ({ data }) => {
  const ctx = data.canvas.getContext('2d');
  const loop = (t) => {
    ctx.clearRect(0, 0, data.canvas.width, data.canvas.height);
    ctx.fillRect(50 + Math.sin(t / 500) * 40, 50, 20, 20);
    requestAnimationFrame(loop);
  };
  requestAnimationFrame(loop);
};