Недавно я обновил анимированную графику на своем веб-сайте, добавив новую тему и группу новаторских персонажей, применив на практике множество приемов, которыми поделился в этой серии. Некоторые из моих анимаций меняют внешний вид, когда кто-то с ними взаимодействует или в разное время суток.

Цвета изображений на страницах моего блога меняются с утра до вечера каждый день. Кроме того, есть режим снега, который добавляет холодные цвета и зимнюю тему благодаря наложению и режиму наложения.

Работая над этим, я начал задаваться вопросом, могут ли относительные значения цвета CSS дать мне больше контроля, одновременно упрощая процесс. Примечание. В этом уроке я сосредоточусь на относительных значениях цвета и цветовом пространстве OKLCH для оформления тем графики и анимации. Если вы хотите глубже погрузиться в относительные цвета, Ахмад Шадид создал превосходное интерактивное руководство. Что касается цветовых пространств, гамм и OKLCH, о них писал наш собственный Джефф Грэм.

Ключевым моментом было многократное использование элементов. Фоны по возможности использовались повторно, а масштабирование и наложение помогали создавать новые сцены из одного и того же изображения. Это было рождено по необходимости, но также побуждало мыслить с точки зрения серий, а не отдельных сцен. Проблема с обновлением цветовых палитр вручную Давайте перейдем непосредственно к моей задаче. В таких мультсериалах, как этот, основанных на эпизоде ​​«Колыбельная-прощай, медведь» шоу Yogi Bear Show 1959 года, и в моих работах в целом палитры ограничены несколькими избранными цветами.

Я создаю оттенки и оттенки из того, что я называю своим «основным» цветом, чтобы расширить палитру, не добавляя дополнительных оттенков.

В 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(): --foundation-dark: oklch(из var(--foundation) выч(л-0,20) ч);

Чтобы добиться более светлого цвета, я вместо этого добавляю разницу: --foundation-light: oklch(из var(--foundation) расчет (l + 0,10) с ч);

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

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

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

Я усвоил ограничения этого подхода на собственном горьком опыте. Когда я полагался на вычитание фиксированных значений цветности, цвета сжимались в сторону серого, как только я менял основу. Палитра, подходящая для одного цвета, развалилась для другого. Умножение ведет себя по-другому. Когда я умножаю цветность, я говорю браузеру: «Уменьшите интенсивность этого цвета на пропорцию». Отношения между цветами остаются неизменными, даже когда меняется основа: расчет (с * 0,10)

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

Переместить легкость (прибавить или убавить), Масштаб цветности (умножить), Поворот оттенка (добавление или убавление градусов).

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

От одного цвета к целой теме Относительный цвет позволяет мне определить основной цвет и генерировать на его основе все остальные цвета — заливки, обводки, градиентные остановки, тени. В этот момент цвет перестает быть палитрой и становится системой. В иллюстрациях SVG обычно используются одни и те же цвета для заливок, обводок и градиентов. Относительный цвет позволяет вам определить эти отношения один раз и повторно использовать их повсюду — так же, как аниматоры повторно используют фон для создания новых сцен.

Измените основной цвет один раз, и каждый производный цвет обновится автоматически, без необходимости пересчитывать что-либо вручную. Помимо анимированной графики, я мог бы использовать тот же подход для определения цветов состояний интерактивных элементов, таких как кнопки и ссылки. Основной цвет, который я использовал в названии мультсериала «Колыбельная-прощай, медведь», — голубой, напоминающий голубой. Фон представляет собой радиальный градиент между моей тональной основой и более темной версией.

Чтобы создать альтернативные версии с совершенно другим настроением, мне нужно всего лишь изменить цвет основы: --основа: #5accd6; --grad-end: var(--foundation); --grad-start: oklch(из var(--foundation) расч(л-0,2357)расч(с*0,833)ч);

Чтобы привязать эти пользовательские свойства к моему градиенту SVG без дублирования значений цвета, я заменил жестко закодированные значения стоп-цвета встроенными стилями:

Затем мне нужно было убедиться, что мой мультяшный текст всегда контрастирует с любым цветом основы, который я выберу. Поворот оттенка на 180 градусов дает дополнительный цвет, который, безусловно, выделяется, но может вызывать неприятные вибрации: .text-light { заливка: oklch(из var(--foundation) l c расчет(h + 180)); }

Сдвиг на 90° дает яркий вторичный цвет, но не является полностью дополняющим: .text-light { заливка: oklch(из var(--foundation) l c расчет (h - 90)); }

В моем воссоздании мультсериала Quick Draw McGraw 1959 года «Эль Кабонг» использованы те же приемы, но с более разнообразной палитрой. Например, есть еще один радиальный градиент между цветом основы и более темным оттенком.

Здание и дерево на заднем плане — это просто разные оттенки одного и того же цвета фундамента. Для этих путей мне понадобилось два дополнительных цвета заливки: .bg-mid { заливка: oklch(из var(--foundation) расч(л-0,04) расч(с*0,91)ч); }

.bg-темный { заливка: oklch(из var(--foundation) расч(л - 0,12) расч(с * 0,64) ч); }

Когда фундамент начинает двигаться До сих пор все, что я показывал, было статичным. Даже когда кто-то использует палитру цветов, чтобы изменить цвет тонального крема, это изменение происходит мгновенно. Но анимированная графика редко стоит на месте — разгадка кроется в названии. Итак, если цвет является частью системы, нет причин, по которым он не может также анимировать. Чтобы анимировать основной цвет, мне сначала нужно разделить его на каналы OKLCH.— яркость, цветность и оттенок. Но есть важный дополнительный шаг: мне нужно зарегистрировать эти значения как типизированные пользовательские свойства. Но что это значит? По умолчанию браузер не знает, представляет ли значение пользовательского свойства CSS цвет, длину, число или что-то еще. Это часто означает, что их нельзя плавно интерполировать во время анимации и переходить от одного значения к другому. Регистрация пользовательского свойства сообщает браузеру тип значения, которое оно представляет, и то, как оно должно вести себя с течением времени. В данном случае я хочу, чтобы браузер воспринимал мои цветовые каналы как числа, чтобы их можно было плавно анимировать. @property --f-l { синтаксис: «<номер>»; наследует: правда; начальное значение: 0,40; }

@property --f-c { синтаксис: «<номер>»; наследует: правда; начальное значение: 0,11; }

@property --fh { синтаксис: «<номер>»; наследует: правда; начальное значение: 305; }

После регистрации эти пользовательские свойства ведут себя как собственный CSS. Браузер может интерполировать их покадрово. Затем я восстанавливаю цвет основы из этих каналов: --foundation: 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="оверлей" fill="var(--overlay-тинт)" [...] style="mix-blend-mode: цвет" />

Я использовал режим смешивания-наложения: цвет, потому что он окрашивает то, что находится под ним, сохраняя при этом основную яркость. Поскольку я хочу, чтобы наложение было видно только при включенной анимации, я включил наложение: .svg-майне #overlay { дисплей: нет; }

@media (предпочитает уменьшение движения: нет предпочтений) { .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; --фл-ч: 95; } 6% { --fl-l: 0,91; --fl-c: 0,10; --фл-ч: 92; } 12% { --fl-l: 0,83; --fl-c: 0,14; --фл-ч: 100; } 18% { --fl-l: 0,88; --fl-c: 0,11; --фл-ч: 94; } 24% { --fl-l: 0,82; --fl-c: 0,16; --фл-ч: 82; } 30% { --fl-l: 0,90; --fl-c: 0,12; --фл-ч: 90; } 36% { --fl-l: 0,79; --fl-c: 0,17; --фл-ч: 76; } 44% { --fl-l: 0,87; --fl-c: 0,12; --фл-ч: 96; } 52% { --fl-l: 0,81; --fl-c: 0,15; --фл-ч: 102; } 60% { --fl-l: 0,89; --fl-c: 0,11; --фл-ч: 93; } 68% { --fl-l: 0,83; --fl-c: 0,16; --фл-ч: 85; } 76% { --fl-l: 0,91; --fl-c: 0,10; --фл-ч: 91; } 84% { --fl-l: 0,85; --fl-c: 0,14; --фл-ч: 98; } 92% {--фл-л: 0,80; --fl-c: 0,17; --фл-ч: 74; } }

Затем я применил эту анимацию к SVG, чтобы общие переменные были доступны как для ламп, так и для моего наложения:

@media (предпочитает уменьшение движения: нет предпочтений) { .svg-mine[data-animations=on] { анимация: пламя 3,6 с, бесконечная линейная; изоляция: изолировать;

/* Создаём цвет пламени из анимированных каналов */ --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) расч(л + 0,06) расч(с * 0,65) расч(ч - 10)); } }

Наконец, я применил полученные цвета к светящимся лампам и наложению, на которое они влияют: @media (предпочитает уменьшение движения: нет предпочтений) { .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-тинт); непрозрачность: 0,5; } }

Когда пламя смещается в сторону оранжевого, лампы нагреваются, и вместе с ними становится теплее сцена. Когда пламя остывает, все сходится. Самое приятное то, что ничего не пишется вручную. Если я изменю основной цвет или настрою диапазоны анимации пламени, вся система освещения обновится одновременно. Конечный результат вы можете увидеть на моем сайте. Повторное использование, перепрофилирование, пересмотр Аниматорам из Ханны-Барбера пришлось менять назначение элементов из-за необходимости, но я повторно использую цвета, потому что это делает мою работу более последовательной и ее легче поддерживать. Относительные значения цвета 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