Функции плавности в CSS переходах и анимации

alexei24/02/2023 - 09:25
Функции плавности в CSS переходах и анимации

Функции плавности (easing) могут менять внешний вид и восприятие анимации, влияя на ее скорость воспроизведения. В повседневной жизни мы чаще видим нелинейное движение. Оно воспринимается нами как естественное. Использование пользовательских функций плавности позволяет улучшить впечатление пользователей от CSS анимации и создает более приятный пользовательский опыт взаимодействия с вашим проектом. В этой статье мы ближе познакомимся с функциями плавности и рассмотрим, как можно их использовать для создания естественных и потрясающих CSS анимаций.

Вы когда-нибудь замечали, как плавно и восхитительно выглядят анимации в хорошо сделанном профессиональном проекте? Дизайн и стиль анимации не только красивы, но и красиво и гармонично сочетаются. Именно поток воспроизведения в сочетании с дизайном и подачей делают анимацию потрясающей и естественной. В управлении потоком воспроизведения и состоит сила функций плавности (или тайминговых функций).

При написании CSS свойств перехода и анимации мы обычно используем предопределенные функции плавности, например, ease-out, потому что их просто использовать и в большинстве случаев все хорошо работает. Однако наличие дюжины или более анимированных элементов с одинаковыми длительностью и значениями функций плавности может сделать пользовательский интерфейс немного скучным и монотонным. Люди лучше реагируют на естественные движения, поэтому, делая анимацию и переходы более разнообразными и естественными, вы улучшите пользовательский опыт.

Если взять профессиональный проект и заглянуть в его таблицу стилей, то вы увидите, что для получения красивого потока анимации применяются различные пользовательские функции cubic-bezier в сочетании с предопределенными тайминговыми функциями linear и ease-in. При этом стоит заметить, что, если использовать только предопределенные функции плавности, то анимации в значительной степени потеряют естественность.

В этой статье мы собираемся глубоко погрузиться в CSS функции плавности, типы функций плавности и как создавать пользовательские функции плавности при помощи кубических кривых Безье.

Что там скрыто от глаз

Чтобы лучше понять функции плавности, нам нужно сделать шаг назад и взглянуть на основы анимации в CSS.

Анимация определяется ключевыми кадрами, которые задают то, как элемент должен выглядеть и где располагаться в определенных точках. В CSS переходах используются два ключевых кадра (начальное и конечное значение), в то время как CSS анимация позволяет задавать все более точно и подробно при помощи правила @keyframes.

Поток анимации (ключевые кадры) квадрата, который движется слева направо от 0px (0% потока) до 500px (100% потока)
Поток анимации (ключевые кадры) квадрата, который движется слева направо от 0px (0% потока) до 500px (100% потока)

Продолжительность анимации (animation duration) определяет время, в течение которого анимация проходит от первого ключевого кадра до последнего. На следующем графике показана связь между ключевыми кадрами анимации и ее продолжительностью.

Поток анимации квадрата, который движется от 0px (0% потока) до 500px (100% потока) длительностью 1000мс
Поток анимации квадрата, который движется от 0px (0% потока) до 500px (100% потока) длительностью 1000мс

Между ключевыми кадрами поток анимации может двигаться по разному. Например, у анимации везде может быть постоянная скорость, или же она может быстро двигаться в начале и замедляться ближе к концу, или же медленно двигаться в начале, а затем ускоряться, пока не дойдет до конца, и т.д. Этот фреймрейт или динамика скорости определяется функциями плавности (или тайминговыми функциями). Если мы посмотрим на предыдущий график, то увидим, что там функция плавности представлена формой линии, соединяющей две точки. Здесь использовалась линейная функция (чистая прямая), но мы также можем использовать кривую для соединения ключевых кадров.

Поток анимации квадрата длительностью 1000мс. Анимация ускоряется в начале и замедляется к концу
Поток анимации квадрата длительностью 1000мс. Анимация ускоряется в начале и замедляется к концу.

Как вы можете видеть, существует множество возможных опций и вариаций функций плавности, и мы рассмотрим их далее.

Типы функций плавности

В CSS существует три основных типа функций плавности:

  • Линейные функции (linear)
  • Функции кубических кривых Безье (включая ease, ease-in, ease-out и ease-in-out)
  • Ступенчатые функции (steps)

Линейные функции

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

Поток анимации квадрата, который движется от 0px (0% потока) до 500px (100% потока) длительностью 1000мс
Поток анимации квадрата, который движется от 0px (0% потока) до 500px (100% потока) длительностью 1000мс
Поток анимации квадрата, который движется от 0px (первый ключевой кадр) до 200px (второй ключевой кадр) и затем до 500px (последний ключевой кадр) длительностью 1000мс
Поток анимации квадрата, который движется от 0px (первый ключевой кадр) до 200px (второй ключевой кадр) и затем до 500px (последний ключевой кадр) длительностью 1000мс

Функции кубических кривых Безье

Хотя функции линейной плавности имеют свои варианты применения, при неправильном или слишком частом использовании они могут сделать анимацию скучной и неестественной.

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

К функциям кубических кривых Безье относятся такие часто используемые предопределенные функции плавности, как ease, ease-in, ease-out и ease-in-out. Их можно использовать как быстрый способ задать нелинейную функцию плавности. Даже линейная функция может быть определена с помощью функции определения пользовательских кривых Безье cubic-bezier.

Функция плавностиЗначение cubic-bezierСкорость в началеСкорость в серединеСкорость в конце
linearcubic-bezier(0.0, 0.0, 1.0, 1.0)постояннаяпостояннаяпостоянная
easecubic-bezier(0.25, 0.1, 0.25, 1.0)быстрое ускорениебыстрое ускорениемедленное ускорение
ease-incubic-bezier(0.42, 0, 1.0, 1.0)медленное ускорениебыстрое ускорениеполная скорость
ease-outcubic-bezier(0, 0, 0.58, 1.0)полная скоростьмедленное ускорениемедленное ускорение
ease-in-outcubic-bezier(0.42, 0, 0.58, 1.0)медленное ускорениеполная скоростьбыстрое ускорение

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

Давайте посмотрим, как работает функция cubic-bezier, которая используется в CSS для определения кубических кривых Безье. Функция кубических кривых Безье определяется четырьмя точками (парами координат x и y), но в функции cubic-bezier мы определяем только 2 точки. Почему это так?

Пример кубической кривой Безье для CSS анимации
Пример кубической кривой Безье для CSS анимации

Это связано с тем, что первая (P0) и последняя точки (P3) привязаны к началу (начальное состояние анимации) и концу (конечное состояние анимации) кривой, поскольку анимация должна заканчиваться на указанном ключевом кадре и в течение указанной продолжительности. При помощи двух оставшихся точек (P1 и P2) мы можем точно настроить кривую и плавность функции, что приводит к нелинейной скорости анимации.


cubic-bezier(x1, y1, x2, y2)

Координаты X (x1 и x2) представляют соотношение времени и ограничены значениями от 0 до 1 (анимация не может начаться раньше или длиться дольше, чем указано), в то время как координаты Y (y1 и y2) представляют выходные данные анимации и их значения, которые обычно устанавливаются где-то между 0 и 1, но не ограничены этим диапазоном. Задав значения y1 и y2 за пределами диапазона 0 и 1, мы можем создать эффект отскока.

Анимация с эффектом отскока
Анимация с эффектом отскока

Если анимация состоит из нескольких ключевых кадров, определенных в CSS правиле @keyframes, то функция плавности будет применяться к каждой кривой между двумя точками. Если мы будем использовать функцию ease-out для анимации с 3 ключевыми кадрами, то анимация будет ускоряться в начале первого ключевого кадра и замедляться около второго ключевого кадра, и то же движение будет повторяться для следующей пары ключевых кадров (второй ключевой кадр и последний ключевой кадр).

Обратите внимание, как функция плавности повторяется между каждой парой ключевых кадров: первым и вторым ключевыми кадрами (первая пара), а также вторым и последним ключевыми кадрами (вторая пара). Продолжительность анимации одинакова как для предыдущего, так и для следующего примеров.

Создание подобных функций может оказаться непростой задачей, и вам, вероятно, не захочется настраивать нужную траекторию, угадывая параметры для функции cubic-bezier. Хотелось бы иметь некий инструмент, который помогал бы подобрать все эти магические числа, чтобы создать функцию плавности, идеально подходящую для вашей анимации. К счастью, существует множество браузерных и онлайн-инструментов, которые могут помочь нам. О них мы поговорим в одном из следующих разделов этой статьи.

Ступенчатые функции

Ступенчатые функции заставляют анимацию двигаться между определенным количеством кадров прерывистым способом. Можно рассматривать это как "тикающую" анимацию.

Например, если мы посмотрим на один из предыдущих примеров, где квадрат движется от 0px до 500px, и ограничим анимацию 5 шагами, анимация будет скачкообразно перемещаться между следующими 5 ключевыми кадрами на позициях 0px, 100px, 200px, 300px и 400px.

В CSS этого можно легко добиться при помощи функции steps.


steps(количество_кадров)


steps(5)

У этой функции есть дополнительная опция, позволяющая контролировать то, какие ключевые кадры включать в анимацию. Как вы видели из предыдущего примера, анимация квадрата, перемещающегося от 0px до 500px пятью шагами, закончится в позиции 400px. Если мы хотим, чтобы анимация начиналась с позиции 100px и заканчивалась в позиции 500px, мы можем в качестве второго аргумента функции использовать дополнительный параметр термин_перехода. Данный параметр влияет на то, как ключевые кадры будут выбраны на временной шкале анимации.


steps(количество_кадров, термин_перехода)


steps(5, jump-start)

CSS функция steps в качестве термина перехода принимает следующие значения:

  • jump-start

    Анимация прыгает прямо из начальной точки, при этом начальная точка не видна. В нашем примере ключевыми кадрами будут 100px, 200px, 300px, 400px, 500px.

  • jump-end

    Последний прыжок происходит, когда анимация заканчивается, и он не отображается. В нашем примере ключевыми кадрами будут 0px, 100px, 200px, 300px, 400px.

  • jump-both

    Первый и последний прыжки будут выполняться при запуске и завершении анимации соответственно, поэтому они не будут видны. Все 5 переходов будут происходить между начальной и конечной точками. В нашем примере ключевыми кадрами будут 80px, 165px, 250px, 335px, 420px.

  • jump-none

    Будут видны как первый, так и последний прыжки. В нашем примере ключевыми кадрами будут 0px, 125px, 250px, 375px, 500px.

Временная шкала анимация с функцией step(5) продолжительностью 1000мс
Временная шкала анимация с функцией step(5) продолжительностью 1000мс

В следующем примере показано, как различные термины перехода влияют на поведение анимации. Здесь к 5-шаговой анимации с одинаковой продолжительностью применяются различные термины перехода.

Отладка анимаций и некоторые полезные инструменты

Как мы видели на примере функции кубической кривой Безье, нам нужен какой-то инструмент, который помог бы точно настроить параметры функции cubic-bezier, чтобы мы могли добиться желаемой анимации.

В этом разделе статьи мы рассмотрим браузерные и онлайн инструменты, которые могут помочь нам сделать именно это.

Инструменты браузера

Инструменты разработчика в браузерах предоставляют полезный инструментарий редактирования функций плавности. Правда, стоит сказать, что для редактирования здесь доступны только функции кубических кривых Безье. Эти инструменты предлагают быстрый и простой предварительный просмотр анимации, таким образом разработчик получает моментальный результат и может должным образом настроить свою функцию плавности.

Инструменты разработчика для анимаций в Chrome, Safari, Firefox
Инструменты разработчика для анимаций в Chrome, Safari, Firefox

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

Специальная вкладка анимации в инструментах разработчика в Chrome, Safari, Firefox
Специальная вкладка анимации в инструментах разработчика в Chrome, Safari, Firefox

Полезные инструменты и веб-сайты

Существует множество полезных онлайн-ресурсов и шаблонов функций плавности, которые могут значительно облегчить и разнообразить настройку ваших анимаций.

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

Анимации и доступность

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


.animated-element {
  animation: /* Обычная анимация */;
}

@media (prefers-reduced-motion) {
  .animated-element {
    /* Анимация с уменьшенной скоростью воспроизведения */
  }
}

Ниже приводится модифицированный пример аналоговых часов Альваро Монторо, который включает альтернативную анимацию для пользователей с установленным флагом preferences-reduced-motion.

В анимации по умолчанию секундная стрелка часов постоянно движется, что может вызвать трудности у некоторых пользователей. Мы можем легко сделать анимацию намного более доступной, изменив функцию плавности на steps. В следующем примере пользователям с установленным флагом preferences-reduced-motion будет отображаться анимация, в которой секундная стрелка "тикает" каждые пять секунд.


@media (prefers-reduced-motion) {
  .arm.second {
    animation-timing-function: steps(12);
  }
}

Заключение

Функции плавности или тайминговые функции или функции синхронизации изменяют внешний вид и восприятие анимации, влияя на ее скорость воспроизведения. Функции плавности позволяют нам создавать анимации, напоминающие естественное движение, что может привести к улучшенному, более приятному UX и лучшему пользовательскому восприятию.

Мы рассмотрели, как можно использовать предопределенные функции, такие как linear, ease-out, ease и др., чтобы быстро определить анимацию, и как создавать пользовательские функции плавности при помощи CSS функции cubic-bezier для более впечатляющих и эффектных анимаций. Мы также рассмотрели ступенчатые функции, которые можно использовать для создания "тикающих" анимаций.

При создании анимации важно учитывать доступность и предоставлять альтернативную, менее отвлекающую анимацию с уменьшенной скоростью воспроизведения для пользователей с установленным флагом prefers-reduced-motion.

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