В Mapbox GL JS управление картой строится вокруг камеры (camera), которая определяет текущий видимый участок карты: центр, масштаб, наклон и поворот. Плавная анимация перемещения камеры — ключевой механизм для создания интерактивных интерфейсов, навигационных систем и визуализаций данных, где резкие скачки ухудшают восприятие.
Библиотека предоставляет несколько встроенных способов плавного перемещения, каждый из которых имеет собственную модель интерполяции и сценарии применения.
flyTo — «перелёт» к
точкеМетод flyTo реализует анимацию с эффектом полёта по
дуге, имитируя перемещение камеры в трёхмерном пространстве.
map.flyTo({
center: [37.6173, 55.7558],
zoom: 12,
speed: 1.2,
curve: 1.42,
essential: true
});
Ключевые параметры:
flyTo подходит для навигационных переходов между
удалёнными точками, когда важно показать контекст перемещения.
easeTo —
плавная линейная интерполяцияМетод easeTo используется для мягкого изменения
параметров камеры без выраженной «дуги».
map.easeTo({
center: [37.6173, 55.7558],
zoom: 10,
duration: 1500,
easing: (t) => t
});
Основные параметры:
В отличие от flyTo, здесь поведение полностью
определяется функцией easing, что позволяет точно контролировать
динамику движения.
Пример более естественного ускорения и замедления:
map.easeTo({
center: [37.6173, 55.7558],
zoom: 13,
duration: 2000,
easing: (t) => t * (2 - t)
});
jumpTo — мгновенное
перемещениеМетод jumpTo полностью отключает анимацию и моментально
устанавливает состояние камеры:
map.jumpTo({
center: [37.6173, 55.7558],
zoom: 8
});
Используется в ситуациях, где анимация не требуется или может мешать:
Плавная анимация в Mapbox GL JS охватывает не только центр и масштаб, но и пространственные характеристики сцены.
map.easeTo({
zoom: 14,
duration: 1200
});
Изменение масштаба влияет на восприятие плотности данных. При анимации zoom важно учитывать, что каждый уровень масштаба пересчитывает тайлы и может вызывать нагрузку на рендер.
map.easeTo({
bearing: 90,
duration: 2000
});
Поворот используется для ориентации по направлению движения или выравнивания карты под интерфейс.
map.easeTo({
pitch: 60,
duration: 2000
});
Наклон активирует перспективную проекцию и часто используется в 3D-визуализациях зданий.
Функция easing определяет характер изменения параметров во времени. Она принимает нормализованное значение t ∈ [0, 1] и возвращает преобразованное значение.
Типовые варианты:
Линейная интерполяция:
t => t
Ускорение:
t => t * t
Замедление:
t => 1 - Math.pow(1 - t, 3)
Комбинированная кривая:
t => t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2
Эти функции напрямую влияют на ощущение «плавности» движения камеры.
Любое новое изменение камеры автоматически прерывает текущую анимацию. Это поведение важно учитывать при построении сложных интерфейсов.
map.flyTo({ center: [30, 50], zoom: 5 });
map.easeTo({ center: [40, 60], zoom: 6 });
В этом случае второй вызов отменяет первый.
Для контроля состояния можно использовать события:
map.on('moveend', () => {
console.log('Анимация завершена');
});
Также доступны события:
movestartmovemoveendzoomstartzoomendПомимо встроенных методов, возможна реализация собственной системы анимации с использованием низкоуровневого управления камерой.
Основой служит метод map.setCenter,
map.setZoom, вызываемые в цикле:
function animateTo(targetLng, targetLat, duration) {
const start = performance.now();
const startCenter = map.getCenter();
function frame(time) {
const t = (time - start) / duration;
if (t >= 1) {
map.setCenter([targetLng, targetLat]);
return;
}
const lng = startCenter.lng + (targetLng - startCenter.lng) * t;
const lat = startCenter.lat + (targetLat - startCenter.lat) * t;
map.setCenter([lng, lat]);
requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
}
Такой подход позволяет реализовать кастомные кривые движения, синхронизацию с внешними системами и сложные сценарии анимации.
Географические координаты требуют аккуратной интерполяции. Простое линейное смешивание допустимо для небольших расстояний, но при глобальных перемещениях возникает искажение.
Mapbox GL JS использует сферическую интерполяцию через Mercator-проекцию внутри движка, однако при кастомной реализации часто применяют:
function interpolate(a, b, t) {
return a + (b - a) * t;
}
Для более точной географической интерполяции используется переход через проекцию:
const start = map.project([lng1, lat1]);
const end = map.project([lng2, lat2]);
const x = start.x + (end.x - start.x) * t;
const y = start.y + (end.y - start.y) * t;
const lngLat = map.unproject([x, y]);
map.setCenter(lngLat);
Плавное перемещение камеры часто используется совместно с динамическими слоями данных. В таких случаях важно учитывать частоту перерисовки карты.
map.on('move', () => {
const center = map.getCenter();
updateData(center);
});
Чрезмерная нагрузка в обработчиках move может приводить
к падению производительности, поэтому вычисления обычно
ограничиваются:
let ticking = false;
map.on('move', () => {
if (!ticking) {
requestAnimationFrame(() => {
const center = map.getCenter();
updateData(center);
ticking = false;
});
ticking = true;
}
});
При построении интерфейсов с несколькими режимами отображения часто требуется переход между заранее заданными состояниями камеры.
const states = {
city: { center: [37.6, 55.7], zoom: 12 },
country: { center: [100, 60], zoom: 3 }
};
function goToState(name) {
map.easeTo({
...states[name],
duration: 1800
});
}
Такая архитектура упрощает управление сложными сценариями навигации.
Пользователь может вмешиваться в процесс анимации, изменяя карту вручную. Это поведение по умолчанию прерывает текущую анимацию.
Для ограничения взаимодействия можно временно отключить управление:
map.scrollZoom.disable();
map.dragPan.disable();
После завершения анимации управление восстанавливается:
map.once('moveend', () => {
map.scrollZoom.enable();
map.dragPan.enable();
});
Качество анимации зависит от сочетания нескольких параметров:
duration — слишком короткое значение создаёт резкие
скачкиzoom — большие изменения масштаба требуют более высокой
длительностиcurve в flyTo — влияет на траекторию
движенияeasing — определяет субъективное восприятие
плавностиКомбинация этих параметров позволяет адаптировать поведение карты под конкретный интерфейс: от навигационных систем до аналитических панелей и сторителлинговых визуализаций.