Načrtovanje in razvoj spletnih aplikacij

Canvas: risalna orodja, efekti in transformacije


Osnovne črte in oblike

Če uporabimo lastnosti fillStyle in strokeStyle lahko nastavimo barvo za prikazovanje likov ali črt. Privzeta barva je črna. Lahko uporabimo enake barvne vrednosti kot v CSS: hex codes, rgb(), rgba() in celo hsla(), če jo brskalnik podpira. Z lastnostjo fillStyle poleg barve lahko določimo tudi vzorec ali preliv. Lastnost strokeStyle je identična lastnosti fillStyle, le da je namenjena robovom in črtam.

Z metodo fillRect(x, y, width, height) lahko rišemo polnjene pravokotnike. Barvo mu določimo z omenjeno lastnostjo fillStyle. Z metodo strokeRect(x, y, width, height) pa lahko rišemo prazne nepobarvane pravokotnike samo z obrobami. Barvo roba določimo z že omenjeno lastnostjo strokeStyle.

Površino na Canvas pa lahko tudi brišemo v obliki pravokotnika, z metodo clearRect(x, y, width, height).

Vse metode imajo enake argumente (x, y, width, height). Prva dva določata koordinate na mreži canvas, druga dva pa širino in višino pravokotnika. Z lastnostjo lineWidth pa določimo debelino črte.

Primer risanja črt in likov na Canvas:

<canvas id="example" width="200" height="200">   
   To besedilo se prikaže v primeru, da vaš brskalnik ne podpira HTML5 Canvas. 
</canvas> 

<script>   
   var example = document.getElementById('example');   
   var context = example.getContext('2d');   
   context.strokeStyle = "gray";    
   context.lineWidth = 1;   
   context.strokeRect(0,0, 200, 200);   
	 /* liki na Canvasu */   
   context.fillStyle = "blue";    
   context.strokeStyle = "darkorange";    
   context.lineWidth = 5;   
   context.fillRect (10,10, 150, 50);   
   context.strokeRect(10,72, 150, 50);   
   context.clearRect (40, 30,90, 60);   
   context.strokeRect(40, 30, 90, 60); 
</script>
To besedilo se prikaže v primeru, da vaš brskalnik ne podpira HTML5 Canvas.

Poti in krivulje

Canvas nam omogoča risanje raznovrstnih likov s pomočjo črt, potez. Poteka podobno kot rišemo z pisalom. Najprej narišemo obris (pot) neke poteze, lika, nato pa vse to poljubno zapolnimo z barvo ali kakšnim drugim vzorcem.

Risanje enostavnega lika je preprosto:

  • beginPath() – s to metodo določimo začetek risanja poti.
  • moveTo(x,y) – s to metodo določimo začetno koordinato na Canvas znački.
  • lineTo(x,y) – metoda s katero narišemo črto od koordinate, ki smo jo določili s prejšnjo metodo moveTo(x,y) ali lineTo(x,y) do poljubne koordinate, ki jo določimo z metodo lineTo(x,y). Omenjeni dve metodi ponavljamo v zaporedju večkrat glede na to kakšen lik imamo namen narisati.
  • Vmesnik 2D Contex API poleg metode za risanje ravnih črt nudi tudi metode za risanje raznih krivulj (kvadratne krivulje, bezierove krivulje,..)
  • Ko smo končali z risanjem poti lahko uporabimo metodo fill in stroke, da se nam izrišejo poteze v poljubni barvi, ki jih določimo z lastnostmi fillStyle, strokeStyle ter lineWidth za debelino črt (poti).
  • Na koncu zaključimo naše risanje z metodo closePath().

Primer risanja poti jn krivulj na Canvas:

<canvas id="example" width="400" height="300">   
   To besedilo se prikaže v primeru, da vaš brskalnik ne podpira HTML5 Canvas. 
</canvas> 

<script>   
   var example = document.getElementById('example');   
   var context = example.getContext('2d');     
	  /* siv okvir Canvasa */   
   context.strokeStyle = "gray";    
   context.lineWidth = 1;   
   context.strokeRect(0,0, 400, 300);   
	 /* trikotnik */   
   context.beginPath();
   context.lineWidth = 3;
   context.strokeStyle = "#000000";
   context.fillStyle = "blue";
   context.moveTo(100, 50);
   context.lineTo(10, 200);
   context.lineTo(200, 200);
   context.closePath();
   context.fill();
   context.stroke();
	 /* bezierova krivulja (srce) */
   x = 250;
   y = 100;
   context.lineWidth = 3;
   context.fillStyle = "red";
   context.beginPath();
   context.moveTo(x + 25, y + 25);
   context.bezierCurveTo(x + 25, y + 25, x + 20, y, x, y);
	context.bezierCurveTo(x - 30, y, x - 30, y + 35,x - 30,y + 35);
   context.bezierCurveTo(x - 30, y + 55, x - 10, y + 77, x + 25, y + 95);
   context.bezierCurveTo(x + 60, y + 77, x + 80, y + 55, x + 80, y + 35);
   context.bezierCurveTo(x + 80, y + 35, x + 80, y, x + 50, y);
   context.bezierCurveTo(x + 35, y, x + 25, y + 25, x + 25, y + 25);
   context.closePath();
   context.fill();
   context.stroke();
</script>
To besedilo se prikaže v primeru, da vaš brskalnik ne podpira HTML5 Canvas.

Besedilo

Na oznako Canvas lahko vstavimo tudi besedilo. Pri pisanju na Canvas nimamo modela škatle kot pri tehniki CSS (padding, margin, floats, word wrapping). Imamo naslednje atribute za določitev lastnosti in poravnave pisave:

  • font – tako kot pri pravilih CSS za pisavo tudi na canvas lahko določimo slog pisave, različico pisave, debelino in velikost pisave, višino vrstice, družino pisav.
  • textAlign – določa horizontalno poravnavo besedila. Podobno kot pri pravilih CSS text-align. Vrednosti za poravnavo besedila so: start (začetek), end (konec), left (levo), right (desno) in center (sredina).
  • textBaseline – določa vertikalno poravnavo besedila. Določimo kje vertikalno na Canvas mreži je lokacija besedila glede na začetni točki Canvas ploskve. Vrednosti so: top, hanging, middle, alphabetic, ideographic ali bottom.

Za izrisanje besedila imamo dve metodi: fillText in strokeText. Prva nam izriše besedilo v obliki, ki jo določimo z lastnostjo fillStyle, druga pa besedilo z obrobljenimi črkami, ki jo določimo z lastnostjo stokeStyle. Obe metodi imata po tri argumente: besedilo, ki ga želimo prikazati ter koordinati (x,y), ki določata, kje na platnu naj se besedilo izriše.

Primer vstavljanja besedila na Canvas:

<canvas id="example" width="400" height="200">
   To besedilo se prikaže v primeru, da vaš brskalnik ne podpira HTML5 Canvas. 
</canvas> 

<script>
   var example = document.getElementById('example');
   var context = example.getContext('2d');

	 /* siv okvir Canvasa */
   context.strokeStyle = "gray";
	context.lineWidth = 1;
   context.strokeRect(0,0, 400, 200);

	 /* besedilo */
   context.fillStyle="blue";
   context.font = "italic 40px sans-serif";
   context.textBaseline = "top";
   context.fillText ("HTML 5 je super!", 0, 0);
   context.font = "bold 40px sans-serif";
   context.strokeText("HTML 5 je zakon!", 0, 50); 
</script>
To besedilo se prikaže v primeru, da vaš brskalnik ne podpira HTML5 Canvas.

Slike

Na Canvas lahko izrisujemo tudi slike. To nam omogoča metoda drawImage, ki ima lahko tri, pet ali devet argumentov:

  • drawImage(image, dx, dy) nam nariše sliko (image) na Canvas. Koordinati dx, dy določata zgornji levi kot slike na Canvas.
  • drawImage(image, dx, dy, dw, dh) metoda je podobna kot prejšnja, le da z argumentoma dw in dh določimo velikost izrisane slike (širina, višina).
  • drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) metodo uporabimo, kadar želimo zajeti oziroma odrezati del slike (image) v obliki pravokotnika, ki ga določimo z koordinatami (sx, sy, sw, sh). Nato pa jo metoda na platnu prikaže in poljubno raztegne, tako kot smo to naredili z prejšno metodo.

Primer slike:
Slovenija

Primer vstavljanja slike na Canvas:

//slika vsebuje atribut "id"
<img id="slovenija" src="slovenija.png" width="300" height="211" alt="Slovenija"> 

<canvas id="example" width="350" height="250">
   To besedilo se prikaže v primeru, da vaš brskalnik ne podpira HTML5 Canvas. 
</canvas> 

<script>
   var example = document.getElementById('example');
   var context = example.getContext('2d');
   var slika = document.getElementById('slovenija');

	 /* siv okvir Canvasa */
   context.strokeStyle = "gray";
	context.lineWidth = 1;
   context.strokeRect(0,0, 350, 250);

	 /* slika */
   context.drawImage(slika, 25, 25);

	 /* pomanjšana slika */
   context.drawImage(slika, 3, 3, 150, 105);

	 /* izrezana slika */
   context.drawImage(slika, 50, 50, 100, 100, 245, 140, 100, 100); 
</script>
To besedilo se prikaže v primeru, da vaš brskalnik ne podpira HTML5 Canvas.

Senčenje

Canvas nam omogoča tudi senčenje. Vmesnik Shadows API nam ponuja štiri lastnosti:

  • shadowColor – določimo barvo senčenja.
  • shadowBlur – določimo količino slikovnih pik za senčenje. Večja kot je vrednost, močnejše je senčenje.
  • shadowOffsetX in shadowOffsetY – določamo x in y oddaljenost senčenja, v slikovnih pikah.

Primer vstavljanja sence objekta na Canvas:

<canvas id="example" width="300" height="200">
   To besedilo se prikaže v primeru, da vaš brskalnik ne podpira HTML5 Canvas. 
</canvas> 

<script>
   var example = document.getElementById('example');
   var context = example.getContext('2d');

	 /* siv okvir Canvasa */
   context.strokeStyle = "gray";
	context.lineWidth = 1;
   context.strokeRect(0,0, 300, 200);

	 /* senčenje */
   context.shadowOffsetX = 10;
   context.shadowOffsetY = 10;
   context.shadowBlur = 15;
   context.shadowColor = 'rgba(50, 50, 10, 0.5)';
   context.fillStyle = 'blue';
   context.fillRect(20, 20, 150, 100); 
</script>
To besedilo se prikaže v primeru, da vaš brskalnik ne podpira HTML5 Canvas.

Barvni prelivi na objektih

V vmesniku 2D Context API imamo dva različna tipa barvnih prehodov, s katerima lahko kreiramo barvne prehode na različnih objektih, kot npr. pravokotnikih, krogih, črtah, tekstih itd.:

  • createLinearGradient(x,y,x1,y1) - kreiranje linearnega barvnega prehoda
  • createRadialGradient(x,y,r,x1,y1,r1) - kreiranje krožnega barvnega prehoda

Z metodo addColorStop() določimo dve ali več barv barvnega prehoda. Z lastnostjo fillStyle ali strokeStyle pa zapolnimo objekt.

Primer kreiranja linearnega in krožnega barvnega prehoda na pravokotniku v Canvas:

<canvas id="example" width="350" height="150" style="border:1px solid #d3d3d3;">
   To besedilo se prikaže v primeru, da vaš brskalnik ne podpira HTML5 Canvas. 
</canvas>  

<script>
   var c=document.getElementById("example");
   var ctx=c.getContext("2d");

	// Linearni barvni prehod
   var grdLin=ctx.createLinearGradient(0,0,200,0);
   grdLin.addColorStop(1,"red");
   grdLin.addColorStop(0,"white");

	// Zapolni z linearnim prehodom
   ctx.fillStyle=grdLin;
   ctx.fillRect(10,10,150,80);

	// Krožni barvni prehod
   var grdRad=ctx.createRadialGradient(255,50,5,255,60,100);
   grdRad.addColorStop(0,"blue");
   grdRad.addColorStop(1,"white");

	// Zapolni s krožnim prehodom
   ctx.fillStyle=grdRad;
   ctx.fillRect(180,10,150,80); 
</script>
To besedilo se prikaže v primeru, da vaš brskalnik ne podpira HTML5 Canvas.

Manipulacija s slikovnimi pikami

V vmesniku 2D Context API imamo tri metode, s katerimi lahko zajemamo, ustvarjamo in izrisujemo slikovne pike:

  • getImageData
  • createImageData
  • putImageData

Neobdelane slikovne pike so zajete v objektu tipa ImageData. Vsak objekt ima tri lastnosti: širino (width), višino (height) in podatki (data). Lastnost data je tipa CanvasPixelArray, ki vsebuje natanko width*height*4 število elementov.

Zmnožek širina*višina (v slikovnih pikah) nam pove, iz koliko slikovnih pik je slika sestavljena. Za vsako slikovno piko lahko določimo štiri podatke: rdeča (red), zelena (green), modra (blue) in alfa vrednost (RGB + alpha =RGBA barvni model). Vse vrednosti so v intervalu od 0 do 255.

Primer vstavljanja slikovnih pik na Canvas:

<canvas id="example" width="350" height="150" style="border:1px solid #d3d3d3;">
   To besedilo se prikaže v primeru, da vaš brskalnik ne podpira HTML5 Canvas. 
</canvas> 

<script>
   var cnv = document.getElementById('example');
   var context= cnv.getContext('2d');

   // Ustvarimo ImageData objekt.
   var imgd1 = context.createImageData(100,100);
   var pix1 = imgd1.data;

   // Z zanko se sprehodimo čez vse slikovne pike in nastavimo slikovno piko prosojno rdečo.
   for (var i = 0; n = pix1.length, i < n; i += 4) {
	 pix1[i] = 255; // kanal rdeče barve     pix1[i+3] = 80; // alfa kanal
   }

   // Narišemo ImageData objekt na podanih (x,y) koordinatah.
   context.putImageData(imgd1, 10,10);

   // Ponovimo postopek še za drugi objekt z drugačno vrednostjo prosojnosti
   var imgd2 = context.createImageData(100,100);
   var pix2 = imgd2.data;
   for (var i = 0; n = pix2.length, i < n; i += 4) {
	 pix2[i] = 255;
	 pix2[i+3] = 200;
   }
   context.putImageData(imgd2, 150,10); 
</script>
To besedilo se prikaže v primeru, da vaš brskalnik ne podpira HTML5 Canvas.