Easing в mo.js задаётся как функция распределения времени, которая преобразует линейный прогресс анимации в нелинейное движение. В контексте сложных анимаций ключевым становится не только выбор одной функции смягчения, но и разбиение кривой времени на участки, где каждый сегмент обладает собственной динамикой ускорения и замедления.
В основе лежит трансформация параметра времени
t ∈ [0, 1], который подаётся на вход easing-функции и
преобразуется в значение прогресса анимации:
f(t) = tВ mo.js easing может задаваться:
"quad.in",
"cubic.out", "expo.inout")[x1, y1, x2, y2]Ключевой особенностью является то, что easing применяется на уровне конкретного tween или сегмента timeline, а не глобально.
При построении сложной анимации единый easing часто оказывается недостаточным. Поведение объекта требуется менять по фазам:
Это достигается разбиением анимации на несколько участков, каждый из которых представляет собой независимый tween с собственным easing.
Пример логического разбиения:
0.0 ──── 0.3 ──── 0.7 ──── 1.0
A B C
Где:
В mo.js timeline позволяет комбинировать несколько tween-объектов, каждый из которых имеет собственную временную длительность и easing:
const timeline = new mojs.Timeline();
const tweenA = new mojs.Tween({
duration: 300,
easing: 'quad.out'
});
const tweenB = new mojs.Tween({
duration: 500,
easing: 'linear'
});
const tweenC = new mojs.Tween({
duration: 200,
easing: 'expo.in'
});
timeline.add(tweenA, tweenB, tweenC);
timeline.play();
Каждый tween здесь формирует отдельный сегмент общей временной кривой. В результате итоговая функция движения становится кусочно-заданной.
С точки зрения математической модели каждый сегмент представляет собой функцию:
F(t) = Fi(t), t ∈ [ti, ti+1]
где:
Fi — easing-функция конкретного сегментаti задают разбиение timelineТакое представление позволяет строить сложные траектории поведения без необходимости создавать одну глобальную сложную кривую Безье.
Большинство easing-функций в mo.js сводятся к кубической кривой Безье:
easing: [0.25, 0.1, 0.25, 1.0]
Каждая такая кривая задаёт характер ускорения:
При сегментации кривой важно учитывать, что разные части анимации могут использовать разные параметры Безье, формируя композицию разных динамических режимов.
При переходе между сегментами возникает задача согласования значений:
Это приводит к эффектам:
Для минимизации используются два подхода:
Сложные анимации часто используют каскадную модель:
segment 1 → ease-out
segment 2 → ease-in-out
segment 3 → ease-in
Такая последовательность создаёт эффект естественного физического движения: объект сначала получает импульс, затем движется по инерции, затем тормозит.
В mo.js shape-анимациях easing может управлять не только позицией, но и параметрами формы:
const shape = new mojs.Shape({
shape: 'circle',
radius: { 0: 80 },
duration: 1000,
easing: 'cubic.out'
});
При разбиении на сегменты можно независимо управлять:
Каждое свойство может иметь собственную сегментную кривую времени, что приводит к многомерному easing-пространству.
При анимации нескольких свойств возникает задача согласования временных функций:
expo.inback.outlinearНесовпадение сегментов создаёт асинхронное поведение, которое может быть как художественным приёмом, так и ошибкой композиции.
Для строгой синхронизации используется:
Разбиение easing на участки позволяет моделировать физические процессы:
Типичная модель:
quad.inlinearcubic.outТакое разделение создаёт ощущение массы и инерции без использования физического движка.
При движении по кривой (motion path) easing управляет не геометрией пути, а параметром прогресса вдоль него:
progress → easing(progress) → position on path
Сегментация здесь позволяет:
При проектировании сложной анимации применяется декомпозиция:
Типовой шаблон:
const t1 = new mojs.Tween({ duration: 200, easing: 'quad.out' });
const t2 = new mojs.Tween({ duration: 600, easing: 'linear' });
const t3 = new mojs.Tween({ duration: 300, easing: 'expo.in' });
new mojs.Timeline().add(t1, t2, t3).play();
Такой подход превращает easing из локальной функции в структурный элемент архитектуры анимации.
Между tween-сегментами могут присутствовать паузы, которые влияют на восприятие кривой времени:
Комбинация delay и easing используется для имитации:
Сложные интерфейсные анимации используют несколько уровней сегментации:
В результате формируется иерархическая модель:
timeline
├── segment A (ease-out)
├── segment B (ease-in-out)
│ ├── opacity easing
│ ├── transform easing
└── segment C (ease-in)
Такая структура позволяет управлять не только движением, но и поведением всей сцены как системы.