Nach dem Fragmentierungseffekt werde ich eine weitere interessante Animation angehen: den Blob! Wir sind uns alle einig, dass ein solcher Effekt mit CSS schwer zu erreichen ist, daher greifen wir normalerweise auf SVG zurück, um diese schleimigen Formen zu erzeugen. Aber jetzt, da die leistungsstarke Paint API verfügbar ist, ist die Verwendung von CSS nicht nur möglich, sondern vielleicht sogar ein vorzuziehender Ansatz, sobald die Browserunterstützung gegeben ist.
Erkundung der CSS Paint API-Reihe
- Teil 1: Bildfragmentierungseffekt
- Teil 2: Blob-Animation (Sie sind hier!)
- Teil 3: Polygon-Rand
- Teil 4: Abrundende Formen
Hier ist, was wir machen. Bisher gibt es nur Unterstützung für Chrome und Edge. Schauen Sie sich das also beim Lesen in einem dieser Browser an.

Den Blob erstellen
Lassen Sie uns die Logik hinter dem Zeichnen eines Blobs mit einem klassischen <canvas>-Element verstehen, um die Form besser zu veranschaulichen.
Wenn wir von einem Blob sprechen, sprechen wir auch von der allgemeinen Form eines verzerrten Kreises, daher können wir diese Form als Basis verwenden. Wir definieren N Punkte, die wir um einen Kreis platzieren (in Grün dargestellt).
const CenterX = 200;
const CenterY = 200;
const Radius = 150;
const N = 10;
var point = [];
for (var i = 0; i < N; i++) {
var x = Math.cos((i / N) * (2 * Math.PI)) * Radius + CenterX;
var y = Math.sin((i / N) * (2 * Math.PI)) * Radius + CenterY;
point[i] = [x, y];
}
Unter Berücksichtigung des Mittelpunkts (definiert durch CenterX/CenterY) und des Radius berechnen wir die Koordinate jedes Punktes mit einfacher Trigonometrie.
Danach zeichnen wir eine kubische Bézierkurve zwischen unseren Punkten mit quadraticCurveTo(). Dazu führen wir weitere Punkte ein (rot dargestellt), da eine kubische Bézierkurve einen Startpunkt, einen Kontrollpunkt und einen Endpunkt benötigt.
Die roten Punkte sind die Start- und Endpunkte, und die grünen Punkte können die Kontrollpunkte sein. Jeder rote Punkt liegt im Mittelpunkt zwischen zwei grünen Punkten.
ctx.beginPath(); /* start the path */
var xc1 = (point[0][0] + point[N - 1][0]) / 2;
var yc1 = (point[0][1] + point[N - 1][1]) / 2;
ctx.moveTo(xc1, yc1);
for (var i = 0; i < N - 1; i++) {
var xc = (point[i][0] + point[i + 1][0]) / 2;
var yc = (point[i][1] + point[i + 1][1]) / 2;
ctx.quadraticCurveTo(point[i][0], point[i][1], xc, yc);
}
ctx.quadraticCurveTo(point[N - 1][0], point[N - 1][1], xc1, yc1);
ctx.closePath(); /* end the path */
Nun müssen wir nur noch die Position unserer Kontrollpunkte aktualisieren, um die Blob-Form zu erzeugen. Versuchen wir es mit einem Punkt, indem wir Folgendes hinzufügen:
point[3][0]= Math.cos((3 / N) * (2 * Math.PI)) * (Radius - 50) + CenterX;
point[3][1]= Math.sin((3 / N) * (2 * Math.PI)) * (Radius - 50) + CenterY;
Der dritte Punkt ist dem Mittelpunkt unseres Kreises am nächsten (um ca. 50px) und unsere kubische Bézierkurve folgt der Bewegung perfekt, um eine gekrümmte Form zu erhalten.
Machen wir dasselbe mit allen Punkten. Wir können die gleiche allgemeine Idee verwenden und diese bestehenden Zeilen ändern:
var x = Math.cos((i / N) * (2 * Math.PI)) * Radius + CenterX;
var y = Math.sin((i / N) * (2 * Math.PI)) * Radius + CenterY;
...in:
var r = 50*Math.random();
var x = Math.cos((i / N) * (2 * Math.PI)) * (Radius - r) + CenterX;
var y = Math.sin((i / N) * (2 * Math.PI)) * (Radius - r) + CenterY;
Jeder Punkt wird um einen zufälligen Wert zwischen 0 und 50 Pixel verschoben, wodurch jeder Punkt um einen leicht unterschiedlichen Betrag näher an die Mitte rückt. Und als Ergebnis erhalten wir unsere Blob-Form!
Nun wenden wir diese Form als Maske auf ein Bild mit der CSS Paint API an. Da wir es mit einer blobigen Form zu tun haben, ist es sinnvoll, auch quadratische Elemente (Höhe gleich Breite) zu verwenden, bei denen der Radius gleich der halben Breite oder Höhe ist.
Hier verwenden wir eine CSS-Variable (N), um die Anzahl der Punkte zu steuern.
Ich empfehle dringend, den ersten Teil meines vorherigen Artikels zu lesen, um die Struktur der Paint API zu verstehen.
Jedes Mal, wenn der Code ausgeführt wird, erhalten wir dank der zufälligen Konfiguration eine neue Form.
Lass uns das animieren!
Einen Blob zu zeichnen ist gut und schön, aber ihn zu animieren ist besser! Die Animation des Blobs ist schließlich der Hauptzweck dieses Artikels. Wir werden sehen, wie wir verschiedene Arten von schleimigen Blob-Animationen mit derselben Codebasis erstellen können.
Die Hauptidee ist, die Position der Punkte – sei es alle oder einige davon – sanft anzupassen, um zwischen zwei Formen zu wechseln. Beginnen wir mit der einfachen: einem Übergang von einem Kreis zu einem Blob, indem wir die Position eines Punktes ändern.

Dafür habe ich eine neue CSS-Variable, B, eingeführt, auf die ich einen CSS-Übergang anwende.
@property --b{
syntax: '<number>';
inherits: false;
initial-value: 0;
}
img {
--b:0;
transition:--b .5s;
}
img:hover {
--b:100
}
Ich hole mir den Wert dieser Variablen innerhalb der paint()-Funktion und verwende ihn, um die Position unseres Punktes zu definieren.
Wenn Sie sich den Code in der eingebetteten verlinkten Demo ansehen, werden Sie Folgendes bemerken:
if(i==0)
var r = RADIUS - B;
else
var r = RADIUS
Alle Punkte haben eine feste Position (definiert durch den Radius der Form), aber der erste Punkt hat speziell eine variable Position (RADIUS - B). Beim Überfahren mit der Maus ändert sich der Wert von B von 0 auf 100, wodurch sich unser Punkt näher an die Mitte bewegt und dieser coole Effekt entsteht.
Machen wir das für mehr Punkte. Nicht alle, sondern nur die geraden. Ich definiere die Position wie folgt:
var r = RADIUS - B*(i%2);

Wir haben unsere erste Blob-Animation! Wir haben 20 Punkte definiert und die Hälfte davon auf Berührung näher an die Mitte bewegt.
Wir können leicht verschiedene Blob-Variationen erhalten, indem wir einfach die CSS-Variablen anpassen. Wir definieren die Anzahl der Punkte und den Endwert der B-Variable.
Versuchen wir es jetzt mit etwas Zufälligem. Anstatt unsere Punkte mit einem festen Wert zu bewegen, lassen wir diesen Wert zufällig alle bewegen. Wir haben das vorher verwendet:
var r = RADIUS - B*(i%2);
Ändern wir das in das hier:
var r = RADIUS - B*random();
…wobei random() uns einen Wert im Bereich [0 1] liefert. Mit anderen Worten, jeder Punkt wird um einen zufälligen Wert zwischen 0 und B bewegt. Hier ist das Ergebnis:
Sehen Sie das? Wir erhalten eine weitere coole Animation mit derselben Codestruktur. Wir haben nur eine Anweisung geändert. Wir können diese Anweisung zu einer Variablen machen, damit wir entscheiden können, ob wir die einheitliche oder die zufällige Konfiguration verwenden möchten, ohne unser JavaScript zu ändern. Wir führen eine weitere Variable, T, ein, die sich wie eine Boolesche Variable verhält:
if(T == 0)
var r = RADIUS - B*(i%2);
else
var r = RADIUS - B*random();
Wir haben zwei Animationen und dank der Variablen T können wir entscheiden, welche wir verwenden. Wir können die Anzahl der Punkte mit N und den Abstand mit der Variablen V steuern. Ja, viele Variablen, aber keine Sorge, wir fassen am Ende alles zusammen.
Was macht diese random()-Funktion?
Das ist die gleiche Funktion, die ich im vorherigen Artikel verwendet habe. Dort haben wir gesehen, dass wir uns nicht auf die Standard-Built-in-Funktion verlassen können, weil wir eine Zufallsfunktion benötigen, bei der wir den Seed kontrollieren können, um sicherzustellen, dass wir immer die gleiche Sequenz von Zufallswerten erhalten. Der Seed-Wert ist also auch eine weitere Variable, die wir kontrollieren können, um eine andere Blob-Form zu erhalten. Ändern Sie diesen Wert manuell und sehen Sie das Ergebnis.
Im vorherigen Artikel habe ich erwähnt, dass die Paint API die gesamte Komplexität auf der CSS-Seite entfernt und uns mehr Flexibilität gibt, komplexe Animationen zu erstellen. Zum Beispiel können wir das, was wir bisher gemacht haben, mit Keyframes und cubic-bezier() kombinieren.

Die Demo enthält ein weiteres Beispiel, das die parabolische Kurve verwendet, die ich in einem früheren Artikel detailliert beschrieben habe.
Steuerung der Bewegung der Punkte
In allen bisher erstellten Blobs betrachteten wir die gleiche Bewegung für unsere Punkte. Ob wir die einheitliche oder die zufällige Konfiguration verwenden, wir bewegen die Punkte immer vom Rand zum Mittelpunkt des Kreises entlang einer Linie.
Lassen Sie uns nun sehen, wie wir diese Bewegung steuern können, um noch *mehr* Animationen zu erhalten. Die Idee hinter dieser Logik ist einfach: Wir bewegen die x- und y-Koordinaten unterschiedlich.
Zuvor machten wir das:
var x = Math.cos((i / N) * (2 * Math.PI)) * (Radius - F(B)) + CenterX;
var y = Math.sin((i / N) * (2 * Math.PI)) * (Radius - F(B)) + CenterY;
…wobei F(B) eine Funktion ist, die auf der Variablen B basiert, die den Übergang speichert.
Nun haben wir stattdessen etwas wie das hier:
var x = Math.cos((i / N) * (2 * Math.PI)) * (Radius - Fx(B)) + CenterX;
var y = Math.sin((i / N) * (2 * Math.PI)) * (Radius - Fy(B)) + CenterY;
…wobei wir die Variablen x und y unterschiedlich aktualisieren, um mehr Animationen zu erzeugen. Versuchen wir ein paar.
Bewegung auf einer Achse
Für diese eine Funktion setzen wir eine der Funktionen gleich 0 und behalten die andere wie zuvor bei. Anders ausgedrückt, eine Koordinate bleibt während der Animation fest.
Wenn wir tun:
Fy(B) = 0
... erhalten wir:

Die Punkte bewegen sich nur horizontal, um einen anderen Effekt zu erzielen. Das Gleiche können wir leicht für die andere Achse tun, indem wir Fx(B)=0 setzen (Demo ansehen).
Ich denke, Sie verstehen das Prinzip. Alles, was wir tun müssen, ist, die Funktionen für jede Achse anzupassen, um eine andere Animation zu erhalten.
Bewegung nach links oder rechts
Versuchen wir eine andere Art der Bewegung. Anstatt die Punkte zum Zentrum konvergieren zu lassen, lassen wir sie sich in die gleiche Richtung bewegen (entweder nach rechts oder nach links). Wir benötigen eine Bedingung, die auf der Position des Punktes basiert, die durch den Winkel definiert ist.

Wir haben zwei Punktgruppen: die Punkte im Bereich [90deg 270deg] (die linke Seite) und die restlichen Punkte auf der rechten Seite der Form. Wenn wir die Indizes betrachten, können wir den Bereich anders ausdrücken, z. B. [0.25N 0.75N], wobei N die Anzahl der Punkte ist.
Der Trick ist, für jede Gruppe ein unterschiedliches Vorzeichen zu verwenden:
var sign = 1;
if(i<0.75*N && i>0.25*N)
sign = -1; /* we invert the sign for the left group */
if(T == 0)
var r = RADIUS - B*sign*(i%2);
else
var r = RADIUS - B*sign*random();
var x = Math.cos((i / N) * (2 * Math.PI)) * r + cx;
Und wir erhalten:

Wir können die gleiche Richtung erhalten, aber mit einem kleinen Nachteil: Eine Gruppe von Punkten ragt aus dem Maskenbereich heraus, weil wir bei einigen Punkten die Entfernung erhöhen, während wir bei anderen die Entfernung verringern. Wir müssen die Größe unseres Kreises verringern, um genügend Platz für alle unsere Punkte zu lassen.
Wir verringern einfach die Größe unseres Kreises mit dem Wert V, der den Endwert für unsere B-Variable definiert. Mit anderen Worten, es ist die maximale Entfernung, die ein Punkt erreichen kann.

Unsere ursprüngliche Form (dargestellt durch den grauen Bereich und mit den grünen Punkten definiert) wird einen kleineren Bereich abdecken, da wir den Radiuswert mit dem Wert von V verringern.
const V = parseFloat(properties.get('--v'));
const RADIUS = size.width/2 - V;

Wir haben das Problem behoben, dass die Punkte herausragen, aber wir haben einen weiteren kleinen Nachteil: Der interaktive Bereich ist derselbe, sodass der Effekt beginnt, noch bevor der Cursor das Bild berührt. Es wäre gut, wenn wir auch diesen Bereich verkleinern könnten, damit alles konsistent ist.
Wir können ein zusätzliches Wrapper-Element und einen Trick mit negativen Rändern verwenden. Hier ist die Demo. Der Trick ist ziemlich einfach:
.box {
display: inline-block;
border-radius: 50%;
cursor: pointer;
margin: calc(var(--v) * 1px);
--t: 0;
}
img {
display: block;
margin: calc(var(--v) * -1px);
pointer-events: none;
-webkit-mask: paint(blob);
--b: 0;
transition:--b .5s;
}
.box:hover img {
--b: var(--v)
}
Das zusätzliche Wrapper-Element ist ein inline-block-Element. Das Bild darin hat negative Ränder, die gleich der V-Variable sind, was die Gesamtgröße der Form verringert. Dann deaktivieren wir den Hover-Effekt auf dem Bildelement (mit pointer-events: none), sodass nur das Box-Element den Übergang auslöst. Schließlich fügen wir dem Box-Element einen Rand hinzu, um Überlappungen zu vermeiden.
Wie der vorherige Effekt kann auch dieser mit cubic-bezier() und Keyframes kombiniert werden, um weitere coole Animationen zu erhalten. Unten ist ein Beispiel, das meine Sinuskurve für einen Wobble-Effekt beim Überfahren verwendet.

Wenn wir einige Transformationen hinzufügen, können wir eine Art seltsame (aber ziemlich coole) Schiebeanimation erstellen.

Kreisförmige Bewegung
Lassen Sie uns eine weitere interessante Bewegung angehen, die uns erlaubt, unendliche und „realistische“ Blob-Animationen zu erstellen. Anstatt unsere Punkte von einem Ort zum anderen zu bewegen, werden wir sie um eine Umlaufbahn rotieren lassen, um eine kontinuierliche Bewegung zu erzielen.

Die anfängliche Position unserer Punkte (in Grün) wird zu einer Umlaufbahn, und der rote Kreis ist der Pfad, den unsere Punkte nehmen werden. Mit anderen Worten, jeder Punkt dreht sich um seine ursprüngliche Position und folgt einem Kreis mit einem Radius r.
Alles, was wir tun müssen, ist sicherzustellen, dass es keine Überlappung zwischen zwei benachbarten Pfaden gibt, daher muss der Radius einen maximal zulässigen Wert haben.

Ich werde die Mathematik nicht im Detail beschreiben, aber der Maximalwert ist gleich:
const r = 2*Radius*Math.sin(Math.PI/(2*N));

Das ist der relevante Teil des Codes:
var r = (size.width)*Math.sin(Math.PI/(N*2));
const RADIUS = size.width/2 - r;
// ...
for(var i = 0; i < N; i++) {
var rr = r*random();
var xx = rr*Math.cos(B * (2 * Math.PI));
var yy = rr*Math.sin(B * (2 * Math.PI));
var x = Math.cos((i / N) * (2 * Math.PI)) * RADIUS + xx + cx;
var y = Math.sin((i / N) * (2 * Math.PI)) * RADIUS + yy + cy;
point[i] = [x,y];
}
Wir ermitteln den Maximalwert des Radius und verringern diesen Wert vom Hauptradius. Denken Sie daran, dass wir genügend Platz für unsere Punkte benötigen, daher müssen wir den Maskenbereich verkleinern, wie wir es bei der vorherigen Animation getan haben. Dann ermitteln wir für jeden Punkt einen zufälligen Radius rr (zwischen 0 und r). Dann berechnen wir die Position innerhalb des kreisförmigen Pfades mit xx und yy. Und schließlich platzieren wir den Pfad um seine Umlaufbahn und erhalten die endgültige Position (die x, y-Werte).
Beachten Sie den Wert B, der wie üblich derjenige mit dem Übergang ist. Dieses Mal haben wir einen Übergang von 0 auf 1, um eine volle Umdrehung um die Umlaufbahn zu machen.
Spiralbewegung
Noch eine für Sie! Diese ist eine Kombination der beiden vorherigen.
Wir haben gesehen, wie man die Punkte um eine feste Umlaufbahn bewegt und wie man einen Punkt vom Rand des Kreises zum Zentrum bewegt. Wir können beides kombinieren und unseren Punkt um eine Umlaufbahn bewegen, und wir tun dasselbe für die Umlaufbahn, indem wir sie vom Rand zum Zentrum bewegen.
Fügen wir eine zusätzliche Variable zu unserem bestehenden Code hinzu:
for(var i = 0; i < N; i++) {
var rr = r*random();
var xx = rr*Math.cos(B * (2 * Math.PI));
var yy = rr*Math.sin(B * (2 * Math.PI));
var ro = RADIUS - Bo*random();
var x = Math.cos((i / N) * (2 * Math.PI)) * ro + xx + cx;
var y = Math.sin((i / N) * (2 * Math.PI)) * ro + yy + cy;
point[i] = [x,y];
}
Wie Sie sehen, habe ich dieselbe Logik wie bei der allerersten Animation verwendet, die wir uns angesehen haben. Wir reduzieren den Radius mit einem zufälligen Wert (in diesem Fall gesteuert mit Bo).

Noch eine schicke Blob-Animation! Jetzt hat jedes Element zwei Animationen: eine animiert die Umlaufbahn (Bo) und die andere animiert den Punkt auf seinem kreisförmigen Pfad (B). Stellen Sie sich all die Effekte vor, die Sie durch einfaches Anpassen der Animationswerte (Dauer, Ease usw.) erzielen können!
Putting everything together
Puh, wir sind mit all den Animationen fertig! Ich weiß, dass einige von Ihnen sich vielleicht bei all den Variationen und all den Variablen, die wir eingeführt haben, verloren gefühlt haben, aber keine Sorge! Wir fassen jetzt alles zusammen und Sie werden sehen, dass es einfacher ist, als Sie vielleicht erwarten.
Ich möchte auch hervorheben, dass das, was ich getan habe, keine erschöpfende Liste aller möglichen Animationen ist. Ich habe nur ein paar davon behandelt. Wir können noch mehr definieren, aber der Hauptzweck dieses Artikels ist es, die Gesamtstruktur zu verstehen und sie bei Bedarf erweitern zu können.
Fassen wir zusammen, was wir getan haben und was die Hauptpunkte sind:
- Die Anzahl der Punkte (
N): Diese Variable steuert die Granularität der Blob-Form. Wir definieren sie in CSS und sie wird später verwendet, um die Anzahl der Kontrollpunkte zu definieren. - Der Bewegungstyp (
T): In fast allen Animationen, die wir uns angesehen haben, habe ich immer zwei Arten von Animationen berücksichtigt: eine „einheitliche“ Animation und eine „zufällige“. Ich nenne dies den Bewegungstyp, den wir mit der VariablenTin CSS steuern können. Wir werden irgendwo im Code eine if-else-Anweisung basierend auf dieserT-Variable haben. - Die Zufallskonfiguration: Wenn wir mit zufälliger Bewegung arbeiten, müssen wir unsere eigene
random()-Funktion verwenden, bei der wir den Seed kontrollieren können, um die gleiche Zufallssequenz für jedes Element zu erhalten. Der Seed kann auch als Variable betrachtet werden, die verschiedene Formen erzeugt. - Die Art der Bewegung: Dies ist der Pfad, den die Punkte nehmen. Wir können viele Variationen haben, zum Beispiel:
- Vom Rand des Kreises zum Zentrum
- Eine Bewegung auf einer Achse (x- oder y-Achse)
- Eine kreisförmige Bewegung
- Eine Spiralbewegung
- und viele mehr...
Ähnlich wie der Bewegungstyp kann die Art der Bewegung auch bedingt gestaltet werden, indem eine weitere Variable eingeführt wird, und es gibt keine Grenzen für das, was hier getan werden kann. Alles, was wir tun müssen, ist, die mathematische Formel zu finden, um eine weitere Animation zu erstellen.
- Die Animationsvariable (
B): Dies ist die CSS-Variable, die den Übergang/die Animation enthält. Wir wenden im Allgemeinen einen Übergang/eine Animation von 0 auf einen bestimmten Wert an (in allen Beispielen mit der VariablenVdefiniert). Diese Variable wird verwendet, um die Position unserer Punkte auszudrücken. Das Aktualisieren dieser Variablen aktualisiert logischerweise die Positionen; daher die Animationen, die wir erhalten. In den meisten Fällen müssen wir nur eine Variable animieren, aber wir können mehr haben, basierend auf der Art der Bewegung (wie bei der Spiralbewegung, bei der wir zwei Variablen verwendet haben). - Der Formbereich: Standardmäßig bedeckt unsere Form den gesamten Elementbereich, aber wir haben gesehen, dass einige Bewegungen erfordern, dass die Punkte außerhalb der Form gehen. Deshalb mussten wir den Bereich verkleinern. Wir tun dies im Allgemeinen über den Maximalwert von
B(definiert durchV) oder einen anderen Wert basierend auf der Art der Bewegung.
Unser Code ist wie folgt strukturiert:
var point = [];
/* The center of the element */
const cx = size.width/2;
const cy = size.height/2;
/* We read all of the CSS variables */
const N = parseInt(properties.get('--n')); /* number of points */
const T = parseInt(properties.get('--t')); /* type of movement */
const Na = parseInt(properties.get('--na')); /* nature of movement */
const B = parseFloat(properties.get('--b')); /* animation variable */
const V = parseInt(properties.get('--v')); /* max value of B */
const seed = parseInt(properties.get('--seed')); /* the seed */
// ...
/* The radius of the shape */
const RADIUS = size.width/2 - A(V,T,Na);
/* Our random() function */
let random = function() {
// ...
}
/* we define the position of our points */
for(var i = 0; i < N; i++) {
var x = Fx[N,T,Na](B) + cx;
var y = Fy[N,T,Na](B) + cy;
point[i] = [x,y];
}
/* We draw the shape, this part is always the same */
ctx.beginPath();
// ...
ctx.closePath();
/* We fill it with a solid color */
ctx.fillStyle = '#000';
ctx.fill();
Wie Sie sehen, ist der Code nicht so komplex, wie Sie vielleicht erwartet haben. Die gesamte Arbeit liegt innerhalb der Funktionen Fx und Fy, die die Bewegung basierend auf N,T und Na definieren. Wir haben auch die Funktion A, die die Größe der Form reduziert, um zu verhindern, dass Punkte während der Animation überlaufen.
Lassen Sie uns das CSS überprüfen:
@property --b {
syntax: '<number>';
inherits: false;
initial-value: 0;
}
img {
-webkit-mask:paint(blob);
--n: 20;
--t: 0;
--na: 1;
--v: 50;
--seed: 125;
--b: 0;
transition: --b .5s;
}
img:hover {
--b: var(--v);
}
Ich denke, der Code ist selbsterklärend. Sie definieren die Variablen, wenden die Maske an und animieren die B-Variable mit einem Übergang oder Keyframes. Das ist alles!
Ich beende diesen Artikel mit einer finalen Demo, in der ich alle Variationen zusammenfüge. Alles, was Sie tun müssen, ist, mit den CSS-Variablen zu spielen.
Erkundung der CSS Paint API-Reihe
- Teil 1: Bildfragmentierungseffekt
- Teil 2: Blob-Animation (Sie sind hier!)
- Teil 3: Polygon-Rand
- Teil 4: Abrundende Formen