Lekce 27 - 2D kontext plátna v JavaScriptu
V minulé lekci, Stylování obrázků a vložení textu na plátno v JavaScriptu, jsme se naučili obrázky na plátně stylovat a ukázali jsme si, jak vkládat na canvas externí obrázky nebo text.
V dnešním JavaScript tutoriálu se podíváme podrobněji na kontext plátna. Naučíme se jej posouvat, přetáčet nebo měnit jeho velikost. Ukážeme si také další barevné efekty jako je přidání stínu nebo barevná výplň obrázků.
Transformace kontextu
Velmi důležité jsou při zpracovávání obrázku
transformace. Představme si, že chceme obrázku nastavit
hodně specifický například 10 pixelů široký rámeček, který bychom jen
v CSS nenastylovali. Samozřejmě všude můžeme vypisovat, aby se vykresloval
na pozici x + 10
, y + 10
, ale jednodušší je
využít posunu kontextu.
Uložení kontextu
Před jakoukoliv manipulací s kontextem si jej uložíme. Mohli bychom ho
sice později vrátit do pozice x - 10
a y - 10
, ale
je to zbytečně pracné a navíc si musíme pamatovat tyto hodnoty. Proto má
kontext metody save()
a restore()
. Ani jedna
nepožaduje žádný parametr. Metoda save()
si uloží
aktuální stav kontextu a metoda restore()
jej
obnoví.
Jako příklad si vykreslíme obrázek s červeným rámečkem. Do těla HTML souboru doplníme obrázek a plátno o trochu větší než obrázek:
<img src="foto.jpg" id="obrazek" /> <canvas id="platno" width="510" height="340"></canvas>
Poté si načteme plátno, kontext a obrázek. Kontextu nastavíme barvu
výplně na červenou a překreslíme jí celý <canvas>
.
Kontext metodou save()
uložíme:
let platno; let kontext; let obrazek; window.onload = function () { platno = document.getElementById("platno") kontext = platno.getContext("2d"); obrazek = document.getElementById("obrazek"); obrazek.parentElement.removeChild(obrazek); // Sem později vložíme metodu scale() pro zmenšení obrázku kontext.fillStyle = "red"; kontext.fillRect(0, 0, 510, 340); kontext.save(); // Zde vzápětí doplníme zbývající kód }
Posun kontextu
Posun kontextu provádíme metodou translate()
,
která přijímá parametry x
a y
pro souřadnice
posunu. Nový nulový bod bude na těchto souřadnicích. My si plátno posuneme
o kladných 10 px
jak po ose x
, tak po ose
y
a na nové pozici vykreslíme obrázek. Kontext plátna pak
obnovíme:
kontext.translate(10, 10); kontext.drawImage(obrazek, 0, 0); kontext.restore();
V prohlížeči vidíme, že se obrázek nakreslil na pozici
[10;10]
, i když jsme pro vykreslení zadali pozici
[0;0]
. Může za to právě náš posun:
Zvětšení a zmenšení kontextu
Kontext můžeme také zmenšovat a zvětšovat. Slouží
k tomu metoda scale()
, která jako parametry přijímá násobky
skutečné hodnoty pro souřadnice x
a y
. Pro
zmenšování se zadávají desetinná čísla menší než 1
.
Doplňme do předchozí ukázky před vykreslení obrázku tento řádek:
kontext.scale(0.5, 0.5);
Obrázek je nyní v prohlížeči poloviční:
Rotace
Poslední transformaci kontextu představuje rotace. Tu si
vyzkoušíme opět na čtverci, který otočíme o 45 stupňů metodou
rotate()
. Ta jako parametr přijímá
úhel v radiánech. V ukázce nejprve kontext uložíme, pak
metodou translate()
nastavíme posun, abychom vykreslili otočený
čtverec celý. Doplníme metodu pro přetočení kontextu, vykreslíme náš
čtverec a kontext obnovíme:
kontext.save(); kontext.translate(100, 100); // Rotace o 45 stupňů převedených na radiány kontext.rotate(45 * Math.PI / 180); kontext.strokeRect(0, 0, 50, 50); kontext.restore();
Výsledek:
Mazání plátna
Kromě vykreslení obrázku budeme určitě někdy chtít vybraný obrázek
nebo obsah celého plátna smazat. Můžeme použít metodu
fillRect()
a překreslit plátno na bílo. Vhodnější je však
použít metodu clearRect()
, která vymaže obsah plátna na dané
ploše. Parametry má stejné jako metoda fillRect()
.
Plátno totiž ve výchozím stavu není bílé, ale je
průhledné. Pokud tedy vymažeme plátno pomocí fillRect()
, sice
uvidíme bílou plochu, ale neuvidíme, co bylo pod plátnem.
Abychom viděli rozdíl mezi zmíněnými metodami, vložíme do těla HTML
<div>
se žlutým pozadím a plátnu nastavíme absolutní
pozici, aby ho částečně překrývalo. Plátnu doplníme černý
rámeček:
<div id="podklad" style="width: 200px; height: 200px; background-color: yellow;"></div> <canvas id="platno" width="200" height="200" style="border: 1px solid black; position: absolute; left: 30px; top: 30px;"></canvas>
V JavaScriptu na plátnu namalujeme dva čtverce:
window.onload = function() { let platno = document.getElementById("platno"); let kontext = platno.getContext("2d"); kontext.fillRect(20, 40, 30, 30); kontext.fillRect(70, 40, 30, 30); };
Výsledek v prohlížeči:
Nyní zavoláme metodu fillRect()
a přebarvíme levý čtverec
bílou barvou. Druhý čtverec vymažeme metodou clearRect()
:
kontext.fillStyle = "white"; kontext.fillRect(20, 40, 30, 30); kontext.clearRect(70, 40, 30, 30);
Výsledek:
Kdybychom chtěli vymazat celé plátno, změníme poslední řádek takto:
kontext.clearRect(0, 0, platno.width, platno.height);
Stín
Obrázkům na plátně můžeme přidat stín. Vlastností
shadowColor
nastavíme barvu stínu, vlastnostmi
shadowOffsetX
a shadowOffsetY
nastavíme
posun stínu a pomocí shadowBlur
určíme, jak
moc bude stín rozostřený:
kontext.shadowColor = "red"; kontext.shadowOffsetX = 6; kontext.shadowOffsetY = 3; kontext.shadowBlur = 10; kontext.strokeRect(10, 10, 50, 50);
Výsledek:
Barevné přechody
Obrázkům kromě stínu můžeme také doplnit lineární nebo kruhové barevné přechody. Oba se dají nastavit jak pro výplň, tak pro obrys.
Lineární přechod
Lineární přechod vytvoříme pomocí metody
createLinearGradient()
na objektu kontextu. Předáváme jí
čtyři parametry. Jsou to souřadnice x
a
y
pro počátek a pro konec gradientu.
Nově vzniklý objekt disponuje metodou addColorStop()
, která
přidá gradientu další barvu. Tato metoda přijímá jako
první parametr pozici "zastavení" v rozmezí 0
– 1
a jako druhý danou barvu. Objekt s takto
nastaveným barevným přechodem předáme jako vlastnost fillStyle
nebo strokeStyle
:
let gradient = kontext.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"); kontext.fillStyle = gradient; kontext.fillRect(0, 0, 100, 100); kontext.font = "19px Calibri" kontext.fillText("ITnetwork.cz", 0, 115);
Výsledek:
Radiální přechod
Radiální neboli kruhový přechod se
používá úplně stejně, jen vytvoří jiný efekt. Vytvoříme jej metodou
createRadialGradient()
, která přijímá šest parametrů.
Souřadnice x
a y
pro počáteční
bod, poloměr a to vše ještě jednou i pro
koncový bod.
V hodnotách je poměrně zmatek. První pozice x
a
y
je vlastně střed, první poloměr je poloměr, u kterého
začne přechod. Pokud bude hodnota tohoto poloměru 0
, přechod
začne již od středu. Pokud uvedeme cokoli jiného, bude od středu první
barva a až na zadaném poloměru začne přecházet v jinou.
Jestliže chceme docílit pravidelného kruhu, tak čtvrtý a pátý parametr bude kopírovat hodnoty prvního a druhého parametru. Šestý parametr poté udává, na jakém poloměru se přechod zastaví. Nastavování barev je stejné jako u lineárního gradientu:
let gradient = kontext.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"); kontext.fillStyle = gradient; kontext.fillRect(0, 0, 100, 100); kontext.font = "19px Calibri" kontext.fillText("ITnetwork.cz", 0, 115);
Výsledek:
Obrázková výplň
Další možnost, jak zpestřit naše obrázky, představuje
obrázková výplň. Docílíme jí tak, že vytvoříme
pattern (vzor) a ten nastavíme vlastnosti
fillStyle
. Vzor vytvoříme metodou createPattern()
,
které jako první parametr předáme obrázek. Ve druhém
parametru nastavujeme způsob opakovaní. Máme na výběr ze
čtyř hodnot:
repeat
nebo prázdný řetězec""
– pro vyplnění po osex
ay
,repeat-x
– pro horizontální výplň,repeat-y
– pro vertikální výplň,no-repeat
– výplň se nebude opakovat.
Obrázek načteme v těle HTML:
<img src="vzor.png" id="obrazek"/>
Počkáme, než se obrázek načte a metodou createPattern()
vytvoříme vzor výplně. Nový vzor nastavíme vlastnosti
fillStyle
a vykreslíme vyplněný čtverec:
window.onload = function() { let platno = document.getElementById("platno"); let kontext = platno.getContext("2d"); let obrazek = document.getElementById("obrazek"); document.body.removeChild(obrazek); let pattern = kontext.createPattern(obrazek, "repeat"); kontext.fillStyle = pattern; kontext.fillRect(50, 50, 100, 100); };
Výsledek:
Tímto jsme si shrnuli základní možnosti práce s plátnem a jeho kontextem v JavaScriptu. Příklady si zkuste upravit a vyzkoušejte si, jak uvedené metody a vlastnosti s jinými parametry mění vzhled obrázků. Využijete je také u cvičení, která má tento kurz k dispozici.
V následujícím cvičení, Řešené úlohy k 24.-27. lekci JavaScriptu, si procvičíme nabyté zkušenosti z předchozích lekcí.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 968x (376.69 kB)
Aplikace je včetně zdrojových kódů v jazyce JavaScript