Stílusjellemzők 3. - Színátmenetek, mintázatok

Ebben a fejezetben az alakzatok kitöltésének két új módszerével fogunk megismerkedni. Először el kell készíteni a mintát, majd el kell nevezni az id attribútum használatával. Ezután a style-ban a fill tulajdonság értékeként kell megadnunk a használandó kitöltést az alábbi formában:
fill: url(#kitoltes_neve). A kitöltések ill. mintázatok díszíthetnek vonalakat is, ekkor a stroke értékét kell beállítani a fentiek szerint. Ilyenkor célszerű a vonalat vastagságát megnövelni.

Mivel a mintázatoknak önmagukban nincs értelmük célszerű a felhasználásra szánt mintákat a dokumentum elején egy <defs> elemben elhelyezni.


Színátmenetek

Elsőként nézzük meg, hogyan lehet színátmenettel kitölteni egy alakzatot. Kétféle lehetőség közül választhatunk. Készíthetünk olyan színátmenetet, amelyben az egyik színből a másikba egy egyenes mentén jutunk el, a másik esetben pedig a változás körkörösen halad, ahogyan távolodunk a középponttól, úgy változik a szín is.

Lineáris színátmenet

Egy vonal mentén változó színátmenetet a <linearGradient> elemmel hozhatunk létre:

<linearGradient id= ""  
  x1= "0%"  
  y1= "0%"  
  x2= "100%"  
  y2= "0%"  
  gradientUnits= "objectBoundingBox"  
  spreadMethod= "pad" >
</linearGradient>  

Az id attribútumban adható meg, hogy mi legyen az átmenet neve. Egyelőre csak erre van szükségünk. A többi attribútumról később lesz szó.

Azzal, hogy elkészítettünk egy ilyen elemet és el is neveztük, tulajdonképpen nem történt semmi. Meg kell adni azt is, hogy hol, milyen színe legyen a kitöltésnek. Az alapértelmezett jellemzőket használva egy vízszintes, balról jobbra, az alakzat két széle között húzódó egyenes mentén kell megadni azokat a pontokat, amelyek a színátmenetet meghatározzák. Néhány értéket kell kijelölni, ezek között pedig egyenletesen változik majd a kitöltőszín. Ilyen színmegadásra a <stop> elemben van mód. Ezt a <linearGradient gyermekelemeként kell elhelyezni, azaz a nyitó és a lezáró rész közé. Egy elemben egyetlen szín megadására van mód, így annyi <stop> elemet kell felvenni, ahány ponton szeretnénk rögzíteni a színeket. Legalább két színt mindenképpen meg kell adni, hogy színátmenetről beszélhessünk.

<stop offset= ""  
  style= "stop-color: #rgb" >

Mint a fenti elemleírásból kiderül, mindössze két attribútumot kötelező megadni. A style-ban a stop-color tulajdonság segítségével mondhatjuk meg, hogy az adott helyen milyen szín jelenjen meg. Az offset értéke pedig megmondja, hogy az egyenesünkön hol helyezkedik el ez a szín. 0 és 100% közötti lehet ez a helymegadás. Nem kötelező a kezdő- és a végpontban a szín megadása, de általában szokott szerepelni. A színmegadáskor a korábbiakban megismert módszerek bármelyike használható a keresett szín leírására.

11/1. feladat:

Készíts egy 60×60-as négyzetet, amelyet kék-sárga színátmenettel töltesz ki.

11/2. feladat:

Rajzolj az előbbi négyzet mellé egy három színből álló színátmenettel kitöltött ellipszist.

Most nézzük, mit jelentenek a leírásban szereplő további attribútumok.
Megadhatjuk, hogy ne egy vízszintes egyenes mentén történjen a változás, hanem valamilyen vektor irányában. Ennek a vektornak a koordinátáit lehet megadni az x1, y1, x2 és y2 attribútumokban. A mértékegység a gradientUnits értékétől függ. Ha az alapértelmezett objectBoundingBox beállítást használjuk, akkor a koordinátarendszer az alakzat befoglaló téglalapja lesz. Emiatt százalékos értéket kell megadni. Ha a userSpaceOnUse beállítást használjuk, akkor a rajzlap koordinátarendszerének megfelelő értékeket kell megadni. Az első esetben minden alakzatnak azonos, saját színe lehet, ami mindösszesen az őt befoglaló téglalapban helyezkedik el. A második esetet felfoghatjuk úgy is, hogy a teljes rajzlap ki van töltve egy mintázattal, majd le van fedve a következő réteggel, egy fehér lappal. Amikor megjelenítünk egy mintázattal kitöltött alakzatot, akkor tulajdonképpen "kivágjuk" a rajzlapot elfedő fehér rétegből, így láthatóvá téve a mintázatot.
Az elem leírásában található értékeket megfigyelve érthető, hogy miért egy vízszintes vonal mentén történik a színátmenet, ha másként nem rendelkezünk.

A spreadMethod tulajdonságban arról rendelkezhetünk, hogy mi történjen a színátmenettel a 0% előtt és a 100% után. Három lehetőség közül választhatunk:

Ezeket az alábbi beállítások használatával érhetjük el:

Lehetőség van arra is, hogy egy színátmenet színeit többféle módon felhasználjuk. Ekkor egyszerűen egy újabb színátmenetet kell létrehozni egy <linearGradient> elemmel. Az elemben el kell helyezni egy xlink:href attribútumot, melyben egy már elkészített és elnevezett színátmenetre kell hivatkozni. A hivatkozás módja ugyanaz, mint a <use> elem esetén. Az így elkészített új mintázatban a színeket nem kell megadni, de irányvektort és kitöltési beállítást meg lehet adni.

11/3. feladat:

A 11/1. feladatban elkészített színátmenet felhasználásával definiálj különböző irányú (függőleges, átlós, ellentétes irányú, stb.) átmeneteket. Használd fel ezeket egymás melletti négyzetek kitöltéséhez. Legalább négy átmenetet használj, de a színeket csak egy helyen add meg. Az alakzatok befoglaló téglalapjának koordinátarendszerét használd.

11/4. feladat:

Készíts egy két színből álló színátmenetet. Az irányt meghatározó vektor végpontjainak koordinátái legyenek (20,20) és (60,60). Használd fel ezt egymás melletti körök kitöltéséhez úgy, hogy a spreadMethod értéke minden esetben más legyen.

Sugaras színátmenet

Ennek a típusnak az elkészítése sokban hasonlít az eddig megismert lineáris átmenethez. Sugaras színátmenetet a radialGradient elem segítségével készíthetünk.

<radialGradient id= ""  
  cx= "50%"  
  cy= "50%"  
  r= "50%"  
  fx= "50%"  
  fy= "50%"  
  gradientUnits= "objectBoundingBox"  
  spreadMethod= "pad" >
</radialGradient>  

A sugaras színátmenetnél nem egy egyenes mentén, hanem egy kör középpontja körül történik a színek módosítása. A cx és cy attribútumokban lehet megadni, hogy a kör középpontja hol helyezkedjen el. Az r pedig a kör sugarát mondja meg. A mértékegység és a használandó koordinátarendszer itt is a gradientUnits beállításától függ, pontosan úgy, mint ahogyan a lineáris színátmenetnél történt. Hasonlóan a spreadMethod értékei is ugyanazok lehetnek, mint az előző esetben és az eredményük is hasonló.

Ha nem teljesen koncentrikus körökben haladó színátmenetre van szükségünk, akkor megadhatók az fx és fy értékek is. Ilyenkor nem a kör középpontja körül, hanem elcsúsztatott elrendezésben fognak változni a színek. Ha nem adunk meg más értéket, akkor a fókusz és a középpont megegyezik, vagyis fx értéke cx, fy értéke pedig cy lesz.

A színek megadására most is a <stop> elemet kell használni.

Ha egy körkörös színátmenetet többféle beállítással is fel szeretnénk használni, azt is ugyanúgy megtehetjük, mint a lineáris esetén.

11/5. feladat:

Hozz létre egy tetszőleges két színből álló körkörös színátmenetet. Ennek felhasználásával definiálj különböző fókusz- ill. középpontú átmeneteket. Használd fel ezeket egymás melletti téglalapok kitöltéséhez. Legalább négy átmenetet használj, de a színeket csak egy helyen add meg.


Mintázatok

Mintázatok létrehozásakor hasonlóan kell eljárni, mint a színátmenetek esetén. Először létre kell hozni azt a "csempét" amit a kitöltéshez szeretnénk használni, majd ezek után az alakzatnál meg kell adni kitöltésként egy hivatkozást az elnevezett mintázatra.

Mintázatként tetszőleges alakzatot vagy alakzatokat felhasználhatunk. A csempe leírását egy <pattern> elemben kell elhelyezni. Az elem gyermekelemei fogják alkotni a csempét.

<pattern id= ""  
  x= "0"  
  y= "0"  
  width= "0"  
  height= "0"  
  patternUnits= "objectBoundingBox"  
  patternContentUnits= "userSpaceOnUse" >
</pattern>  

Az id attribútum az eddigiekhez hasonlóan a minta elnevezésére szolgál. Az x és y értéke a minta bal felső sarkát, a width és a height a szélességét és a magasságát határozza meg.

A bal felső sarok megadása első ránézésre furcsának tűnhet. A szokások azt diktálnák, hogy kezdjük el a kitöltést a bal felső sarokban egy teljes csempével, majd folytassuk vízszintesen és függőlegesen, amíg nem végzünk a kitöltendő területtel. Erre is van lehetőség, de sok más érdekes hatást is el tudunk érni mintázatokkal. Így néhány beállítási lehetőséget meg kell ismerni. Az alapértelmezett beállításokkal elkészített csempék esetén a kitöltő minta méreteit a rajzlap koordinátarendszerében kell megadnunk, majd a minta szélességét és magasságát a kitöltendő alakzat befoglaló téglalapjának oldalaihoz képest kell megadni, százalékos értékekkel.

11/6. feladat:

Készíts egy csempét, amely tartalmaz egy 20×20-as zöld vonalú négyzetet, aminek nincs kitöltése és helyezz el benne egy piros "spirált", amely a következő pontokon halad át: 10,10 15,10 15,5 5,5 5,15 15,15. Hozz létre egy 400×200-as koordinátarendszert és rajzolj meg benne három téglalapot az alábbi méretekkel:

x y width height
10 10 100 100
120 10 50 100
180 10 150 150

A téglalapokat töltsd ki az előbb létrehozott mintázattal úgy, hogy a csempék szélessége és magassága is 20% legyen. Hogy a téglalapok széle is látható legyen, adj nekik fekete keretet.

A feladat megoldásában a csempék meglehetősen furcsán néznek ki. Nem egészen ezt várnánk a kitöltéstől. A pontos megértéshez csupán a koordinátarendszerek rendbetételére van szükség. Kétféle döntést kell meghoznunk a csempék elhelyezésekor.

Az egyik, hogy a csempe méretét milyen koordinátarendszerben adjuk meg. Az előző feladatban szereplő csempe 20×20-as méretű volt. Ezt a méretet a rajzlapon felvett koordinátarendszerben kell érteni. A másik lehetőség, hogy a kitöltendő alakzat befoglaló téglalapját használjuk a már megszokott módon, azaz a bal felső sarok a (0,0) ill. (0%,0%), a jobb alsó pedig az (1,1) ill. (100%,100%) pont. A méreteket ennek megfelelően százalékosan kell megadni. Ha a rajzlap koordinátarendszerét szeretnénk használni, akkor a patternContentUnits értéke userSpaceOnUse legyen. Mivel ez az alapértelmezett megadás, nem is kell külön beleírni a kódba. Ha a kitöltendő alakzat koordinátarendszerében adjuk meg a méreteket, akkor a patternContentUnits-nak az objectBoundingBox értéket kell adni.

Ezen kívül azt kell eldönteni, hogy az elkészült mintát milyen módon szeretnénk felhasználni. Itt is két koordinátarendszert választhatunk, a rajzlap ill. a kitöltendő alakzat koordinátarendszerét. Ha a rajzlapon működő méretekre van szükségünk, akkor a patternUnits értékét át kell állítani userSpaceOnUse-ra. Ha a befoglaló téglalap koordinátarendszere a megfelelő, akkor meg kell hagyni az alapértelmezett objectBoundingBox beállítást.

Azaz ugyanaz a mintázat mindösszesen a koordinátarendszerek megváltoztatásával teljesen más jellegűvé alakítható.

11/7. feladat:

Alakítsd át az előző feladatban elkészített mintázatot úgy, hogy a téglalapokon a csempék mérete a megrajzolttal egyező, 20×20-as legyen.

A 11/7. feladat eredménye már jobban megközelítette a szokásos csempézési eljárások eredményét. Megfigyelhető, hogy az első téglalap esetében nem a bal felső sarokban kezdődik a mintázat. Ennek oka az, hogy a téglalap bal felső sarka a (10,10) pontban van. Mivel a mintázatnak nem adtunk meg x és y értéket, ezért a csempézés a (0,0) pontból indul. Így amikor elkezdődik a téglalap területe, éppen egy csempe közepénél tartunk.

A koordinátarendszerek összehangolásához használható a viewBox és a preserveAspectRatio attribútum is. Ezzel akkor célszerű élni, amikor van egy elkészített csempénk, amit más méretekkel, méretarányokkal szeretnénk felhasználni. Ilyenkor általában az átméretezés kézzel nem túl célravezető. Egyszerűen a <pattern> attribútumai közé fel kell venni egy viewBox, ill. szükség esetén egy preserveAspectRatio nevűt, melyben a már megszokott jellemzőket kell megadni. Erről részletesen a "Koordinátarendszerek" fejezetben olvashattál.

11/8. feladat:

Alakítsd át a 11/6. feladatban elkészített mintázatot úgy, hogy a téglalapokon a csempék mérete mindig a téglalap 1/5-része legyen. Szükség esetén a csempe megnyúlhat vagy összezsugorodhat.


Mintázott mintázatok

Mintázatokat is lehet mintázni. Ehhez mintázatként egy olyan alakzatot kell használni, ami már mintázva van.

11/9. feladat:

Készítsd el két vonalból egy négyzet átlóit. A négyzet kerete legyen zöld. Hozz létre egy belső mintázatot, melynek magassága és szélessége is a kitöltendő alakzat 50%-a. Készíts egy mintázatot, melynek kitöltéséhez felhasználod a négyzetet. Ez a minta piros körvonalú körökből álljon. Mindkét esetben a patternUnits értéke objectBoundingBox legyen. Használd a mintázatot az eddigi három téglalap kitöltéséhez úgy, hogy a mérete mindkét irányban az alakzat 20%-a legyen.

Ezzel a módszerrel gyorsan érdekes és látványos hatások hozhatók létre. Első ránézésre úgy tűnik, hogy feleslegesen készítettünk el két mintát, hiszen egyszerűen megrajzolhattuk volna a szükséges vonalakat a körön belül is. Azonban már ennél az egyszerű példánál is mutatkoztak volna nehézségek. Például külön ki kellett volna számolni, hogy meddig tartsanak az átlók, hogy ne lógjanak túl a körvonalon. Nézzünk azonban egy olyan példát, amit a most megismert módszer nélkül gyakorlatilag lehetetlen lenne megvalósítani.

11/10. feladat:

Az előző feladatban elkészített kör kitöltéseként ne mintázatot használj, hanem egy lineáris színátmenetet, amely legalább két színből áll. Alkalmazd ezt a kitöltést a téglalapokra.