Timing-функции и характер движения

Кодинг
Q_Time

7 минут чтения

hero image

Содержание

В предыдущей статье мы разобрали, как @keyframes задают что происходит. Теперь поговорим о том, как это происходит. Timing-функция определяет характер движения между ключевыми кадрами: равномерно ли элемент перемещается, разгоняется ли в начале, тормозит ли в конце, дёргается ли рывками. Это то, что отличает механическое движение от живого.

Пять встроенных функций

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

linear
ease
ease-in
ease-out
ease-in-out

<div class="dot tf-linear"></div>
<div class="dot tf-ease"></div>
<div class="dot tf-ease-in"></div>
<div class="dot tf-ease-out"></div>
<div class="dot tf-ease-in-out"></div>
      

.tf-linear     { animation-timing-function: linear; }
.tf-ease       { animation-timing-function: ease; }
.tf-ease-in    { animation-timing-function: ease-in; }
.tf-ease-out   { animation-timing-function: ease-out; }
.tf-ease-in-out { animation-timing-function: ease-in-out; }
 
/* Одна дистанция, одна длительность,
   пять разных характеров движения.
   Следите за тем, как каждая точка
   ускоряется и замедляется. */
      

Пять точек проходят одну и ту же дистанцию за одно и то же время. Но характер движения у каждой совершенно разный.

linear — постоянная скорость от начала до конца. Нет ускорения и замедления. Движение выглядит механическим, как конвейерная лента. Хорошо подходит для бесконечных вращений и бегущих строк, где плавность не нужна.

ease — значение по умолчанию. Быстрый старт, замедление к концу. Похоже на то, как ведёт себя тяжёлый предмет, которому дали толчок.

ease-in — медленный старт, ускорение к концу. Элемент как будто набирает обороты. Полезно, когда что-то уходит с экрана — объект ускоряется и исчезает за краем.

ease-out — быстрый старт, замедление к концу. Как будто элемент прилетел и притормаживает. Хорошо для появления: объект влетает и плавно встаёт на место.

ease-in-out — медленный старт, ускорение в середине, замедление к концу. Самая «живая» из встроенных функций. Напоминает дыхание или качание маятника. Для большинства декоративных анимаций в веб-плакате это оптимальный выбор.

linear
ease-in-out

<div class="box-linear"></div>
<div class="box-easeio"></div>
      

.box-linear {
  animation: run 3s linear infinite alternate;
}
 
.box-easeio {
  animation: run 3s ease-in-out infinite alternate;
}
 
/* linear — робот. Одна скорость
   от начала до конца.
   ease-in-out — живое существо.
   Разгоняется, едет, тормозит. */
      

На крупном масштабе разница особенно заметна. linear движется равномерно, как робот. ease-in-out разгоняется, набирает скорость и мягко тормозит, как живое существо. Если не знаете, какую функцию выбрать, начните с ease-in-out — она работает почти всегда.

Если вы не указываете timing-функцию, браузер использует ease, а не linear. Это значит, что animation: slide 3s infinite уже имеет ускорение. Для равномерного движения (бегущие строки, вращения) нужно явно прописать linear.

cubic-bezier()

Пять встроенных функций — это частные случаи более общей записи cubic-bezier(x1, y1, x2, y2). Четыре числа задают форму кривой, которая определяет распределение скорости. Вместо того чтобы объяснять математику, проще показать на примерах.

snappy (0.5, 0, 0.2, 1)
bounce (0.34, 1.56, 0.64, 1)
sluggish (0.8, 0, 0.7, 1)
dramatic (0.9, 0, 0.1, 1)

<div class="dot snappy"></div>
<div class="dot bounce"></div>
<div class="dot sluggish"></div>
<div class="dot dramatic"></div>
      

.snappy {
  animation-timing-function:
    cubic-bezier(0.5, 0, 0.2, 1);
}
 
.bounce {
  animation-timing-function:
    cubic-bezier(0.34, 1.56, 0.64, 1);
}
/* cubic-bezier(x1, y1, x2, y2) —
   четыре числа задают кривую.
   y > 1 создаёт «пролёт»: элемент
   проскакивает конечную точку
   и возвращается. */
      

snappy (0.5, 0, 0.2, 1) — быстро срывается с места и плавно останавливается. Ощущение решительности.

bounce (0.34, 1.56, 0.64, 1) — элемент проскакивает конечную точку и возвращается. Значение y больше единицы создаёт этот эффект «пролёта». Ощущение упругости, как у резинового мячика.

sluggish (0.8, 0, 0.7, 1) — долго разгоняется, медленно тормозит. Ощущение тяжести и инерции.

dramatic (0.9, 0, 0.1, 1) — почти не двигается в начале и конце, резко проносится в середине. Ощущение контраста, как у затяжного вдоха перед прыжком.

Запоминать числа не нужно. Откройте cubic-bezier.com, подвигайте контрольные точки кривой и скопируйте результат. Визуальный редактор превращает абстрактные четыре числа в понятный инструмент.

Встроенные функции в терминах cubic-bezier: linear = (0, 0, 1, 1). ease = (0.25, 0.1, 0.25, 1). ease-in = (0.42, 0, 1, 1). ease-out = (0, 0, 0.58, 1). ease-in-out = (0.42, 0, 0.58, 1). Это просто пресеты, как шрифтовые пары — удобно для быстрого старта, но свои значения дают более точный контроль.

steps(): дискретное движение

Все предыдущие функции создают плавное движение — браузер интерполирует промежуточные значения. steps() работает иначе. Он разбивает анимацию на фиксированное количество рывков, без интерполяции между ними.


<div class="clock">
  <div class="hand"></div>
</div>
<div class="blink-text">СИГНАЛ</div>
      

/* Часовая стрелка: 12 шагов = 12 позиций */
.hand {
  animation: clock 12s steps(12) infinite;
}
 
@keyframes clock {
  to { transform: rotate(360deg); }
}
 
/* Мигание: 2 шага = вкл/выкл */
.blink-text {
  animation: blink 1s steps(2) infinite;
}
 
@keyframes blink {
  to { opacity: 0; }
}
/* steps(2) — самый резкий переход.
   Никакой плавности, чистое
   переключение между состояниями. */
      

steps(4) — четыре дискретные позиции, элемент прыгает между ними. steps(8) — восемь позиций, движение чуть плавнее, но всё ещё рывковое. steps(16) — уже похоже на плавное, но с лёгким «желе-эффектом». linear внизу для сравнения — полная плавность.

steps() полезен в двух контекстах. Первый — спрайтовые анимации, которые мы разбирали в статье про подготовку графики. Там steps() переключает кадры спрайтового листа без интерполяции. Второй — стилистическое решение, когда нужно покадровое, «механическое» движение.

steps(4)
steps(8)
steps(16)
linear (для сравнения)

<div class="dot st-4"></div>
<div class="dot st-8"></div>
<div class="dot st-16"></div>
<div class="dot st-linear"></div>
      

.st-4  { animation-timing-function: steps(4); }
.st-8  { animation-timing-function: steps(8); }
.st-16 { animation-timing-function: steps(16); }
 
/* steps() отключает интерполяцию.
   Вместо плавного движения — рывки.
   4 шага = 4 дискретные позиции.
   Чем больше шагов, тем ближе
   к плавному движению. */
      

Часовая стрелка с steps(12) — 12 позиций за полный оборот, как на настоящих часах. Текст «Сигнал» с steps(2) — чистое мигание: видимый → невидимый, без плавного затухания. Два шага — это минимум, и он создаёт самый резкий из возможных переходов.

Timing-функция как настроение

Вот, пожалуй, самое практическое, что можно сказать о timing-функциях. Характер движения — это настроение. Не абстрактная кривая, а ощущение, которое зритель получает от анимации. И выбор timing-функции — дизайнерское решение, такое же, как выбор цвета или шрифта.

нервозность
спокойствие
механика
упругость

<div class="mood-nervous"></div>
<div class="mood-calm"></div>
<div class="mood-mechanical"></div>
<div class="mood-elastic"></div>
      

/* Нервозность: быстро, linear, мелко */
.nervous {
  animation: shake 0.15s linear infinite alternate;
}
 
/* Спокойствие: медленно, ease-in-out */
.calm {
  animation: breathe 4s ease-in-out infinite alternate;
}
 
/* Механика: steps, ровные рывки */
.mechanical {
  animation: tick 2s steps(4) infinite;
}
 
/* Упругость: cubic-bezier с y > 1 */
.elastic {
  animation: bounce 1.5s
    cubic-bezier(0.34, 1.56, 0.64, 1)
    infinite alternate;
}
      

Четыре квадрата, четыре настроения.

Нервозность — linear, 0.15 секунды, амплитуда 3 пикселя. Мелкая быстрая дрожь. Подходит для элементов, передающих сбой, тревогу, нестабильность. Именно так сделан эффект в веб-плакате «Доигрались».

Спокойствие — ease-in-out, 4 секунды, масштаб 1 → 1.15. Медленная пульсация, похожая на дыхание. Подходит для фоновых элементов, которые должны создавать ощущение жизни, не отвлекая внимание.

Механика — steps(4), 2 секунды, вращение на 360 градусов. Ровные рывки, как шестерёнка. Подходит для элементов, связанных с техникой, промышленностью, цифровой эстетикой.

Упругость — cubic-bezier(0.34, 1.56, 0.64, 1), 1.5 секунды. Элемент проскакивает конечную точку и пружинит обратно. Подходит для игривых, энергичных интерфейсов.

Когда выбираете timing-функцию, задайте себе вопрос: «Какой характер у этого движения?» Если элемент — это механизм, используйте linear или steps. Если живое существо — ease-in-out или кастомный cubic-bezier с мягким ускорением. Если энергичный персонаж — cubic-bezier с y > 1 для эффекта упругости. Технология следует за метафорой.

Понравилась статья?

Забыли главное или есть что предложить?
Напишите нам в телеграм

Читайте также