Signatur
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 alsBlob; speichereffizienter alstoDataURL().captureStream(frameRate)– erzeugt einenMediaStreamaus dem Canvas-Inhalt (z. B. für Aufnahmen oder WebRTC).transferControlToOffscreen()– übergibt die Zeichenkontrolle an einOffscreenCanvas, 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);
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);
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);
};