Неодамна ја освежив анимираната графика на мојата веб-страница со нова тема и група пионерски ликови, применувајќи многу од техниките што ги споделив во оваа серија. Неколку од моите анимации го менуваат изгледот кога некој ќе комуницира со нив или во различни периоди од денот.
Боите на графиката на горниот дел од страниците на мојот блог се менуваат од утро до вечер секој ден. Потоа, тука е режимот на снег, кој додава ладни бои и зимска тема, благодарение на слојот за преклопување и режимот на мешање.
Додека работев на ова, почнав да се прашувам дали релативните вредности на бојата на CSS би можеле да ми дадат поголема контрола, а истовремено да го поедностават процесот. Забелешка: во ова упатство, ќе се фокусирам на релативните вредности на бојата и просторот за бои OKLCH за графики и анимации со теми. Ако сакате да нурнете длабоко во релативната боја, Ахмад Шадед создаде извонреден интерактивен водич. Што се однесува до просторите на боите, гамата и OKLCH, нашиот сопствен Џеф Греам пишуваше за нив.
Повторената употреба на елементи беше клучна. Позадините беа повторно користени секогаш кога беше можно, со зумирање и преклопувања кои помагаа да се конструираат нови сцени од истото уметничко дело. Се роди од неопходност, но исто така поттикна размислување во смисла на серии, а не на индивидуални сцени. Проблемот со рачно ажурирање на палетите на бои Да преминеме директно на мојот предизвик. Во Toon Titles како овој - заснован на епизодата на Yogi Bear Show од 1959 година „Lullabye-bye Bear“ - и мојата работа генерално, палетите се ограничени на неколку одбрани бои.
Јас создавам нијанси и нијанси од она што јас го нарекувам мојата „основа“ боја за да ја проширам палетата без да додавам повеќе нијанси.
Во Sketch, јас работам во просторот на бои HSL, така што овој процес вклучува зголемување или намалување на вредноста на леснотијата на мојата боја на основата. Искрено, тоа не е напорна задача - но изборот на различна боја на основата бара создавање на сосема нов сет на нијанси и нијанси. Да се прави тоа рачно, повторно и повторно, брзо станува макотрпно.
Го споменав HSL - H (нијанса), S (заситеност) и L (леснотија) - простор на бои, но тоа е само еден од неколкуте начини за опишување на бојата. RGB - R (црвено), G (зелено), B (сино) - е веројатно најпознатиот, барем во неговата хексадетична форма. Има и LAB - L (леснотија), A (зелено-црвено), B (сино-жолто) - и поновиот, но сега широко поддржан LCH - L (леснотија), C (хрома), H (нијанса) - модел во неговата форма OKLCH. Со LCH - конкретно OKLCH во CSS - можам да ја прилагодам вредноста на леснотијата на мојата боја на основата.
Или можам да му ја сменам хромата. LCH хромата и HSL сатурацијата и двете го опишуваат интензитетот или богатството на бојата, но тие го прават тоа на различни начини. LCH ми дава поширок опсег и попредвидливо мешање помеѓу боите.
Можам и да ја сменам нијансата за да создадам палета на бои што ја делат истата леснотија и хроматски вредности. И во HSL и LCH, спектарот на нијанси започнува со црвено, се движи низ зелената и сината и се враќа во црвено.
Зошто OKLCH го промени начинот на кој размислувам за бојата Поддршката на прелистувачот за просторот за бои OKLCH сега е широко распространета, дури и ако алатките за дизајн - вклучително и Sketch - не успеале. За среќа, тоа не треба да ве спречи да користите OKLCH. Прелистувачите со задоволство ќе ги претворат вредностите Hex, HSL, LAB и RGB во OKLCH за вас. Можете да дефинирате прилагодено својство на CSS со боја на основата во кој било простор, вклучувајќи Hex: /* Боја на основата */ --основа: #5accd6;
Сите бои добиени од него автоматски ќе се претворат во OKLCH: --Foundation-light: oklch(од var(--Foundation) [...]; } --Foundation-mid: oklch(од var(--Foundation) [...]; } -- темел-темно: оклч(од var(--темел) [...]; }
Релативна боја како систем за дизајн Размислете за релативната боја како што вели: „Земете ја оваа боја, дотерете ја, па дајте ми го резултатот“. Постојат два начини за прилагодување на бојата: апсолутни промени и пропорционални промени. Тие изгледаат слично во кодот, но се однесуваат многу поинаку откако ќе почнете да ги менувате боите на основата. Разбирањето на таа разлика е она што може да ја претвори употребата на релативна боја во систем. /* Боја на основата */ --основа: #5accd6;
На пример, вредноста на светлината на мојата боја на основата е 0,7837, додека потемната верзија има вредност од 0,5837. За да ја пресметам разликата, ја одземам помалата вредност од повисоката и го применувам резултатот користејќи функција calc(): -- темел-темна: oklch(од var(--основа) калц(l - 0,20) c h);
За да постигнам посветла боја, наместо тоа ја додавам разликата: ---темел-светло: oklch(од var(--основа) калц(l + 0,10) c h);
Chromaприлагодувањата го следат истиот процес. За да го намалам интензитетот на бојата на основата од 0,1035 на 0,0035, ја одземам едната вредност од другата: oklch(од var(--основа) l калц(c - 0,10) h);
За да создадам палета на нијанси, ја пресметувам разликата помеѓу вредноста на бојата на мојата основна боја (200) и мојата нова нијанса (260): oklch(од var(--основа) l c калк (h + 60));
Тие пресметки се апсолутни. Кога ќе одземам фиксна сума, всушност велам: „Секогаш одземај толку“. Истото важи и кога се додаваат фиксни вредности: калк (c - 0,10) калк (c + 0,10)
Ги научив границите на овој пристап на потешкиот начин. Кога се потпирав на одземање на фиксните вредности на хромата, боите паднаа кон сиво штом ја сменив основата. Палетата што работеше за една боја се распадна за друга. Множењето се однесува поинаку. Кога ја множам хромата, му кажувам на прелистувачот: „Намали го интензитетот на оваа боја за пропорција“. Врската помеѓу боите останува недопрена, дури и кога основата се менува: калк (c * 0,10)
Правила „Мој премести, размери, ротирање“.
Поместување на леснотија (додавање или одземање), Скалира хрома (множи), Ротирајте ја нијансата (додавајте или одземете степени).
Ја скалирам хромата затоа што сакам промените на интензитетот да останат пропорционални со основната боја. Врските со нијанси се ротациони, така што множењето на нијансата нема смисла. Леснотијата е перцептивна и апсолутна - нејзиното множење често дава чудни резултати.
Од една боја до цела тема Релативната боја ми овозможува да ја дефинирам бојата на основата и да ја генерирам секоја друга боја што ми треба - пополнувања, потези, запирања на градиент, сенки - од неа. Во тој момент, бојата престанува да биде палета и почнува да биде систем. SVG илустрациите имаат тенденција повторно да ги користат истите неколку бои низ пополнувањата, потезите и градиентите. Релативната боја ви овозможува да ги дефинирате тие врски еднаш и повторно да ги користите насекаде - слично како што аниматорите повторно користеа позадини за да создадат нови сцени.
Променете ја бојата на основата еднаш и секоја добиена боја се ажурира автоматски, без да пресметувате ништо рачно. Надвор од анимирана графика, би можел да го користам истиот пристап за да ги дефинирам боите за состојбите на интерактивни елементи како што се копчињата и врските. Бојата на основата што ја користев во мојот наслов „Lullabye-bye Bear“ е сина со цијан изглед. Заднината е радијален градиент помеѓу мојата основа и потемната верзија.
За да создадам алтернативни верзии со сосема различни расположенија, треба само да ја сменам бојата на основата: --основа: #5accd6; --град-крај: var(--основа); --град-почеток: oklch(од var(--основа) калц (l - 0,2357) калц (c * 0,833) h);
За да ги поврзам тие сопствени својства со мојот SVG градиент без дуплирање на вредностите на бојата, ги заменив тврдокодираните вредности за стоп-боја со вградени стилови:
Следно, требаше да се осигурам дека мојот Toon Text секогаш е во контраст со која било боја на основата што ќе ја изберам. Ротација на нијанси од 180 степени произведува дополнителна боја која секако се појавува - но може да вибрира непријатно: .text-light { пополнете: oklch(од var(--основа) l c калк (h + 180)); }
Поместувањето од 90° создава жива секундарна боја без да биде целосно комплементарна: .text-light { пополнете: oklch(од var(--основа) l c калк (h - 90)); }
Мојата рекреација на Quick Draw McGraw's Toon Title „El Kabong“ од 1959 година ги користи истите техники, но со поразновидна палета. На пример, има уште еден радијален градиент помеѓу бојата на основата и потемната нијанса.
Зградата и дрвото во позадина се едноставно различни нијанси на иста боја на основата. За тие патеки, ми требаа две дополнителни бои за полнење: .bg-mid { пополнете: oklch(од var(--основа) калц(l - 0,04) калц(c * 0,91) ч); }
.bg-dark { пополнете: oklch(од var(--основа) калц(l - 0,12) калц(c * 0,64) ч); }
Кога основите ќе почнат да се движат Досега, сè што покажав беше статично. Дури и кога некој користи избирач на бои за да ја смени бојата на основата, таа промена се случува веднаш. Но, анимираната графика ретко застанува - поимот е во името. Значи, ако бојата е дел од системот, нема причина и таа да не може да анимира. За да ја анимирам бојата на основата, прво треба да ја поделам на нејзините OKLCH канали- леснотија, хрома и нијанса. Но, има важен дополнителен чекор: треба да ги регистрирам тие вредности како напишани сопствени својства. Но, што значи тоа? Стандардно, прелистувачот не знае дали приспособената вредност на својството CSS претставува боја, должина, број или нешто сосема друго. Тоа често значи дека тие не можат непречено да се интерполираат за време на анимацијата и да скокаат од една вредност на друга. Регистрирањето приспособено својство му кажува на прелистувачот за типот на вредноста што ја претставува и како треба да се однесува со текот на времето. Во овој случај, сакам прелистувачот да ги третира моите канали во боја како бројки за да можат непречено да се анимираат. @property --f-l { синтакса: "<број>"; наследува: точно; почетна-вредност: 0,40; }
@property --f-c { синтакса: "<број>"; наследува: точно; почетна вредност: 0,11; }
@property --f-h { синтакса: "<број>"; наследува: точно; почетна вредност: 305; }
Откако ќе се регистрираат, овие сопствени својства се однесуваат како мајчин CSS. Прелистувачот може да ги интерполира рамка по рамка. Потоа ја обновувам бојата на основата од тие канали: --основа: oklch(var(--f-l) var(--f-c) var(--f-h));
Ова ја прави бојата на основата да стане жива, исто како и секоја друга нумеричка вредност. Еве едноставна анимација за „дишење“ која нежно ја менува леснотијата со текот на времето: @keyframes дише { 0%, 100% { --f-l: 0,36; } 50% { --f-l: 0,46; } }
.toon-title { анимација: дишете 10 секунди лесно-во-излез бесконечно; }
Бидејќи секоја друга боја во пополнувањата, градиентите и потезите е изведена од ---основа, сите тие анимираат заедно и ништо не треба да се ажурира рачно. Една анимирана боја, многу ефекти На почетокот на овој процес, се прашував дали релативните вредности на бојата на CSS би можеле да понудат повеќе можности, а истовремено да ги направат поедноставни за имплементација. Неодамна додадов нова позадина на рудникот за злато на страницата за контакт на мојата веб-страница, а првата итерација вклучуваше маслени светилки што светат и се лулаат.
Сакав да истражам како анимирањето на релативните бои на CSS може да ја направи внатрешноста на рудникот пореалистична со тоа што ќе ја затемнува со бои од светилките. Сакав тие да влијаат на светот околу нив, како што тоа го прави вистинската светлина. Така, наместо да анимирам повеќе бои, изградив мал систем за осветлување што анимира само една боја.
Мојата прва задача беше да отворам слој за преклопување помеѓу позадината и моите светилки: <пат id = "преклоп" fill = "var(--overlay-tint)" [...] style="mix-blend-mode: color" />
Го користев режимот на мешање мешање: боја затоа што тоа го обојува она што е под него додека ја зачувува основната осветленост. Бидејќи сакам преклопот да биде видлив само кога се вклучени анимациите, се пријавив за преклопување: .svg-mine #overlay { приказ: нема; }
@media (prefers-reduced-motion: no-preference) { .svg-mine[data-animations=on] #overlay { приказ: блок; непроѕирност: 0,5; } }
Преклопот беше на место, но сè уште не беше поврзан со светилките. Ми требаше извор на светлина. Моите светилки се едноставни и секоја содржи круг елемент што го заматив со филтер. Филтерот создава многу меко заматување на целиот круг.
Наместо да ги анимрам преклопот и светилките одделно, јас анимирам единствен токен во боја „пламен“ и од тоа извлекувам сè друго. Прво, регистрирам три напишани сопствени својства за OKLCH каналите: @property --fl-l { синтакса: "<број>"; наследува: точно; почетна-вредност: 0,86; } @property --fl-c { синтакса: "<број>"; наследува: точно; почетна вредност: 0,12; } @property --fl-h { синтакса: "<број>"; наследува: точно; почетна вредност: 95; }
Ги анимирав тие канали, намерно туркајќи неколку рамки кон портокалово, така што треперењето јасно се чита како огнено светло:
@keyframes пламен { 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; } }
Потоа ја опфатив таа анимација во SVG, така што споделените променливи се достапни и за светилките и за мојот преклоп:
@media (prefers-reduced-motion: no-preference) { .svg-mine[data-animations=on] { анимација: пламен 3.6s бесконечна линеарна; изолација: изолирам;
/* Изградете боја на пламен од анимирани канали */ --пламен: oklch(var(--fl-l) var(--fl-c) var(--fl-h));
/* Боја на светилката добиена од пламен */ --светилка-јадро: oklch(од var(--пламен) калц(l + 0,05) калц(c * 0,70) h);
/* Нијанса на прекривка добиена од истиот пламен */ --преклопување-нијанса: oklch(од var(--пламен) калц(l + 0,06) калц(c * 0,65) калц(h - 10)); } }
Конечно, ги применив тие добиени бои на светлечките светилки и на преклопот на кој влијаат: @media (prefers-reduced-motion: no-preference) { .svg-mine[data-animations=on] #mine-lamp-1 > круг, .svg-mine[data-animations=on] #mine-lamp-2 > круг { пополнете: var(--ламба-јадро); }
.svg-mine[data-animations=on] #overlay { приказ: блок; пополнете: var(--преклоп-нијанса); непроѕирност: 0,5; } }
Кога пламенот ќе се префрли кон портокалово, светилките се загреваат и сцената се загрева со нив. Кога пламенот се олади, сè се смирува заедно. Најдобриот дел е што ништо не е напишано рачно. Ако ја сменам бојата на основата или ги дотерувам опсегот на анимација на пламенот, целиот систем за осветлување се ажурира истовремено. Конечниот резултат можете да го видите на мојата веб-страница. Повторна употреба, повторно намена, повторно прегледано Оние аниматори на Хана-Барбера беа принудени да ги пренаменат елементите од потреба, но јас повторно ги користам боите бидејќи тоа ја прави мојата работа поконзистентна и полесна за одржување. CSS релативните вредности на боја ми дозволуваат:
Дефинирајте единствена боја на основата, Опишете како другите бои се поврзани со него, Повторно користете ги тие врски насекаде, и Анимирајте го системот со промена на една вредност.
Релативната боја не само што ја олеснува темата. Охрабрува начин на размислување каде бојата, како движењето, е намерна - и каде што менувањето на една вредност може да трансформира цела сцена без препишување на делото под неа.