Содержание
В предыдущей статье мы разобрали, как @keyframes задают что происходит. Теперь поговорим о том, как это происходит. Timing-функция определяет характер движения между ключевыми кадрами: равномерно ли элемент перемещается, разгоняется ли в начале, тормозит ли в конце, дёргается ли рывками. Это то, что отличает механическое движение от живого.
Пять встроенных функций
CSS предоставляет пять готовых timing-функций. Все они описывают, как распределяется скорость анимации по времени.
<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 — медленный старт, ускорение в середине, замедление к концу. Самая «живая» из встроенных функций. Напоминает дыхание или качание маятника. Для большинства декоративных анимаций в веб-плакате это оптимальный выбор.
<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). Четыре числа задают форму кривой, которая определяет распределение скорости. Вместо того чтобы объяснять математику, проще показать на примерах.
<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() переключает кадры спрайтового листа без интерполяции. Второй — стилистическое решение, когда нужно покадровое, «механическое» движение.
<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 для эффекта упругости. Технология следует за метафорой.




