Easing функции

Easing-функции определяют характер изменения анимации во времени при переходах камеры, изменении свойств слоёв и любых интерполяциях, выполняемых библиотекой. В контексте Mapbox GL JS easing — это математическая функция, принимающая нормализованное время t в диапазоне от 0 до 1 и возвращающая модифицированное значение прогресса анимации.

Фактически easing управляет тем, как именно происходит движение между начальным и конечным состоянием: равномерно, ускоряясь, замедляясь или комбинируя несколько фаз.


Базовая модель интерполяции

Любая анимация в Mapbox GL JS сводится к интерполяции параметров:

  • координаты центра карты
  • zoom
  • bearing
  • pitch
  • свойства слоёв (color, opacity, width и др.)

Общий принцип:

result = start + (end - start) * f(t)

где:

  • t — линейный прогресс от 0 до 1
  • f(t) — easing-функция
  • result — текущее значение параметра

При отсутствии easing используется линейная функция:

f(t) = t

Формат easing-функций

В Mapbox GL JS easing задаётся как функция:

easing: function (t) {
    return t;
}

или в виде стрелочной функции:

easing: t => t

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

  • принимать число t в диапазоне [0, 1]
  • возвращать число (обычно тоже в диапазоне [0, 1], но допускаются нелинейные формы)

Применение easing в анимации камеры

easeTo

Метод easeTo использует easing для плавного изменения параметров камеры:

map.easeTo({
    center: [30.5, 50.5],
    zoom: 10,
    duration: 2000,
    easing: t => t
});

Особенности:

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

flyTo

Метод flyTo использует easing для имитации «полёта» камеры:

map.flyTo({
    center: [30.5, 50.5],
    zoom: 12,
    speed: 1.2,
    curve: 1.5
});

Хотя flyTo не всегда принимает пользовательский easing напрямую, его поведение основано на встроенной кривой, близкой к экспоненциальному замедлению.

Типичная характеристика:

  • ускорение в начале
  • плавное замедление при приближении к цели
  • более «физическая» траектория движения

Типовые easing-функции

Линейная функция

t => t

Характеристики:

  • постоянная скорость
  • отсутствует ускорение
  • используется как базовый эталон

Ease-in (ускорение)

t => t * t

Поведение:

  • медленный старт
  • постепенное ускорение
  • резкое завершение

Применяется для акцентирования начала движения.


Ease-out (замедление)

t => 1 - Math.pow(1 - t, 2)

Поведение:

  • быстрое начало
  • постепенное замедление
  • мягкое завершение

Часто используется в навигации карты.


Ease-in-out (комбинированная кривая)

t => t < 0.5
    ? 2 * t * t
    : 1 - Math.pow(-2 * t + 2, 2) / 2

Характеристики:

  • плавный старт
  • ускорение в середине
  • замедление в конце

Одна из наиболее универсальных кривых для интерфейсов.


Easing в анимации слоёв

Mapbox GL JS позволяет задавать переходы свойств слоёв через transition, где easing влияет на изменение визуальных параметров.

Пример:

map.setPaintProperty('water-layer', 'fill-opacity', 0.8);

map.setPaintProperty('water-layer', 'fill-opacity-transition', {
    duration: 1500,
    delay: 0
});

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


Пользовательские easing-функции

Mapbox GL JS позволяет задавать произвольные кривые, что даёт полный контроль над анимацией.

Пример синусоидального easing

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

Поведение:

  • мягкое начало
  • плавное ускорение
  • естественное замедление

Пример «пружинного» эффекта

easing: t => {
    return Math.pow(2, -10 * t) * Math.sin((t - 0.3) * 5 * Math.PI) + 1;
}

Особенности:

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

Влияние easing на UX карты

Easing напрямую влияет на восприятие пространственных переходов:

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

В картографических интерфейсах это особенно важно, так как камера заменяет физическое перемещение пользователя по пространству.


Взаимодействие easing с параметром duration

Easing-функция всегда работает совместно с длительностью анимации:

  • duration определяет общий временной интервал
  • easing распределяет прогресс внутри этого интервала

Пример:

map.easeTo({
    center: [10, 40],
    zoom: 5,
    duration: 3000,
    easing: t => 1 - Math.pow(1 - t, 3)
});

При одинаковом duration разные easing-функции создают полностью различное ощущение скорости.


Использование easing в последовательных анимациях

При цепочках переходов важно учитывать накопление визуального эффекта:

map.easeTo({
    center: [0, 0],
    zoom: 3,
    duration: 1000,
    easing: t => t
});

setTimeout(() => {
    map.easeTo({
        center: [30, 50],
        zoom: 8,
        duration: 1500,
        easing: t => 1 - Math.pow(1 - t, 2)
    });
}, 1100);

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


Ограничения и особенности вычислений

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

Оптимальная реализация — простые математические выражения без побочных эффектов.


Практическая роль easing в архитектуре Mapbox GL JS

Easing является частью более широкой системы интерполяции, включающей:

  • camera animations
  • style transitions
  • layout recalculation
  • WebGL рендеринг кадра

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