W3docs

JavaScript Canvas API

Grafiken mit dem HTML-Canvas-Element und JavaScript zeichnen: 2D-Kontext abrufen, Formen und Linien zeichnen, Transformationen anwenden und mit requestAnimationFrame animieren.

Einführung in HTML Canvas mit JavaScript

Das HTML <canvas>-Element ist eine Zeichenfläche, die Sie mit JavaScript steuern. Im Gegensatz zu Bildern oder SVG arbeitet Canvas im Immediate-Mode: Es gibt keine Shape-Objekte, die verfolgt werden müssen. Sie geben Zeichenbefehle aus und Pixel werden sofort gemalt. Sobald etwas gezeichnet ist, sind es nur noch farbige Pixel — das Canvas hat keinerlei Erinnerung daran, weshalb das Neuzeichnen die zentrale Idee hinter jeder Animation ist.

Dieses Kapitel führt Sie durch das Abrufen eines 2D-Kontexts, das Zeichnen von Formen und Linien, die Transformation des Koordinatensystems sowie die Animation mit requestAnimationFrame.

Diese Seite behandelt den 2D-Rendering-Kontext (getContext('2d')). Canvas bietet außerdem einen webgl-Kontext für hardwarebeschleunigte 3D-Grafik, der eine separate API darstellt.

Das canvas-Element verstehen

Das <canvas>-Element erzeugt eine Zeichenfläche mit fester Größe, die Grafiken dynamisch rendert. Es eignet sich besonders für grafikintensive Anwendungen — Spiele, Diagramme, Bildbearbeitung, Partikeleffekte — bei denen Sie pixelgenaue Kontrolle und hohe Bildwiederholraten benötigen. Das Tag selbst zeichnet nichts; es ist ein leerer Behälter, und JavaScript übernimmt das gesamte Zeichnen.

Ein häufiger Fallstrick: Die width- und height-Attribute legen die Größe des Zeichenpuffers fest, während die CSS-Eigenschaften width/height die angezeigte Größe bestimmen. Stimmen diese nicht überein, wird das Canvas gestreckt und Zeichnungen erscheinen unscharf oder verzerrt. Legen Sie die Größe über die Attribute fest (oder in JS über canvas.width/canvas.height), nicht über CSS — es sei denn, Sie möchten bewusst skalieren.

Grundlegendes Canvas-Setup

Um mit dem Zeichnen zu beginnen, platzieren Sie ein <canvas>-Tag in Ihrem HTML und rufen Sie dann in JavaScript den 2D-Zeichenkontext mit getContext('2d') ab. Das Kontextobjekt enthält alle Zeichenmethoden.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Canvas Example</title>
<style>
  canvas {
    border: 1px solid #000;
  }
</style>
</head>
<body>
<canvas id="myCanvas" width="200" height="200"></canvas>
<script>
  const canvas = document.getElementById('myCanvas');
  const ctx = canvas.getContext('2d');
</script>
</body>
</html>

Hier definieren wir ein 200×200-Canvas, versehen es mit einem Rahmen, damit die Grenzen sichtbar sind, und rufen den Kontext mit getContext('2d') ab. Der Rahmen dient nur der Visualisierung; die Canvas-Fläche selbst ist zunächst vollständig transparent.

Beachten Sie das Koordinatensystem: Der Ursprung (0, 0) liegt in der oberen linken Ecke. Die x-Achse wächst nach rechts und die y-Achse wächst nach unten, sodass (0, 0) der obere Rand ist und größere y-Werte nach unten zeigen. Dies verwirrt Einsteiger, die mathematische Achsen erwarten.

Formen zeichnen

Der schnellste Weg, etwas auf den Bildschirm zu bringen, ist fillRect(x, y, width, height), das mit einem einzigen Aufruf ein gefülltes Rechteck zeichnet. Setzen Sie zuerst fillStyle, um die Farbe festzulegen (jeder CSS-Farbwert ist gültig). Es gibt außerdem strokeRect für ein Rechteck mit reiner Kontur und clearRect, um einen Bereich wieder transparent zu machen.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Rectangle Example</title>
<style>
  canvas {
    border: 1px solid black;
  }
</style>
</head>
<body>
<canvas id="rectangleCanvas" width="200" height="200"></canvas>
<script>
  const canvas = document.getElementById('rectangleCanvas');
  const ctx = canvas.getContext('2d');
  ctx.fillStyle = '#FF0000'; // Set the fill color to red
  ctx.fillRect(20, 20, 150, 100); // Draw the rectangle
</script>
</body>
</html>

Linien und Pfade erstellen

Linien, Kurven und benutzerdefinierte Formen werden alle aus Pfaden aufgebaut. Das Muster ist stets dasselbe:

  1. beginPath() — startet einen neuen Pfad (wird dies ausgelassen, wird die neue Linie an den vorherigen Pfad angehängt).
  2. moveTo(x, y) — hebt den Stift an und setzt ihn neu, ohne zu zeichnen.
  3. lineTo(x, y) — zeichnet ein Liniensegment zu einem neuen Punkt (kann mehrfach aufgerufen werden, um Segmente zu verketten).
  4. stroke(), um die Kontur zu zeichnen, oder fill(), um den eingeschlossenen Bereich zu füllen.

Steuern Sie das Erscheinungsbild der Linie mit lineWidth, strokeStyle und lineCap, bevor Sie stroke() aufrufen.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Line Drawing Example</title>
<style>
  canvas {
    border: 1px solid black;
  }
</style>
</head>
<body>
<canvas id="lineCanvas" width="200" height="200"></canvas>
<script>
  const canvas = document.getElementById('lineCanvas');
  const ctx = canvas.getContext('2d');
  ctx.beginPath(); // Start the path
  ctx.moveTo(50, 50); // Move the pen to (50, 50)
  ctx.lineTo(150, 50); // Draw a line to (150, 50)
  ctx.lineTo(150, 150); // Continue to (150, 150)
  ctx.lineWidth = 4; // Thicker line
  ctx.strokeStyle = 'navy'; // Line color
  ctx.stroke(); // Render the path visible
</script>
</body>
</html>

Kreise und Bögen zeichnen

Kreise werden mit arc(x, y, radius, startAngle, endAngle) gezeichnet, wobei die Winkel in Bogenmaß angegeben werden (ein vollständiger Kreis entspricht 2 * Math.PI). Binden Sie es in einen Pfad ein und rufen Sie anschließend fill() oder stroke() auf:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Circle Example</title>
<style>
  canvas {
    border: 1px solid black;
  }
</style>
</head>
<body>
<canvas id="circleCanvas" width="200" height="200"></canvas>
<script>
  const canvas = document.getElementById('circleCanvas');
  const ctx = canvas.getContext('2d');
  ctx.beginPath();
  // Center (100, 100), radius 60, full circle
  ctx.arc(100, 100, 60, 0, 2 * Math.PI);
  ctx.fillStyle = 'orange';
  ctx.fill();
  ctx.stroke(); // Add an outline on top of the fill
</script>
</body>
</html>

Erweiterte Canvas-Operationen

Canvas-Transformationen

translate, rotate und scale verändern das Canvas-Koordinatensystem, nicht einzelne Formen. Entscheidend ist, dass sie kumulativ wirken — jede Transformation baut auf der vorherigen auf, und eine Rotation dreht sich um den aktuellen Ursprung, nicht um den Mittelpunkt der Form. Um um einen bestimmten Punkt zu rotieren, verschieben Sie zunächst mit translate zu diesem Punkt und rufen dann rotate auf.

Da sich Transformationen aufaddieren, schließen Sie sie in ctx.save() / ctx.restore() ein, um zum vorherigen Zustand zurückzukehren, ohne jede Transformation manuell rückgängig zu machen:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Transformation Example</title>
<style>
  canvas {
    border: 1px solid black;
  }
</style>
</head>
<body>
<canvas id="transformCanvas" width="200" height="200"></canvas>
<script>
  const canvas = document.getElementById('transformCanvas');
  const ctx = canvas.getContext('2d');
  ctx.save(); // Remember the untransformed state
  ctx.translate(50, 50); // Move the canvas origin to (50, 50)
  ctx.rotate((Math.PI / 180) * 25); // Rotate 25 degrees (converted to radians)
  ctx.fillStyle = 'blue'; // Set fill color to blue
  ctx.fillRect(0, 0, 100, 50); // Draw at the new, rotated origin
  ctx.restore(); // Back to the original coordinate system
</script>
</body>
</html>

Animationen mit Canvas

Canvas hat keine eingebaute Animation; Bewegung entsteht, indem die gesamte Fläche wiederholt gelöscht und neu gezeichnet wird. Das browser-eigene requestAnimationFrame plant Ihre Zeichenfunktion so, dass sie vor dem nächsten Repaint ausgeführt wird — typischerweise 60-mal pro Sekunde — und pausiert automatisch, wenn der Tab verborgen ist. Deshalb ist es setInterval vorzuziehen.

Die Schleife folgt stets drei Schritten: Canvas löschen (clearRect), den Zustand aktualisieren (hier die Position x) und den neuen Frame zeichnen. Vergessen Sie clearRect, sehen Sie einen Nachzieheffekt aller vergangenen Frames statt einer bewegenden Form.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Animation Example</title>
<style>
  canvas {
    border: 1px solid black;
  }
</style>
</head>
<body>
<canvas id="animationCanvas" width="200" height="200"></canvas>
<script>
  const canvas = document.getElementById('animationCanvas');
  const ctx = canvas.getContext('2d');
  let x = 0; // Starting position
  function drawFrame() {
    ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear the canvas for the new frame
    ctx.fillStyle = 'green'; // Set the fill color to green
    ctx.fillRect(x, 20, 50, 50); // Draw a moving rectangle
    x++; // Increment the horizontal position
    if (x > canvas.width) {
      x = 0;
    }
    requestAnimationFrame(drawFrame); // Continue the animation
  }
  drawFrame();
</script>
</body>
</html>

Häufige Fallstricke

  • Unscharfe Ausgabe: Puffergröße und CSS-Größe stimmen nicht überein. Legen Sie die Abmessungen über die width/height-Attribute fest, nicht über CSS — es sei denn, Sie skalieren bewusst.
  • Zusammenhängende Formen: Wird beginPath() vor einem neuen Pfad vergessen, wird dieser an den vorherigen angehängt.
  • Linien verschwinden: Sie haben stroke() oder fill() aufgerufen, aber keinen Pfad aufgebaut, oder Sie haben außerhalb der Canvas-Grenzen gezeichnet.
  • Animation hinterlässt Spuren: fehlendes clearRect am Anfang jedes Frames.
  • Nichts wird gerendert: Das Skript wurde ausgeführt, bevor das <canvas> im DOM vorhanden war. Platzieren Sie das Skript nach dem Element oder führen Sie es bei DOMContentLoaded aus.

Fazit

Das <canvas>-Element bietet Ihnen eine niederschwellige, pixelgenaue Fläche für Grafiken, die HTML und CSS nicht erzeugen können: Diagramme, Bildbearbeitung, Partikelsysteme und vollständige Spiele. Die API ist überschaubar — Kontext abrufen, Stil festlegen, Zeichenbefehl ausgeben — und Animationen sind schlicht diese Schleife, die viele Male pro Sekunde ausgeführt wird.

Um tiefer einzusteigen, lesen Sie das HTML-Canvas-Tag und Canvas-Zeichengrundlagen für die Markup-Seite sowie JavaScript-Animationen und die requestAnimationFrame-basierte Animations-API für flüssigere Bewegungen. Um Ihr Canvas zuverlässig auszuwählen, lesen Sie getElement und querySelector.

Übungen

Übung
Was können Sie laut dem Inhalt auf w3docs.com mit dem Canvas-Element in JavaScript tun?
Was können Sie laut dem Inhalt auf w3docs.com mit dem Canvas-Element in JavaScript tun?
Was this page helpful?