Представете си това: присъединявате се към нов проект, гмуркате се в кодовата база и в рамките на първите няколко часа откривате нещо разочароващо познато. Разпръснати из стиловите таблици, намирате множество дефиниции на @keyframes за едни и същи основни анимации. Три различни ефекта на затихване, две или три вариации на слайдове, шепа анимации за увеличение и поне две различни анимации за въртене, защото защо не? @keyframes pulse { от { мащаб: 1; } до { мащаб: 1.1; } }

@keyframes bigger-pulse { 0%, 20%, 100% { мащаб: 1; } 10%, 40% { мащаб: 1.2; } }

Ако този сценарий ви звучи познато, не сте сами. Според моя опит в различни проекти, една от най-последователните бързи победи, които мога да постигна, е консолидирането и стандартизирането на ключови кадри. Стана толкова надежден модел, че сега очаквам с нетърпение това почистване като една от първите ми задачи за всяка нова кодова база. Логиката зад хаоса Това излишък има идеален смисъл, когато се замислите. Всички използваме едни и същи основни анимации в ежедневната си работа: избледняване, слайдове, мащабиране, завъртане и други често срещани ефекти. Тези анимации са доста ясни и е лесно да създадете бърза дефиниция на @keyframes, за да свършите работата. Без централизирана система за анимация, разработчиците естествено пишат тези ключови кадри от нулата, без да знаят, че подобни анимации вече съществуват другаде в кодовата база. Това е особено често срещано при работа в базирани на компоненти архитектури (което повечето от нас правят в наши дни), тъй като екипите често работят паралелно в различни части на приложението. Резултатът? Анимационен хаос. Малкият проблем Най-очевидните проблеми с дублирането на ключови кадри са загубеното време за разработка и ненужното раздуване на кода. Множество дефиниции на ключови кадри означават множество места за актуализиране, когато изискванията се променят. Трябва да коригирате времето на вашата избледняваща анимация? Ще трябва да преследвате всеки екземпляр във вашата кодова база. Искате да стандартизирате функциите за облекчаване? Успех в намирането на всички вариации. Това умножаване на точките за поддръжка прави дори обикновените актуализации на анимации трудоемка задача. По-големият проблем Това дублиране на ключови кадри създава много по-коварен проблем, който се крие под повърхността: капанът на глобалния обхват. Дори когато работите с базирани на компоненти архитектури, ключовите кадри на CSS винаги се дефинират в глобалния обхват. Това означава, че всички ключови кадри се прилагат за всички компоненти. Винаги. Да, вашата анимация не използва непременно ключовите кадри, които сте дефинирали във вашия компонент. Той използва последните ключови кадри, които съответстват на точно същото име, които са били заредени в глобалния обхват. Докато всичките ви ключови кадри са идентични, това може да изглежда като незначителен проблем. Но в момента, в който искате да персонализирате анимация за конкретен случай на употреба, вие имате проблеми или по-лошо, вие ще ги причинявате. Или вашата анимация няма да работи, защото друг компонент се е заредил след вашия, презаписвайки вашите ключови кадри, или вашият компонент се зарежда последен и случайно променя поведението на анимацията за всеки друг компонент, използващ името на този ключов кадър, и може дори да не го осъзнаете. Ето прост пример, който демонстрира проблема: .component-one { /* стилове на компоненти */ анимация: импулс 1s улесняване на влизане навън безкрайно редуване; }

/* тази дефиниция на @keyframes няма да работи */ @keyframes pulse { от { мащаб: 1; } до { мащаб: 1.1; } }

/* по-късно в кода... */

.component-two { /* стилове на компоненти */ анимация: импулс 1s леко влизане-излизане безкрайно; }

/* тези ключови кадри ще се прилагат и за двата компонента */ @keyframes pulse { 0%, 20%, 100% { мащаб: 1; } 10%, 40% { мащаб: 1.2; } }

И двата компонента използват едно и също име на анимация, но втората дефиниция на @keyframes презаписва първата. Сега и компонент едно, и компонент две ще използват вторите ключови кадри, независимо кой компонент е дефинирал кои ключови кадри. Вижте жетоните за ключови кадри на писалката - Демо 1 [разклонено] от Амит Шийн. Най-лошата част? Това често работи перфектно при локално разработване, но прекъсва мистериозно в производството, когато процесите на изграждане променят реда на зареждане на вашите таблици със стилове. В крайна сметка получавате анимации, които се държат различно в зависимост от това кои компоненти са заредени и в каква последователност. Решението: Унифицирани ключови кадри Отговорът на този хаос е изненадващо прост: предварително дефинирани динамични ключови кадри, съхранени в споделен лист със стилове. Вместо да позволяваме на всеки компонент да дефинира свои собствени анимации, ние създаваме централизирани ключови кадри, които са добре документирани и лесни заизползване, поддръжка и съобразени със специфичните нужди на вашия проект. Мислете за това като за символи на ключови кадри. Точно както използваме токени за цветове и разстояние и много от нас вече използват токени за свойства на анимация, като продължителност и функции за облекчаване, защо да не използваме токени и за ключови кадри? Този подход може да се интегрира естествено с всеки текущ работен процес на токен за дизайн, който използвате, като същевременно решава както малкия проблем (дублиране на код), така и по-големия проблем (конфликти в глобален обхват) наведнъж. Идеята е проста: създайте един източник на истина за всички наши общи анимации. Този споделен лист със стилове съдържа внимателно изработени ключови кадри, които покриват моделите на анимация, които нашият проект всъщност използва. Край на гадаенето дали избледняваща анимация вече съществува някъде в нашата кодова база. Няма повече случайно презаписване на анимации от други компоненти. Но ето ключът: това не са просто статични анимации за копиране и поставяне. Те са проектирани да бъдат динамични и персонализирани чрез персонализирани свойства на CSS, което ни позволява да поддържаме последователност, като същевременно имаме гъвкавостта да адаптираме анимации към конкретни случаи на употреба, например ако имате нужда от малко по-голяма „пулсираща“ анимация на едно място. Изграждане на първия токен за ключови кадри Един от първите ниско висящи плодове, с които трябва да се заемем, е анимацията „избледняване“. В един от скорошните ми проекти открих над дузина отделни дефиниции за затихване и да, всички те просто анимираха непрозрачността от 0 до 1. И така, нека създадем нов стилов лист, да го наречем kf-tokens.css, да го импортираме в нашия проект и да поставим нашите ключови кадри с подходящи коментари вътре в него. /* keyframes-tokens.css */

/* * Fade In - избледняване на входната анимация * Употреба: анимация: kf-fade-in 0.3s ease-out; */ @keyframes kf-fade-in { от { непрозрачност: 0; } до { непрозрачност: 1; } }

Тази единична декларация на @keyframes замества всички тези разпръснати постепенно затихващи анимации в нашата кодова база. Чисто, просто и глобално приложимо. И сега, когато имаме дефиниран този токен, можем да го използваме от всеки компонент в нашия проект: .modal { анимация: kf-fade-in 0.3s леко изключване; }

.tooltip { анимация: kf-fade-in 0.2s леко влизане-навън; }

.notification { анимация: kf-fade-in 0.5s леко изключване; }

Вижте жетоните за ключови кадри на писалката - демонстрация 2 [разклонена] от Амит Шийн. Забележка: Ние използваме префикс kf- във всички наши имена на @keyframes. Този префикс служи като пространство от имена, което предотвратява конфликти на именуване със съществуващи анимации в проекта и веднага прави ясно, че тези ключови кадри идват от нашия файл с токени за ключови кадри. Създаване на динамичен слайд Kf-fade-in ключовите кадри работят чудесно, защото са прости и има малко място за объркване на нещата. В други анимации обаче трябва да сме много по-динамични и тук можем да използваме огромната сила на персонализираните CSS свойства. Това е мястото, където символите на ключови кадри наистина блестят в сравнение с разпръснатите статични анимации. Нека вземем общ сценарий: „плъзгащи се“ анимации. Но да се плъзне откъде? 100px отдясно? 50% отляво? Трябва ли да влиза от горната част на екрана? Или може би изплува от дъното? Толкова много възможности, но вместо да създаваме отделни ключови кадри за всяка посока и всяка вариация, можем да изградим един гъвкав токен, който се адаптира към всички сценарии: /* * Slide In - насочена слайд анимация * Използвайте --kf-slide-from за управление на посоката * По подразбиране: плъзга се отляво (-100%) * Употреба: * анимация: kf-slide-in 0.3s ease-out; * --kf-slide-from: -100px 0; // слайд отляво * --kf-slide-from: 100px 0; // плъзнете отдясно * --kf-slide-from: 0 -50px; // слайд отгоре */

@keyframes kf-slide-in { от { превод: var(--kf-slide-from, -100% 0); } до { превеждам: 0 0; } }

Сега можем да използваме този единичен токен @keyframes за всяка посока на слайд, просто като променим персонализираното свойство --kf-slide-from: .sidebar { анимация: kf-slide-in 0.3s ease-out; /* Използва стойност по подразбиране: слайдове отляво */ }

.notification { анимация: kf-slide-in 0.4s ease-out; --kf-слайд-от: 0 -50px; /* слайд отгоре */ }

.modal { анимация: kf-изчезване 0,5 s, kf-slide-in 0,5 s кубичен безие (0,34, 1,56, 0,64, 1); --kf-слайд-от: 50px 50px; /* слайд от долния десен ъгъл */ }

Този подход ни дава невероятна гъвкавост, като същевременно поддържа последователност. Декларация на един ключов кадър, безкрайни възможности. Вижте жетоните за ключови кадри на писалката - демонстрация 3 [разклонена] от Амит Шийн. И ако искаме да направим анимациите си още по-гъвкави, позволявайки и „плъзгащи се“ ефекти, можемпросто добавете персонализирано свойство --kf-slide-to, подобно на това, което ще видим в следващия раздел. Ключови кадри с двупосочно увеличение Друга често срещана анимация, която се дублира в проекти, са ефектите „увеличаване“. Независимо дали става въпрос за фино увеличаване на мащаба за тост съобщения, драматично увеличение за модали или нежен ефект на намаляване на мащаба за заглавия, анимациите за мащабиране са навсякъде. Вместо да създаваме отделни ключови кадри за всяка стойност на мащаба, нека изградим един гъвкав набор от kf-zoom ключови кадри:

/* * Zoom - мащабиране на анимация * Използвайте --kf-zoom-from и --kf-zoom-to, за да контролирате стойностите на мащаба * По подразбиране: мащабиране от 80% до 100% (0,8 до 1) * Употреба: * анимация: kf-zoom 0.2s ease-out; * --kf-увеличение-от: 0,5; --kf-увеличаване-до: 1; // мащабиране от 50% до 100% * --kf-увеличение-от: 1; --kf-увеличаване-до: 0; // мащабиране от 100% до 0% * --kf-увеличение-от: 1; --kf-увеличаване-до: 1.1; // мащабиране от 100% до 110% */

@keyframes kf-zoom { от { мащаб: var(--kf-zoom-from, 0.8); } до { мащаб: var(--kf-zoom-to, 1); } }

С една дефиниция можем да постигнем всеки вариант на увеличение, от който се нуждаем: .toast { анимация: kf-slide-in 0,2 s, kf-zoom 0.4s улесняване; --kf-слайд-от: 0 100%; /* слайд отгоре */ /* Използва мащабиране по подразбиране: мащабира се от 80% до 100% */ }

.modal { анимация: kf-zoom 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); --kf-увеличение-от: 0; /* драматично увеличение от 0% до 100% */ }

.заглавие { анимация: kf-fade-in 2s, kf-zoom 2s лесно включване; --kf-увеличение-от: 1.2; --kf-увеличение-до: 0,8; /* леко намаляване на мащаба */ }

Стойността по подразбиране от 0,8 (80%) работи перфектно за повечето елементи на потребителския интерфейс, като тост съобщения и карти, като същевременно е лесна за персонализиране за специални случаи. Вижте жетоните за ключови кадри на писалката - демонстрация 4 [разклонена] от Амит Шийн. Може би сте забелязали нещо интересно в последните примери: ние комбинирахме анимации. Едно от ключовите предимства на работата с @keyframes токени е, че те са проектирани да се интегрират безпроблемно един с друг. Тази гладка композиция е умишлена, а не случайна. Ще обсъдим композицията на анимацията по-подробно по-късно, включително къде могат да станат проблематични, но повечето комбинации са ясни и лесни за изпълнение. Забележка: Докато пишех тази статия и може би заради писането й, открих, че преосмислям цялата идея за входните анимации. С всички скорошни постижения в CSS, имаме ли още нужда от тях изобщо? За щастие Адам Аргайл проучи същите въпроси и ги изрази брилянтно в своя блог. Това не противоречи на написаното тук, но представлява подход, който си струва да се обмисли, особено ако вашите проекти разчитат в голяма степен на входни анимации. Непрекъснати анимации Докато входните анимации, като „избледняване“, „плъзгане“ и „мащабиране“, се случват веднъж и след това спират, непрекъснатите анимации се повтарят безкрайно, за да привлекат вниманието или да покажат текуща дейност. Двете най-често срещани непрекъснати анимации, които срещам, са „въртене“ (за индикатори за зареждане) и „пулс“ (за подчертаване на важни елементи). Тези анимации представляват уникални предизвикателства, когато става въпрос за създаване на токени за ключови кадри. За разлика от входните анимации, които обикновено преминават от едно състояние в друго, непрекъснатите анимации трябва да бъдат силно персонализирани в своите модели на поведение. Спин докторът Всеки проект изглежда използва множество въртящи се анимации. Някои се въртят по посока на часовниковата стрелка, други обратно. Някои правят едно завъртане на 360 градуса, други правят няколко завъртания за по-бърз ефект. Вместо да създаваме отделни ключови кадри за всяка вариация, нека изградим едно гъвкаво завъртане, което обработва всички сценарии:

/* * Завъртане - ротационна анимация * Използвайте --kf-spin-from и --kf-spin-to, за да контролирате диапазона на въртене * Използвайте --kf-spin-turns, за да контролирате количеството на въртене * По подразбиране: върти се от 0 градуса до 360 градуса (1 пълно завъртане) * Употреба: * анимация: kf-spin 1s линеен безкраен; * --kf-spin-обороти: 2; // 2 пълни завъртания * --kf-spin-от: 0deg; --kf-spin-to: 180deg; // половин ротация * --kf-spin-от: 0deg; --kf-spin-to: -360deg; // обратно на часовниковата стрелка */

@keyframes kf-spin { от { завъртане: var(--kf-spin-from, 0deg); } до { завъртане: calc(var(--kf-spin-from, 0deg) + var(--kf-spin-to, 360deg) * var(--kf-spin-turns, 1)); } }

Сега можем да създадем всяка вариация на завъртане, която харесваме:

.loading-spinner { анимация: kf-spin 1s линеен безкраен; /* Използва по подразбиране: върти се от 0 градуса до 360 градуса */ }

.fast-loader { анимация: kf-spin 1.2s лекота на влизане-навън безкрайно редуване; --kf-завъртания: 3; /* 3 пълни завъртания за всяка посока на цикъл*/ }

.steped-reverse { анимация: kf-spin 1,5 s стъпки (8) безкрайни; --kf-spin-to: -360deg; /* обратно на часовниковата стрелка */ }

.subtle-wiggle { анимация: kf-spin 2s леко влизане и излизане безкрайно редуване; --kf-spin-от: -16deg; --kf-spin-to: 32deg; /* мърдане 36 градуса: между -18 градуса и +18 градуса */ }

Вижте жетоните за ключови кадри на писалката - демонстрация 5 [разклонена] от Амит Шийн. Красотата на този подход е, че едни и същи ключови кадри работят за зареждане на ротатори, въртящи се икони, мърдащи ефекти и дори сложни многооборотни анимации. Парадоксът на пулса Импулсните анимации са по-трудни, защото могат да „пулсират“ различни свойства. Някои пулсират мащаба, други пулсират непрозрачността, а някои пулсират свойствата на цвета като яркост или наситеност. Вместо да създаваме отделни ключови кадри за всяко свойство, можем да създадем ключови кадри, които работят с всяко CSS свойство. Ето пример за импулсен ключов кадър с опции за мащаб и непрозрачност:

/* * Pulse - пулсираща анимация * Използвайте --kf-pulse-scale-from и --kf-pulse-scale-to, за да контролирате обхвата на скалата * Използвайте --kf-pulse-opacity-from и --kf-pulse-opacity-to, за да контролирате диапазона на непрозрачност * По подразбиране: без импулс (всички стойности 1) * Употреба: * анимация: kf-pulse 2s ease-in-out infinite alternate; * --kf-pulse-scale-от: 0,95; --kf-pulse-scale-to: 1.05; // скала импулс * --kf-pulse-opacity-от: 0,7; --kf-pulse-opacity-to: 1; // импулс на непрозрачност */

@keyframes kf-пулс { от { мащаб: var(--kf-pulse-scale-from, 1); непрозрачност: var(--kf-pulse-opacity-from, 1); } до { мащаб: var(--kf-pulse-scale-to, 1); непрозрачност: var(--kf-pulse-opacity-to, 1); } }

Това създава гъвкав импулс, който може да анимира множество свойства: .call-to-action { анимация: kf-импулс 0.6s безкраен алтернативен; --kf-pulse-opacity-от: 0,5; /* импулс на непрозрачност */ }

.notification-dot { анимация: kf-импулс 0.6s леко влизане-излизане безкрайно редуване; --kf-импулсна-скала-от: 0,9; --kf-pulse-scale-to: 1.1; /* скалиран импулс */ }

.text-highlight { анимация: kf-pulse 1.5s безкрайно успокояване; --kf-импулсна-скала-от: 0,8; --kf-pulse-opacity-от: 0,2; /* импулс на мащаб и непрозрачност */ }

Вижте жетоните за ключови кадри на писалката - демонстрация 6 [разклонена] от Амит Шийн. Този единичен ключов кадър с kf-импулс може да се справи с всичко - от фино привличане на вниманието до драматични акценти, като същевременно е лесен за персонализиране. Разширено облекчаване Едно от страхотните неща при използването на токени за ключови кадри е колко лесно е да разширим нашата анимационна библиотека и да предоставим ефекти, които повечето разработчици не биха си направили труда да пишат от нулата, като еластичност или отскачане. Ето пример за обикновен токен за ключови кадри „отскачане“, който използва персонализирано свойство --kf-bounce-from, за да контролира височината на скока. /* * Bounce - подскачаща входна анимация * Използвайте --kf-bounce-from, за да контролирате височината на скока * По подразбиране: скача от 100vh (извън екрана) * Употреба: * анимация: kf-bounce 3s ease-in; * --kf-отскачане-от: 200px; // скок от 200px височина */

@keyframes kf-bounce { 0% { превод: 0 calc(var(--kf-bounce-from, 100vh) * -1); }

34% { превод: 0 calc(var(--kf-bounce-from, 100vh) * -0.4); }

55% { превод: 0 calc(var(--kf-bounce-from, 100vh) * -0.2); }

72% { превод: 0 calc(var(--kf-bounce-from, 100vh) * -0.1); }

85% { превод: 0 calc(var(--kf-bounce-from, 100vh) * -0.05); }

94% { превод: 0 calc(var(--kf-bounce-from, 100vh) * -0,025); }

99% { превод: 0 calc(var(--kf-bounce-from, 100vh) * -0.0125); }

22%, 45%, 64%, 79%, 90%, 97%, 100% { превеждам: 0 0; функция за време на анимация: успокояване; } }

Анимации като „еластичен“ са малко по-трудни поради изчисленията в ключовите кадри. Трябва да дефинираме --kf-elastic-from-X и --kf-elastic-from-Y отделно (и двете не са задължителни) и заедно те ни позволяват да създадем еластичен вход от всяка точка на екрана.

/* * Elastic In - еластична входна анимация * Използвайте --kf-elastic-from-X и --kf-elastic-from-Y за контрол на началната позиция * По подразбиране: влиза от горния център (0, -100vh) * Употреба: * анимация: kf-elastic-in 2s ease-in-out двете; * --kf-еластичен-от-X: -50px; * --kf-еластичен-от-Y: -200px; // въведете от (-50px, -200px) */

@keyframes kf-elastic-in { 0% { превод: calc(var(--kf-elastic-from-X, -50vw) * 1) calc(var(--kf-elastic-from-Y, 0px) * 1); }

16% { превод: calc(var(--kf-elastic-from-X, -50vw) * -0.3227) calc(var(--kf-elastic-from-Y, 0px) * -0.3227); }

28% { превод: calc(var(--kf-elastic-from-X, -50vw) * 0.1312)calc(var(--kf-elastic-from-Y, 0px) * 0.1312); }

44% { превод: calc(var(--kf-elastic-from-X, -50vw) * -0.0463) calc(var(--kf-elastic-from-Y, 0px) * -0.0463); }

59% { превод: calc(var(--kf-elastic-from-X, -50vw) * 0.0164) calc(var(--kf-elastic-from-Y, 0px) * 0.0164); }

73% { превод: calc(var(--kf-elastic-from-X, -50vw) * -0.0058) calc(var(--kf-elastic-from-Y, 0px) * -0.0058); }

88% { превод: calc(var(--kf-elastic-from-X, -50vw) * 0.0020) calc(var(--kf-elastic-from-Y, 0px) * 0.0020); }

100% { превеждам: 0 0; } }

Този подход улеснява повторното използване и персонализиране на разширени ключови кадри в нашия проект, само чрез промяна на едно персонализирано свойство.

.bounce-and-zoom { анимация: kf-bounce 3s ease-in, kf-zoom 3s линеен; --kf-увеличение-от: 0; }

.bounce-and-slide { анимация-композиция: добавяне; /* И двете анимации използват превод */ анимация: kf-bounce 3s ease-in, kf-slide-in 3s леко изключване; --kf-слайд-от: -200px; }

.elastic-in { анимация: kf-elastic-in 2s ease-in-out двете; }

Вижте жетоните за ключови кадри на писалката – демонстрация 7 [разклонена] от Амит Шийн. До този момент видяхме как можем да консолидираме ключови кадри по интелигентен и ефективен начин. Разбира се, може да искате да промените нещата, за да отговарят по-добре на нуждите на вашия проект, но ние разгледахме примери за няколко общи анимации и случаи на ежедневна употреба. И с тези токени за ключови кадри на място, сега имаме мощни градивни елементи за създаване на последователни, поддържаеми анимации в целия проект. Няма повече дублирани ключови кадри, няма повече глобални конфликти в обхвата. Просто чист, удобен начин да се справим с всички наши нужди от анимация. Но истинският въпрос е: Как да съставим тези градивни елементи заедно? Сглобяване на всичко Видяхме, че комбинирането на основни символи на ключови кадри е лесно. Не се нуждаем от нищо специално, освен да дефинираме първата анимация, да дефинираме втората, да зададем променливите според нуждите и това е всичко. /* Избледняване + плъзгане навътре */ .toast { анимация: kf-избледняване 0,4 s, kf-slide-in 0.4s кубичен безие (0.34, 1.56, 0.64, 1); --kf-слайд-от: 0 40px; }

/* Увеличаване + избледняване */ .modal { анимация: kf-изчезване 0,3 s, kf-увеличение 0,3 s кубичен безие (0,34, 1,56, 0,64, 1); --kf-увеличение-от: 0,7; --kf-увеличаване-до: 1; }

/* Плъзнете навътре + импулс */ .notification { анимация: kf-slide-in 0,5s, kf-импулс 1.2s безкрайно алтернативно улесняване на влизане и излизане; --kf-слайд-от: -100px 0; --kf-импулсна-скала-от: 0,95; --kf-pulse-scale-to: 1.05; }

Тези комбинации работят прекрасно, защото всяка анимация е насочена към различно свойство: непрозрачност, трансформация (превод/мащаб) и т.н. Но понякога има конфликти и трябва да знаем защо и как да се справим с тях. Когато две анимации се опитват да анимират едно и също свойство — например и двете анимират мащаб или и двете анимират непрозрачност — резултатът няма да бъде това, което очаквате. По подразбиране само една от анимациите действително се прилага към това свойство, което е последното в списъка с анимации. Това е ограничение на начина, по който CSS обработва множество анимации на едно и също свойство. Например, това няма да работи по предназначение, защото ще се приложи само анимацията на kf-pulse. .bad-combo { анимация: kf-zoom 0.5s напред, kf-импулс 1.2s безкраен алтернативен; --kf-увеличение-от: 0,5; --kf-увеличаване-до: 1.2; --kf-импулсна-скала-от: 0,8; --kf-pulse-scale-to: 1.1; }

Добавка за анимация Най-простият и директен начин за обработка на множество анимации, които засягат едно и също свойство, е да се използва свойството animation-composition. В последния пример по-горе анимацията kf-pulse замества анимацията kf-zoom, така че няма да видим първоначалното увеличение и няма да получим очаквания мащаб от 1,2. Като зададем анимационната композиция за добавяне, казваме на браузъра да комбинира и двете анимации. Това ни дава желания резултат. .component-two { анимация-композиция: добавяне; }

Вижте жетоните за ключови кадри на писалката - демонстрация 8 [разклонена] от Амит Шийн. Този подход работи добре в повечето случаи, когато искаме да комбинираме ефекти върху едно и също свойство. Също така е полезно, когато трябва да комбинираме анимации със стойности на статични свойства. Например, ако имаме елемент, който използва свойството translate, за да го позиционира точно където искаме, и след това искаме да го анимираме с kf-slide-in ключови кадри, получаваме неприятен видим скок без композиция на анимация. Вижте жетоните за ключови кадри на писалката – демонстрация 9 [разклонена] от Амит Шийн. С настройката за добавяне на анимационна композиция, анимацията се комбинира гладко със съществуващататрансформира, така че елементът да остане на място и да се анимира според очакванията. Анимация Залитане Друг начин за обработка на множество анимации е да ги „залитате“ — тоест да започнете втората анимация малко след края на първата. Това не е решение, което работи за всеки случай, но е полезно, когато имаме входна анимация, последвана от непрекъсната анимация. /* избледняване + импулс на непрозрачност */ .notification { анимация: kf-fade-in 2s облекчаване, kf-импулс 0,5 s 2 s леко влизане и излизане безкрайно редуване; --kf-pulse-opacity-to: 0,5; }

Вижте жетоните за ключови кадри на писалката - демонстрация 10 [разклонена] от Амит Шийн. Поръчката има значение Голяма част от анимациите, с които работим, използват свойството transform. В повечето случаи това е просто по-удобно. Освен това има предимство в производителността, тъй като анимациите за трансформация могат да бъдат ускорени с GPU. Но ако използваме трансформации, трябва да приемем, че редът, в който извършваме нашите трансформации, има значение. много. В нашите ключови кадри досега сме използвали отделни трансформации. Според спецификациите те винаги се прилагат във фиксиран ред: първо елементът се превежда, след това се завърта, след това се мащабира. Това има смисъл и е това, което повечето от нас очакват. Въпреки това, ако използваме свойството transform, редът, в който са записани функциите, е редът, в който се прилагат. В този случай, ако преместим нещо 100 пиксела по оста X и след това го завъртим на 45 градуса, това не е същото като първо да го завъртим на 45 градуса и след това да го преместим 100 пиксела. /* Розов квадрат: Първо преведете, след това завъртете */ .example-one { трансформация: translateX(100px) rotate(45deg); }

/* Зелен квадрат: Първо завъртете, след това транслирайте */ .example-two { трансформиране: rotate(45deg) translateX(100px); }

Вижте жетоните за ключови кадри на писалката - демонстрация 11 [разклонена] от Амит Шийн. Но според реда на трансформация, всички индивидуални трансформации – всичко, което сме използвали за токените на ключови кадри – се случва преди функциите за трансформация. Това означава, че всичко, което зададете в свойството transform ще се случи след анимациите. Но ако зададете, например, превод заедно с kf-spin ключови кадри, преводът ще се случи преди анимацията. Още ли сте объркани?! Това води до ситуации, при които статичните стойности могат да причинят различни резултати за една и съща анимация, като в следния случай:

/* Обща анимация за двата спинера */ .spinner { анимация: kf-spin 1s линеен безкраен; }

/* Розов спинер: превеждане преди завъртане (индивидуална трансформация) */ .spinner-pink { превод: 100% 50%; }

/* Зелен въртящ се бутон: завъртете и след това транслирайте (ред на функциите) */ .spinner-green { трансформиране: превод (100%, 50%); }

Вижте жетоните за ключови кадри на писалката - демонстрация 12 [разклонена] от Амит Шийн. Можете да видите, че първият спинер (розов) получава транслация, която се случва преди завъртането на kf-spin, така че първо се премества на мястото си и след това се завърта. Вторият въртящ се (зелен) получава функция translate(), която се случва след индивидуалната трансформация, така че елементът първо се върти, след това се движи спрямо текущия си ъгъл и получаваме този ефект на широка орбита. Не, това не е грешка. Това е само едно от нещата, които трябва да знаем за CSS и да имаме предвид, когато работим с множество анимации или множество трансформации. Ако е необходимо, можете също да създадете допълнителен набор от ключови кадри kf-spin-alt, които завъртат елементи с помощта на функцията rotate(). Намалено движение И докато говорим за алтернативни ключови кадри, не можем да пренебрегнем опцията „без анимация“. Едно от най-големите предимства на използването на токени за ключови кадри е, че достъпността може да бъде включена и всъщност е доста лесно да се направи. Като проектираме нашите ключови кадри с оглед на достъпността, можем да гарантираме, че потребителите, които предпочитат намалено движение, получават по-плавно, по-малко разсейващо изживяване, без допълнителна работа или дублиране на код. Точното значение на „Намалено движение“ може да се промени малко от една анимация на друга и от проект на проект, но ето няколко важни момента, които трябва да имате предвид: Заглушаване на ключови кадри Въпреки че някои анимации могат да бъдат омекотени или забавени, има други, които трябва да изчезнат напълно, когато се поиска намалено движение. Пулсовите анимации са добър пример. За да сме сигурни, че тези анимации не се изпълняват в режим на намалено движение, можем просто да ги увием в подходящата медийна заявка.

@media (prefers-reduced-motion: no-preference) { @keyfrmaes kf-пулс { от { мащаб: var(--kf-pulse-scale-from, 1); непрозрачност: var(--kf-pulse-opacity-from, 1); } до { мащаб: var(--kf-pulse-scale-to, 1); непрозрачност:var(--kf-pulse-opacity-to, 1); } } }

Това гарантира, че потребителите, които са задали предпочитания за намаляване на движението, няма да видят анимацията и ще получат изживяване, което отговаря на техните предпочитания. Моментално влизане Има някои ключови кадри, които не можем просто да премахнем, като входни анимации. Стойността трябва да се променя, трябва да се анимира; в противен случай елементът няма да има правилните стойности. Но при намалено движение този преход от първоначалната стойност трябва да е мигновен. За да постигнем това, ще дефинираме допълнителен набор от ключови кадри, където стойността скача незабавно до крайното състояние. Те стават нашите ключови кадри по подразбиране. След това ще добавим обикновените ключови кадри в медийна заявка за prefers-reduced-motion, зададена на no-preference, точно както в предишния пример. /* появява се незабавно за намалено движение */ @keyframes kf-zoom { от, до { мащаб: var(--kf-zoom-to, 1); } }

@media (prefers-reduced-motion: no-preference) { /* Оригинални ключови кадри за увеличение */ @keyframes kf-zoom { от { мащаб: var(--kf-zoom-from, 0.8); } до { мащаб: var(--kf-zoom-to, 1); } } }

По този начин потребителите, които предпочитат намалено движение, ще видят елемента да се появява незабавно в окончателното си състояние, докато всички останали получават анимирания преход. Мекият подход Има случаи, в които искаме да запазим някакво движение, но много по-меко и по-спокойно от оригиналната анимация. Например, можем да заменим отскачащ вход с леко затихване.

@keyframes kf-bounce { /* Плавно затихване за намалено движение */ }

@media (prefers-reduced-motion: no-preference) { @keyframes kf-bounce { /* Оригинални ключови кадри за отскачане */ } }

Сега потребителите с активирано намалено движение все още получават усещане за външен вид, но без интензивното движение на отскачане или еластична анимация. След като градивните елементи са поставени, следващият въпрос е как да ги направите част от действителния работен процес. Писането на гъвкави ключови кадри е едно нещо, но за да ги направиш надеждни в голям проект, са необходими няколко стратегии, които трябваше да науча по трудния начин. Стратегии за внедряване и най-добри практики След като имаме солидна библиотека от токени за ключови кадри, истинското предизвикателство е как да ги включим в ежедневната работа.

Изкушението е да изпусна всички ключови кадри наведнъж и да обявя проблема за разрешен, но на практика открих, че най-добрите резултати идват от постепенното възприемане. Започнете с най-често срещаните анимации, като избледняване или плъзгане. Това са лесни печалби, които показват незабавна стойност, без да изискват големи пренаписвания. Наименуването е друг момент, който заслужава внимание. Един последователен префикс или пространство от имена прави очевидно кои анимации са токени и кои са локални еднократни. Той също така предотвратява случайни сблъсъци и помага на новите членове на екипа да разпознаят споделената система с един поглед. Документацията е също толкова важна, колкото и самият код. Дори кратък коментар над всеки токен на ключови кадри може да спести часове гадаене по-късно. Разработчикът трябва да може да отвори файла с токени, да сканира за ефекта, от който се нуждае, и да копира модела на използване направо в своя компонент. Гъвкавостта е това, което прави този подход си струва усилията. Чрез излагане на разумни персонализирани свойства, ние даваме на екипите място да адаптират анимацията, без да нарушават системата. В същото време се опитайте да не усложнявате твърде много. Осигурете копчетата, които имат значение, и запазете останалото мнение. И накрая, не забравяйте за достъпността. Не всяка анимация се нуждае от алтернатива за намалено движение, но много от тях имат нужда. Изпичането на тези корекции на ранен етап означава, че никога не трябва да ги преоборудваме по-късно и показва ниво на грижа, което нашите потребители ще забележат, дори и никога да не го споменават.

Според моя опит, третирането на токените за ключови кадри като част от работния процес на дизайна на токените е това, което ги кара да се придържат. След като са на място, те престават да се чувстват като специални ефекти и стават част от дизайнерския език, естествено продължение на това как продуктът се движи и реагира. Завършване Анимациите могат да бъдат една от най-приятните части на изграждането на интерфейси, но без структура те могат да се превърнат и в един от най-големите източници на разочарование. Като третирате ключови кадри като токени, вие приемате нещо, което обикновено е объркано и трудно за управление, и го превръщате в ясна, предвидима система. Истинската стойност не е само в спестяването на няколко реда код. Това е увереността, че когато използвате избледняване, слайд, мащабиране или завъртане, знаете точно как ще се държи в целия проект. Тя е в гъвкавостта, която идва от персонализирани свойства без хаоса от безкрайни вариации. И това е в достъпността, вградена в основата, а не добавена катопоследваща мисъл. Виждал съм как тези идеи работят в различни екипи и различни кодови бази и моделът винаги е един и същ. След като токените са на мястото си, ключовите кадри спират да бъдат разпръсната колекция от трикове и стават част от езика на дизайна. Те карат продукта да се чувства по-преднамерен, по-последователен и по-жив. Ако вземете едно нещо от тази статия, нека бъде следното: анимациите заслужават същата грижа и структура, които вече придаваме на цветовете, типографията и разстоянието. Малка инвестиция в токени за ключови кадри се изплаща всеки път, когато вашият интерфейс се движи.

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