Aplikacje Internetowe: Kurs › Canvas, rysowanie na podstawie danych
Mamy taką zawartośc strony:
<!DOCTYPE html>
<html>
<head>
<title>Rysowanie</title>
<script>
domek = {"Paths" : [
[
{"Type" : "Rectangle", "X" : 100, "Y" : 100, "Width": 100, "Height": 100},
{"Type" : "Move", "X" : 100, "Y" : 100},
{"Type" : "LineTo", "X" : 150, "Y" : 0},
{"Type" : "LineTo", "X" : 200, "Y" : 100}
],[
{"Type" : "Rectangle", "X" : 120, "Y" : 120, "Width": 20, "Height": 20}
],[
{"Type" : "Rectangle", "X" : 160, "Y" : 120, "Width": 20, "Height": 20}
],[
{"Type" : "Rectangle", "X" : 140, "Y" : 150, "Width": 20, "Height": 50}
]
]} </script>
<script>
function rysujdomek() {
}
</script> </head>
<body>
<button id="rysuj" onclick="rysujdomek()">Rysuj domek</button>
<canvas id="canvas" width="400" height="300">Twoja przeglądarka nie obsługuje canvas</canvas>
</body>
</html>
Zadanie:
Nalezy tak napisac treśc funkcji rysujdomek() aby powstał domek opisany przez zmienną domek:
popatrzmy najpierw na zawartosc pliku domek.js i zdefiniowaną tam zmienną domek
domek = {Paths: [....]};
klamry { i } oznaczają ze mamy do czynienia z obiektem, jego jedyną właściwością jest Paths:
domek.Paths
teraz popatrzmy jaką partośc ma Paths
Paths: [....];
klamry [ i ] wskazują ze mamy do czynienia z tablicą przypatrzmy się jak wyglądają kolejne elementy tablicy:
Paths: [[...],[...],[...],[...]];
każdy z elementów tablicy jest określony przez klamry [ i ] co oznacza że każdy element tablicy jest tablicą (strukturę taką zwykle nazywa się tablicą tablic)) odczytajmy pierwszy element tablicy Paths (pamiętajmy że Paths jest właściwością obiektu domek):
var obiekty = domek.Paths[0];
przypatrzmy się teraz co jest zawartością zmiennej obiekty:
obiekty = [{...},{...},{...}]
każdy element tablicy obiekty jest określony przez klamry { i } co zonacza ze jest obiektem (podobnie jak zmienna domek) odczytajmy pierwszy element tablicy obiekty (czyli ten o indeksie 0):
var obiekt = obiekty[0];
sprawdzmy co jest w zmiennej obiekt:
obiekt = { "Type" : "Rectangle", "X" : 100, "Y" : 100, "Width": 100, "Height": 100 }
(cudzysłowy w nazwach właściwości są nieobowiązkowe w tym przypadku, odczytuje się je identycznie jakby codzysłowów nie było) mamy tu obiekt mający właściwości: Type, X, Y, Width, Height naszym zadaniem jest narywanie na canvasie figury opisanej przez parametr Type oraz poprzez pozostałe parametry, w przypadku Rectange będą to X, Y, Width i Height, więc kod w powyższym przypadku powinien być taki:
ctx.rect(obiekt.X,obiekt.Y,obiekt.Width,obiekt.Height);
w przypadku przesuniecia to będzie
ctx.moveTo(obiekt.X,obiekt.Y);
a w przypadku lini
ctx.lineTo(obiekt.X,obiekt.Y);
podsumowując ten fragment kod rysujący uwzględniający odczyt właściwości Type będzie wyglądał tak:
switch (obiekt.Type) { case "Rectangle": ctx.rect(obiekt.X,obiekt.Y,obiekt.Width,obiekt.Height);break; case "Move": ctx.moveTo(obiekt.X,obiekt.Y);break; case "LineTo": ctx.lineTo(obiekt.X,obiekt.Y);break; }
będziemy musieli powtórzyć ten kod dla każdego obiektu na ścieżce, a więc tworzymy pętlę odczytująca każdy obiekt ścieżki:
for (var i=0;i<obiekty.length;i++) { var obiekt = obiekty[i]; switch (obiekt.Type) { ... } }
ok, ale to dopiero pierwsza scieżka, jak widać nasz ryzunek składa się z większej ilości ścieżek, ponieważ również są one tablicą możemy je po kolei odczytywać w pętli
for (var j=0;j<domek.Paths.length;j++) { var obiekty = domek.Paths[j]; .... //tutaj kod powyżej rysujący obiekty ścieżki }
proszę zauważyć ze celowo użyłem innej zmiennej pętli (wcześniej i do obiektów, teraz j dla ścieżek), chodzi o to aby wartości zmiennych się nie pomieszały należy również pamięteać ze aby narysować coś na canvasie trzeba rozpocząć scieżekę przez beginPath() i ją narysować poprzez stroke(), dopiszmy więc w odpowiednich miejscach
for (var j=0;j<domek.Paths.length;j++) { var obiekty = domek.Paths[j]; ctx.beginPath(); .... //tutaj kod powyżej rysujący obiekty ścieżki ctx.stroke(); }
no to jeszcze trzeba w znany sposób "pobrac" canvas z interfejsu:
var canvas = document.getElementById("canvas");
oraz utworzyć kontekst rysowania:
var ctx = canvas.getContext("2d");
i można skompletowac kod:
function rysujdomek() { var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); //pętla dla ścieżek for (var j=0;j<domek.Paths.length;j++) { var obiekty = domek.Paths[j]; ctx.beginPath(); //pętla dla obiektów for (var i=0;i<obiekty.length;i++) { var obiekt = obiekty[i]; switch (obiekt.Type) { case "Rectangle": ctx.rect(obiekt.X,obiekt.Y,obiekt.Width,obiekt.Height);break; case "Move": ctx.moveTo(obiekt.X,obiekt.Y);break; case "LineTo": ctx.lineTo(obiekt.X,obiekt.Y);break; } } ctx.stroke(); } }