27. diel - 2D kontext plátna v JavaScripte
V minulej lekcii, Štylovanie obrázkov a vloženie textu na plátno v JavaScripte, sme sa naučili obrázky na plátne štylovať a ukázali sme si, ako vkladať na canvas externé obrázky alebo text.
V dnešnom JavaScript tutoriálu 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
Veľmi dôležité sú pri spracovávaní obrázku
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äčší 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. Kontexte nastavíme farbu
výplne na červenú a prekreslíme ju 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é. Pokiaľ 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. Pokiaľ bude hodnota tohto polomeru 0
, prechod začne už
od stredu. Pokiaľ 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()
,
ktoré 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 pri cvičení, ktoré má tento kurz k dispozícii.
V nasledujúcom cvičení, Riešené úlohy k 24.-27. lekciu 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é 3x (374.72 kB)
Aplikácia je vrátane zdrojových kódov v jazyku JavaScript