1. Web Design
  2. HTML/CSS
  3. SVG

Ein Anfängerleitfaden zum Zeichnen von 2D-Grafiken mit Two.js

Scroll to top

German (Deutsch) translation by Ines Willenbrock (you can also view the original English article)

Two.js eine API, die es einfach macht, 2D-Formen mit Code zu erstellen. Folgen Sie diesem Tutorial und Sie erfahren, wie Sie Formen mit JavaScript erstellen und animieren.

Two.js ist rendererunabhängig, sodass Sie sich beim Zeichnen mit Canvas, SVG oder WebGL auf dieselbe API verlassen können. Die Bibliothek verfügt über viele Methoden, mit denen sie steuern können, wie verschiedene Formen auf dem Bildschirm angezeigt werden oder wie sie animiert werden.

Installation

Die unkomprimierte Version der Bibliothek hat eine Größe von etwa 128 KB, während die komprimierte Version 50 KB groß ist. Wenn Sie die neueste Version verwenden, können Sie die Größe der Bibliothek mithilfe eines benutzerdefinierten Builds weiter reduzieren.

Sie können entweder die minifizierte Version der Bibliothek von GitHub herunterladen oder direkt auf die vom CDN gehostete Version verlinken. Nachdem Sie die Bibliothek zu Ihrer Webseite hinzugefügt haben, können Sie mit dem Zeichnen und Animieren verschiedener Formen oder Objekte beginnen.

Erstellen von Basisformen

Zuerst müssen Sie Two.js über das Element informieren, auf dem Sie zeichnen und Ihre Formen animieren möchten. Sie können einige Parameter an den Two-Konstruktor übergeben, um Dinge einzurichten.

Legen Sie den Renderertyp mithilfe der type-Eigenschaft fest. Sie können einen Wert wie svg, webgl, canvas usw. angeben. Der type ist standardmäßig auf svg festgelegt. Die Breite und Höhe des Zeichenraums kann mit den Parametern width und height angegeben werden. Sie können den Zeichenbereich auch mit dem fullscreen-Parameter auf den vollständigen verfügbaren Bildschirm festlegen. Wenn der fullscreen auf true festgelegt ist, werden die Werte für width und height nicht berücksichtigt.

Schließlich können Sie Two.js anweisen, eine Animation mit Hilfe des booleschen autostart-Parameters automatisch zu starten.

Nachdem Sie alle gewünschten Parameter an den Konstruktor übergeben haben, können Sie mit dem Zeichnen von Linien, Rechtecken, Kreisen und Ellipsen beginnen.

Sie können eine Linie mit two.makeLine(x1, y1, x2, y2) zeichnen. Hier sind (x1, y1) die Koordinaten des ersten Endpunkts und (x2, y2) die Koordinaten des zweiten Endpunkts. Diese Funktion gibt ein Two.Line-Objekt zurück, das zur weiteren Bearbeitung zu einem späteren Zeitpunkt in einer Variablen gespeichert werden kann.

Auf ähnliche Weise können Sie normale und abgerundete Rechtecke mit two.makeRectangle(x, y, width, height) bzw. two.makeRoundedRectangle(x, y, width, height, radius) zeichnen. Denken Sie daran, dass x und y den Mittelpunkt des Rechtecks bestimmen, anstatt seiner Koordinaten oben links wie bei vielen anderen Bibliotheken. Die Parameter width und height bestimmen die Größe des Rechtecks. Der radius-Parameter wird verwendet, um den Wert des Radius für die abgerundete Ecke anzugeben.

Sie können Kreise und Ellipsen auf einer Webseite auch mit two.makeCircle(x, y, radius) bzw. two.makeEllipse(x, y, width, height) rendern. Genau wie die Rechtecke geben die Parameter x und y den Mittelpunkt des Kreises oder der Ellipse an. Wenn Sie die width und height im Falle einer Ellipse auf den gleichen Wert einstellen, wird sie wie ein Kreis dargestellt.

Please accept marketing cookies to load this content.

Eine nützliche Methode in Two.js, die Sie häufig verwenden werden, ist two.makeGroup(objects). Sie können entweder eine Liste verschiedener Objekte übergeben oder ein Array von Objekten, Pfaden oder Gruppen als Parameter an diese Methode übergeben. Außerdem wird ein Two.Group-Objekt zurückgegeben.

Bearbeiten von Objekten in einer Gruppe

Nachdem Sie eine Gruppe erstellt haben, können Sie alle untergeordneten Gruppen gleichzeitig mithilfe von Eigenschaften bearbeiten, die Ihnen die Gruppe zur Verfügung stellt.

Die stroke- und fill-Eigenschaften können verwendet werden, um die Kontur- und Füllfarbe für alle untergeordneten Objekte in einer Gruppe festzulegen. Sie akzeptieren alle gültigen Formulare, in denen Sie eine Farbe in CSS darstellen können. Dies bedeutet, dass Sie RGB, HSL- oder Hex-Notation verwenden können. Sie können auch einfach den Namen der Farbe verwenden, z. B. orange, red oder blue. Ebenso können Sie Werte für alle anderen Eigenschaften wie linewidth, opacity, miter und cap festlegen. Mit den Methoden noFill() und noStroke() ist es möglich, die Füllung und Kontur von allen untergeordneten Kindern in einer Gruppe zu entfernen.

Sie können auch andere physikalische Transformationen wie scale, rotation und translation anwenden. Diese Transformationen werden auf einzelne Objekte angewendet. Das Hinzufügen neuer Objekte zu einer Gruppe und deren Entfernen ist mit Methoden wie add() und remove() einfach.

Definieren von Verläufen und Schreiben von Text

Sie können sowohl lineare als auch radiale Verläufe in Two.js definieren. Das Definieren eines Farbverlaufs bedeutet nicht, dass er automatisch auf dem Bildschirm gerendert wird, aber er steht Ihnen beim Festlegen der Werter von fill oder stroke verschiedener Objekte zur Verfügung.

Sie können einen linearen Farbverlauf mit two.makeLinearGradient(x1, y1, x2, y2, stops) definieren. Die Werte x1 und y1 bestimmen die Koordinaten des Beginns des Farbverlaufs. Ebenso bestimmen die Werte x2 und y2 die Koordinaten des Endes des Farbverlaufs. Der stops-Parameter ist ein Array von Two.Stop-Instanzen. Diese definieren die Farben jedes Teils des Arrays und wo jede Farbe in den nächsten übergeht. Sie können mit dem new Two.Stop (offsert, color, opacity) definiert werden, wobei der Wert von offset den Punkt auf dem Farbverlauf bestimmt, an dem diese bestimmte Farbe vollständig gerendert werden muss. Der color-Parameter bestimmt die Farbe des Verlaufs an der jeweiligen Stelle. Sie können alle gültigen CSS-Farbdarstellungen als Wert verwenden. Schließlich bestimmt der opacity-Parameter die Deckkraft der Farbe. Die Deckkraft ist optional und kann einen beliebigen Wert zwischen 0 und 1 haben.

Sie können radiale Verläufe auf ähnliche Weise mit two.makeRadialGradient(x, y, radius, stops, fx, fy) definieren. In diesem Fall bestimmen die Werte x und y den Mittelpunkt des Farbverlaufs. Der Parameter radius gibt an, wie weit sich der Farbverlauf erstrecken soll. Sie können dieser Methode auch ein Array von Stopps übergeben, um die Farbzusammensetzung der Verläufe festzulegen. Die Parameter fx und fy sind optional und können verwendet werden, um die Fokusposition für den Farbverlauf anzugeben.

Sehen Sie sich einige der Arten von Farbverläufen und deren Code im CodePen unten an.

Please accept marketing cookies to load this content.

Denken Sie daran, dass die x- und y-Position der Farbverläufe in Bezug auf den Ursprung der Form ist, die sie ausfüllen möchten. Zum Beispiel wird ein radialer Farbverlauf, der eine Form von der Mitte aus füllen soll, immer x und y auf Null gesetzt.

Two.js ermöglicht es Ihnen auch, Text auf den Zeichenbereich zu schreiben und ihn später nach Ihren Bedürfnissen zu aktualisieren. Dies erfordert die Verwendung der Methode two.makeText(message, x, y, styles). Aus dem Namen der Parameter kann hervorgehen, dass die message der eigentliche Text ist, den Sie schreiben möchten. Die Parameter x und y sind die Koordinaten des Punktes, der als Mittelpunkt für das Schreiben des Textes fungiert. Der styles-Parameter ist ein Objekt, mit dem die Werte eines großen Satzes von Eigenschaften festgelegt werden können.

Sie können Stile verwenden, um die Werte von Eigenschaften wie font family, size und alignment festzulegen. Sie können auch den Wert von Eigenschaften wie fill, stroke, opacity, rotation, scale und translation angeben.

Erstellen eines Two.js Projekts

Nachdem Sie all diese Methoden und Eigenschaften kennen gelernt haben, ist es an der Zeit, sie auf ein Projekt anzuwenden. In diesem Tutorial zeige ich Ihnen, wie wir Two.js verwenden können, um die ersten zehn Elemente des Periodensystems mit Elektronen zu rendern, die sich um den Kern drehen. Der Kern wird auch eine leichte Bewegung haben, um die visuelle Attraktivität unserer Darstellung zu verbessern.

Wir beginnen mit der Definition einiger Variablen und Funktionen, die später verwendet werden.

1
var centerX = window.innerWidth / 2;
2
var centerY = window.innerHeight / 2;
3
4
var elem = document.getElementById("atoms");
5
6
var elementNames = [
7
  "",
8
  "Hydrogen",
9
  "Helium",
10
  "Lithium",
11
  "Beryllium",
12
  "Boron",
13
  "Carbon",
14
  "Nitrogen",
15
  "Oxygen",
16
  "Fluorine",
17
  "Neon"
18
];
19
20
var styles = {
21
  alignment: "center",
22
  size: 36,
23
  family: "Lato"
24
};
25
26
var nucleusCount = 10;
27
var nucleusArray = Array();
28
29
var electronCount = 10;
30
var electronArray = Array();
31
32
function intRange(min, max) {
33
  return Math.random() * (max - min) + min;
34
}

Der obige Code speichert die Koordinaten des Mittelpunkts unseres Fensters in den Variablen centerX und centerY. Diese werden später verwendet, um unser Atom in die Mitte zu stellen. Das elementNames-Array enthält die Namen der ersten zehn Elemente des Periodensystems. Der Index jedes Namens entspricht der Anzahl der Elektronen und Protonen dieses Elements und beginnt mit einer leeren Zeichenfolge. Das styles-Objekt enthält Eigenschaften zum Formatieren des Textobjekts.

Wir haben auch eine Funktion intRange() definiert, um einen zufälligen ganzzahligen Wert innerhalb bestimmter Extreme zu erhalten.

1
var two = new Two({ fullscreen: true }).appendTo(elem);
2
3
var protonColor = two.makeRadialGradient(
4
  0,
5
  0,
6
  15,
7
  new Two.Stop(0, "red", 1),
8
  new Two.Stop(1, "black", 1)
9
);
10
11
var neutronColor = two.makeRadialGradient(
12
  0,
13
  0,
14
  15,
15
  new Two.Stop(0, "blue", 1),
16
  new Two.Stop(1, "black", 1)
17
);
18
19
for (i = 0; i < nucleusCount; i++) {
20
  nucleusArray.push(two.makeCircle(intRange(-10, 10), intRange(-10, 10), 8));
21
}
22
23
nucleusArray.forEach(function(nucleus, index) {
24
  if (index % 2 == 0) {
25
    nucleus.fill = protonColor;
26
  }
27
  if (index % 2 == 1) {
28
    nucleus.fill = neutronColor;
29
  }
30
  nucleus.noStroke();
31
});

Dadurch wird eine Instanz von Two erstellt und zwei radiale Verläufe definiert. Die rot/schwarzen radialen Gradienten repräsentieren Protonen und blau/schwarze Gradienten Neutronen.

Wir haben die Funktion intRange() verwendet, um all diese Neutronen und Protonen innerhalb von 20 Pixeln voneinander zu platzieren. Die makeCircle()-Methode setzt auch den Radius dieser Protonen und Neutronen auf 10 Pixel. Danach iterieren wir über nucleusArray und füllen jeden Kreis abwechselnd mit einem anderen Gradienten.

1
for (var i = 0; i < 10; i++) {
2
  if (i < 2) {
3
    var shellRadius = 50;
4
    var angle = i * Math.PI;
5
    electronArray.push(
6
      two.makeCircle(
7
        Math.cos(angle) * shellRadius,
8
        Math.sin(angle) * shellRadius,
9
        5
10
      )
11
    );
12
  }
13
  if (i >= 2 && i < 10) {
14
    var shellRadius = 80;
15
    var angle = (i - 2) * Math.PI / 4;
16
    electronArray.push(
17
      two.makeCircle(
18
        Math.cos(angle) * shellRadius,
19
        Math.sin(angle) * shellRadius,
20
        5
21
      )
22
    );
23
  }
24
}

Neutronen und Protonen im Kern zu platzieren war einfach. Die richtige Platzierung der Elektronen in einem gleichmäßigen Abstand erfordert jedoch ein wenig Mathematik. Wir verwenden die variable shellRadius, um den Abstand verschiedener Elektronenschalen vom Kern anzugeben. Ein ganzer Kreis deckt einen Winkel ab, der 2 PI Bogenmaß entspricht. Wir können verschiedene Elektronen gleichmäßig platzieren, indem wir die 2 PI Bogenmaße gleichmäßig zwischen ihnen verteilen.

Die Funktionen Math.cos() und Math.sin() werden verwendet, um die vertikalen und horizontalen Komponenten des Positionsvektors verschiedener Elektronen basierend auf ihrem Winkel zu trennen.

1
var orbitA = two.makeCircle(centerX, centerY, 50);
2
orbitA.fill = "transparent";
3
orbitA.linewidth = 2;
4
orbitA.stroke = "rgba(0, 0, 0, 0.1)";
5
6
var orbitB = two.makeCircle(centerX, centerY, 80);
7
orbitB.fill = "transparent";
8
orbitB.linewidth = 2;
9
orbitB.stroke = "rgba(0, 0, 0, 0.1)";
10
11
var groupElectronA = two.makeGroup(electronArray.slice(0, 2));
12
groupElectronA.translation.set(centerX, centerY);
13
groupElectronA.fill = "orange";
14
groupElectronA.linewidth = 1;
15
16
var groupElectronB = two.makeGroup(electronArray.slice(2, 10));
17
groupElectronB.translation.set(centerX, centerY);
18
groupElectronB.fill = "yellow";
19
groupElectronB.linewidth = 1;
20
21
var groupNucleus = two.makeGroup(nucleusArray);
22
groupNucleus.translation.set(centerX, centerY);

Dieser Teil des Codes stellt Elektronen aus verschiedenen Schalen sowie Neutronen und Protonen in ihre eigenen separaten Gruppen. Es legt auch die Füllfarben für alle Elektronen in einer bestimmten Umlaufbahn gleichzeitig fest.

1
two
2
  .bind("update", function(frameCount) {
3
    groupElectronA.rotation += 0.025 * Math.PI;
4
    groupElectronB.rotation += 0.005 * Math.PI;
5
    groupNucleus.rotation -= 0.05;
6
  })
7
  .play();
8
9
var text = two.makeText("", centerX, 100, styles);
10
11
nucleusArray.forEach(function(nucleus, index) {
12
  nucleus.opacity = 0;
13
});
14
15
electronArray.forEach(function(electron, index) {
16
  electron.opacity = 0;
17
});

Dieser Teil des Codes setzt die Opazität einzelner Elektronen und Protonen auf Null. Es sagt Two.js auch, die Elektronen und Protonen mit bestimmten Geschwindigkeiten zu drehen.

1
visible = 0;
2
3
document.addEventListener("click", function(event) {
4
  if (visible < nucleusArray.length) {
5
    nucleusArray[visible].opacity = 1;
6
    electronArray[visible].opacity = 1;
7
    visible++;
8
    text.value = elementNames[visible];
9
  }
10
  else {
11
    nucleusArray.forEach(el => el.opacity=0);
12
    electronArray.forEach(el => el.opacity=0);
13
    visible = 0;
14
    text.value = elementNames[0];
15
  }
16
});         
17

Der letzte Teil des Codes ermöglicht es uns, durch die Elemente zu iterieren, indem wir mit der Maus klicken oder tippen. Um das nächste Element zu laden, machen wir ein weiteres Elektron und ein weiteres Proton oder Neutron sichtbar und aktualisieren den Elementnamen. Nach dem Klick auf das letzte Element werden alle Partikel wieder ausgeblendet, damit wir von vorne beginnen können. Die visible-Variable verfolgt die Anzahl der derzeit sichtbaren atomaren Teilchen, so dass wir sie entsprechend ein- oder ausblenden können.

Klicken oder tippen Sie auf die folgende CodePen-Demo, um die ersten zehn Elemente des Periodensystems anzuzeigen.

Please accept marketing cookies to load this content.

Abschließende Gedanken

Wir haben dieses Tutorial mit einer kurzen Einführung in die Two.js Bibliothek und wie sie zum Zeichnen von Formen wie Rechtecken, Kreisen und Ellipsen verwendet werden kann, begonnen. Danach diskutierten wir, wie wir verschiedene Objekte gruppieren können, um sie alle auf einmal zu manipulieren. Wir haben diese Fähigkeit genutzt, um Elemente zu gruppieren, um sie synchron zu verschieben und zu drehen. Diese Werkzeuge kamen alle in unserer Animation der Atome der ersten zehn Elemente im Periodensystem zusammen.

Wie Sie sehen können, ist das Erstellen animierter 2D-Grafiken mit Two.js sehr einfach. Der Fokus dieses Beitrags lag darauf, Ihnen den schnellen Einstieg zu erleichtern, daher haben wir nur die Grundlagen behandelt. Sie sollten jedoch die offizielle Dokumentation lesen, um mehr über die Bibliothek zu erfahren!