Bearbeiten von HTML5-Canvas mit Konva: Teil 3, Komplexe Formen und Sprites
German (Deutsch) translation by Federicco Ancie (you can also view the original English article)
Im zweiten Tutorial dieser Serie haben Sie gelernt, wie Sie mit Konva Grundformen zeichnen. Sie können die Grundformen auf die eine oder andere Weise kombinieren, um Sterne, Ringe, Pfeile, Uhren oder eine Hütte zu erstellen. Mit Konva können Sie auch einige häufig verwendete komplexe Formen erstellen, indem Sie die von der Bibliothek bereitgestellten integrierten Funktionen verwenden.
In diesem Tutorial erfahren Sie, wie Sie in Konva Sterne und Ringe erstellen. Danach werden wir diskutieren, wie man Text mit Konva schreibt und wie man ihn entlang eines bestimmten Pfades schreibt. Sie lernen auch, wie Sie mit Konva Bilder und Sprites auf eine Leinwand zeichnen.
Sterne und Ringe zeichnen
Im Vergleich zu vielen anderen komplexen Formen, die Sie auf die Leinwand zeichnen können, ist eine Sternform eine der häufigsten. Mit den richtigen Werten können Sie auch spitze Sterne in einfache abzeichenartige Formen verwandeln. Mit Konva können Sie mit dem Objekt Konva.Star() Sterne zeichnen.
Mit der numPoints-Eigenschaft können Sie die Anzahl der Spitzen angeben, die ein Stern haben soll. Sie können die Größe dieser Spitzen mithilfe der Eigenschaften innerRadius und outerRadius steuern. Ein großer Unterschied im Wert dieser Eigenschaften macht die Sterne stacheliger. Wenn Sie den äußeren Radius gleich dem inneren Radius setzen, wird ein reguläres Polygon erstellt, dessen Anzahl der Seiten doppelt so hoch ist wie der Wert von numPoints. Das Variieren der Werte von numPoints, innerRadius und outerRadius kann zu interessanten Formen führen.
1 |
var canvasWidth = 600; |
2 |
var canvasHeight = 400; |
3 |
|
4 |
var stage = new Konva.Stage({ |
5 |
container: "example", |
6 |
width: canvasWidth, |
7 |
height: canvasHeight |
8 |
});
|
9 |
|
10 |
var layerA = new Konva.Layer(); |
11 |
|
12 |
var starA = new Konva.Star({ |
13 |
x: 70, |
14 |
y: 80, |
15 |
numPoints: 4, |
16 |
innerRadius: 10, |
17 |
outerRadius: 50, |
18 |
stroke: "black", |
19 |
fill: "rgba(200,0,200, 1)", |
20 |
});
|
21 |
|
22 |
var starB = new Konva.Star({ |
23 |
x: 200, |
24 |
y: 100, |
25 |
numPoints: 8, |
26 |
innerRadius: 10, |
27 |
outerRadius: 50, |
28 |
stroke: "black", |
29 |
fill: "rgba(0, 0, 200, 1)", |
30 |
});
|
31 |
|
32 |
var starC = new Konva.Star({ |
33 |
x: 475, |
34 |
y: 175, |
35 |
numPoints: 20, |
36 |
innerRadius: 90, |
37 |
outerRadius: 100, |
38 |
stroke: "orange", |
39 |
fill: "yellow", |
40 |
});
|
41 |
|
42 |
var starD = new Konva.Star({ |
43 |
x: 325, |
44 |
y: 75, |
45 |
numPoints: 5, |
46 |
innerRadius: 20, |
47 |
outerRadius: 40, |
48 |
stroke: "black", |
49 |
fill: "lightgreen", |
50 |
});
|
51 |
|
52 |
var starE = new Konva.Star({ |
53 |
x: 100, |
54 |
y: 250, |
55 |
numPoints: 25, |
56 |
innerRadius: 25, |
57 |
outerRadius: 80, |
58 |
stroke: "black", |
59 |
fill: "white", |
60 |
});
|
61 |
|
62 |
var starF = new Konva.Star({ |
63 |
x: 300, |
64 |
y: 275, |
65 |
numPoints: 40, |
66 |
innerRadius: 5, |
67 |
outerRadius: 80, |
68 |
stroke: "black", |
69 |
fill: "black", |
70 |
});
|
71 |
|
72 |
layerA.add(starA, starB, starC, starD, starE, starF); |
73 |
|
74 |
stage.add(layerA); |
Wie üblich können Sie die von Ihnen erstellten Sternformen mithilfe der Eigenschaften rotation, skale, saleX und skaleY drehen und skalieren. Ebenso können Sie die opacity eines Sterns mithilfe der opacity-Eigenschaft steuern und mithilfe der visible Eigenschaft ein- oder ausblenden.
Ringe in Konva bestehen aus einem größeren durchgezogenen Kreis und einem kleineren hohlen Kreis, der darüber gelegt wird. Der Radius des inneren Kreises wird mit der Eigenschaft innerRadius angegeben, und der Radius des äußeren Kreises wird mit der Eigenschaft outerRadius angegeben. Die x- und y-Eigenschaften steuern die Position des Mittelpunkts des Sterns.
Sie können die von Ihnen erstellten Ringe mithilfe der Eigenschaften scaleX, scaleY, scale und rotation skalieren und drehen. Beachten Sie jedoch, dass die Drehung keine Auswirkungen zu haben scheint, es sei denn, Sie haben den Ring mit unterschiedlichen Größen in x- und y-Richtung skaliert.
1 |
var canvasWidth = 600; |
2 |
var canvasHeight = 400; |
3 |
|
4 |
var stage = new Konva.Stage({ |
5 |
container: "example", |
6 |
width: canvasWidth, |
7 |
height: canvasHeight |
8 |
});
|
9 |
|
10 |
var layerA = new Konva.Layer(); |
11 |
|
12 |
var ringA = new Konva.Ring({ |
13 |
x: 125, |
14 |
y: 100, |
15 |
innerRadius: 10, |
16 |
outerRadius: 50, |
17 |
stroke: "black", |
18 |
fill: "rgba(200,0,200, 1)", |
19 |
});
|
20 |
|
21 |
var ringB = new Konva.Ring({ |
22 |
x: 200, |
23 |
y: 100, |
24 |
innerRadius: 10, |
25 |
outerRadius: 50, |
26 |
stroke: "black", |
27 |
fill: "rgba(0, 0, 200, 0.5)", |
28 |
});
|
29 |
|
30 |
var ringC = new Konva.Ring({ |
31 |
x: 475, |
32 |
y: 175, |
33 |
innerRadius: 90, |
34 |
outerRadius: 100, |
35 |
stroke: "orange", |
36 |
fill: "yellow", |
37 |
});
|
38 |
|
39 |
var ringD = new Konva.Ring({ |
40 |
x: 325, |
41 |
y: 100, |
42 |
innerRadius: 20, |
43 |
outerRadius: 40, |
44 |
scaleY: 2, |
45 |
scaleX: 0.3, |
46 |
rotation: 45, |
47 |
stroke: "black", |
48 |
fill: "lightgreen", |
49 |
});
|
50 |
|
51 |
var starA = new Konva.Star({ |
52 |
x: 200, |
53 |
y: 275, |
54 |
numPoints: 20, |
55 |
innerRadius: 50, |
56 |
outerRadius: 115, |
57 |
stroke: "black", |
58 |
fill: "black", |
59 |
});
|
60 |
|
61 |
var ringE = new Konva.Ring({ |
62 |
x: 200, |
63 |
y: 275, |
64 |
innerRadius: 10, |
65 |
outerRadius: 90, |
66 |
stroke: "black", |
67 |
fill: "red", |
68 |
});
|
69 |
|
70 |
var starB = new Konva.Star({ |
71 |
x: 200, |
72 |
y: 275, |
73 |
numPoints: 10, |
74 |
innerRadius: 50, |
75 |
outerRadius: 80, |
76 |
stroke: "black", |
77 |
fill: "white", |
78 |
});
|
79 |
|
80 |
var starC = new Konva.Star({ |
81 |
x: 200, |
82 |
y: 275, |
83 |
numPoints: 10, |
84 |
innerRadius: 25, |
85 |
outerRadius: 50, |
86 |
stroke: "black", |
87 |
fill: "orange", |
88 |
});
|
89 |
|
90 |
var ringF = new Konva.Ring({ |
91 |
x: 200, |
92 |
y: 275, |
93 |
innerRadius: 10, |
94 |
outerRadius: 20, |
95 |
stroke: "black", |
96 |
fill: "white", |
97 |
});
|
98 |
|
99 |
layerA.add(ringA, ringB, ringC, ringD, starA, ringE, starB, starC, ringF); |
100 |
|
101 |
stage.add(layerA); |
Im folgenden Beispiel habe ich mehrere Stern- und Ringformen zusammengelegt, um ein schönes Muster zu erstellen. Die drei Sterne und zwei Ringe im Muster sind konzentrisch. Denken Sie daran, dass Sie immer die größte Form zuerst zeichnen, wenn Sie versuchen, so etwas zu erstellen. Wenn ich später starA zur Ebene hinzugefügt hätte, hätte es alle kleineren Ringe und Sterne bedeckt und sie vor den Zuschauern versteckt.
Text und TextPath in Konva
Mit dem Objekt Konva.Text() können Sie Text auf eine Leinwand schreiben. Beim Erstellen eines Textobjekts können Sie den Wert für Schriftfamilie, Schriftgröße, Schriftstil und Schriftvariante mithilfe der Eigenschaften fontFamily, fontSize, fontStyle und fontVariant angeben. Die Standardschriftfamilie ist Arial und die Standardschriftgröße ist 12. Sie können die fontStyle-Eigenschaft auf normal, fett oder kursiv setzen. Ebenso kann fontVariant entweder auf Normal oder Smallcaps gesetzt werden.
Der tatsächliche Text, den Sie schreiben möchten, kann mithilfe der text-Eigenschaft angegeben werden. Wenn in einem mehrzeiligen Kommentar nicht genügend Platz zwischen den Zeilen vorhanden ist, können Sie ihn mit der Eigenschaft lineHeight erhöhen.
Der Punkt oben links, von dem aus Konva mit dem Schreiben des Textes beginnen soll, wird mithilfe der Eigenschaften x und y angegeben. Sie können die Breite des Texts mithilfe der Eigenschaft width begrenzen. Jeder Text, den Sie schreiben, wird standardmäßig ausgerichtet. Sie können es mit der align-Eigenschaft nach rechts oder mittig ausrichten.
1 |
var canvasWidth = 600; |
2 |
var canvasHeight = 400; |
3 |
|
4 |
var stage = new Konva.Stage({ |
5 |
container: "example", |
6 |
width: canvasWidth, |
7 |
height: canvasHeight |
8 |
});
|
9 |
|
10 |
var layerA = new Konva.Layer(); |
11 |
|
12 |
var textA = new Konva.Text({ |
13 |
y: 25, |
14 |
width: canvasWidth, |
15 |
align: 'center', |
16 |
text: "QUOTE OF THE DAY", |
17 |
fontSize: 50, |
18 |
fontFamily: "Lato" |
19 |
});
|
20 |
|
21 |
var textB = new Konva.Text({ |
22 |
x: canvasWidth/10, |
23 |
y: 175, |
24 |
width: canvasWidth*8/10, |
25 |
align: 'center', |
26 |
lineHeight: 1.4, |
27 |
text: "You've gotta dance like there's nobody watching,\n Love like you'll never be hurt,\n Sing like there's nobody listening,\n And live like it's heaven on earth.", |
28 |
fontSize: 25, |
29 |
fontFamily: "Lato" |
30 |
});
|
31 |
|
32 |
var rectA = new Konva.Rect({ |
33 |
x: canvasWidth/10 - 10, |
34 |
y: 140, |
35 |
width: canvasWidth*8/10 + 20, |
36 |
height: 240, |
37 |
stroke: "black", |
38 |
fill: "brown" |
39 |
});
|
40 |
|
41 |
var rectB = new Konva.Rect({ |
42 |
x: canvasWidth/10, |
43 |
y: 150, |
44 |
width: canvasWidth*8/10, |
45 |
height: 220, |
46 |
stroke: "black", |
47 |
fill: "lightblue" |
48 |
});
|
49 |
|
50 |
var starA = new Konva.Star({ |
51 |
x: canvasWidth/10, |
52 |
y: 150, |
53 |
innerRadius: 40, |
54 |
outerRadius: 30, |
55 |
numPoints: 10, |
56 |
stroke: "black", |
57 |
fill: "orange" |
58 |
});
|
59 |
|
60 |
layerA.add(textA, rectA, starA, rectB, textB); |
61 |
|
62 |
stage.add(layerA); |
Im obigen Beispiel sollten Sie beachten, dass ich der Ebene nach dem Hinzufügen aller anderen Elemente textB hinzugefügt habe. Auf diese Weise können wir sicherstellen, dass das tatsächliche Zitat über allen anderen Formen bleibt.
Der Text, den Sie auf die Leinwand schreiben, muss keinen geraden Linien folgen. Mithilfe der data-Eneigenschaft können Sie auch einen Pfad für den folgenden Text angeben. Der Pfad wird in Form einer SVG-Datenzeichenfolge bereitgestellt und kann Befehle zum Folgen von Linien, Kurven und Bögen enthalten.
Eine wichtige Sache, an die Sie denken sollten, ist, dass der Text, den Sie entlang eines bestimmten Pfades schreiben möchten, mit dem Objekt Konva.TextPath() erstellt werden muss. Hier ist ein Beispiel, das den Pfad für den Text in Form einer Cubic Bezier-Kurve bereitstellt.
1 |
var canvasWidth = 600; |
2 |
var canvasHeight = 400; |
3 |
|
4 |
var stage = new Konva.Stage({ |
5 |
container: "example", |
6 |
width: canvasWidth, |
7 |
height: canvasHeight |
8 |
});
|
9 |
|
10 |
var layerA = new Konva.Layer(); |
11 |
|
12 |
var textA = new Konva.TextPath({ |
13 |
y: 25, |
14 |
align: 'center', |
15 |
data: 'M100,300 C150,100 200,50 500 60', |
16 |
text: "THIS TEXT GOES ALONG A PATH", |
17 |
fontSize: 35, |
18 |
fontFamily: "Lato", |
19 |
fill: "orange" |
20 |
});
|
21 |
|
22 |
var textB = new Konva.TextPath({ |
23 |
y: 28, |
24 |
align: 'center', |
25 |
data: 'M100,320 C200,200 400,400 500 80', |
26 |
text: "THIS TEXT GOES ALONG ANOTHER PATH", |
27 |
fontSize: 25, |
28 |
fontFamily: "Lato", |
29 |
fill: "green" |
30 |
});
|
31 |
|
32 |
layerA.add(textA, textB); |
33 |
|
34 |
stage.add(layerA); |
Zeichnen von Bildern und Sprites mit Konva
Sie sollten jetzt in der Lage sein, eine Vielzahl von Formen mit den in diesem und dem vorherigen Lernprogramm beschriebenen Methoden zu erstellen. Manchmal ist es jedoch sinnvoller, ein Bild direkt zu verwenden, wenn Sie versuchen, eine Grafik auf die Leinwand zu zeichnen. Mit Konva können Sie Bilder mit dem Objekt Konva.Image() zeichnen.
Die Position der oberen linken Ecke eines Bildes wird durch den Wert der x- und y-Eigenschaften bestimmt. In ähnlicher Weise werden width und height mithilfe der Eigenschaften angegeben. Die Werte der Eigenschaften width und height müssen nicht den tatsächlichen Abmessungen des Bildes entsprechen. Sie können das Bild auch mithilfe der Eigenschaften rotation, skale, skaleX und skaleY skalieren oder drehen.
1 |
var canvasWidth = 600; |
2 |
var canvasHeight = 400; |
3 |
|
4 |
var stage = new Konva.Stage({ |
5 |
container: "example", |
6 |
width: canvasWidth, |
7 |
height: canvasHeight |
8 |
});
|
9 |
|
10 |
var layerA = new Konva.Layer(); |
11 |
|
12 |
var theImage = new Image(); |
13 |
theImage.src = "path/to/the/image.jpg"; |
14 |
|
15 |
theImage.onload = function() { |
16 |
var field = new Konva.Image({ |
17 |
x: 35, |
18 |
y: 115, |
19 |
image: theImage, |
20 |
width: 500, |
21 |
height: 250, |
22 |
rotation: -10, |
23 |
stroke: "black", |
24 |
strokeWidth: 15 |
25 |
});
|
26 |
|
27 |
layerA.add(field); |
28 |
stage.add(layerA); |
29 |
};
|
Es ist erwähnenswert, dass ich im obigen Code das Konva.Image() -Objekt instanziiert habe, nachdem das Bild bereits geladen wurde. Der Versuch, das Konva.Image() -Objekt zu instanziieren, bevor das Bild geladen wurde, führt zu einem Fehler. Das Bild des Feldes wurde von Pixabay aufgenommen.
Mit Konva können Sie mithilfe des Konva.Sprite() -Objekts auch Sprites auf der Leinwand rendern. Der einzige Unterschied besteht darin, dass Sie dieses Mal zusätzlich zu dem Bildschlüssel, den wir zuvor beim Rendern des Bildes verwendet haben, die animation- und animation-Tasten verwenden müssen.
Die animation-Taste akzeptiert eine Zeichenfolge, die die id der abzuspielenden Animation angibt. Der animation-Schlüssel akzeptiert ein Objekt, in dem die Animationskarte für das Sprite als Wert gespeichert ist. Mit der frameRate-Eigenschaft können Sie die Geschwindigkeit steuern, mit der eine Sprite-Animation abgespielt werden soll.
1 |
var canvasWidth = 600; |
2 |
var canvasHeight = 400; |
3 |
|
4 |
var stage = new Konva.Stage({ |
5 |
container: "example", |
6 |
width: canvasWidth, |
7 |
height: canvasHeight |
8 |
});
|
9 |
|
10 |
var layerA = new Konva.Layer(); |
11 |
var theSprite = new Image(); |
12 |
|
13 |
theSprite.src = |
14 |
"path/to/hero_spritesheet.png"; |
15 |
|
16 |
var animations = { |
17 |
standing: [0, 0, 80, 94], |
18 |
walking: [0, 94, 80, 94, |
19 |
80, 94, 80, 94, |
20 |
160, 94, 80, 94, |
21 |
240, 94, 80, 94, |
22 |
320, 94, 80, 94, |
23 |
400, 94, 80, 94], |
24 |
jumping: [0, 282, 80, 94, |
25 |
80, 282, 80, 94, |
26 |
160, 282, 80, 94] |
27 |
};
|
28 |
|
29 |
theSprite.onload = function() { |
30 |
var heroA = new Konva.Sprite({ |
31 |
x: 50, |
32 |
y: 50, |
33 |
image: theSprite, |
34 |
animation: 'standing', |
35 |
animations: animations, |
36 |
frameRate: 6, |
37 |
frameIndex: 0 |
38 |
});
|
39 |
|
40 |
var heroB = new Konva.Sprite({ |
41 |
x: 50, |
42 |
y: 150, |
43 |
image: theSprite, |
44 |
animation: 'walking', |
45 |
animations: animations, |
46 |
frameRate: 6, |
47 |
frameIndex: 0 |
48 |
});
|
49 |
|
50 |
var heroC = new Konva.Sprite({ |
51 |
x: 50, |
52 |
y: 250, |
53 |
image: theSprite, |
54 |
animation: 'walking', |
55 |
animations: animations, |
56 |
frameRate: 60, |
57 |
frameIndex: 0 |
58 |
});
|
59 |
|
60 |
var heroD = new Konva.Sprite({ |
61 |
x: 275, |
62 |
y: 150, |
63 |
scale: 2, |
64 |
image: theSprite, |
65 |
animation: 'jumping', |
66 |
animations: animations, |
67 |
frameRate: 2, |
68 |
frameIndex: 0 |
69 |
});
|
70 |
|
71 |
layerA.add(heroA, heroB, heroC, heroD); |
72 |
stage.add(layerA); |
73 |
|
74 |
heroA.start(); |
75 |
heroB.start(); |
76 |
heroC.start(); |
77 |
heroD.start(); |
78 |
};
|
Die Breite und Höhe unseres Helden-Sprites beträgt 80px bzw. 94px. Ich habe diese Werte verwendet, um Konva die Position eines Sprites mitzuteilen, die beim Abspielen einer bestimmten Animationssequenz angezeigt werden soll. Jede Animationssequenz wurde mit einer id versehen, um zu identifizieren, was der Held tut. Diese id wird später verwendet, wenn Sie Konva mitteilen möchten, welche Animation abgespielt werden soll. Genau wie im vorherigen Beispiel habe ich den Helden nach dem Laden des Bildes instanziiert, um Fehler zu vermeiden.
Das Hero Sprite-Blatt, das wir in der Demo verwenden, wurde von tokka erstellt. Ich habe das gleiche Bild auch im Tutorial Crafty Beyond the Basics: Sprites verwendet, um eine Sprite-Animation zu erstellen. Die Tutorials in dieser Serie zeigen Ihnen, wie Sie mit Crafty ein einfaches 2D-Spiel erstellen.
Zurück zu Konva: Das folgende Beispiel zeigt eine wandelnde und springende Heldenanimation. Der Held unten hat einen höheren frameRate-Wert, was den Anschein erweckt, als würde der Held mit übermenschlicher Geschwindigkeit laufen.
Abschluss
Nach Abschluss des zweiten und dritten Tutorials sollten Sie nun in der Lage sein, mit Konva viele Formen, Muster und Designs selbst zu erstellen. Der letzte Abschnitt zeigte Ihnen auch, wie Sie Bilder und Sprites auf Ihre Leinwand zeichnen. Dies sollte alle Ihre zeichnungsbezogenen Anforderungen abdecken.
Wenn Sie Fragen zu diesem Tutorial haben, helfe ich Ihnen gerne weiter. Im nächsten Tutorial erfahren Sie, wie Sie Ihre Formen mit Verläufen füllen und Schatten auf alles anwenden, was Sie auf der Leinwand zeichnen.



