Lekce 27 - Transformace kontextu 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 je vhodné jej uložit. 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. Práci
nám usnadní metody:
save()
- pro uložení aktuálního stavu kontextu,restore()
- pro obnovení uloženého stavu.
Ani jedna z těchto metod nepožaduje žádný parametr.
Jako příklad si vykreslíme tento obrázek s červeným rámečkem:
![Obrázek mostu - Základní konstrukce jazyka JavaScript](images/3588/jstut/foto.png)
Obrázek uložíme pod názvem foto.png
do složky projektu.
Připravíme HTML dokument, do jehož těla vložíme obrázek, plátno o něco
větší než samotný obrázek, a element <script>
:
<!DOCTYPE html> <html lang="cs-cz"> <head> <meta charset="utf-8" /> <title>Plátno</title> </head> <body> <img src="foto.png" alt="Most" id="obrazek" /> <canvas id="platno" width="510" height="340"></canvas> <script src="script.js"></script> </body> </html>
Ve Windows najdeme rozměry po kliknutí pravým tlačítkem na obrázek v nabídce Vlastnosti v záložce Podrobnosti. Na Macu použijeme možnost Získat informace (Command + I)
Ve složce s projektem vytvoříme soubor script.js
a dopíšeme
do něj následující kód:
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 }
Načetli jsme do proměnných plátno, kontext a obrázek. Kontextu jsme
nastavili červenou barvu výplně a překreslili jí celý
<canvas>
. Metodou removeChild()
jsme obrázek
odstranili z dokumentu, aby se nám po jeho vykreslení JavaScriptem nezobrazil
dvakrát. Nakonec jsme kontext uložili metodou save()
.
Posun kontextu
Posun kontextu provádíme metodou
translate()
:
kontext.translate(10, 10); kontext.drawImage(obrazek, 0, 0); kontext.restore();
Metoda přijímá parametry x
a y
pro souřadnice
posunu. Nový nulový bod bude na těchto souřadnicích. My jsme plátno
posunuli o kladných 10 px
jak po ose x
, tak po ose
y
a na nové pozici vykreslili obrázek. Kontext plátna jsme pak
obnovili.
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()
:
kontext.scale(0.5, 0.5);
Metoda 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ž jedna.
Obrázek je nyní v prohlížeči poloviční:
Rotace
Poslední transformací kontextu je rotace. Z HTML dokumentu
odstraníme obrázek (celý element <img>
) a v JavaScriptu
ponecháme pouze načtené plátno a kontext:
let platno = document.getElementById("platno"); let kontext = platno.getContext("2d");
Pro všechny následující příklady tyto dvě proměnné ponecháme a budeme měnit pouze kód za nimi.
Rotaci si vyzkoušíme opět na čtverci, který otočíme o 45 stupňů
metodou rotate()
:
kontext.save(); kontext.translate(100, 100); kontext.rotate(45 * Math.PI / 180); kontext.strokeRect(0, 0, 50, 50); kontext.restore();
Metoda rotate()
přijímá jako parametr úhel v
radiánech. V příkladu jsme nejprve uložili aktuální stav
kontextu, poté jsme pomocí metody translate()
nastavili posun,
aby se otočený čtverec zobrazil celý. Následně jsme použili metodu
rotate()
pro otočení kontextu. Protože parametr vyžaduje úhel
v radiánech, bylo potřeba úhel ze stupňů převést. Poté jsme čtverec
vykreslili a nakonec obnovili původní stav kontextu:
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. Plátno ale ve
výchozím stavu není bílé, je průhledné. Pokud tedy překreslíme plátno
pomocí fillRect()
, sice uvidíme bílou plochu, ale neuvidíme, co
bylo pod plátnem. Vhodnější je tedy použít metodu
clearRect()
:
kontext.fillRect(0, 0, 200, 200); kontext.clearRect(10, 10, 100, 100);
Nejprve jsme vytvořili černý čtverec metodou fillRect()
a
následně vymazali jeho část pomocí metody clearRect()
.
Parametry mají obě metody stejné - první dva určují souřadnice levého
horního rohu, třetí parametr představuje šířku a čtvrtý výšku dané
oblasti:
Kdybychom chtěli vymazat celé plátno, změníme parametry metody při volání takto:
kontext.clearRect(0, 0, platno.width, platno.height);
Stín
Obrázkům na plátně můžeme přidat stín:
kontext.shadowColor = "red"; kontext.shadowOffsetX = 6; kontext.shadowOffsetY = 3; kontext.shadowBlur = 10; kontext.strokeRect(10, 10, 50, 50);
Při nastavování použijeme vlastnosti:
shadowColor
– pro nastavení barvy stínu,shadowOffsetX
– pro nastavení vodorovného posunu stínu,shadowOffsetY
– pro nastavení svislého posunu stínu,shadowBlur
– pro určení míry rozostření stínu.
Nakonec metodou strokeRect()
vykreslíáme čtverec s
nastaveným stínem:
Barevné přechody
Obrázkům můžeme kromě stínu přidat také lineární nebo kruhový barevný přechod. Jde o způsob, jak vybarvit plochu více barvami, které na sebe postupně navazují. Přechody lze použít jak pro výplň, tak pro obrys.
Lineární přechod
Lineární přechod vytvoříme pomocí metody
createLinearGradient()
volané na objektu kontextu:
let prechod = kontext.createLinearGradient(0, 0, 100, 0);
Metoda přijímá čtyři parametry. První dva určují
souřadnice x
a y
pro
počáteční bod gradientu, druhé dva jeho koncový
bod. Gradient jsme uložili do proměnné prechod
.
Nyní můžeme pomocí metody addColorStop()
přidat do
gradientu další barvy:
let prechod = kontext.createLinearGradient(0, 0, 100, 0); prechod.addColorStop(0, "yellow"); prechod.addColorStop(0.2, "orange"); prechod.addColorStop(0.4, "pink"); prechod.addColorStop(0.6, "red"); prechod.addColorStop(0.8, "green"); prechod.addColorStop(1, "blue"); kontext.fillStyle = prechod; kontext.fillRect(0, 0, 100, 100); kontext.font = "19px Calibri" kontext.fillText("ITnetwork.cz", 0, 115);
Tato metoda přijímá jako první parametr pozici přidávané
barvy v rozmezí od 0
pro začátek až po 1
pro konec přechodu. Druhý parametr určuje samotnou barvu.
Přechod jsme použili k nastavení výplně pro vykreslované prvky pomocí
vlastnosti fillStyle
(podobně jako při nastavování barvy) a
vykreslili jsme čtverec pomocí fillRect()
. Nakonec jsme ještě
do grafiky přidali metodou fillText()
nápis
ITnetwork.cz
:
Radiální přechod
Radiální neboli kruhový přechod se
používá úplně stejně, jen vytvoří jiný efekt. Vytvoříme jej metodou
createRadialGradient()
:
let prechod = kontext.createRadialGradient(50, 50, 0, 50, 50, 75);
Tato metoda přijímá šest parametrů. První tři určují
souřadnice x
a y
a poloměr
počátečního bodu. Další tři určují
souřadnice a poloměr koncového bodu.
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 prechod = kontext.createRadialGradient(50, 50, 0, 50, 50, 75); prechod.addColorStop(0, "yellow"); prechod.addColorStop(0.2, "orange"); prechod.addColorStop(0.4, "pink"); prechod.addColorStop(0.6, "red"); prechod.addColorStop(0.8, "green"); prechod.addColorStop(1, "blue"); kontext.fillStyle = prechod; kontext.fillRect(0, 0, 100, 100); kontext.font = "19px Calibri" kontext.fillText("ITnetwork.cz", 0, 115);
Opět jsme využili vlastnost fillStyle
a pomocí metody
fillRect()
vykreslili čtverec s nastaveným barevným přechodem.
Tento přechod se pak automaticky použil i na text, který jsme vykreslili
metodou fillText()
:
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.
Pro náš vzor použijeme obrázek s otazníkem:
Ten si stáhneme, uložíme do složky s projektem a poté ho vložíme do těla HTML dokumentu doplněním následujícího kódu:
<img src="vzor.png" id="obrazek"/>
Do souboru script.js
vložíme následující kód:
window.onload = function() { let platno = document.getElementById("platno"); let kontext = platno.getContext("2d"); let obrazek = document.getElementById("obrazek"); document.body.removeChild(obrazek); let vzor = kontext.createPattern(obrazek, "repeat"); kontext.fillStyle = vzor; kontext.fillRect(50, 50, 100, 100); };
Kromě plátna a kontextu jsem si načetli náš obrázek a následně ho
odstranili z dokumentu metodou removeChild()
. Metodou
createPattern()
jsme vytvořili náš vzor a uložili ho do
proměnné. Tu jsme potom nastavili jako hodnotu vlastnosti
fillStyle
. Následně jsme vykreslili metodou
fillRect()
vyplněný čtverec:
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 1012x (381.28 kB)
Aplikace je včetně zdrojových kódů v jazyce JavaScript