Nemrég frissítettem a weboldalam animációs grafikáját egy új témával és egy úttörő karaktercsoporttal, sok technikát alkalmazva a gyakorlatban, amelyeket ebben a sorozatban megosztottam. Néhány animációm megváltoztatja a megjelenését, amikor valaki kapcsolatba lép velük, vagy a nap különböző szakaszaiban.
A blogoldalaim tetején lévő grafika színei minden nap reggeltől estig változnak. Aztán ott van a hó mód, amely hideg színeket és télies témát ad hozzá egy átfedő réteg és egy keverési mód jóvoltából.
Miközben ezen dolgoztam, azon kezdtem töprengeni, hogy a CSS relatív színértékei nagyobb irányítást biztosítanak-e, miközben leegyszerűsítik a folyamatot. Megjegyzés: Ebben az oktatóanyagban a relatív színértékekre és a tematikus grafikák és animációk OKLCH színterére összpontosítok. Ha mélyre szeretne merülni a relatív színekben, Ahmad Shadeed készített egy nagyszerű interaktív útmutatót. Ami a színtereket, a skálákat és az OKLCH-t illeti, saját Geoff Graham írt róluk.
Az elemek többszöri használata kulcsfontosságú volt. A háttereket lehetőség szerint újrahasznosítottuk, a nagyításokkal és átfedések segítségével új jeleneteket lehetett létrehozni ugyanabból a műből. A szükség szülte, de egyben inkább sorozatokban, mint egyedi jelenetekben való gondolkodásra ösztönzött. Probléma a színpaletták kézi frissítésével Térjünk is közvetlenül a kihívásomhoz. Az ehhez hasonló Toon-címekben – az 1959-es Yogi Bear Show „Lullabye-Bye Bear” epizódja alapján – és általában a munkámban a paletták néhány kiválasztott színre korlátozódnak.
Árnyalatokat és árnyalatokat készítek abból, amit „alapszínemnek” nevezek, hogy bővítsem a palettát anélkül, hogy további árnyalatokat adnék hozzá.
A Sketchben a HSL színtérben dolgozom, tehát ez a folyamat magában foglalja az alapozó színem világossági értékének növelését vagy csökkentését. Őszintén szólva, ez nem nehéz feladat – de egy másik alapozószín kiválasztásához teljesen új árnyalatok és árnyalatok létrehozása szükséges. Ennek manuális, újra és újra elvégzése gyorsan fáradságossá válik.
Említettem a HSL – H (színárnyalat), S (telítettség) és L (lightness) – színteret, de ez csak egy a szín leírásának számos módja közül. Az RGB – R (piros), G (zöld), B (kék) – valószínűleg a legismertebb, legalábbis Hex formában. LAB – L (világosság), A (zöld–piros), B (kék–sárga) – és az újabb, de mára széles körben támogatott LCH – L (világosság), C (chroma), H (színárnyalat) – modell is létezik OKLCH formájában. Az LCH-val – különösen az OKLCH-val a CSS-ben – beállíthatom az alapozószínem világosságát.
Vagy módosíthatom a színét. Az LCH színárnyalat és a HSL-telítettség egyaránt leírja a szín intenzitását vagy gazdagságát, de ezt különböző módon teszik. Az LCH szélesebb tartományt és kiszámíthatóbb keverést biztosít a színek között.
Módosíthatom az árnyalatot is, hogy olyan színpalettát hozzak létre, amely ugyanazokkal a világosság- és színárnyalatokkal rendelkezik. A HSL-ben és az LCH-ban is a színárnyalat-spektrum a pirossal kezdődik, áthalad a zölden és a kéken, majd visszatér a piroshoz.
Miért változtatta meg az OKLCH a színről való gondolkodásomat? Az OKLCH színtér böngésző támogatása mára széles körben elterjedt, még akkor is, ha a tervezőeszközök – köztük a Sketch – nem utolérték. Szerencsére ez nem akadályozhatja meg az OKLCH használatát. A böngészők boldogan konvertálják a Hex, HSL, LAB és RGB értékeket OKLCH formátumba. Bármilyen térben megadhat egyéni CSS-tulajdonságot alapszínnel, beleértve a hexadecimális helyet is: /* Alapozó szín */ --alap: #5accd6;
Az ebből származó színek automatikusan OKLCH-ba konvertálódnak: --foundation-light: oklch( from var(--foundation) [...]; } --foundation-mid: oklch( from var(--foundation) [...]; } --foundation-dark: oklch( from var(--foundation) [...]; }
Relatív szín, mint tervezési rendszer Képzelje el a relatív színt a következőképpen: „Vedd ezt a színt, finomítsd meg, majd add meg az eredményt.” A színek beállításának két módja van: abszolút változtatások és arányos változtatások. Hasonlóan néznek ki a kódban, de nagyon eltérően viselkednek, ha elkezdi cserélni az alapozó színét. Ennek a különbségnek a megértése az, ami a relatív szín használatával rendszerré változhat. /* Alapozó szín */ --alap: #5accd6;
Például az én alapozó színem világossági értéke 0,7837, míg a sötétebb változaté 0,5837. A különbség kiszámításához kivonom az alacsonyabb értéket a magasabbból, és az eredményt a calc() függvény segítségével alkalmazom: --alap-sötét: oklch(a var(--alapítvány) számított (l - 0,20) c h);
A világosabb szín eléréséhez hozzáadom a különbséget: --alapfény: oklch(a var(--alapítvány) számított (l + 0,10) c h);
Chromaa kiigazítások ugyanazt a folyamatot követik. Az alapozószínem intenzitásának 0,1035-ről 0,0035-re való csökkentésére az egyik értéket levonom a másikból: oklch(a var(--alapítvány) l számított (c - 0,10) h);
Színpaletta létrehozásához kiszámolom az alapszínem (200) és az új árnyalatom (260) árnyalatértéke közötti különbséget: oklch(a var(--alapítvány) l c számolt(h + 60));
Ezek a számítások abszolút. Amikor levonok egy fix összeget, akkor azt mondom: „Mindig vonjon le ennyit.” Ugyanez vonatkozik rögzített értékek hozzáadására is: kalkul(c - 0,10) kalc(c + 0,10)
Nehéz úton tanultam meg ennek a megközelítésnek a határait. Amikor a rögzített színárnyalat-értékek kivonására hagyatkoztam, a színek a szürke felé omlottak, amint megváltoztattam az alapot. Az egyik színhez működő paletta szétesett a másiknál. A szorzás másként viselkedik. Amikor megszorzom a színárnyalatot, azt mondom a böngészőnek: "Csökkentse ennek a színnek az intenzitását egy arányban." A színek közötti kapcsolat érintetlen marad, még akkor is, ha megváltozik az alap: calc(c * 0,10)
Saját mozgatni, méretezni, elforgatni szabályokat
A világosság mozgatása (összeadás vagy kivonás), Skála chroma (többszörözés), Színárnyalat elforgatása (fokok hozzáadása vagy kivonása).
A színárnyalatot azért skálázom, mert azt szeretném, hogy az intenzitásváltozások arányosak maradjanak az alapszínnel. A színárnyalat-viszonyok rotációsak, így nincs értelme a színárnyalat sokszorosításának. A könnyedség érzékelhető és abszolút – sokszorozása gyakran furcsa eredményeket hoz.
Egy színtől egy teljes témáig A relatív szín lehetővé teszi, hogy meghatározzak egy alapozó színt, és ebből generáljak minden más színt, amire szükségem van – kitöltéseket, körvonalakat, színátmenet megállókat, árnyékokat. Ezen a ponton a szín megszűnik paletta lenni, és rendszerré válik. Az SVG-illusztrációk általában ugyanazt a néhány színt használják újra kitöltések, körvonalak és színátmenetek során. A relatív szín lehetővé teszi, hogy egyszer meghatározza ezeket a kapcsolatokat, és mindenhol újra felhasználja őket – hasonlóan ahhoz, ahogy az animátorok újra felhasználták a háttereket új jelenetek létrehozásához.
Változtassa meg egyszer az alapozó színét, és minden származtatott szín automatikusan frissül, anélkül, hogy bármit is kézzel kellene újraszámolnia. Az animált grafikákon kívül ugyanezt a megközelítést használhatom az interaktív elemek, például a gombok és hivatkozások állapotainak színeinek meghatározására. Az alapszín, amit a „Lullabye-Bye Bear” Toon címemben használtam, egy ciánnak tűnő kék. A háttér egy radiális gradiens az alapozóm és egy sötétebb változat között.
Teljesen eltérő hangulatú alternatív változatok létrehozásához csak az alapozó színét kell megváltoztatnom: --alap: #5accd6; --grad-end: var(--foundation); --grad-start: oklch(a var(--foundation) számított (l - 0,2357) számított (c * 0,833) h);
Ahhoz, hogy ezeket az egyéni tulajdonságokat az SVG színátmenetemhez köthessem a színértékek megkettőzése nélkül, lecseréltem a keménykódolt stop-color értékeket soron belüli stílusokra:
Ezután gondoskodnom kellett arról, hogy a Toon szövegem mindig kontrasztban legyen az általam választott alapozó színével. A 180 fokos árnyalatú elforgatás egy kiegészítő színt eredményez, amely biztosan kiugrik – de kényelmetlenül vibrálhat: .text-light { kitöltés: oklch(a var(--alapítványból) lc számított(h + 180)); }
A 90°-os eltolás élénk másodlagos színt eredményez anélkül, hogy teljesen kiegészítené: .text-light { kitöltés: oklch(a var(--alapítványból) lc számított(h-90)); }
Az általam készített Quick Draw McGraw 1959-es „El Kabong” Toon címe ugyanazokat a technikákat használja, de változatosabb palettával. Például van egy másik sugárirányú gradiens az alapozó színe és a sötétebb árnyalat között.
A háttérben látható épület és fa egyszerűen ugyanazon alapszín különböző árnyalatai. Ezekhez az útvonalakhoz két további kitöltőszínre volt szükségem: .bg-mid { kitöltés: oklch(a var(--alapítvány) számított (l - 0,04) számított (c * 0,91) h); }
.bg-dark { kitöltés: oklch(a var(--alapítványból) számított (l - 0,12) számított (c * 0,64) h); }
Amikor az alapok mozogni kezdenek
Eddig minden, amit mutattam, statikus volt. Még akkor is, ha valaki színválasztót használ az alapozó színének megváltoztatásához, ez a változás azonnal megtörténik. De az animált grafika ritkán áll meg – a nyom a névben rejlik. Tehát, ha a szín a rendszer része, nincs ok arra, hogy ne tudna animálni is.
Az alapozó színének animálásához először fel kell osztanom az OKLCH csatornáira- világosság, színárnyalat és színárnyalat. De van egy fontos extra lépés: regisztrálnom kell ezeket az értékeket begépelt egyéni tulajdonságokként. De mit jelent ez?
Alapértelmezés szerint a böngésző nem tudja, hogy az egyéni CSS-tulajdonság értéke színt, hosszt, számot vagy valami mást jelent-e. Ez gyakran azt jelenti, hogy nem interpolálhatók zökkenőmentesen az animáció során, és egyik értékről a másikra ugorhatnak.
Egy egyéni tulajdonság regisztrálása közli a böngészővel, hogy milyen típusú értéket képvisel, és hogyan kell viselkednie idővel. Ebben az esetben azt szeretném, ha a böngésző számokként kezelné a színes csatornáimat, így azok zökkenőmentesen animálhatók.
@tulajdon --f-l {
szintaxis: "
@tulajdon --f-c {
szintaxis: "
@tulajdon --f-h {
szintaxis: "
A regisztráció után ezek az egyéni tulajdonságok natív CSS-ként viselkednek. A böngésző képes kockánként interpolálni őket. Ezután ezekből a csatornákból újraépítem az alapszínt: --alap: oklch(var(--f-l) var(--f-c) var(--f-h));
Ezáltal az alapozó színe animálhatóvá válik, akárcsak bármely más numerikus érték. Íme egy egyszerű „lélegző” animáció, amely idővel finoman változtatja a világosságot: @keyframes lélegzik { 0%, 100% { --f-l: 0,36; } 50% { --f-l: 0,46; } }
.toon-title { animáció: lélegezzen 10 másodperces könnyű be-ki végtelen; }
Mivel a kitöltések, színátmenetek és körvonalak minden más színe a --foundation-ből származik, mindegyik együtt animál, és semmit sem kell manuálisan frissíteni. Egy animált szín, sok effektus A folyamat elején azon töprengtem, vajon a CSS relatív színértékei kínálhatnak-e több lehetőséget, miközben egyszerűbbé teszik a megvalósításukat. Nemrég hozzáadtam egy új aranybánya hátteret a webhelyem kapcsolati oldalához, és az első iterációban világító és lengő olajlámpák szerepeltek.
Azt szerettem volna feltárni, hogy a CSS relatív színeinek animációja hogyan teheti valósághűbbé a bánya belsejét a lámpák színeivel színezve. Azt akartam, hogy hatással legyenek az őket körülvevő világra, ahogy a valódi fény teszi. Tehát ahelyett, hogy több színt animáltam volna, egy apró világítási rendszert építettem, amely csak egy színt animál.
Az első feladatom az volt, hogy egy fedőréteget helyezzek a háttér és a lámpáim közé: <útvonal id="overlay" fill="var(--overlay-tint)" [...] style="mix-blend-mode: color" />
A mix-blend-mode: színt azért használtam, mert az elszínezi az alatta lévőt, miközben megőrzi a mögöttes fénysűrűséget. Mivel azt szeretném, hogy a fedvény csak akkor legyen látható, amikor az animációk be vannak kapcsolva, ezért engedélyeztem a fedvényt: .svg-mine #overlay { kijelző: nincs; }
@media (prefers-redduced-motion: no-preference) { .svg-mine[data-animations=on] #overlay { kijelző: blokk; átlátszatlanság: 0,5; } }
A rátét a helyén volt, de még nem volt csatlakoztatva a lámpákhoz. Szükségem volt egy fényforrásra. A lámpáim egyszerűek, és mindegyikben van egy kör elem, amit szűrővel homályosítottam el. A szűrő nagyon lágy elmosódást hoz létre az egész körön.
Ahelyett, hogy külön animálnám a fedőréteget és a lámpákat, egyetlen „láng” színjelzőt animálok, és ebből származtatok minden mást. Először három beírt egyéni tulajdonságot regisztrálok az OKLCH csatornákhoz:
@tulajdon --fl-l {
szintaxis: "
Animáltam ezeket a csatornákat, szándékosan a narancssárga felé tolva néhány képkockát, így a villogás egyértelműen tűzfényként jelenik meg:
@keyframes láng { 0%, 100% { --fl-l: 0,86; --fl-c: 0,12; --fl-h: 95; } 6% { --fl-l: 0,91; --fl-c: 0,10; --fl-h: 92; } 12% { --fl-l: 0,83; --fl-c: 0,14; --fl-h: 100; } 18% { --fl-l: 0,88; --fl-c: 0,11; --fl-h: 94; } 24% { --fl-l: 0,82; --fl-c: 0,16; --fl-h: 82; } 30% { --fl-l: 0,90; --fl-c: 0,12; --fl-h: 90; } 36% { --fl-l: 0,79; --fl-c: 0,17; --fl-ó: 76; } 44% { --fl-l: 0,87; --fl-c: 0,12; --fl-h: 96; } 52% { --fl-l: 0,81; --fl-c: 0,15; --fl-ó: 102; } 60% { --fl-l: 0,89; --fl-c: 0,11; --fl-h: 93; } 68% { --fl-l: 0,83; --fl-c: 0,16; --fl-h: 85; } 76% { --fl-l: 0,91; --fl-c: 0,10; --fl-h: 91; } 84% { --fl-l: 0,85; --fl-c: 0,14; --fl-h: 98; } 92% {--fl-l: 0,80; --fl-c: 0,17; --fl-ó: 74; } }
Ezután az animációt az SVG-re bontottam, így a megosztott változók elérhetők mind a lámpák, mind a fedvény számára:
@media (prefers-redduced-motion: no-preference) { .svg-mine[data-animations=on] { animáció: láng 3.6s végtelen lineáris; izoláció: izolátum;
/* Lángszín létrehozása animált csatornákból */ --flame: oklch(var(--fl-l) var(--fl-c) var(--fl-h));
/* A lámpa színe lángból származik */ --lámpamag: oklch(a var(--flame) calc(l + 0,05) calc(c * 0,70) h);
/* A fedőszín ugyanabból a lángból származik */ --overlay-tint: oklch(a var(--flame) számított (l + 0,06) számolt (c * 0,65) számolt (h - 10)); } }
Végül ezeket a származtatott színeket alkalmaztam az izzó lámpákra és az általuk érintett átfedésre: @media (prefers-redduced-motion: no-preference) { .svg-mine[data-animations=on] #mine-lamp-1 > circle, .svg-mine[data-animations=on] #mine-lamp-2 > circle { fill: var(--lámpa-mag); }
.svg-mine[data-animations=on] #overlay { kijelző: blokk; fill: var(--overlay-tint); átlátszatlanság: 0,5; } }
Amikor a láng narancssárga felé tolódik, a lámpák felmelegednek, és a jelenet is felmelegszik velük. Amikor a láng lehűl, minden összeáll. A legjobb az egészben az, hogy semmit sem írnak kézzel. Ha megváltoztatom az alapozó színét vagy módosítom a láng-animációs tartományokat, a teljes világítási rendszer egyszerre frissül. A végeredményt a honlapomon láthatjátok. Újrafelhasználás, újrafelhasználás, újrafelhasználás A Hanna-Barbera animátorok kénytelenek voltak újrahasznosítani az elemeket, de én újra használom a színeket, mert így konzisztensebbé és könnyebben karbantarthatóvá válik a munkám. A CSS relatív színértékei lehetővé teszik számomra, hogy:
Határozzon meg egyetlen alapozószínt, Írja le, hogy más színek hogyan kapcsolódnak hozzá, Használja újra ezeket a kapcsolatokat mindenhol, és Animálja a rendszert egy érték megváltoztatásával.
A relatív szín nem csak megkönnyíti a témaválasztást. Olyan gondolkodásmódra ösztönöz, ahol a színek, akárcsak a mozgás, szándékosak – és ahol egy érték megváltoztatása az egész jelenetet átalakíthatja anélkül, hogy átírná az alatta lévő művet.