27. diel - 2D kontext plátna v JavaScripte
V minulej lekcii, Štýlovanie obrázkov a vloženie textu na plátno v JavaScripte, sme sa naučili obrázky na plátne štýlovať a ukázali sme si, ako vkladať na canvas externé obrázky alebo text.
V dnešnom JavaScript tutoriále sa pozrieme podrobnejšie na kontext plátna. Naučíme sa ho posúvať, pretáčať alebo meniť jeho veľkosť. Ukážeme si aj ďalšie farebné efekty ako je pridanie tieňa alebo farebná výplň obrázkov.
Transformácia kontextu
Pri spracovávaní obrázku sú veľmi dôležité
transformácie. Predstavme si, že chceme obrázku nastaviť
veľmi špecifický, napríklad 10 pixelov široký rámček, ktorý by sme len
v CSS nenaštýlovali. Samozrejme všade môžeme vypisovať, aby sa
vykresľoval na pozícii x + 10
, y + 10
, ale
jednoduchšie je využiť posun kontextu.
Uloženie kontextu
Pred akoukoľvek manipuláciou s kontextom si ho uložíme. Mohli by sme ho
síce neskôr vrátiť do pozície x - 10
a y - 10
,
ale je to zbytočne pracné a navyše si musíme pamätať tieto hodnoty. Preto
má kontext metódy save()
a restore()
. Ani jedna
nepožaduje žiadny parameter. Metóda save()
si uloží
aktuálny stav kontextu a metóda restore()
ho
obnoví.
Ako príklad si vykreslíme obrázok s červeným rámčekom. Do tela HTML súboru doplníme obrázok a plátno o trochu väčšie ako obrázok:
<img src="photo.jpg" id="image" /> <canvas id="canvas" width="510" height="340"></canvas>
Potom si načítame plátno, kontext a obrázok. Kontextu nastavíme farbu
výplne na červenú a prekreslíme ňou celé <canvas>
.
Kontext metódou save()
uložíme:
let canvas; let context; let image; window.onload = function () { canvas = document.getElementById("canvas") context = canvas.getContext("2d"); image = document.getElementById("image"); image.parentElement.removeChild(image); // Here we will later put the scale() method to scale the image down context.fillStyle = "red"; context.fillRect(0, 0, 510, 340); context.save(); // We'll add the remaining code right away }
Posun kontextu
Posun kontextu vykonávame metódou
translate()
, ktorá prijíma parametre x
a
y
pre súradnice posunu. Nový nulový bod bude na týchto
súradniciach. My si plátno posunieme o kladných 10 px
ako po osi
x
, tak po osi y
a na novej pozícii vykreslíme
obrázok. Kontext plátna potom obnovíme:
context.translate(10, 10); context.drawImage(image, 0, 0); context.restore();
V prehliadači vidíme, že sa obrázok nakreslil na pozíciu
[10;10]
, aj keď sme na vykreslenie zadali pozíciu
[0;0]
. Môže za to práve náš posun:
Zväčšenie a zmenšenie kontextu
Kontext môžeme tiež zmenšovať a zväčšovať. Slúži
na to metóda scale()
, ktorá ako parametre prijíma násobky
skutočnej hodnoty pre súradnice x
a y
. Na
zmenšovanie sa zadávajú desatinné čísla menšie ako 1
.
Doplňme do predchádzajúcej ukážky pred vykreslením obrázku tento
riadok:
context.scale(0.5, 0.5);
Obrázok je teraz v prehliadači polovičný:
Rotácia
Poslednú transformáciu kontextu predstavuje rotácia. Tú
si vyskúšame opäť na štvorci, ktorý otočíme o 45 stupňov metódou
rotate()
. Tá ako parameter prijíma uhol
v radiánoch. V ukážke najprv kontext uložíme, potom metódou
translate()
nastavíme posun, aby sme vykreslili otočený štvorec
celý. Doplníme metódu na pretočenie kontextu, vykreslíme náš štvorec a
kontext obnovíme:
context.save(); context.translate(100, 100); // 45 degree rotation converted to radians context.rotate(45 * Math.PI / 180); context.strokeRect(0, 0, 50, 50); context.restore();
Výsledok:
Mazanie plátna
Okrem vykreslenia obrázku budeme určite niekedy chcieť vybraný obrázok
alebo obsah celého plátna zmazať. Môžeme použiť metódu
fillRect()
a prekresliť plátno na bielo. Vhodnejšie je však
použiť metódu clearRect()
, ktorá vymaže obsah plátna na danej
ploche. Parametre má rovnaké ako metóda fillRect()
.
Plátno totiž vo východiskovom stave nie je biele, ale je
priehľadné. Ak teda vymažeme plátno pomocou fillRect()
, síce
uvidíme bielu plochu, ale neuvidíme, čo bolo pod plátnom.
Aby sme videli rozdiel medzi spomínanými metódami, vložíme do tela HTML
<div>
so žltým pozadím a plátnu nastavíme absolútnu
pozíciu, aby ho čiastočne prekrývalo. Plátnu doplníme čierny
rámček:
<div id="background" style="width: 200px; height: 200px; background-color: yellow;"></div> <canvas id="canvas" width="200" height="200" style="border: 1px solid black; position: absolute; left: 30px; top: 30px;"></canvas>
V JavaScripte na plátne namaľujeme dva štvorce:
window.onload = function() { let canvas = document.getElementById("canvas"); let context = canvas.getContext("2d"); context.fillRect(20, 40, 30, 30); context.fillRect(70, 40, 30, 30); };
Výsledok v prehliadači:
Teraz zavoláme metódu fillRect()
a prefarbíme ľavý štvorec
bielou farbou. Druhý štvorec vymažeme metódou clearRect()
:
context.fillStyle = "white"; context.fillRect(20, 40, 30, 30); context.clearRect(70, 40, 30, 30);
Výsledok:
Keby sme chceli vymazať celé plátno, zmeníme posledný riadok takto:
context.clearRect(0, 0, canvas.width, canvas.height);
Tieň
Obrázkom na plátne môžeme pridať tieň. Vlastnosťou
shadowColor
nastavíme farbu tieňa, vlastnosťami
shadowOffsetX
a shadowOffsetY
nastavíme
posun tieňa a pomocou shadowBlur
určíme, ako
veľmi bude tieň rozostrený:
context.shadowColor = "red"; context.shadowOffsetX = 6; context.shadowOffsetY = 3; context.shadowBlur = 10; context.strokeRect(10, 10, 50, 50);
Výsledok:
Farebné prechody
Obrázkom okrem tieňa môžeme tiež doplniť lineárne alebo kruhové farebné prechody. Oba sa dajú nastaviť ako pre výplň, tak aj pre obrys.
Lineárny prechod
Lineárny prechod vytvoríme pomocou metódy
createLinearGradient()
na objekte kontextu. Odovzdávame jej štyri
parametre. Sú to súradnice x
a y
pre začiatok a pre koniec gradientu.
Novovzniknutý objekt disponuje metódou addColorStop()
, ktorá
pridá gradientu ďalšiu farbu. Táto metóda prijíma ako
prvý parameter pozíciu "zastavenia" v rozmedzí
0
- 1
a ako druhý danú farbu.
Objekt s takto nastaveným farebným prechodom odovzdáme ako vlastnosť
fillStyle
alebo strokeStyle
:
let gradient = context.createLinearGradient(0, 0, 100, 0); gradient.addColorStop(0, "yellow"); gradient.addColorStop(0.2, "orange"); gradient.addColorStop(0.4, "pink"); gradient.addColorStop(0.6, "red"); gradient.addColorStop(0.8, "green"); gradient.addColorStop(1, "blue"); context.fillStyle = gradient; context.fillRect(0, 0, 100, 100); context.font = "19px Calibri" context.fillText("ICTdemy.com", 0, 115);
Výsledok:
Radiálny prechod
Radiálny alebo kruhový prechod sa
používa úplne rovnako, len vytvorí iný efekt. Vytvoríme ho metódou
createRadialGradient()
, ktorá prijíma šesť parametrov.
Súradnice x
a y
pre počiatočný
bod, polomer a to všetko ešte raz aj pre
koncový bod.
V hodnotách je pomerne zmätok. Prvá pozícia x
a
y
je vlastne stred, prvý polomer je polomer, pri ktorom začne
prechod. Ak bude hodnota tohto polomeru 0
, prechod začne už od
stredu. Ak uvedieme čokoľvek iné, bude od stredu prvá farba a až na zadanom
polomere začne prechádzať v inú.
Ak chceme docieliť pravidelný kruh, tak štvrtý a piaty parameter bude kopírovať hodnoty prvého a druhého parametra. Šiesty parameter potom udáva, na akom polomere sa prechod zastaví. Nastavovanie farieb je rovnaké ako u lineárneho gradientu:
let gradient = context.createRadialGradient(50, 50, 0, 50, 50, 75); gradient.addColorStop(0, "yellow"); gradient.addColorStop(0.2, "orange"); gradient.addColorStop(0.4, "pink"); gradient.addColorStop(0.6, "red"); gradient.addColorStop(0.8, "green"); gradient.addColorStop(1, "blue"); context.fillStyle = gradient; context.fillRect(0, 0, 100, 100); context.font = "19px Calibri" context.fillText("ICTdemy.com", 0, 115);
Výsledok:
Obrázková výplň
Ďalšia možnosť, ako spestriť naše obrázky, predstavuje
obrázková výplň. Docielime ju tak, že vytvoríme
pattern (vzor) a ten nastavíme vlastnosti
fillStyle
. Vzor vytvoríme metódou createPattern()
,
ktorej ako prvý parameter odovzdáme obrázok. V druhom
parametri nastavujeme spôsob opakovania. Máme na výber zo
štyroch hodnôt:
repeat
alebo prázdny reťazec""
– na vyplnenie po osix
ay
,repeat-x
– pre horizontálnu výplň,repeat-y
– pre vertikálnu výplň,no-repeat
– výplň sa nebude opakovať.
Obrázok načítame v tele HTML:
<img src="pattern.png" id="image"/>
Počkáme, kým sa obrázok načíta a metódou createPattern()
vytvoríme vzor výplne. Nový vzor nastavíme vlastnosti fillStyle
a vykreslíme vyplnený štvorec:
window.onload = function() { let canvas = document.getElementById("canvas"); let context = canvas.getContext("2d"); let image = document.getElementById("image"); document.body.removeChild(image); let pattern = context.createPattern(image, "repeat"); context.fillStyle = pattern; context.fillRect(50, 50, 100, 100); };
Výsledok:
Týmto sme si zhrnuli základné možnosti práce s plátnom a jeho kontextom v JavaScripte. Príklady si skúste upraviť a vyskúšajte si, ako uvedené metódy a vlastnosti s inými parametrami menia vzhľad obrázkov. Využijete ich aj v cvičeniach, ktoré má tento kurz k dispozícii.
V nasledujúcom cvičení, Riešené úlohy k 24.-27. lekcii JavaScriptu, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 19x (375.21 kB)
Aplikácia je vrátane zdrojových kódov v jazyku JavaScript