← Zurück zu Mediendesign & Digitale Medien
Die HTML Canvas API ist eine JavaScript-Schnittstelle zum programmatischen, pixelbasierten Zeichnen auf einem <canvas>-Element im Browser – ohne DOM-Elemente, direkt auf Rasterebene.

Was ist die Canvas API?

Das <canvas>-Element wurde mit HTML5 eingeführt und stellt eine zweidimensionale Zeichenfläche zur Verfügung. Im Gegensatz zu SVG, das vektorbasierte DOM-Elemente erzeugt, rendert Canvas direkt in einen Pixel-Puffer. Es gibt keinen „Szenegraph" – was gezeichnet wird, ist gezeichnet, nicht in einem Baum gespeichert.

Das macht Canvas ideal für:

  • Animationen mit Hunderten oder Tausenden Elementen (Partikel, Sterne, Punkte)
  • Generative Grafiken und algorithmische Kunst
  • Bildverarbeitung (Filter, Effekte auf Bilder anwenden)
  • Interaktive Visualisierungen (Zeichnen, Malen)
  • Spiele (2D-Spiele im Browser)

Für komplexe 3D-Szenen nutzt man WebGL – Grundlagen für Kreative (WebGL) oder Three.js – 3D im Browser (Three.js als Abstraktion darüber).

Erklärung

Setup

``html <canvas id="meinCanvas" width="800" height="600"></canvas> ``

```javascript const canvas = document.getElementById('meinCanvas'); const ctx = canvas.getContext('2d');

// Responsives Canvas function canvasGroesseAnpassen() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; } window.addEventListener('resize', canvasGroesseAnpassen); canvasGroesseAnpassen(); ```

Wichtig: Canvas-width und height sind die Pixel-Auflösung, nicht die CSS-Größe. Für Retina-Displays:

``javascript const dpr = window.devicePixelRatio || 1; canvas.width = window.innerWidth * dpr; canvas.height = window.innerHeight * dpr; canvas.style.width = window.innerWidth + 'px'; canvas.style.height = window.innerHeight + 'px'; ctx.scale(dpr, dpr); ``

Grundlegende Zeichenbefehle

```javascript // Rechteck ctx.fillStyle = '#0078ff'; ctx.fillRect(10, 10, 100, 60);

ctx.strokeStyle = '#333'; ctx.lineWidth = 2; ctx.strokeRect(10, 10, 100, 60);

// Kreis ctx.beginPath(); ctx.arc(200, 200, 50, 0, Math.PI * 2); ctx.fillStyle = 'rgba(255, 100, 0, 0.8)'; ctx.fill();

// Linie / Pfad ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(400, 300); ctx.quadraticCurveTo(200, 100, 400, 300); // Bézier-Kurve ctx.stroke();

// Text ctx.font = 'bold 48px Inter, sans-serif'; ctx.fillStyle = '#333'; ctx.fillText('Hallo Canvas', 100, 100); ```

Das Animations-Grundprinzip

Canvas-Animation funktioniert durch Wiederholen dieser drei Schritte:

  1. Löschen – Vorherigen Frame übermalen
  2. Zeichnen – Neuen Frame zeichnen
  3. Nächsten Frame anfragenrequestAnimationFrame

```javascript function animationsLoop(zeitstempel) { // 1. Alles löschen ctx.clearRect(0, 0, canvas.width, canvas.height);

// 2. Frame zeichnen zeichneFrame(zeitstempel);

// 3. Nächsten Frame anfragen requestAnimationFrame(animationsLoop); }

// Loop starten requestAnimationFrame(animationsLoop); ```

requestAnimationFrame ist der optimale Weg für Browser-Animationen: Er synchronisiert mit der Bildwiederholrate des Monitors (meist 60Hz oder 120Hz) und pausiert automatisch, wenn der Tab nicht sichtbar ist.

Delta-Time für frame-rate-unabhängige Animation

```javascript let letzterZeitstempel = 0;

function animationsLoop(zeitstempel) { const delta = (zeitstempel - letzterZeitstempel) / 1000; // Sekunden letzterZeitstempel = zeitstempel;

ctx.clearRect(0, 0, canvas.width, canvas.height); aktualisiereObjekte(delta); // delta = Sekunden seit letztem Frame zeichneObjekte();

requestAnimationFrame(animationsLoop); } ```

Beispiele

Partikel-System

```javascript class Partikel { constructor() { this.zurücksetzen(); }

zurücksetzen() { this.x = Math.random() canvas.width; this.y = Math.random() canvas.height; this.vx = (Math.random() - 0.5) 2; // Geschwindigkeit X this.vy = (Math.random() - 0.5) 2; // Geschwindigkeit Y this.radius = Math.random() 3 + 1; this.lebensdauer = 1; // 0–1 this.verfall = Math.random() 0.01 + 0.005; }

aktualisieren(delta) { this.x += this.vx; this.y += this.vy; this.lebensdauer -= this.verfall; if (this.lebensdauer <= 0) this.zurücksetzen(); }

zeichnen(ctx) { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2); ctx.fillStyle = rgba(0, 120, 255, ${this.lebensdauer}); ctx.fill(); } }

const partikel = Array.from({ length: 200 }, () => new Partikel());

function loop() { ctx.fillStyle = 'rgba(0, 0, 0, 0.05)'; // Langsam ausblendender Trail ctx.fillRect(0, 0, canvas.width, canvas.height);

partikel.forEach(p => { p.aktualisieren(); p.zeichnen(ctx); }); requestAnimationFrame(loop); }

requestAnimationFrame(loop); ```

Maus-interaktive Verbindungslinien

```javascript const punkte = []; const maus = { x: 0, y: 0 }; const maxAbstand = 120;

// Punkte erstellen for (let i = 0; i < 80; i++) { punkte.push({ x: Math.random() canvas.width, y: Math.random() canvas.height, vx: (Math.random() - 0.5) 0.5, vy: (Math.random() - 0.5) 0.5 }); }

canvas.addEventListener('mousemove', e => { maus.x = e.clientX; maus.y = e.clientY; });

function loop() { ctx.clearRect(0, 0, canvas.width, canvas.height);

punkte.forEach(p => { p.x += p.vx; p.y += p.vy; if (p.x < 0 || p.x > canvas.width) p.vx = -1; if (p.y < 0 || p.y > canvas.height) p.vy = -1;

// Punkt zeichnen ctx.beginPath(); ctx.arc(p.x, p.y, 2, 0, Math.PI * 2); ctx.fillStyle = '#0078ff'; ctx.fill();

// Linie zur Maus const abstandMaus = Math.hypot(maus.x - p.x, maus.y - p.y); if (abstandMaus < maxAbstand) { ctx.beginPath(); ctx.moveTo(p.x, p.y); ctx.lineTo(maus.x, maus.y); ctx.strokeStyle = rgba(0, 120, 255, ${1 - abstandMaus / maxAbstand}); ctx.stroke(); } });

requestAnimationFrame(loop); }

requestAnimationFrame(loop); ```

In der Praxis

Wann Canvas, wann SVG?

  • Canvas für viele dynamische Objekte (>100 simultane Elemente)
  • SVG für interaktive Einzelelemente mit DOM-Events
  • Canvas für Bildmanipulation
  • SVG für Animationen, die zugänglich sein müssen (Text in SVG ist zugänglich, Canvas ist blind für Screenreader)

Performance-Tipps:

  • ctx.save() / ctx.restore() für State-Management
  • offscreenCanvas für aufwändige Berechnungen im WebWorker (Chrome 69+)
  • Nicht unnötig bei jedem Frame clearRect über die gesamte Fläche ausführen – nur dirty regions
  • canvas.willReadFrequently = true wenn oft getImageData gerufen wird

Vergleich & Abgrenzung

Canvas 2DSVG AnimationenWebGL – Grundlagen für Kreative
TypRasterVektor/DOMRaster/GPU
Performance bei vielen ElementenGutSchlechtSehr gut
DOM-EventsManuellAutomatischManuell
3DNeinBegrenztJa
BarrierefreiheitSchlechtGutSchlecht

Häufige Fragen (FAQ)

Kann ich Canvas-Inhalte als Bild exportieren? Ja: canvas.toDataURL('image/png') oder canvas.toBlob(callback, 'image/jpeg', 0.9).

Warum ist mein Canvas unscharf auf Retina-Displays? Weil Canvas-Pixels physische Bildschirm-Pixels sind. Für Retina: Canvas mit devicePixelRatio multiplizieren (siehe Setup oben).

Wie mache ich Canvas barrierefrei? Alternativ-Inhalt im <canvas>-Tag einfügen. Für komplexe Visualisierungen: ARIA-Live-Regionen für Updates und textuelle Beschreibungen.

Verwandte Einträge

Weiterführend

  • MDN: Canvas API (2024) – developer.mozilla.org/Web/API/Canvas_API
  • MDN: Canvas tutorial – developer.mozilla.org
  • Eloquent JavaScript: Kapitel 17: Drawing on Canvas (Marijn Haverbeke, 2023)
  • The Coding Train: Programming with p5.js – Youtube-Kanal von Daniel Shiffman
  • Keith Peters: Foundation HTML5 Canvas (2011) – Apress
← Zurück zu Mediendesign & Digitale Medien
Infotag · 13. Mai · 15:00 Uhr · Vor Ort

Sei am Mittwoch dabei.
Bring Eltern oder Freunde mit.

Ein halber Nachmittag, der dir drei Jahre Klarheit bringen kann. Kostenlos, unverbindlich, ehrlich.

  • Rundgang durch Studios, Schnitträume und Tonstudio
  • Echte Absolventenfilme sehen
  • 1:1-Beratung zu Bewerbung & BAföG
  • Studierende direkt fragen
  • Kaffee, kein Sales-Pitch
  • Auch online möglich

Platz beim Infotag reservieren

Dauert 30 Sekunden. Bestätigung per E-Mail.
100 % kostenlos · keine Verpflichtung · jederzeit absagbar