mgr inż. Wacław Libront * Bobowa 2017-2019

ZSO Bobowa, ul. Długoszowskich 1, 38-350 Bobowa, tel: 0183514009, fax: 0183530221, email: sekretariat@zsobobowa.eu, www: zsobobowa.eu

Lekcja 14

Bitmapy w JS

  1. wyświetlanie
  2. animacja
  3. poklatkowa
  4. panorama

Za pomocą HTML i znacznika <img> potrafimy wyświetlać grafiki na stronie WWW. Wykorzystując JS będziemy mogli podmieniać grafiki na inne i dokonywać wielu różnorodnych przekształceń. Służy do tego instrukcja DrawImage.

Wyświetlanie

<canvas id="c1" width="800" height="800"></canvas>

<script>
  var c = c1.getContext('2d')
  //tworzenie
  var img = new Image();
  img.src = 'zsologo.jpg';
  //ładowanie z dysku
  img.onload=function(){
    //wyswietlanie
    c.drawImage(img, 100, 0);
    //skalowanie
    c.drawImage(img, 0, 0,150,200);
    //wycinanie
    c.drawImage(img,180,130,320,70,0,500,200,200);
  }
</script>

Animacja
Wykorzystamy sposób opisany na poprzednich lekcjach i podmienimy proste obiekty geometryczne na załadowane wcześniej obrazki. Procedura jest podobna. Ładujemy obrazek do pamięci, ale nie musimy go inicjować metodą onload() – animacja narysuje go sama. Obrazek będzie się obracał i odbijał od brzegów canvas. Rysowanie i obracanie obrazka w funkcji tarcza().

<canvas width="400" height="200" id="can"></canvas>
<script>
  var c = can.getContext("2d");
  var w = c.canvas.width;
  var h = c.canvas.height;
  
  var skok = 10;
  var czas;
  var WY=60; 
  var SZ=50;
  var x=100;
  var y=100;
  var kat=0;
  var dx=2;
  var dy=3;
  var dk=1;

  //ładowanie obrazka
  var img=new Image();   
  img.src='tarcza.png';
    
//rysowanie i obracanie tarczy
function tarcza(xs,ys,kat){
  c.save();
  c.translate(xs+SZ/2,ys+WY/2);
  c.rotate(Math.PI*kat/180);
  c.drawImage(img,-SZ/2,-WY/2,SZ,WY);
  c.restore();
} 
//animacja
function animacja() {
  c.clearRect(0, 0, w, h);
  c.strokeRect(0, 0, w, h);
  tarcza(x,y,kat);
  x=x+dx;
  y=y+dy;
  kat=kat+dk;
  if (kat>360) kat=0;
  if (x<0 || x>w-SZ) dx=-dx;
  if (y<0 || y>h-WY) dy=-dy;  
  clearTimeout(czas);
  czas = setTimeout(animacja, skok); 
}

animacja();
</script>

Animacja poklatkowa
W praktyce ten typ animacji wykonuje się wczytując jeden plik graficzny, składający się z jednakowych ułożonych obok siebie klatek, tak jak w przykładowym rysunku sportowca. Cały obrazek ma 480 pikseli, a pojedyncza klatka 30. Będziemy wyświetlać kolejne klatki posługując się instrukcją drawImage. Instrukcje odpowiedzialne za przeliczanie ramek i rysowanie fragmentu obrazka umieszczamy w procedurze animacyjnej. Czas, po którym uruchamiana jest kolejna pętla rekurencyjna powinien być zdecydowanie większy – około 300-400 ms.

<canvas width="150" height="300" id="can"></canvas>
<script>
  var c = can.getContext("2d");
  var skok = 100;
  var czas;
  //załadowanie obrazka do pamięci
  var img = new Image();
  img.src = 'sportowiec.png';
  var ramka=0;  
  
function animacja() {
  c.clearRect(0, 0, 150, 300);
  //współrzędne kolejnej ramki
  var xr=ramka*300;
  //numer ramki
  if (ramka==5) ramka=0; else ramka++;
  //wycinanie i wyświetlanie ramki z całego obrazka
  c.drawImage(img,xr+1,0,300,480,0,0,150,240);

  clearTimeout(czas);
  czas = setTimeout(animacja, skok); 
}

animacja();
</script>

Przewijany baner
Ładujemy jeden plik graficzny, ale wyświetlamy obok siebie dwa. Należy tak przygotować panoramy, aby początek i koniec był taki sam (lub bardzo podobny kolorystycznie). Jeśli pierwszy obrazek przekroczy brzeg obszaru canvas (druga panorama jest również wyświetlana), to proces rozpoczynamy od nowa.

<canvas width="400" height="138" id="can"></canvas>
<script>
  var c = can.getContext("2d");
  var w = c.canvas.width;
  var h = c.canvas.height;
  var skok = 30;
  var czas;
  //załadowanie obrazka panoramy
  var pan = new Image();
  pan.src="asbyrgi.jpg";
  var WY=138; 
  var SZ=600; 
  var x=0;
  
function animacja() {
  //rysowanie
  c.drawImage(pan,x,0);
  //rysowanie drugiego obok
  c.drawImage(pan,x-SZ,0);
  //popychamy do przodu o jeden piksel
  if (x>=SZ) x=0; else x++;
 
  clearTimeout(czas);
  czas = setTimeout(animacja, skok); 
}

animacja();
</script>