Behandelte Konzepte/Konstrukte: JavaScript, p5.js

Lernziele

  • Sie kennen die Vorteile der Nutzung von JavaScript
  • Sie kennen die wichtigsten Unterschiede zwischen Java und JavaScript
  • Sie können einfache Processing-Programme mit Hilfe von p5.js in einem Browser laufen lassen
Neueste Aktualisierungen (zuletzt 14.11.2021)
  • 14.11.2021: Seite angelegt

In diesem Kapitel geht es um die JavaScript-Variante von Processing, die unter dem Namen p5.js läuft. Sie finden die Homepage dieses Projekts unter p5js.org. Der Grund für die "5" ist übrigens, dass die Domain "processing.org" zu Gründungszeiten nicht verfügbar war und man daher auf "proce55ing.org" auswich.

Eine wichtige Ressource für die Sprache JavaScript ist das JavaScript-Kapitel meines Online-Skripts "Grundlagen der Webtechnologien".

Sie können jederzeit JavaScript-Code in Ihrem Browser testen, indem Sie die JavaScript-Konsole öffnen. Zum Beispiel in Chrome unter Anzeigen > Entwickler > JavaScript-Konsole. Probieren Sie also alle Beispiele am besten immer gleich aus.

Weiterer wichtiger Link ist die p5.js Reference mit allen Befehlen in p5.js.

E2.1 Warum JavaScript?

Warum ist eine JavaScript-Variante von Processing interessant? Processing ist ja in Java geschrieben, aber Java ist natürlich eine andere Sprache als JavaScript. JavaScript hat sich in den letzten 10-20 Jahren als die Web-Sprache etabliert und ist praktisch auf jeder Webseite im Einsatz. Genauer gesagt, ist JavaScript vor allem in der Frontend-Programmierung im Einsatz, d.h. dass JavaScript tatsächlich direkt im Browser ausgeführt wird. Der dazugehörige Code ist entweder direkt in die Webseiten eingebettet oder wird als Datei von der Webseite nachgeladen.

Warum also p5.js benutzen?

  • Man kann die Programme leicht in Webseiten einbinden, da auf praktisch allen modernen Webseiten sowieso JavaScript-Code eingebunden ist.
  • Man kann p5.js sogar in einem Webbrowser programmieren. Sie finden den Webeditor unter editor.p5js.org/

Was ist processing.js?

Es gibt auch eine ältere JavaScript-Variante von Processing namens processing.js. Diese Bibliothek erlaubt es, normalen Processing-Code in Webseiten einzubinden. Tatsächlich nutzt mein Processing-Skript diese alte Bibliothek, die seit 2018 nicht mehr weiterentwickelt wird.

Im Gegensatz zu "processing.js" ist bei "p5.js" die Grundidee, dass man tatsächlich die Programmiersprache wechselt, d.h. dass man in JavaScript programmiert und dabei aber sehr ähnliche Funktionen nutzt wie in Processing.

E2.2 Unterschiede in JavaScript

Wenn Sie gelernt haben, in Processing zu programmieren, müssen Sie sich nur an ein paar Unterschiede gewöhnen.

Schauen Sie sich gern auch die Seite p5.js and Processing an, wo die Unterschiede kurz und übersichtlich dargestellt werden (auf Englisch).

Variablen

In JavaScript gibt man beim Anlegen neuer Variablen keinen Datentypen an. Intern merkt JS zwar schon, ob man eine Zahl oder einen String in einer Variablen ablegt, aber für die Programmiererin macht das keinen Unterschied. Daher nennt man JavaScript auch eine dynamisch typisierte Sprache.

Schlüsselwort var

Bei der Deklaration einer neuen Variable stellt man das Schlüsselwort var voran.

var foo;
foo = 42;

var bar = -1.5;

var message = "hallo";

Die Variablen sind global, d.h. sie sind im gesamten Programm sichtbar.

Strings

In JavaScript kann man für Strings sowohl einfache als auch doppelte Anführungszeichen verwenden.

var s1 = "hallo";
var s2 = 'welt';
var s3 = s1 + ' ' + s2;

Sie können die beiden auch kombinieren, wenn Sie Anführungszeichen innerhalb von Strings benötigen:

print('Das ist nicht "perfekt".');
print("Das ist nicht 'perfekt'.");

Tatsächlich ist es in den meisten Fällen egal, welche Art von Anführungszeichen Sie verwenden. Tendenziell würde ich sagen, dass man in der JavaScript-Welt vielleicht etwas mehr zu einfachen Anführungszeichen tendiert. Außerdem können Sie die einfachen Anführungszeichen für sich als Erkennungsmerksmal nutzen, damit Sie dem Code besser ansehen, dass Sie jetzt bei JavaScript sind (und nicht bei Java).

Typänderung

Es ist auch erlaubt, den Typ zu ändern, während das Programm läuft. Das heißt, Sie können die selbe Variable für Zahlen und Strings verwenden.

var misc = 42;
print(misc);

misc = 'Hallo, Welt'; // Erlaubt!
print(misc);

Nur weil etwas erlaubt ist, heißt das natürlich nicht, dass man es auch nutzen muss. Sie sollten allgemein schon darauf achten, dass Ihre Variablen konsistent verwendet werden.

Schlüsselwort let für lokale Variablen

In JavaScript gibt es neben var noch das Schlüsselwort let, um Variablen zu deklarieren:

let x = 100;
print(x);

let a = x * 200;
print(a);

Variablen, die mit let deklariert werden, verhalten sich wie lokale Variablen in Processing, insofern schlagen wir vor, dass Sie var für alle globalen Variablen und let für alle lokalen Variablen verwenden. Die echten Unterschiede zwischen den beiden Verwendungsarten sind noch ein bisschen komplexer, aber diese Empfehlung soll hier erst einmal reichen.

Schleifen

Schleifen funktionieren zwar praktisch genauso wie in Java, aber die Laufvariable wir entsprechend dem Gesagten anders deklariert:

for (let i = 0; i < 3; i++) {
  print(i);
}

Wie Sie sehen, benutzen wir hier let, damit die Laufvariable lokal bleibt.

Funktionen

Funktionen werden in JavaScript so definiert, dass Sie mit dem Schlüsselwort function eingeleitet werden. Außerdem finden Sie keine Typenangaben bei den Parametern.

function sayHello(greeting, name) {
  print(greeting + ' ' + name);
}

Da bei Funktionen kein Rückgabetyp festgelegt wird, erkennen Sie Funktionen mit Rückgabe lediglich an dem Schlüsselwort return.

function add(a, b) {
  return a + b;
}

Funktionen nehmen in JavaScript eine wichtige Rolle ein und haben einige erstaunliche Eigenschaften:

  • Funktionen können anonym (ohne Namen) definiert werden
  • Funktionen können in Variablen gespeichert werden
  • Funktionen können als Parameter bei Funktionsaufrufen übergeben werden

Mehr zu Funktionen finden Sie im JavaScript-Kapitel meines Web-Skripts.

Arrays

Arrays in JavaScript weisen doch einige Unterschiede zu den Arrays in Processing auf:

  • Arrays können ihre Länge jederzeit ändern
  • Arrayelemente können unterschiedliche Datentypen speichern

Schauen wir uns ein Beispiel an:

var xa = []; // neuen, leeren Array erstellen (Längenangabe nicht nötig)

xa.push(5); // Wert hinzufügen, hat Indexposition 0
xa.push(3); // Wert hinzufügen, hat Indexposition 1
xa.push(22); // Wert hinzufügen, hat Indexposition 2

print(xa[1]); // Zugriff auf zweites Element, gibt Wert 3 aus

Mit der Funktion pop() kann man auch das jeweils letzte Element wieder entfernen.

Man kann Arrays auch mit Werten initialisieren:

var names = ['Harry', 'Sally', 'Mary'];

for (let i = 0; i < names.length; i++) {
  print(names[i] + " ");
}

Tatsächlich würde man in JavaScript den obigen Code eher mit Hilfe von forEach und einer anonymen Funktion umsetzen.

var names = ['Harry', 'Sally', 'Mary'];

names.forEach(function(n) {
  print(n + ' ');
});

Mehr zu Arrays finden Sie im JavaScript-Kapitel meines Web-Skripts.

Schauen Sie sich auch das folgende P5js-Beispiel "Abprallende Bälle" an:

Animation 4

E2.3 Programme im Browser

Erstes Programm

Wir gehen hier davon aus, dass Sie eine Webseite erstellen möchten, in der ein Processing-Programm läuft. Sie sollten ein bisschen HTML verstehen. Wenn nicht, schauen Sie in mein Skript Grundlagen der Webtechnologien. Erstellen Sie ein Verzeichnis mit dem Namen "hello". Erstellen Sie dort zwei Dateien.

  • index.html: Diese Datei können Sie mit einem Webbrowser (z.B. Firefox oder Chrome) öffnen.
  • sketch.js: Hier steht Ihr eigentliches p5.js-Programm.

Dateien erstellen Sie am besten mit einem Texteditor, der für Code-Eingabe optimiert ist. Ich empfehle Visual Studio Code oder Atom. Beide sind kostenlos nutzbar und werden auch im Profibereich genutzt.

index.html

Hier übernehmen Sie folgenden Code:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>hello</title>
    <script src="https://cdn.jsdelivr.net/npm/p5@1.4.0/lib/p5.js">
    </script>
    <script src="sketch.js"></script>
  </head>
  <body>
  </body>
</html>

Sie speichern die Datei unter "index.html" ab. Sie sehen im Code auch den Verweis auf die zweite Datei "sketch.js", die im gleichen Verzeichnis liegen sollte.

sketch.js

Hier steht Ihr Processing-Code drin. Als Beispiel schreiben wir "hello" auf die Konsole und zeichnen einen Kreis.

function setup() {
  print("hello");
  createCanvas(100, 100);
}

function draw() {
  background(0);
  ellipse(50, 50, 80, 80);
}

Sie schon gesagt, müssen beide Dateien im gleichen Verzeichnis liegen. Sie sehen in dem Beispiel auch, dass Sie die Anweisung createCanvas anstatt size nehmen müssen. Ansonsten deutet nur das Wort function auf den Unterschied zu Processing hin.

Wenn Sie die HTML-Datei in einem Browser öffnen, sollten Sie dies sehen:

Programm im Browser

Um die Konsolenausgabe zu sehen, müssen Sie in die Entwicklungsansicht wechseln.

Entwickleransicht

Canvas einbetten

Nachdem wir das einfachst mögliche Beispiel gesehen haben, können wir uns ein paar Detailfragen zuwenden.

Sketch einbetten

Wie können wir unseren Sketch - also das Grafikfenster - genau platzieren? Dazu müssen wir in HTML einen Container mit einem ID definieren. Wir nennen den ID 'sketch' (das kann aber auch ein anderer Name sein).

<div id='sketch'></div>

In Sketch steht dann in setup Folgendes:

function setup() {
  let canvas = createCanvas(200, 200); // binde Canvas an Variable
  canvas.parent('sketch'); // ordne Canvas Container mit ID 'sketch' zu
}

function draw() {
  ...
}

Touch-Input

Programme, die im Browser laufen, können natürlich - wenn Sie z.B. auf einem Tablet laufen - über mehrere Finger bedient werden. Wir verarbeitet man diese Eingabepunkte? Man kann sich das wir mehrere Mauszeiger vorstellen.

Um die Finger-Inputs einzufangen, greifen Sie auf den Array touches zu. Schauen Sie sich auch das Beispielprogramm unten an.

E2.4 Anwendungsbeispiele

Wie immer lernt man am besten, indem man sich Beispiele ansieht. Wir gehen hier einige Programme durch, die im Skript eingeführt wurden.

Sie finden noch viele weitere Beispiele auf der Seite Examples von p5.js. Dort können Sie sogar interaktiv den Code ändern und neu starten.

Animation

Hier zeigen wir mehrere Beispiele, wo Bälle animiert werden. Die Links führen Sie zu Einzelseiten, wo der Code live im Browser ausgeführt wird.

Fligender Ball

Hier sehen Sie eine einfache Animation, wo der Ball von links nach rechts fliegt und wieder in den Bildschirm eintritt, wenn er rechts hinausfliegt:

Animation 1

Einfaches Abprallen

Hier fliegt ein Ball von links nach rechts und prallt dann von der Wand ab, so dass er zurückfliegt:

Animation 2

Abprallen in 2D

Hier sehen Sie eine Animation, wo ein Ball in eine zufällige Richtung losfliegt und von den Wänden abprallt:

Animation 3

Animation mit Array

Abprallende Bälle

Hier sehen Sie eine Animation mit 10 Bällen, die in zufällige Richtungen fliegen und von den Wänden abprallen:

Animation 4

Interaktion

Interaktion per Touch

Hier sehen Sie ein Eingabefenster für mehrere Finger, wo die Eingabe lediglich visualisiert wird:

Touch 1

Transformationen

Rotation

Hier sehen Sie einen rotierenden Balken mit Hilfe von translate und rotate:

Transformation 1

Verschachtelte Rotation

Hier sehen Sie drei rotierende Balken. Zwei kleine Balken hängen dabei an einem großen Balken. Das wird mit mit Hilfe von push und pop erreicht. Diese Anweisungen ersetzen pushMatrix/popMatrix von Processing:

Transformation 2