Синтаксис описания кривых

Кривые в mo.js используются как математическое описание изменения значения параметра во времени или как траектория движения объекта в пространстве. В основе лежат функции интерполяции (easing) и SVG-подобные пути, задающие непрерывные линии различной сложности.

Любая кривая в контексте mo.js интерпретируется как функция отображения времени:

t ∈ [0, 1] → value

где:

  • t — нормализованное время анимации
  • value — вычисленное значение свойства (позиции, масштаба, прозрачности и т.д.)

Такое представление позволяет унифицировать различные типы кривых: от простых линейных интерполяций до сложных траекторий Безье и SVG-path.

Кубические кривые Безье

Основной математический инструмент описания плавных кривых — кубическая кривая Безье. Она задаётся четырьмя точками:

P0 — начальная точка P1, P2 — контрольные точки P3 — конечная точка

Функция имеет вид:

B(t) = (1-t)^3 P_0 + 3(1-t)^2 t P_1 + 3(1-t)t^2 P_2 + t^3 P_3

В mo.js для easing-логики обычно фиксируются крайние точки:

  • P0 = (0, 0)
  • P3 = (1, 1)

Остаются только управляющие коэффициенты P1 и P2.

Синтаксис cubicBezier

В mo.js кастомная кривая ускорения задаётся через:

mojs.easing.cubicBezier(x1, y1, x2, y2)

где:

  • (x1, y1) — первая контрольная точка
  • (x2, y2) — вторая контрольная точка

Пример:

const customEasing = mojs.easing.cubicBezier(0.25, 0.1, 0.25, 1);

new mojs.Tween({
  duration: 1000,
  easing: customEasing,
  onUpdate: (p) => {
    console.log(p);
  }
}).play();

Значения координат ограничиваются диапазоном [0, 1], что обеспечивает стабильную нормализацию времени и предсказуемую интерполяцию.

Предустановленные функции сглаживания

Встроенные кривые представлены как набор заранее определённых функций:

  • linear
  • quad.in / quad.out / quad.inout
  • cubic.in / cubic.out / cubic.inout
  • quart.in / quart.out
  • bounce.out
  • elastic.out

Их синтаксис:

easing: 'cubic.out'

Структура строки:

  • первая часть — тип кривой
  • вторая часть — режим интерполяции

Режимы:

  • in — ускорение от нуля
  • out — замедление к завершению
  • inout — комбинированная кривая

SVG path как универсальная кривая

Более сложный способ задания траекторий основан на SVG path синтаксисе. В mo.js он используется для описания движения объектов вдоль произвольных линий.

Пример:

path: 'M 0 0 C 100 200, 200 0, 300 100'

Основные команды path

  • M x y — перемещение без рисования
  • L x y — линейное соединение
  • C x1 y1, x2 y2, x y — кубическая кривая Безье
  • Q x1 y1, x y — квадратичная кривая
  • Z — замыкание контура

Каждая команда формирует сегмент общей кривой, которая затем параметризуется по длине.

Привязка движения к пути

В mo.js движение вдоль кривой реализуется через модуль MotionPath:

new mojs.Shape({
  shape: 'circle',
  motionPath: {
    path: 'M 0 0 C 50 100, 150 100, 200 0',
    align: true,
    autoRotate: true
  }
}).play();

Параметры:

  • path — SVG-описание кривой
  • align — выравнивание объекта по касательной
  • autoRotate — автоматический поворот по направлению движения

Нормализация длины пути

При работе с SVG path используется преобразование координаты времени t в расстояние вдоль кривой:

s = t × L

где:

  • L — общая длина кривой
  • s — текущая позиция вдоль пути

Далее происходит обратное преобразование в координаты (x, y) через интерполяцию сегментов.

Кривые в timeline и композиции анимаций

При использовании timeline каждый tween получает собственную кривую интерполяции, но синхронизируется по общей временной оси.

new mojs.Timeline({
  children: [
    new mojs.Tween({
      duration: 600,
      easing: 'quad.out'
    }),
    new mojs.Tween({
      duration: 600,
      easing: mojs.easing.cubicBezier(0.42, 0, 0.58, 1)
    })
  ]
}).play();

Кривые в этом контексте управляют не только значением, но и характером синхронизации элементов внутри общей анимационной системы.

Кастомные функции интерполяции

Помимо Bezier и SVG-path допускается использование произвольных функций:

easing: (t) => Math.sin(t * Math.PI)

Такая функция должна:

  • принимать t ∈ [0, 1]
  • возвращать нормализованное значение
  • быть непрерывной для избежания рывков анимации

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

Дискретизация и вычислительная модель

При рендеринге кривая разбивается на набор дискретных шагов кадровой частоты. Каждый кадр вычисляется отдельно:

valueₙ = f(tₙ)

где tₙ = n / N

При увеличении N возрастает точность аппроксимации, но повышается вычислительная нагрузка.

Особенности комбинирования кривых

При наложении нескольких easing-кривых применяется последовательная композиция:

f(g(t))

где:

  • g(t) — временная трансформация
  • f(t) — интерполяция значения

Такой подход используется при сложных анимациях, где движение и изменение параметров подчинены разным законам кривизны.

Геометрическая интерпретация

Каждая кривая может рассматриваться как отображение единичного интервала на плоскость или в одномерное пространство параметра. В случае SVG-path это становится отображением:

[0,1] → ℝ²

В случае easing:

[0,1] → [0,1]

что обеспечивает совместимость всех типов кривых внутри единой системы mo.js.