Path-based easing

Path-based easing в mo.js основан на использовании SVG-пути как функции изменения прогресса анимации, где движение по кривой интерпретируется как временная кривая ускорения. В отличие от классических easing-функций (linear, ease-in, ease-out), здесь поведение анимации определяется геометрией произвольного пути, что позволяет задавать практически неограниченные нелинейные кривые изменения скорости.

Каждый easing в mo.js можно представить как отображение времени t ∈ [0, 1] в значение прогресса p ∈ [0, 1]. В path-based подходе эта функция заменяется траекторией в двумерном пространстве, где:

  • ось X соответствует нормализованному времени
  • ось Y соответствует значению прогресса анимации

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

Кривая интерпретируется как набор сегментов SVG path (M, L, C, Q и другие), но для easing используется дискретизация: путь преобразуется в последовательность точек, после чего строится функция интерполяции.

Принцип дискретизации SVG-пути

SVG-path не является функцией в аналитическом смысле, поэтому mo.js выполняет предварительную обработку:

  1. Разворачивание команд пути в плотный набор точек
  2. Нормализация координат в диапазон [0, 1]
  3. Приведение длины пути к равномерному шагу по оси X
  4. Построение lookup-таблицы значений Y для каждого X

В результате формируется массив вида:

  • t0 → p0
  • t1 → p1
  • t2 → p2

где t — нормализованное время, p — прогресс анимации.

Интерполяция значений

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

p(t) = p_i + (p_{i+1} - p_i) * (t - t_i) / (t_{i+1} - t_i)

p(t)=p_i + (p_{i+1}-p_i)

Такая схема обеспечивает стабильное поведение даже при сложных кривых с множественными перегибами.

Использование SVG path как easing-кривой

mo.js позволяет передавать SVG path напрямую в качестве easing-функции. Классический пример включает кривую Безье, преобразованную в путь:

  • M 0 0
  • C 0.25 0.1, 0.25 1, 1 1

Такая форма создаёт ускорение в начале и плавное замедление к концу.

При этом важно учитывать, что координаты должны быть нормализованы: X и Y в диапазоне [0, 1], иначе происходит обрезка или некорректная интерпретация прогресса.

Внутренняя структура path-easing

Внутри mo.js easing на основе пути обычно включает три слоя:

  • Parser SVG path
  • Sampler (генерация точек)
  • Interpolator (вычисление значения по времени)

Parser отвечает за преобразование строки path в команды. Sampler преобразует команды в массив точек с фиксированным шагом. Interpolator работает на этапе выполнения анимации и возвращает значение прогресса по входному времени.

Такой подход разделяет вычислительно тяжёлую часть (парсинг и семплирование) от runtime-логики.

Нормализация координат

Любой путь приводится к единичному квадрату. Это критично, поскольку easing-функция должна быть инвариантна к масштабу.

Пусть исходные координаты точки:

(x, y)

После нормализации:

x’ = (x - x_min) / (x_max - x_min) y’ = (y - y_min) / (y_max - y_min)

x’ = , y’ =

Это позволяет гарантировать, что easing всегда укладывается в диапазон от 0 до 1.

Особенности поведения сложных кривых

Path-based easing поддерживает кривые с:

  • несколькими локальными максимумами
  • участками отрицательной скорости (визуально — «откат»)
  • резкими изменениями наклона

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

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

Связь с временной функцией анимации

В традиционной модели easing время линейно отображается в прогресс:

p = f(t)

В path-based модели функция f(t) задаётся геометрически, но семантически остаётся той же трансформацией временной оси. Это позволяет интегрировать path-easing в любые tween-системы mo.js без изменения основного цикла анимации.

Практическая интерпретация в анимациях

Использование path-based easing особенно заметно в:

  • масштабировании объектов с «инерцией»
  • появлении элементов с overshoot-эффектом
  • сложных морфинг-анимациях
  • синхронизации нескольких объектов с разной динамикой

Каждый из этих эффектов достигается не изменением ключевых кадров, а изменением формы кривой.

Аппроксимация кривых Безье

Хотя SVG path может содержать кривые Безье, для easing они всегда приводятся к полилинии. При этом каждая кубическая кривая C разбивается на набор линейных сегментов с контролируемой погрешностью.

Чем выше число сегментов, тем ближе поведение easing к исходной кривой Безье.

Производительность и кеширование

Поскольку построение path-easing может быть дорогостоящим, mo.js обычно выполняет:

  • кеширование обработанных кривых
  • переиспользование lookup-таблиц
  • предварительную нормализацию при инициализации tween

Это снижает нагрузку в runtime, оставляя только O(1) доступ к значениям прогресса.

Ограничения подхода

Несмотря на гибкость, path-based easing имеет ограничения:

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

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

Поведение на границах интервала

Особое внимание уделяется участкам t = 0 и t = 1. В этих точках easing обязан возвращать строго 0 и 1 соответственно. При некорректной нормализации пути возможно смещение границ, поэтому применяется принудительное закрепление крайних значений.

Такой подход гарантирует согласованность с системой tween-движка и предотвращает визуальные «дрожания» на старте и конце анимации.