Velocity.js реализует систему easing как фундаментальный механизм управления динамикой анимации. Easing определяет характер изменения значений во времени: скорость ускорения, замедления, наличие колебаний и степень плавности переходов между состояниями.
В основе лежит функция времени t, нормализованная в
диапазоне от 0 до 1, где:
0 — начало анимации1 — завершение анимацииEasing-функция преобразует это значение в кривую, определяющую фактическое изменение свойства.
Любая easing-функция в Velocity.js описывается как преобразование:
f(t) → t'
где:
t — линейный прогресс времениt' — скорректированный прогресс с нелинейной
динамикойЛинейная анимация:
t' = t
Easing вводит нелинейность:
t' = t²
t' = √t
t' = sin(t · π / 2)
Такие преобразования позволяют моделировать физически правдоподобное движение.
Самая простая форма:
linear: t
Характеристика:
Используется для технических индикаторов, прогресс-баров без акцента на UX.
Классические easing-функции:
easeInQuad: t²
easeOutQuad: t(2 - t)
easeInOutQuad: 2t² (t < 0.5)
Поведение:
Кубические варианты усиливают эффект:
easeInCubic: t³
easeOutCubic: (t - 1)³ + 1
Экспоненциальное поведение создаёт резкие изменения скорости:
easeInExpo: 2^(10(t - 1))
easeOutExpo: 1 - 2^(-10t)
Особенности:
Основаны на тригонометрии:
easeInSine: 1 - cos(t · π/2)
easeOutSine: sin(t · π/2)
Характер:
Velocity.js поддерживает easing в нескольких формах:
Velocity(element, { opacity: 1 }, { duration: 800, easing: "easeInOutQuad" });
Строка указывает на встроенную функцию.
Velocity.js поддерживает расширенные модели:
easing: [0.25, 0.1, 0.25, 1.0]
Это cubic-bezier кривая:
cubic-bezier(x1, y1, x2, y2)
Параметры:
Такая модель позволяет задавать произвольные траектории ускорения.
Поддерживается передача функции:
easing: function (t) {
return t * t * (3 - 2 * t);
}
Функция получает нормализованное время и возвращает преобразованное значение.
Типичная сигнатура:
f(t: number) → number
Ограничение:
[0, 1] для корректной
интерполяцииVelocity.js применяет easing на этапе вычисления промежуточных кадров.
Процесс:
Вычисляется прогресс анимации:
t = elapsed / durationПрименяется easing-функция:
t' = easing(t)Интерполяция свойств:
value = start + (end - start) · t'Для числовых свойств применяется линейная интерполяция, для цветов — компонентная.
Для свойства opacity:
start = 0
end = 1
При easeOutQuad:
t' = t(2 - t)
Итог:
opacity = 0 + (1 - 0) · t'
Для координат:
x = x0 + (x1 - x0) · t'
y = y0 + (y1 - y0) · t'
Модель cubic-bezier лежит в основе большинства современных easing-кривых.
Форма:
B(t) = (1 - t)^3·P0 + 3(1 - t)^2·t·P1 + 3(1 - t)·t^2·P2 + t^3·P3
Где:
Velocity.js использует упрощённую интерпретацию для расчёта прогресса по оси Y.
slow start → fast end
Примеры:
Используется для появления элементов из состояния покоя.
fast start → slow end
Примеры:
Применяется для завершения движения и фиксации объектов.
slow start → fast middle → slow end
Примеры:
Оптимален для UI-переходов.
Расширенные сценарии включают создание составных функций.
function easeSoft(t) {
return Math.min(1, t * 1.2);
}
function easeSpring(t) {
return 1 - Math.exp(-6 * t) * Math.cos(12 * t);
}
Поведение:
function easeElastic(t) {
return Math.pow(2, -10 * t) * Math.sin((t - 0.1) * 5 * Math.PI);
}
t' < 0 или t' > 1
Приводит к:
Если:
t = elapsed / duration
не ограничивается:
t ∈ [0, 1]
возникает некорректная интерполяция.
Резкие кривые:
создают визуальный диссонанс при длительных анимациях.
Easing вызывается на каждый кадр анимации.
При 60 FPS:
60 вызовов в секунду на одно свойство
При множественных анимациях:
N × 60 вычислений
Поэтому:
| Тип | Характер | Интенсивность |
|---|---|---|
| Linear | равномерное движение | низкая |
| Quad | мягкое ускорение | средняя |
| Cubic | выраженная динамика | высокая |
| Expo | резкие изменения | очень высокая |
| Sine | плавность | низкая |
Easing является промежуточным слоем между временем и визуальным состоянием. Он отделяет:
Такое разделение позволяет: