Recentemente actualicei os gráficos animados do meu sitio web cun tema novo e un grupo de personaxes pioneiros, poñendo en práctica moitas das técnicas que compartín nesta serie. Algunhas das miñas animacións cambian de aparencia cando alguén interactúa con elas ou a diferentes horas do día.
As cores do gráfico na parte superior das páxinas do meu blog cambian de mañá a noite todos os días. Despois, está o modo de neve, que engade cores frías e un tema invernal, cortesía dunha capa de superposición e un modo de fusión.
Mentres traballaba nisto, comecei a preguntarme se os valores relativos da cor CSS podían darme máis control ao mesmo tempo que simplificaban o proceso. Nota: neste tutorial, centrareime nos valores de cor relativos e no espazo de cor OKLCH para temas gráficos e animacións. Se queres mergullo profundamente na cor relativa, Ahmad Shadeed creou unha excelente guía interactiva. En canto aos espazos de cor, gamas e OKLCH, o noso propio Geoff Graham escribiu sobre eles.
O uso repetido de elementos foi fundamental. Os fondos reutilizaron sempre que foi posible, con zooms e superposicións que axudan a construír novas escenas a partir da mesma obra de arte. Naceu por necesidade, pero tamén animou a pensar en series e non en escenas individuais. O problema coa actualización manual das paletas de cores Imos directo ao meu reto. En Toon Titles como este, baseado no episodio "Lullabye-Bye Bear" de 1959, e no meu traballo en xeral, as paletas limítanse a unhas poucas cores.
Creo matices e tintes a partir do que chamo a miña cor de "fundación" para ampliar a paleta sen engadir máis matices.
En Sketch, traballo no espazo de cor HSL, polo que este proceso implica aumentar ou diminuír o valor de claridade da miña cor base. Sinceramente, non é unha tarefa ardua, pero escoller unha cor de base diferente require crear un novo conxunto de tons e matices. Facelo manualmente, unha e outra vez, rapidamente faise laborioso.
Mencionei o espazo de cor HSL - H (matriz), S (saturación) e L (luminosidade), pero esa é só unha das varias formas de describir a cor. RGB - R (vermello), G (verde), B (azul) - é probablemente o máis familiar, polo menos na súa forma hexadecimal. Tamén hai LAB - L (luminosidade), A (verde-vermello), B (azul-amarelo) - e o modelo LCH - L (luminosidade), C (croma), H (ton) máis novo, pero agora amplamente admitido, na súa forma OKLCH. Con LCH, específicamente OKLCH en CSS, podo axustar o valor de claridade da miña cor de base.
Ou podo alterar o seu croma. A croma LCH e a saturación HSL describen a intensidade ou riqueza dunha cor, pero fano de diferentes xeitos. LCH ofréceme unha gama máis ampla e unha mestura máis previsible entre as cores.
Tamén podo modificar o ton para crear unha paleta de cores que compartan os mesmos valores de luminosidade e croma. Tanto en HSL como en LCH, o espectro de tons comeza no vermello, móvese polo verde e o azul e volve ao vermello.
Por que OKLCH cambiou a forma en que penso sobre a cor A compatibilidade do navegador para o espazo de cores OKLCH está agora estendida, aínda que as ferramentas de deseño, incluído Sketch, non se puxeron ao día. Afortunadamente, iso non debería impedirche usar OKLCH. Os navegadores converterán os valores Hex, HSL, LAB e RGB en OKLCH para ti. Podes definir unha propiedade personalizada CSS cunha cor de base en calquera espazo, incluído Hex: /* Cor de base */ --fundación: #5accd6;
Calquera cor derivada del converterase en OKLCH automaticamente: --fundación-luz: oklch(de var(--fundación) [...]; } --fundación-medio: oklch(de var(--fundación) [...]; } --fundación-escuro: oklch(de var(--fundación) [...]; }
A cor relativa como sistema de deseño Pensa na cor relativa como dicindo: "Toma esta cor, axusta e despois dáme o resultado". Hai dúas formas de axustar unha cor: cambios absolutos e cambios proporcionais. Semellan no código, pero compórtanse de forma moi diferente cando comezas a cambiar as cores de base. Comprender esa diferenza é o que pode converter a cor relativa nun sistema. /* Cor de base */ --fundación: #5accd6;
Por exemplo, o valor de claridade da miña cor base é 0,7837, mentres que unha versión máis escura ten un valor de 0,5837. Para calcular a diferenza, resto o valor máis baixo do maior e aplico o resultado usando unha función calc(): --fundación-escuro: oklch(de var(--fundación) calc(l - 0,20) c h);
Para conseguir unha cor máis clara, engado a diferenza: --luz-fundación: oklch(de var(--fundación) calc(l + 0,10) c h);
Cromaos axustes seguen o mesmo proceso. Para reducir a intensidade da miña cor de base de 0,1035 a 0,0035, resto un valor do outro: oklch(de var(--fundación) l calc(c - 0,10) h);
Para crear unha paleta de tonalidades, calculo a diferenza entre o valor de tonalidade da miña cor de base (200) e a miña nova tonalidade (260): oklch(de var(--fundación) lc calc(h + 60));
Eses cálculos son absolutos. Cando resta unha cantidade fixa, estou dicindo: "Sempre resta tanto". O mesmo aplícase ao engadir valores fixos: calc (c - 0,10) calc (c + 0,10)
Aprendín os límites deste enfoque do xeito difícil. Cando eu confiaba en restar valores de croma fixas, as cores colapsaban cara ao gris en canto cambiei a base. Unha paleta que funcionaba para unha cor desmoronouse para outra. A multiplicación compórtase de forma diferente. Cando multiplico a croma, dígolle ao navegador: "Reduce a intensidade desta cor nunha proporción". A relación entre as cores permanece intacta, mesmo cando a base cambia: calc (c * 0,10)
As miñas regras Move It, Scale It, Rote It
Mover lixeireza (suma ou resta), Escala de croma (multiplicar), Xira a tonalidade (suma ou resta graos).
Escalo o croma porque quero que os cambios de intensidade sexan proporcionais á cor base. As relacións de tonalidade son rotatorias, polo que multiplicar a tonalidade non ten sentido. A lixeireza é perceptiva e absoluta; multiplicala a miúdo produce resultados estraños.
Desde unha cor ata un tema enteiro A cor relativa permíteme definir unha cor de base e xerar todas as outras cores que necesito (recheos, trazos, paradas de degradado, sombras) a partir dela. Nese momento, a cor deixa de ser unha paleta e comeza a ser un sistema. As ilustracións SVG tenden a reutilizar as mesmas cores en recheos, trazos e degradados. A cor relativa permíteche definir esas relacións unha vez e reutilizalas en todas partes, ao igual que os animadores reutilizaron fondos para crear novas escenas.
Cambia a cor de base unha vez e cada cor derivada actualízase automaticamente, sen recalcular nada a man. Fóra dos gráficos animados, podería usar este mesmo enfoque para definir cores para os estados de elementos interactivos como botóns e ligazóns. A cor de base que usei no meu título de Toon "Lullabye-Bye Bear" é un azul de aspecto cian. O fondo é un degradado radial entre a miña base e unha versión máis escura.
Para crear versións alternativas con estados de ánimo totalmente diferentes, só teño que cambiar a cor de base: --fundación: #5accd6; --grad-end: var(--fundación); --grad-start: oklch(de var(--fundación) calc(l - 0,2357) calc(c * 0,833) h);
Para vincular esas propiedades personalizadas ao meu degradado SVG sen duplicar os valores de cor, substituín os valores de cores de parada codificados por estilos en liña:
A continuación, necesitaba asegurarme de que o meu texto Toon contrastase sempre coa cor de base que escolla. Unha rotación de tonalidade de 180 graos produce unha cor complementaria que certamente aparece, pero pode vibrar incómodamente: .text-light { recheo: oklch(de var(--fundación) lc calc(h + 180)); }
Un desprazamento de 90° produce unha cor secundaria viva sen ser totalmente complementaria: .text-light { recheo: oklch(de var(--fundación) lc calc(h - 90)); }
A miña recreación do título Toon de 1959 de Quick Draw McGraw "El Kabong" utiliza as mesmas técnicas pero cunha paleta máis variada. Por exemplo, hai outro degradado radial entre a cor da base e unha sombra máis escura.
O edificio e a árbore do fondo son simplemente tons diferentes da mesma cor de base. Para eses camiños, necesitaba dúas cores de recheo adicionais: .bg-medio { recheo: oklch(de var(--fundación) calc(l - 0,04) calc(c * 0,91) h); }
.bg-escuro { recheo: oklch(de var(--fundación) calc(l - 0,12) calc(c * 0,64) h); }
Cando os cimentos comezan a moverse
Ata agora, todo o que mostrei foi estático. Mesmo cando alguén usa un selector de cores para cambiar a cor de base, ese cambio ocorre ao instante. Pero os gráficos animados raramente se quedan parados: a pista está no nome. Polo tanto, se a cor forma parte do sistema, non hai razón para que tampouco poida animarse.
Para animar a cor base, primeiro teño que dividila nas súas canles OKLCH- claridade, croma e ton. Pero hai un paso adicional importante: teño que rexistrar eses valores como propiedades personalizadas escritas. Pero que significa iso?
Por defecto, un navegador non sabe se un valor de propiedade personalizada CSS representa unha cor, lonxitude, número ou outra cousa. Isto moitas veces significa que non se poden interpolar sen problemas durante a animación e saltar dun valor a outro.
O rexistro dunha propiedade personalizada indica ao navegador o tipo de valor que representa e como debe comportarse ao longo do tempo. Neste caso, quero que o navegador trate as miñas canles de cores como números para que poidan animarse sen problemas.
@propiedade --f-l {
sintaxe: "
@propiedade --f-c {
sintaxe: "
@propiedade --f-h {
sintaxe: "
Unha vez rexistradas, estas propiedades personalizadas compórtanse como CSS nativo. O navegador pode interpolalos fotograma por fotograma. Despois reconstruín a cor base a partir desas canles: --fundación: oklch(var(--f-l) var(--f-c) var(--f-h));
Isto fai que a cor de base sexa animable, como calquera outro valor numérico. Aquí tes unha sinxela animación de "respiración" que cambia suavemente a lixeireza ao longo do tempo: @keyframes respiran { 0 %, 100 % { --f-l: 0,36; } 50 % { --f-l: 0,46; } }
.toon-title { animación: respira 10s de facilidade de entrada e saída infinita; }
Dado que todas as outras cores dos recheos, degradados e trazos derivan de --foundation, todas se animan xuntos e non hai que actualizar nada manualmente. Unha cor animada, moitos efectos Ao comezo deste proceso, pregunteime se os valores relativos de cor CSS poderían ofrecer máis posibilidades ao tempo que os facían máis sinxelos de implementar. Recentemente engadín un novo fondo de mina de ouro á páxina de contacto do meu sitio web e a primeira versión incluíu lámpadas de aceite que brillan e balancean.
Quería explorar como a animación de cores relativas CSS podería facer que o interior da mina fose máis realista teñéndoo coas cores das lámpadas. Quería que afectasen ao mundo que os rodeaba, como fai a luz real. Entón, en lugar de animar varias cores, construín un pequeno sistema de iluminación que anima só unha cor.
A miña primeira tarefa foi colocar unha capa de superposición entre o fondo e as miñas lámpadas:
Usei o modo de mestura: cor porque matiza o que hai debaixo mentres preserva a luminancia subxacente. Como só quero que a superposición estea visible cando as animacións están activadas, active a superposición: .svg-mine #overlay { visualización: ningunha; }
@media (prefers-reduced-motion: sen preferencia) { .svg-mine[data-animations=on] #overlay { visualización: bloque; opacidade: 0,5; } }
A superposición estaba no seu lugar, pero aínda non estaba conectada ás lámpadas. Necesitaba unha fonte de luz. As miñas lámpadas son sinxelas e cada unha contén un elemento circular que difuminei cun filtro. O filtro produce un desenfoque moi suave sobre todo o círculo.
En lugar de animar a superposición e as lámpadas por separado, animo un único token de cor "chama" e deduzo todo o demais. Primeiro, rexistro tres propiedades personalizadas escritas para as canles OKLCH:
@propiedade --fl-l {
sintaxe: "
Animei esas canles, empurrando deliberadamente algúns fotogramas cara a laranxa para que o parpadeo se lea claramente como luz do lume:
@keyframes chama { 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; } }
A continuación, amplíe esa animación ao SVG, polo que as variables compartidas están dispoñibles tanto para as lámpadas como para a miña superposición:
@media (prefers-reduced-motion: sen preferencia) { .svg-mine[data-animations=on] { animación: chama 3,6 s lineal infinito; illamento: illar;
/* Crea unha cor de chama a partir de canles animados */ --flame: oklch(var(--fl-l) var(--fl-c) var(--fl-h));
/* Cor da lámpada derivada da chama */ --núcleo da lámpada: oklch(de var(--flame) calc(l + 0,05) calc(c * 0,70) h);
/* Tinte de superposición derivado da mesma chama */ --overlay-tint: oklch(de var(--flame) calc(l + 0,06) calc(c * 0,65) calc(h - 10)); } }
Finalmente, apliquei esas cores derivadas ás lámpadas brillantes e á superposición que afectan: @media (prefers-reduced-motion: sen preferencia) { .svg-mine[data-animations=on] #mine-lamp-1 > círculo, .svg-mine[data-animations=on] #mine-lamp-2 > círculo { recheo: var(--núcleo da lámpada); }
.svg-mine[data-animations=on] #overlay { visualización: bloque; recheo: var(--overlay-tint); opacidade: 0,5; } }
Cando a chama cambia cara á laranxa, as lámpadas quéntanse e a escena quéntase con elas. Cando a chama arrefría, todo se asenta. A mellor parte é que non se escribe nada manualmente. Se cambio a cor de base ou axusto os intervalos de animación de chamas, todo o sistema de iluminación actualízase simultaneamente. Podes ver o resultado final na miña páxina web. Reutilizar, reutilizar, revisar Eses animadores de Hanna-Barbera víronse obrigados a reutilizar elementos por necesidade, pero reutilizo as cores porque fai que o meu traballo sexa máis consistente e máis fácil de manter. Os valores de cor relativos CSS permítenme:
Definir unha única cor de base, Describe como se relacionan outras cores con ela, Reutiliza esas relacións en todas partes, e Anima o sistema cambiando un valor.
A cor relativa non só facilita a temática. Fomenta unha forma de pensar onde a cor, como o movemento, é intencional, e onde cambiar un valor pode transformar unha escena enteira sen reescribir a obra debaixo dela.