Нещодавно я оновив анімаційну графіку на своєму веб-сайті за допомогою нової теми та групи новаторських персонажів, застосовуючи на практиці багато технік, якими я поділився в цій серії. Кілька моїх анімацій змінюють вигляд, коли хтось з ними взаємодіє або в різний час доби.

Кольори графіки на сторінках мого блогу змінюються з ранку до вечора кожного дня. Крім того, є режим снігу, який додає холодні кольори та зимову тему завдяки шару накладання та режиму змішування.

Працюючи над цим, я почав думати, чи можуть відносні значення кольорів 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(from var(--foundation) [...]; } --foundation-mid: oklch(from var(--foundation) [...]; } --foundation-dark: oklch(from var(--foundation) [...]; }

Відносний колір як система дизайну Подумайте про відносний колір як про фразу: «Візьміть цей колір, налаштуйте його, а потім дайте мені результат». Існує два способи налаштування кольору: абсолютні зміни та пропорційні зміни. Вони виглядають схожими за кодом, але поводяться дуже по-різному, коли ви починаєте міняти основні кольори. Розуміння цієї різниці – це те, що може перетворити використання відносного кольору на систему. /* Колір основи */ --основа: #5accd6;

Наприклад, значення світлості мого тонального кольору становить 0,7837, тоді як більш темна версія має значення 0,5837. Щоб обчислити різницю, я віднімаю нижче значення від більшого та застосовую результат за допомогою функції calc(): --основний темний: oklch(від var(--foundation) розрах.(l - 0,20) c h);

Щоб отримати світліший колір, я додаю різницю: --фундамент-світло: oklch(від var(--foundation) розрах.(l + 0,10) c h);

Колірністькоригування відбувається за тим самим процесом. Щоб зменшити інтенсивність мого тонального кольору з 0,1035 до 0,0035, я віднімаю одне значення від іншого: oklch(від var(--foundation) l розрах.(c - 0,10) год);

Щоб створити палітру відтінків, я обчислюю різницю між значенням відтінку мого основного кольору (200) і мого нового відтінку (260): oklch(від var(--foundation) l c calc(h + 60));

Ці розрахунки є абсолютними. Коли я віднімаю фіксовану суму, я фактично кажу: «Завжди віднімайте стільки». Те саме стосується додавання фіксованих значень: розрах.(c - 0,10) обчислення (c + 0,10)

Я пізнав межі цього підходу на важкому шляху. Коли я покладався на віднімання фіксованих значень кольоровості, кольори згорталися до сірого, щойно я змінював основу. Палітра, яка підійшла для одного кольору, розвалилася для іншого. Множення поводиться інакше. Коли я множу кольоровість, я кажу браузеру: «Зменшіть інтенсивність цього кольору на пропорцію». Співвідношення між кольорами залишається незмінним, навіть коли змінюється основа: обчислення (c * 0,10)

Мої правила переміщення, масштабування, повороту

Перемістіть легкість (додайте або відніміть), Шкала кольоровості (множення), Обертання відтінку (додавання або віднімання градусів).

Я масштабую кольоровість, тому що хочу, щоб зміни інтенсивності залишалися пропорційними базовому кольору. Відношення відтінків обертаються, тому множення відтінків не має сенсу. Легкість перцептивна й абсолютна — її множення часто призводить до дивних результатів.

Від одного кольору до цілої теми Відносний колір дозволяє мені визначити основний колір і генерувати з нього будь-який інший потрібний мені колір — заливки, штрихи, градієнти, тіні. У цей момент колір перестає бути палітрою і починає бути системою. Ілюстрації SVG мають тенденцію повторно використовувати кілька тих самих кольорів у заливках, штрихах і градієнтах. Відносний колір дає змогу визначити ці зв’язки один раз і використовувати їх всюди — подібно до того, як аніматори повторно використовували фони для створення нових сцен.

Змініть основний колір один раз, і кожен отриманий колір оновиться автоматично, без перерахунку вручну. За межами анімованої графіки я міг би використати той самий підхід для визначення кольорів для станів інтерактивних елементів, таких як кнопки та посилання. Основний колір, який я використав у назві мультфільму «Lullabye-Bye Bear», — блакитно-блакитний. Фон - це радіальний градієнт між моєю основою та більш темною версією.

Щоб створити альтернативні версії з абсолютно різними настроями, мені потрібно лише змінити колір основи: --основа: #5accd6; --grad-end: var(--foundation); --grad-start: oklch(з var(--foundation) calc(l - 0,2357) calc(c * 0,833) h);

Щоб прив’язати ці спеціальні властивості до градієнта SVG без дублювання значень кольорів, я замінив жорстко закодовані значення стоп-кольору вбудованими стилями:

Потім мені потрібно було переконатися, що мій Toon Text завжди контрастує з будь-яким кольором основи, який я виберу. Обертання відтінку на 180 градусів створює додатковий колір, який, безперечно, виривається, але може неприємно вібрувати: .text-light { fill: oklch(from var(--foundation) l c calc(h + 180)); }

Зміщення на 90° створює яскравий вторинний колір, не будучи повністю комплементарним: .text-light { fill: oklch(from var(--foundation) l c calc(h - 90)); }

У моєму відтворенні мультфільму Quick Draw McGraw 1959 року «El Kabong» використовуються ті самі методи, але з більш різноманітною палітрою. Наприклад, є ще один радіальний градієнт між кольором основи та більш темним відтінком.

Будівля та дерево на задньому плані просто мають різні відтінки одного основного кольору. Для цих контурів мені знадобилися два додаткові кольори заливки: .bg-mid { fill: oklch(from var(--foundation) calc(l - 0,04) calc(c * 0,91) h); }

.bg-dark { fill: oklch(from var(--foundation) calc(l - 0,12) calc(c * 0,64) h); }

Коли основи починають рухатися Поки що все, що я показав, було статичним. Навіть коли хтось використовує засіб вибору кольору, щоб змінити колір основи, ця зміна відбувається миттєво. Але анімована графіка рідко стоїть на місці — підказка в назві. Отже, якщо колір є частиною системи, немає причин, щоб він також не міг анімувати. Щоб анімувати основний колір, мені спочатку потрібно розділити його на канали OKLCH— світлота, кольоровість і відтінок. Але є важливий додатковий крок: мені потрібно зареєструвати ці значення як введені власні властивості. Але що це означає? За замовчуванням браузер не знає, чи значення спеціальної властивості CSS представляє колір, довжину, число чи щось інше. Це часто означає, що їх не можна плавно інтерполювати під час анімації та переходити від одного значення до іншого. Реєстрація спеціальної властивості повідомляє браузеру тип значення, яке воно представляє, і те, як воно має поводитися з часом. У цьому випадку я хочу, щоб браузер розглядав мої кольорові канали як числа, щоб їх можна було плавно анімувати. @property --f-l { синтаксис: "<число>"; успадковує: true; початкове значення: 0,40; }

@property --f-c { синтаксис: "<число>"; успадковує: true; початкове значення: 0,11; }

@property --f-h { синтаксис: "<число>"; успадковує: true; початкове значення: 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 секунд, легкість, нескінченність; }

Оскільки всі інші кольори в заливках, градієнтах і обведеннях походять від --foundation, усі вони анімуються разом, і нічого не потрібно оновлювати вручну. Один анімований колір, багато ефектів На початку цього процесу я задавався питанням, чи можуть відносні значення кольорів CSS запропонувати більше можливостей, а також спростити їх реалізацію. Нещодавно я додав новий фон золотої копальні на сторінку контактів свого веб-сайту, і перша ітерація включала масляні лампи, які світяться та коливаються.

Я хотів дослідити, як анімація відносних кольорів CSS може зробити інтер’єр шахти більш реалістичним, відтінивши його кольорами від ламп. Я хотів, щоб вони впливали на світ навколо, як справжнє світло. Тож замість того, щоб анімувати кілька кольорів, я створив крихітну систему освітлення, яка анімує лише один колір.

Моїм першим завданням було розмістити накладний шар між фоном і лампами: <шлях id="overlay" fill="var(--overlay-tint)" [...] style="mix-blend-mode: color" />

Я використовував 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 { синтаксис: "<число>"; успадковує: true; початкове значення: 0,86; } @property --fl-c { синтаксис: "<число>"; успадковує: true; початкове значення: 0,12; } @property --fl-h { синтаксис: "<число>"; успадковує: true; початкове значення: 95; }

Я анімував ці канали, навмисно підштовхнувши кілька кадрів до помаранчевого кольору, щоб мерехтіння чітко читалося як світло вогню:

@keyframes flame { 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 нескінченна лінійна; ізоляція: ізолювати;

/* Створення кольору полум'я з анімованих каналів */ --flame: oklch(var(--fl-l) var(--fl-c) var(--fl-h));

/* Колір лампи, отриманий від полум’я */ --lamp-core: oklch(from var(--flame) calc(l + 0,05) calc(c * 0,70) h);

/* Відтінок накладення, отриманий від того самого полум’я */ --overlay-tint: oklch(від var(--flame) calc(l + 0,06) calc(c * 0,65) calc(h - 10)); } }

Нарешті, я застосував отримані кольори до ламп, що світяться, і накладання, на яке вони впливають: @media (prefers-reduced-motion: no-preference) { .svg-mine[data-animations=on] #mine-lamp-1 > коло, .svg-mine[data-animations=on] #mine-lamp-2 > коло { fill: var(--lamp-core); }

.svg-mine[data-animations=on] #overlay { дисплей: блок; заливка: var(--overlay-tint); непрозорість: 0,5; } }

Коли полум'я зміщується в бік помаранчевого кольору, лампи нагріваються, а разом з ними нагрівається і сцена. Коли полум'я охолоне, все разом осідає. Найприємніше те, що нічого не написано вручну. Якщо я зміню основний колір або налаштую діапазони анімації полум’я, уся система освітлення оновлюється одночасно. Ви можете побачити кінцевий результат на моєму сайті. Повторне використання, перепрофілювання, перегляд Ті аніматори Hanna-Barbera були змушені змінити призначення елементів через необхідність, але я повторно використовую кольори, тому що це робить мою роботу більш узгодженою та легшою для підтримки. Відносні значення кольорів CSS дозволяють:

Визначте єдиний колір основи, Опишіть, як до нього відносяться інші кольори, Повторно використовуйте ці відносини всюди та Анімуйте систему, змінивши одне значення.

Відносний колір не лише полегшує створення тем. Це заохочує спосіб мислення, де колір, як і рух, є навмисним — і де зміна одного значення може перетворити всю сцену без переписування роботи під нею.

You May Also Like

Enjoyed This Article?

Get weekly tips on growing your audience and monetizing your content — straight to your inbox.

No spam. Join 138,000+ creators. Unsubscribe anytime.

Create Your Free Bio Page

Join 138,000+ creators on Seemless.

Get Started Free