Du hast deinen AdBlocker an?

Es wäre ein Traum, wenn du ihn für t3n.de deaktivierst. Wir zeigen dir gerne, wie das geht. Und natürlich erklären wir dir auch, warum uns das so wichtig ist. Digitales High-five, deine t3n-Redaktion

Entwicklung & Design

Fabric.js – Einführung in die mächtige JavaScript-Library

Mit unserer Mini-Serie für Web-Entwickler „WebDev hands on“ geben wir euch in Kooperation mit Microsoft modern.ie spannende Einblicke in Developer-Themen. Heute gibt es eine Einführung in Fabric.js.

Dieser Artikel stellt Fabric.js vor – eine mächtige JavaScript-Library, die den Umgang mit dem HTML5-Element <canvas> zum Kinderspiel macht. Fabric stellt ein fehlendes Objektmodell zur Verfügung, sowie einen SVG Parser, eine Ebene für Interaktivität und eine ganze Suite voller unverzichtbarer Werkzeuge. Es ist ein Open-Source-Projekt unter der MIT-Lizenz, zu welchem über Jahre hinweg viel beigetragen wurde.

Ich habe vor drei Jahren angefangen, Fabric zu entwickeln, da mir die Arbeit mit der nativen Canvas-API viel zu kompliziert war. Ich erstellte einen interaktiven Design-Editor für die Website meines Startup-Unternehmens printio.ru, über die sich Kunden ihre eigene Kleidung gestalten können. Damals gab es die Art von Interaktivität, die ich mir vorstellte, nur in Flash-Anwendungen. Heutzutage allerdings gibt es nur sehr wenige Libraries, die auch nur annähernd an das herankommen, was mit Fabric möglich ist.

Warum Fabric?

Mit Canvas kann man heute absolut beeindruckende Grafiken im Web erstellen, aber die API, die dafür zur Verfügung steht, arbeitet auf einer enttäuschend niedrigen Ebene. Wenn man nur ein paar Grundformen auf eine Fläche zeichnen will und sie danach nicht mehr anfassen muss, ist das eine Sache. Braucht ihr aber auch nur die geringste Interaktivität, wollt ihr ein Bild zu einem späteren Zeitpunkt ändern oder müsst ihr komplexere Formen zeichnen, dann erhöht sich der Arbeitsaufwand erheblich. Fabric soll dieses Problem lösen.

Native Canvas-Methoden erlauben euch lediglich, einfache grafische Befehle abzusetzen und damit quasi im Blindflug die ganze Canvas-Bitmap zu verändern. Wollt ihr ein Rechteck? Dann schreibt ihr fillRect(left, top, width, height). Wollt ihr eine Linie? Dann verwendet ihr eine Kombination aus moveTo(left, top) und lineTo(x,y). Es ist gerade so, als ob ihr mit einem Pinsel Schicht für Schicht immer mehr Öl- und Acrylfarbe auftragt, jedoch mit sehr wenig Kontrolle.

Anstatt auf so niedriger Ebene zu arbeiten, bietet Fabric ein einfaches, aber gleichzeitig mächtiges Objektmodell an, das auf den nativen Methoden aufsetzt. Es kümmert sich um den Canvas-Zustand und das Rendern und lässt euch direkt mit den Objekten arbeiten.

Hier ist ein einfaches Beispiel, das den Unterschied demonstriert: Das folgende Codebeispiel zeigt, wie ein rotes Rechteck mittels nativer Canvas-API irgendwo auf den Canvas gezeichnet würde:

// Das Canvas-Element referenzieren (with id="c")
var canvasEl = document.getElementById('c');
// Einen 2D-Kontext erstellen um darauf zu zeichnen (die vorhin erwŠhnte "Bitmap")
var ctx = canvasEl.getContext('2d');
// Die FŸllfarbe fŸr den Kontext setzen
ctx.fillStyle = 'red';
// Ein gefŸlltes Rechteck auf Position 100,100 Pixel, mit einer Ausdehnung von 20x20 Pixel erstellen.
ctx.fillRect(100, 100, 20, 20);

Der untere Code zeigt euch, wie man genau das selbe mit Fabric erreicht. Das (identische) Ergebnis beider Herangehensweisen ist in Bild 1 gezeigt.

// Erstelle einen Wrapper um das native canvas-Element (with id="c")
var canvas = new fabric.Canvas('c');
// erstelle ein Rectangle-Objekt
var rect = new fabric.Rect({
  left: 100,
  top: 100,
  fill: 'red',
  width: 20,
  height: 20
});
// das Rechteck auf den canvas "hinzufŸgen". 
canvas.add(rect);
Rotes Rechteck gezeichnet mit Fabric oder nativen Methoden
Bild 1. Rotes Rechteck gezeichnet mit Fabric oder nativen Methoden

In diesem Beispiel ist der Code noch annähernd gleich lang, ihr könnt aber schon sehen, wie unterschiedlich die Arbeit mit Fabric ist. Mit den nativen Methoden arbeitet ihr auf dem Kontext – einem Objekt, das für die gesamte Canvas-Bitmap steht. In Fabric dagegen arbeiten ihr an Objekten: Ihr definieren nur Instanzen, ändert deren Eigenschaften und fügt sie dem Canvas hinzu. Ihr seht schon, dass sich in der Fabric-Welt alles um diese Objekte dreht.

Ein schlichtes Rechteck zeichnen zu lassen, ist viel zu einfach. Macht es doch ein bisschen interessanter und dreht die Form ein wenig. Probieren wir mal 45 Grad, zuerst mit den nativen Canvas-Methoden:

var canvasEl = document.getElementById('c');
var ctx = canvasEl.getContext('2d');
ctx.fillStyle = 'red';
ctx.translate(100, 100);
ctx.rotate(Math.PI / 180 * 45);
ctx.fillRect(-10, -10, 20, 20);

Und so würdet ihr das mit Fabric machen. (Siehe Bild 2 für die grafische Ausgabe)

var canvas = new fabric.Canvas('c');
// create a rectangle with angle=45
var rect = new fabric.Rect({
  left: 100,
  top: 100,
  fill: 'red',
  width: 20,
  height: 20,
  angle: 45
});
canvas.add(rect);
Ein rotes, gedrehtes Rechteck, mit Fabric oder mit den nativen Canvas-Methoden gezeichnet.
Bild 2. Ein rotes, gedrehtes Rechteck, mit Fabric oder mit den nativen Canvas-Methoden gezeichnet.

Lasst uns rekapitulieren: In Fabric müsst ihr lediglich den Wert des Objektwinkels auf 45 ändern. Mit den nativen Methoden ist da schon mehr Arbeit nötig. Denkt daran, dass ihr nicht mit Objekten arbeiten könnt. Stattdessen müsst ihr die Positionierung und den Winkel der gesamten Canvas-Bitmap (ctx.translate, ctx.rotate) euren Anforderungen anpassen. Erst dann zeichnet ihr das Rechteck. Vergesst dabei nicht, die Bitmap entsprechend zu versetzen (-10, -10), damit das gedrehte Rechteck immer noch am Punkt 100,100 gezeichnet wird. Damit es nicht zu langweilig wird, dürfen ihr beim Drehen der Canvas-Bitmap auch noch die Winkelgrade ins Bogenmaß umrechnen.

Sicher könnt ihr schon sehen, warum es Fabric gibt und wie viel nervigen, sich wiederholenden Low-Level-Kauderwelsch es einem spart.

Schauen wir uns noch ein Beispiel an: Verfolgung des Canvas-Zustands.

Was ist, wenn ihr irgendwann das Rechteck an eine andere Stelle auf dem Canvas verschieben wollt? Wie könntet ihr das tun, ohne mit Objekten zu arbeiten? Würdet ihr einfach einen weiteren fillRect-Befehl auf einer Canvas-Bitmap aufrufen? Bestimmt nicht. Ein neuer fillRect-Befehl legt ja einfach ein Rechteck über alles, was bereits auf dem Canvas gezeichnet wurde. Um das Rechteck zu verschieben, müsst ihr zuerst den ganzen vorher gezeichneten Inhalt löschen und dann das Rechteck an einer neuen Position zeichnen (siehe Bild 3).

var canvasEl = document.getElementById('c');
...
ctx.strokRect(100, 100, 20, 20);
...
// gesamten Canvas lšschen
ctx.clearRect(0, 0, canvasEl.width, canvasEl.height);
ctx.fillRect(20, 50, 20, 20);

Und so würden Sie das mit Fabric machen:

var canvas = new fabric.Canvas('c');
...
canvas.add(rect);
...
rect.set({ left: 20, top: 50 });
canvas.renderAll();
Das rote Rechteck an einer neuen Stelle gezeichnet.
Bild 3. Das rote Rechteck an einer neuen Stelle gezeichnet.

Achtet auf folgenden wichtigen Unterschied: Mit Fabric müsst ihr nicht erst den Inhalt löschen, bevor ihr irgendeinen Inhalt ändert. Ihr arbeitet ja immernoch nur mit Objekten, deren Eigenschaften ihr einfach ändern könnt. Erst am Schluss lasst ihr den Canvas rendern, um ein neues Bild zu erhalten.

Objekte

Im obigen Kapitel habt ihr gesehen, wie man mit Rechtecken arbeitet, indem man Instanzen des fabric.Rect-Konstruktors erstellt. Fabric unterstützt natürlich auch noch andere Grundformen – Kreise, Dreiecke, Ellipsen und so weiter. Die Formen sind im Fabric-Namensraum als fabric.Circle, fabric.Triangle, fabric.Ellipse et cetera ansprechbar. Fabric stellt sieben Grundformen zur Verfügung:

Um einen Kreis zu zeichnen, braucht ihr nur ein Kreis-Objekt erstellen und es zum Canvas hinzufügen.

var circle = new fabric.Circle({
  radius: 20, fill: 'green', left: 100, top: 100
});
var triangle = new fabric.Triangle({
  width: 20, height: 30, fill: 'blue', left: 50, top: 50
});
canvas.add(circle, triangle);

Auf die selbe Weise könnt ihr alle anderen Grundformen erstellen. Bild 4 zeigt ein Beispiel, bei dem ein grüner Kreis an Position 100,100 gezeichnet wird und ein blaues Dreieck auf Position 50,50.

Ein blaues Dreieck und ein grüner Kreis mit Fabric gezeichnet.
Bild 4. Ein blaues Dreieck und ein grüner Kreis mit Fabric gezeichnet.

Objekte manipulieren

Grafische Objekte wie Rechtecke oder Kreise zu erstellen, ist nur der Anfang. Irgendwann werden Sie wahrscheinlich Ihre Objekte verändern müssen. Vielleicht soll eine bestimmte Aktion eine Zustandsveränderung auslösen oder eine Art von Animation abspielen. Oder vielleicht wollen Sie die Objekteigenschaften, wie Farbe, Transparenz, Größe oder Position, auf irgendwelche Mausaktionen hin ändern.

Fabric übernimmt für euch das Rendern des Canvas' und die Verwaltung der Zustände. Wir müssen nur die Objekte selbst verändern. Das vorherige Beispiel verwendete die set-Methode und zeigte, wie das Aufrufen von set({ left: 20, top: 50 }) das Objekt von seiner ursprünglichen Position verschob. In einer ähnlichen Weise könnt ihr die Eigenschaften eines Objektes ändern.

Bitte beachte unsere Community-Richtlinien

Eine Reaktion
fimbim

Die Liste der Github-Links führt zu 404ern. Ansonsten ne sehr geile Library!

Antworten

Melde dich mit deinem t3n-Account an oder fülle die unteren Felder aus.

Abbrechen

Finde einen Job, den du liebst