Grafikprogrammierung unter JavaScript
Willemers Informatik-Ecke
JavaScript kann in einem mit dem HTML-Tag CANVAS bezeichneten Feld innerhalb einer Webseite Grafiken erstellen.

Der Canvas

Ein Canvas ist eine Zeichenfläche, auf der man zeichnen kann. Um die Zeichenbefehle auszuführen, benötigt man noch einen Kontext, der sich beispielsweise die aktuelle Zeichenfarbe merkt.

Das folgende Beispiel zeichnet 10 gefüllte Quadrate nebeneinander:
<html>
<head>
<script language=javascript>
function malWas() {
   var canvas = document.getElementById("myCanvas");
   if (canvas && canvas.getContext) {
      var context = canvas.getContext("2d");
      if (context) {
         context.fillStyle = "#9FC0D0";
         // Zeichne 10 Quadrate
         for (var i=0; i<10; i++) {
              context.fillRect(i*50, 5, 40, 40);
         }
      }
   }
}
</script>
</head>
<body onload="malWas()">
<canvas id="myCanvas" width="600" height="50">
</canvas>
</body>
</html>
Das Ergebnis sieht so aus:

Grafikprimitive

JavaScript verfügt über einige Grafikprimitive:

Der abschließende Aufruf von stroke() sorgt erst dafür, dass die stroke-Funktionen gezeichnet werden.

<canvas id="PrimCanvas" style="background-color:lightgrey;"
    width=500 height=200> </canvas>
<script type='application/javascript'>
function primdraw() {
    var canvas= document.getElementById('PrimCanvas');
    var context = canvas.getContext('2d');
    context.strokeStyle = "rgb(255, 255, 0)"; // gelb
    x = 0;
    y = 0;
    w = canvas.width;
    h = canvas.height;
    // Zwei kreuzende Linien
    context.moveTo(x, y); context.lineTo(w, h);
    context.moveTo(x, h); context.lineTo(w, y);
    // 
    context.fillStyle = "rgb(255, 0, 0)"; // gelb
    context.fillRect(w/4, h/4, w*2/4, h*2/4);
    context.fillStyle = "rgb(0, 0, 255)"; // blau
    context.font = '12pt serif'; // auch 12px möglich
    context.fillText("Hallo Canvas!", w/8, h/8);
    context.stroke(); // erst jetzt werden die Linien gezeichnet
}
primdraw();
</script>

Pfade

Es können komplexere Zeichnungen als Pfad definiert werden. Die Definition beginnt mit dem Aufruf von beginPath(). Es folgen Befehle zur Zeichnung der Figur. Gezeichnet wird die Figur durch den Aufruf stroke() für die Umrisslinien oder aber durch fill(), um die Figur zu füllen.

Farben und Linienstärken

Für die Darstellung können Farben und Stile durch folgende Methoden verändert werden:

Diese Einstellungen bleiben im Kontext gespeichert, bis sie wieder geändert werden.

Sonstiges

Über den Grafikkontext kann die Canvas-Größe über canvas.height und canvas.width ermittelt werden.

Links:

Umgang mit der Maus

Klick

Wer keine Sommersprossen hat, muss sich welche malen. Das folgende Programm fängt das Mausereignis click und weist ihm eine Funktion zu. Etwas trickreich ist, dass die Funktion anonym ist, sie hat keinen Namen. Das ist nicht erforderlich, solange die Funktion nicht von anderer Stelle aufgerufen wird.

Die Canvas-Methode addEventListener leitet das Ereignis click auf die folgende Funktion ohne Namen, die die Ereignisumgebung als Parameter erhält. Dessen Attribut pageX gibt die X-Koordinate an, wo die Maus geklickt wurde. Allerdings bezieht sich diese auf das Gesamtfenster. Um die Position innerhalb des Canvas auszurechnen, wird der Versatz zum linken Rand abgezogen, der in dem Canvas-Attribut offsetLeft zu finden ist. Analog wird mit der Y-Koordinate vorgegangen.

<canvas id="ClickCanvas" style="background-color:lightgrey;"
    width=500 height=200> </canvas>

<script type='application/javascript'>
function sommersprossen() {
    var canvas= document.getElementById('ClickCanvas');
    var context = canvas.getContext('2d');
    context.fillStyle = "rgb(255, 0, 0)";
    canvas.addEventListener("click", function(e) {
          var x = e.pageX - canvas.offsetLeft;
          var y = e.pageY - canvas.offsetTop;
          context.beginPath();
          context.arc(x, y, 5, 0, 2*Math.PI);
          context.fill();
    }, false);
}
sommersprossen();
</script>

Klicken, um Sommersprossen zu erzeugen:

Als Ereignisse können click, touchstart und andere verfolgt werden.

Die rechte Maustaste

Um die rechte Maustaste zu erwischen, fügt man einen EventHandler für "contextmenu" hinzu.
canvas.addEventListener("contextmenu", function(e) {
    e.preventDefault(); // unterdrücke das Kontextmenü
    var x = e.pageX - canvas.offsetLeft;
    var y = e.pageY - canvas.offsetTop;
}, false);
Die Auswertung der Mausposition erfolgt wie bei dem Event "click". Mit dem Aufruf von preventDefault() wird verhindert, dass der Browser das Standardkontextmenü aufsteigen lässt. Dieses Kontextmenü dürfte in den meisten Anwendungsfällen eher lästig als nützlich sein.

Das folgende Listing wird bei einem Klick mit der linken Maustaste eine rote Sommersprosse erzeugen. Wird mit der rechten Maustaste geklickt, gibt es einen blauen Fleck.

<canvas id="RClickCanvas" style="background-color:lightgrey;"
    width=500 height=200> </canvas>

<script type='application/javascript'>
function rechtslinksklick() {
    var canvas= document.getElementById('RClickCanvas');
    var context = canvas.getContext('2d');
    canvas.addEventListener("click", function(e) {
          context.fillStyle = "rgb(255, 0, 0)";
          var x = e.pageX - canvas.offsetLeft;
          var y = e.pageY - canvas.offsetTop;
          context.beginPath();
          context.arc(x, y, 5, 0, 2*Math.PI);
          context.fill();
    }, false);
    canvas.addEventListener("contextmenu", function(e) {
          context.fillStyle = "rgb(0, 0, 255)";
          e.preventDefault(); // unterdrücke das Kontextmenü
          var x = e.pageX - canvas.offsetLeft;
          var y = e.pageY - canvas.offsetTop;
          context.beginPath();
          context.arc(x, y, 5, 0, 2*Math.PI);
          context.fill();
    }, false);
}
rechtslinksklick();

Klicken Sie mit der linken oder der rechten Maustaste:

Bewegungsverfolgung

Eine andere Herangehensweise ist die Zuweisung der Bearbeitungsfunktion an das Canvas-Attribut onmousedown. Auch hier wird im Folgenden eine anonyme Funktion verwendet. Neben dem Herunterdrücken der Maustaste kann auch das Bewegen der Maus über onmousemove und das Loslassen der Maustaste über onmouseup verwendet werden.

Das folgende Programm nutzt dies, um mit der Maus auf dem Canvas herumkrakeln zu können. Die boolesche Variabe draw merkt sich, ob die Maustaste gerade gedrückt ist. Nur dann zieht onmousemove eine Linie zur neuen Mausposition.

<canvas id="KrakelCanvas" style="background-color:lightgrey;"
    width=500 height=200> </canvas>
<script type='application/javascript'>
function krakeln() {
    var canvas= document.getElementById('KrakelCanvas');
    var context = canvas.getContext('2d');
    var draw = false;
    context.fillStyle = "rgb(20, 255, 0)";
    canvas.onmousedown = function(e) {
          var x = e.pageX - canvas.offsetLeft;
          var y = e.pageY - canvas.offsetTop;
          context.beginPath();
          context.lineTo(x, y);
          draw = true;
    };
    canvas.onmousemove = function(e) {
        if (draw) {
        var x = e.pageX - canvas.offsetLeft;
        var y = e.pageY - canvas.offsetTop;
        context.lineTo(x, y);
        context.stroke();
        }
    };
    canvas.onmouseup = function() {
        draw = false;
    };
}
krakeln();
</script>

Durch Maustaste-Drücken kann auf dem folgenden Canvas gezeichnet werden.