Nedavno sam osvježio animiranu grafiku na svojoj web stranici novom temom i grupom pionirskih likova, primjenjujući u praksi mnoge tehnike koje sam podijelio u ovoj seriji. Nekoliko mojih animacija mijenja izgled kada neko stupi u interakciju s njima ili u različito doba dana.
Boje na grafici na vrhu mojih stranica bloga se mijenjaju od jutra do mraka svaki dan. Zatim, tu je režim snijega, koji dodaje prohladne boje i zimsku temu, zahvaljujući sloju preklapanja i načinu miješanja.
Dok sam radio na ovome, počeo sam da se pitam da li CSS relativne vrednosti boja mogu da mi daju veću kontrolu, a istovremeno pojednostavljuju proces. Napomena: U ovom vodiču fokusirat ću se na relativne vrijednosti boja i OKLCH prostor boja za tematske grafike i animacije. Ako želite da zaronite duboko u relativne boje, Ahmad Shadeed je napravio vrhunski interaktivni vodič. Što se tiče prostora boja, gamuta i OKLCH-a, naš Geoff Graham je pisao o njima.
Ponovljena upotreba elemenata je bila ključna. Pozadine su ponovo korišćene kad god je to bilo moguće, sa zumiranjem i preklapanjem koji su pomogli da se konstruišu nove scene od istog umetničkog dela. Nastao je iz nužde, ali je također podstakao razmišljanje u smislu serija, a ne pojedinačnih scena. Problem sa ručnim ažuriranjem paleta boja Pređimo direktno na moj izazov. U naslovima Toon kao što je ovaj — baziran na epizodi Yogi Bear Show-a iz 1959. „Lullabye-Bye Bear“ — i općenito u mom radu, palete su ograničene na nekoliko odabranih boja.
Kreiram nijanse i nijanse od onoga što zovem svojom bojom „temelj“ da proširim paletu bez dodavanja više nijansi.
U Sketchu radim u HSL prostoru boja, tako da ovaj proces uključuje povećanje ili smanjenje vrijednosti svjetline moje temeljne boje. Iskreno, to nije težak zadatak - ali odabir druge boje podloge zahtijeva stvaranje potpuno novog seta nijansi i nijansi. Raditi to ručno, iznova i iznova, brzo postaje naporno.
Spomenuo sam HSL — H (nijansa), S (zasićenost) i L (svjetlina) — prostor boja, ali to je samo jedan od nekoliko načina da se opiše boja. RGB — R (crveno), G (zeleno), B (plavo) — je vjerovatno najpoznatiji, barem u svom Hex obliku. Tu je i LAB — L (svjetlina), A (zeleno-crvena), B (plavo-žuta) — i noviji, ali sada široko podržan LCH — L (svjetlina), C (kroma), H (nijansa) — model u svom OKLCH obliku. Sa LCH-om — posebno OKLCH-om u CSS-u — mogu podesiti vrijednost svjetline svoje temeljne boje.
Ili mogu da promenim njenu boju. LCH hroma i HSL zasićenost opisuju intenzitet ili bogatstvo boje, ali to čine na različite načine. LCH mi daje širi raspon i predvidljivije miješanje između boja.
Također mogu promijeniti nijansu kako bih stvorio paletu boja koje dijele iste vrijednosti svjetlosti i boje. I kod HSL-a i kod LCH-a, spektar nijansi počinje crvenom, kreće se kroz zelenu i plavu i vraća se u crvenu.
Zašto je OKLCH promijenio svoje mišljenje o boji Podrška pretraživača za OKLCH prostor boja sada je široko rasprostranjena, čak i ako alati za dizajn - uključujući Sketch - nisu sustigli korak. Srećom, to vas ne bi trebalo spriječiti da koristite OKLCH. Pretraživači će za vas rado pretvoriti Hex, HSL, LAB i RGB vrijednosti u OKLCH. Možete definirati CSS prilagođeno svojstvo s temeljnom bojom u bilo kojem prostoru, uključujući hex: /* Boja podloge */ --temelj: #5accd6;
Sve boje izvedene iz njega će se automatski konvertovati u OKLCH: --foundation-light: oklch(od var(--foundation) [...]; } --foundation-mid: oklch(od var(--foundation) [...]; } --foundation-dark: oklch(od var(--foundation) [...]; }
Relativna boja kao sistem dizajna Zamislite relativnu boju kao da kažete: „Uzmi ovu boju, podesi je, a zatim mi daj rezultat.“ Postoje dva načina za podešavanje boje: apsolutne promjene i proporcionalne promjene. Izgledaju slično u kodu, ali se ponašaju sasvim drugačije kada počnete mijenjati temeljne boje. Razumijevanje te razlike je ono što korištenje relativne boje može pretvoriti u sistem. /* Boja podloge */ --temelj: #5accd6;
Na primjer, vrijednost svjetline moje temeljne boje je 0,7837, dok tamnija verzija ima vrijednost 0,5837. Da bih izračunao razliku, oduzimam nižu vrijednost od veće i primjenjujem rezultat pomoću funkcije calc(): --temna-temna: oklch (od var(--foundation) izračun (l - 0,20) c h);
Da bih postigao svjetliju boju, umjesto toga dodajem razliku: --temelj-svjetlo: oklch (od var(--foundation) izračun (l + 0,10) c h);
Chromaprilagođavanja prate isti proces. Da smanjim intenzitet svoje temeljne boje sa 0,1035 na 0,0035, oduzimam jednu vrijednost od druge: oklch (od var(--foundation) l izrač (c - 0,10) h);
Da kreiram paletu nijansi, izračunavam razliku između vrijednosti nijanse moje temeljne boje (200) i moje nove nijanse (260): oklch (od var(--foundation) l c izračun (h + 60));
Te kalkulacije su apsolutne. Kada oduzmem fiksni iznos, zapravo kažem: "Uvijek oduzmi ovoliko." Isto vrijedi i za dodavanje fiksnih vrijednosti: izračun (c - 0,10) izračun (c + 0,10)
Na teži način sam naučio granice ovog pristupa. Kada sam se oslanjao na oduzimanje fiksnih vrijednosti boje, boje su padale u sivu čim sam promijenio temelj. Paleta koja je radila za jednu boju raspala se za drugu. Množenje se ponaša drugačije. Kada množim hromu, govorim pretraživaču: "Smanji intenzitet ove boje za proporciju." Odnos između boja ostaje netaknut, čak i kada se temelj promijeni: izračun (c * 0,10)
Pravila su moji pokreti, skaliranje, rotiranje
Pomjerite lakoću (dodajte ili oduzmite), Skala hroma (množenje), Rotirajte nijansu (dodajte ili oduzmite stepene).
Skaliram hromu jer želim da promjene intenziteta ostanu proporcionalne osnovnoj boji. Odnosi nijansi su rotacijski, tako da množenje nijansi nema smisla. Lakoća je perceptivna i apsolutna - njeno umnožavanje često daje čudne rezultate.
Od jedne boje do cijele teme Relativna boja mi omogućava da definiram temeljnu boju i generiram svaku drugu boju koja mi je potrebna — ispune, potezi, prestanci gradijenta, sjene — iz nje. U tom trenutku boja prestaje da bude paleta i počinje da bude sistem. SVG ilustracije imaju tendenciju da ponovo koriste istih nekoliko boja u ispunama, potezima i gradijentima. Relativna boja vam omogućava da jednom definirate te odnose i da ih svugdje ponovo koristite – slično kao što su animatori ponovo koristili pozadinu za kreiranje novih scena.
Jednom promijenite temeljnu boju i svaka izvedena boja se automatski ažurira, bez ručnog preračunavanja. Izvan animirane grafike, mogao bih koristiti isti pristup za definiranje boja za stanja interaktivnih elemenata kao što su dugmad i veze. Podloga koju sam koristila u svom naslovu "Lullabye-Bye Bear" Toon Title je plava cijan izgleda. Pozadina je radijalni gradijent između moje podloge i tamnije verzije.
Da bih stvorio alternativne verzije s potpuno drugačijim raspoloženjima, samo trebam promijeniti boju temeljca: --temelj: #5accd6; --grad-end: var(--temelj); --grad-start: oklch(od var(--foundation) kalc(l - 0,2357) kalc(c * 0,833) h);
Da povežem ta prilagođena svojstva za moj SVG gradijent bez dupliciranja vrijednosti boja, zamijenio sam tvrdo kodirane vrijednosti stop-boja sa umetnutim stilovima:
Zatim, morao sam osigurati da moj Toon Text uvijek bude u kontrastu s bilo kojom bojom podloge koju odaberem. Rotacija nijansi od 180 stepeni proizvodi komplementarnu boju koja svakako iskače - ali može neugodno vibrirati: .text-light { fill: oklch(od var(--foundation) l c izračun (h + 180)); }
Pomak od 90° proizvodi živopisnu sekundarnu boju koja nije u potpunosti komplementarna: .text-light { fill: oklch(od var(--foundation) l c izračun (h - 90)); }
Moja rekreacija Quick Draw McGrawovog Toon Title iz 1959. godine „El Kabong“ koristi iste tehnike, ali s raznolikijom paletom. Na primjer, postoji još jedan radijalni gradijent između temeljne boje i tamnije nijanse.
Zgrada i drvo u pozadini su jednostavno različite nijanse iste temeljne boje. Za te staze, trebale su mi dvije dodatne boje ispune: .bg-mid { fill: oklch(od var(--foundation) kalc(l - 0,04) kalc(c * 0,91) h); }
.bg-dark { fill: oklch(od var(--foundation) kalc(l - 0,12) kalc(c * 0,64) h); }
Kada se temelji počnu pomicati
Do sada je sve što sam prikazao bilo statično. Čak i kada neko koristi birač boja za promjenu osnovne boje, ta promjena se događa trenutno. Ali animirana grafika retko stoji - trag je u imenu. Dakle, ako je boja dio sistema, nema razloga da ne može i animirati.
Da bih animirao temeljnu boju, prvo je trebam podijeliti na njene OKLCH kanale— lakoća, boja i nijansa. Ali postoji važan dodatni korak: moram registrirati te vrijednosti kao upisana prilagođena svojstva. Ali šta to znači?
Prema zadanim postavkama, pretraživač ne zna da li vrijednost prilagođenog svojstva CSS-a predstavlja boju, dužinu, broj ili nešto sasvim drugo. To često znači da se ne mogu glatko interpolirati tokom animacije i skakati s jedne vrijednosti na drugu.
Registrovanje prilagođenog svojstva govori pretraživaču tip vrijednosti koju predstavlja i kako bi se trebao ponašati tokom vremena. U ovom slučaju, želim da pretraživač moje kanale u boji tretira kao brojeve kako bi se mogli glatko animirati.
@property --f-l {
sintaksa: "
@property --f-c {
sintaksa: "
@property --f-h {
sintaksa: "
Kada se registruju, ova prilagođena svojstva se ponašaju kao izvorni CSS. Pretraživač ih može interpolirati okvir po okvir. Zatim obnavljam temeljnu boju iz ovih kanala: --temelj: oklch(var(--f-l) var(--f-c) var(--f-h));
Ovo čini da osnovna boja postaje animirana, baš kao i svaka druga numerička vrijednost. Evo jednostavne animacije "disanja" koja lagano mijenja lakoću tokom vremena: @keyframes disati { 0%, 100% { --f-l: 0,36; } 50% { --f-l: 0,46; } }
.toon-title { animacija: beskonačno udahnite 10s lakoće ulaska-izdaha; }
Budući da je svaka druga boja u ispunama, gradijentima i potezima izvedena iz --temelj, sve one animiraju zajedno i ništa ne treba ručno ažurirati. Jedna animirana boja, mnogo efekata Na početku ovog procesa pitao sam se da li CSS relativne vrijednosti boja mogu ponuditi više mogućnosti, a istovremeno ih učiniti jednostavnijim za implementaciju. Nedavno sam dodao novu pozadinu rudnika zlata na kontakt stranicu svoje web stranice, a prva iteracija uključivala je uljne lampe koje svijetle i ljuljaju.
Želio sam istražiti kako bi animiranje CSS relativnih boja moglo učiniti unutrašnjost rudnika realističnijim nijansiranjem bojama iz lampi. Želeo sam da utiču na svet oko sebe, na način na koji deluje prava svetlost. Dakle, umjesto da animiram više boja, napravio sam sićušni sistem rasvjete koji animira samo jednu boju.
Moj prvi zadatak je bio da postavim sloj za prekrivanje između pozadine i mojih lampi:
Koristio sam mix-blend-mode: boju jer to nijansira ono što se nalazi ispod, a zadržava osnovno osvjetljenje. Pošto želim da preklapanje bude vidljivo samo kada su animacije uključene, omogućio sam preklapanje: .svg-mine #overlay { prikaz: nema; }
@media (prefers-reduced-motion: no-preference) { .svg-mine[data-animations=on] #overlay { displej: blok; neprozirnost: 0,5; } }
Preklop je bio na mjestu, ali još nije povezan sa lampama. Trebao mi je izvor svjetlosti. Moje lampe su jednostavne, a svaka sadrži element kruga koji sam zamutio filterom. Filter proizvodi vrlo meko zamućenje po cijelom krugu.
Umjesto da animiram preklop i lampe odvojeno, animiram jedan token boje „plamena“ i iz toga izvodim sve ostalo. Prvo, registrujem tri ukucana prilagođena svojstva za OKLCH kanale:
@property --fl-l {
sintaksa: "
Animirao sam te kanale, namjerno gurajući nekoliko kadrova prema narandžastoj, tako da se treperenje jasno čita kao svjetlo vatre:
@keyframes plamen { 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-h: 76; } 44% { --fl-l: 0,87; --fl-c: 0,12; --fl-h: 96; } 52% { --fl-l: 0,81; --fl-c: 0,15; --fl-h: 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-h: 74; } }
Zatim sam proširio tu animaciju na SVG, tako da su zajedničke varijable dostupne i za lampe i za moj preklop:
@media (prefers-reduced-motion: no-preference) { .svg-mine[data-animations=on] { animacija: plamen 3.6s beskonačno linearno; izolacija: izolirati;
/* Napravite boju plamena iz animiranih kanala */ --flame: oklch(var(--fl-l) var(--fl-c) var(--fl-h));
/* Boja lampe izvedena iz plamena */ --lamp-core: oklch(od var(--plamen) calc(l + 0,05) calc(c * 0,70) h);
/* Nijansa preklapanja izvedena iz istog plamena */ --overlay-tint: oklch(od var(--flame) izračun (l + 0,06) izračun (c * 0,65) izračun (h - 10)); } }
Konačno, primijenio sam te izvedene boje na svjetleće lampe i sloj na koji utiču: @media (prefers-reduced-motion: no-preference) { .svg-mine[data-animations=on] #mine-lamp-1 > krug, .svg-mine[data-animations=on] #mine-lamp-2 > krug { fill: var(--lamp-core); }
.svg-mine[data-animations=on] #overlay { displej: blok; fill: var(--overlay-tint); neprozirnost: 0,5; } }
Kada se plamen pomakne prema narandžastoj, lampe se zagrijavaju, a scena se zagrijava s njima. Kada se plamen ohladi, sve se slegne. Najbolji dio je što se ništa ne piše ručno. Ako promijenim boju temelja ili podesim raspon animacije plamena, cijeli sistem rasvjete se ažurira istovremeno. Konačan rezultat možete vidjeti na mojoj web stranici. Ponovna upotreba, prenamjena, revizija Ti animatori Hanna-Barbera bili su prisiljeni mijenjati elemente iz nužde, ali ja ponovo koristim boje jer to čini moj rad konzistentnijim i lakšim za održavanje. CSS relativne vrijednosti boja mi omogućavaju:
Definirajte jednu temeljnu boju, Opišite kako se druge boje odnose na njega, Ponovo koristite te odnose svuda, i Animirajte sistem promjenom jedne vrijednosti.
Relativna boja ne samo da olakšava postavljanje tema. Podstiče način razmišljanja u kojem je boja, kao i pokret, namjerna — i gdje promjena jedne vrijednosti može transformirati cijelu scenu bez ponovnog pisanja djela ispod nje.