Kurs HTML5 - WebMatrix - Canvas  Udostępnij na: Facebook

Autor: Piotr Bubacz

Opublikowano: 2011-12-01

Grafika jest podstawą każdej dobrej strony. Najczęściej jest to statyczny obrazek, osadzany za pomocą polecenia img. Jednak na nowoczesnych stronach nie jest to już w pełni wystarczające. Użytkownicy oczekują animacji i interakcji z elementami grafiki. Do tego celu doskonale nadaje się element canvas, wprowadzany w HTML5. Umożliwia on wyświetlenie grafiki rastrowej na stronie.

Przed wykonaniem zadań powinieneś wiedzieć:

Po wykonaniu zadań nauczysz się:

  • jak dodać tło,
  • jak animować elementy,
  • jak dodać obsługę klawiatury.

Implementacja

Twoim zadaniem będzie przedstawienie animacji piłki (koła) na stronie. Użytkownik będzie mógł wpływać na szybkość przemieszczania elementu za pomocą klawiszy strzałek. Widok końcowy aplikacji został przedstawiony na Rys. 1.

Rys. 1. Efekt końcowy.

Przygotowanie strony

Dodaj szablon i obramuj element canvas kolorem niebieskim tak, aby zaznaczyć obszar elementu.

  1. W programie WebMatrix utwórz nową stronę i nazwij ją SVG.
  • Uruchom program WebMatrix.
  • Kliknij przycisk Templates.
  • Wybierz szablon Empty Site i w polu Site Name wpisz Canvas.
  • Kliknij przycisk OK.
  • Następnie kliknij przycisk Files.
  • Potem prawym przyciskiem myszki kliknij plik Default.cshtml. Następnie kliknij przycisk Delete. W oknie potwierdź chęć usunięcia pliku.
  1. Dodaj nowy plik do projektu w WebMatrix.
  • Na wstążce Home kliknij New, a następnie New File.
  • Na liście dostępnych typów plików, kliknij HTML, a następnie jako nazwę określ index.html. (Rys. 2.).

Rys. 2. Dodanie pliku html w WebMatrix.

  1. Umieść niezbędne elementy do obsługi Canvas.
  • W znaczniku title wpisz:
Canvas w WebMatrix
  • Ustaw kursor za znacznikiem title i dodaj nową linię. Wklej:
<script type="text/javascript">
        // Uruchom funkcję draw po załadowaniu wszystkich obiektów na stronie.
        window.onload = draw;   

        function draw(){
          var canvas = document.getElementById('canvas1');
          if (canvas.getContext){
            var context = canvas.getContext('2d');
            // w tym miejscu będą umieszczone wszystkie polecenia rysujące
          }
          else{
            // Tutaj umieść kod, który zostanie wykonany w momencie, kiedy przeglądarka nie wspiera elementu canvas
          }
        }
</script>
<style type="text/css">
    canvas { border: 1px solid blue; }
</style>
  • W elemencie body umieść znacznik canvas:
<canvas id="canvas1" width="600" height="600"></canvas>
  1. Zapisz stronę index.html.
Informacja
Przygotowany szablon jest uniwersalny i możesz stosować go w Twoich projektach. Więcej informacji o szablonie znajdziesz w cyklu poświęconym SVG w HTML5 w samouczku Canvas podstawy.

Narysowanie piłki

Narysuj „piłkę” – koło. Więcej informacji o rysowaniu okręgów i kół znajdziesz w samouczku Kształty w Canvas.

  1. W punkcie o współrzędnych (300,300) narysuj czerwone koło o promieniu 30 pikseli.
  • Poniżej linii komentarza: // w tym miejscu będą umieszczone wszystkie polecenia rysujące, umieść następujący kod:
context.fillStyle='red';
context.arc(300,300,30,0,Math.PI*2,true);
context.closePath;
context.fill();
  1. Zapisz stronę index.html i na wstążce kliknij przycisk Run. Sprawdź, czy strona wygląda tak, jak na Rys. 3.

Rys. 3. Piłka umieszczona na elemencie canvas.

Animacja piłki

Teraz, gdy wiesz już, jak narysować piłkę nadszedł czas na jej animację. W Canvas animacja polega na cyklicznym odświeżaniu obrazu co określony interwał czasu, co można najprościej wykonać za pomocą funkcji:

  • setInterval (funkcja, czas); – gdzie funkcja jest nazwą funkcji, która ma być uruchamiana co czas milisekund.

Do określenia aktualnej pozycji piłki będziesz używać zmiennych x i y. Dodatkowo określisz przesunięcie w poziomie i pionie: dx i dy oraz umieścisz deklarację obiektu context tak, aby wszystkie funkcje miały do niego dostęp.

  1. Zdefiniuj zmienne.
  • Powyżej linii function draw(){ dodaj następujące definicje zmiennych:
var x=300;
var y=300;
var dx=10;
var dy=10;
var context;
  1. W funkcji draw zamień var context na context (usuń słowo kluczowe var przed nazwą context).
  2. Usuń cztery linijki kodu dodane poprzednio, a odpowiedzialne za rysowanie piłki.
  3. Dodaj funkcję, umożliwiającą wywoływanie funkcji anim co 10 ms. W miejsce usuniętych linijek wpisz:
setInterval(anim,10);
  1. Zdefiniuj funkcję anim, umożliwiającą animację piłki. Poniżej funkcji draw wklej:
function anim() {
    x+=dx;
    y+=dy;
    context.beginPath();
    context.fillStyle='red';
    context.arc(x,y,30,0,Math.PI*2,true);
    context.closePath;
    context.fill();
}
  1. Zapisz stronę index.html i odśwież ją w przeglądarce. Sprawdź, czy wygląda tak, jak na Rys. 4.

Rys. 4. Pierwsze podejście do animacji w Canvas.

Informacja
Udało Ci się animować linię powstałą z połączenia kolejnych, czerwonych kół na elemencie canvas. Zgodnie z zasadą działania elementu canvas, rysunek powstaje z wszystkich jego poprzednich elementów. Aby usunąć kontent, znajdujący się na canvas, należy użyć metody clearRect (x,y,dx,dy), która umożliwia wyczyszczenie od punktu (x,y) aż do szerokości dx i wysokości dy.
  1. W pierwszej linijce funkcji anim (po linii) umieść następujący kod:
context.clearRect(0,0, 600,600);
  1. Zapisz stronę index.html i odśwież ją w przeglądarce.
Informacja
Tym razem piłka ucieka poza obszar elementu canvas. Aby temu zapobiec, musisz ograniczyć jej ruch do pola elementu canvas. Pole to ma wymiar 600x600 pikseli. Piłka ma promień 30 pikseli. W związku z tym, aby nie „wychodziła” za pole, musisz ograniczyć jej ruch w pionie i poziomie od 30 do 570 pikseli.
  1. Poniżej linijki y+=dy; wpisz:
if( x<30 || x>570) dx=-dx;
if( y<30 || y>570) dy=-dy;
  1. Zapisz stronę index.html i odśwież ją w przeglądarce. Sprawdź, czy piłka utrzymuje się na elemencie canvas.

Sterowanie klawiaturą

Twoja piłka porusza się od prawego dolnego rogu elementu do lewego górnego. Aby zmienić jej tor przejścia wprowadź możliwość interakcji z użytkownikiem – możliwość wpływania na parametr dx i dy po wciśnięciu klawiszy kursorów. Kody klawiszy zostały przedstawione w poniższej tabeli:

Klawisz Kod  
Strzałka lewo 37
Strzałka góra 38
Strzałka prawo 39
Strzałka dół 40
  1. Dodaj śledzenie zdarzenia wciśnięcia klawiszy. Poniżej linii window.onload = draw; dodaj:
window.addEventListener('keydown',doKeyDown,true);
  1. Dodaj funkcję obsługi wciśnięcia klawiszy. Poniżej funkcji anim dodaj:
function doKeyDown(evt){
    switch (evt.keyCode) {
        case 38:
            dy-=1;
            break;
        case 40:
            dy+=1
            break;
        case 37:  
            dx-=1;
            break;
        case 39:  
            dx+=1;
            break;
        }
}
  1. Zapisz stronę index.html i odśwież ją w przeglądarce. Sprawdź, czy piłka zmienia kierunek lub szybkość przesuwania po wciśnięciu klawiszy kursorów.

Dodanie tła

Często podczas tworzenia aplikacji potrzebujesz dodać tło w postaci obrazka. Aby to zrobić, musisz wykorzystać podstawowy mechanizm taki, jaki został przedstawiony w samouczku Grafika w Canvas:

tlo = new Image();
tlo.src = "adres_obrazka" 
tlo.onload = function () { context.drawImage(tlo, 0, 0); };
  1. Zapisz obrazek z Rys. 5. jako tlo.png. Na wstążce kliknij przycisk Add Existing i wskaż lokalizację pliku tlo.png.

Rys. 5. Obrazek tła na elemencie canvas - tlo.png.

  1. Dodaj obsługę tła.
  • W funkcji draw, przed poleceniem setInterval(anim,10); wstaw następujący kod:
tlo = new Image();
tlo.src = "tlo.png" 
tlo.onload = function () { context.drawImage(tlo, 0, 0); };
  • Po linii var context; dodaj:
var tlo ;
  1. Zapisz stronę index.html i odśwież ją w przeglądarce. Sprawdź, czy tło zostało wyświetlone na elemencie canvas.
Informacja
Niestety tło zostało wyświetlone tylko przez 10ms, ponieważ po tym czasie została wywołana metoda context.clearRect(), która usunęła wszystkie elementy z Canvas. Aby zachować tło, musisz je za każdym krokiem animacji dodać ponownie do elementu canvas. Na szczęście nie musisz pobierać pliku tła ponownie i możesz wykorzystać tło wgrane w funkcji draw.
  1. W funkcji anim, za poleceniem context.clearRect(0,0, 600,600); dodaj:
context.drawImage(tlo, 0, 0);

Podsumowanie

W tym artykule nauczyłeś się tworzyć prostą animowaną grafikę rastrową na stronach WWW. Poznałeś ograniczenia elementu canvas, zawiązane z koniecznością przerysowania wszystkich elementów graficznych w kolejnych krokach animacji.

W kolejnym artykule nauczysz się tworzyć animowaną grafikę wektorową w SVG.

Dodatkowo zobacz:

Zadanie

Aby sprawdzić swoje umiejętności, spróbuj wykorzystać element canvas do sterowania piłką (czerwone koło o promieniu 30 pikseli) po polu 600x600 pikseli.

  • Utwórz funkcje moveHorizontal i moveVertical, umożliwiające przesuwanie elementu o określony wektor (odpowiednio poziomo lub pionowo).
  • W funkcji doKeyDown wywołuj odpowiednio funkcje, przekazując jako parametr 10 (ruch w dół i prawo) lub -10 (ruch w lewo i do góry).
  • W dodanych funkcjach nie zapomnij ograniczyć pola możliwego ruchu.
<!DOCTYPE html>
<html lang="pl">
    <head>
        <meta charset="utf-8" />
        <title>Canvas w WebMatrix</title>
        <script type="text/javascript">
        // Uruchom funkcję draw po załadowaniu wszystkich obiektów na stronie.
        window.onload = draw; 
        window.addEventListener('keydown',doKeyDown,true);  
        var x=300;
        var y=300;
        var context;
        function draw(){
          var canvas = document.getElementById('canvas1');
            if (canvas.getContext){
                context = canvas.getContext('2d');
                // w tym miejscu będą umieszczone wszystkie polecenia rysujące               
               
            context.beginPath();
            context.fillStyle='red';
            context.arc(x,y,30,0,Math.PI*2,true);
            context.closePath;
            context.fill();
            }
          else{
            // Tutaj umieść kod, który zostanie wykonany w momencie, kiedy przeglądarka nie wspiera elementu canvas
            }
          }
        function moveHorizontal(dir) {
            x=x+dir;
            if (x<30) x=30;
            if (x>570) x=570;
            context.clearRect(0,0, 600,600);
            context.beginPath();
            context.fillStyle='red';
            context.arc(x,y,30,0,Math.PI*2,true);
            context.closePath;
            context.fill();
            }
        function moveVertical(dir) {
            y=y+dir;
            if (y<30) y=30;
            if (y>570) y=570;
            context.clearRect(0,0, 600,600);
            context.beginPath();
            context.fillStyle='red';
            context.arc(x,y,30,0,Math.PI*2,true);
            context.closePath;
            context.fill();
            }

          function doKeyDown(evt){
            switch (evt.keyCode) {
            case 38:  
                moveVertical(-10);
                break;
            case 40:  
                moveVertical(10);
                break;              
            case 37:  
                moveHorizontal(-10);
                break;
            case 39:  
                moveHorizontal(10);
                break; 
            }
            }
</script>
        <style type="text/css">
            canvas { border: 1px solid blue; }
        </style>
    </head>
    <body>
        <canvas id="canvas1" width="600" height="600"></canvas>
    </body>
</html>