Камера в Mapbox GL JS определяет положение наблюдателя относительно карты и отвечает за отображаемую область, масштаб, наклон и ориентацию. Анимация камеры позволяет плавно изменять эти параметры, создавая эффект перемещения по карте без резких скачков.
Камера управляет следующими характеристиками:
Анимация камеры используется для:
Mapbox GL JS предоставляет несколько способов изменения положения камеры.
Метод выполняет мгновенное перемещение без анимации.
map.jumpTo({
center: [37.6176, 55.7558],
zoom: 12
});
Особенности:
Создаёт плавное перемещение между двумя состояниями камеры.
map.easeTo({
center: [37.6176, 55.7558],
zoom: 12,
duration: 3000
});
Переход выполняется с использованием функции сглаживания, благодаря чему движение выглядит естественно.
Имитирует полёт над картой.
map.flyTo({
center: [37.6176, 55.7558],
zoom: 12
});
В отличие от easeTo(), данный метод изменяет не только
положение, но и траекторию движения камеры, создавая эффект приближения
и удаления во время перелёта.
Автоматически подбирает положение камеры так, чтобы заданная область полностью помещалась в окне карты.
map.fitBounds([
[37.5, 55.7],
[37.8, 55.9]
]);
По умолчанию переход анимируется.
Метод easeTo() является наиболее универсальным
инструментом анимации.
map.easeTo({
center: [30.3141, 59.9386],
duration: 2000
});
Камера плавно переместится к Санкт-Петербургу за две секунды.
map.easeTo({
zoom: 14,
duration: 1500
});
Анимация затрагивает только уровень приближения.
map.easeTo({
center: [30.3141, 59.9386],
zoom: 14,
pitch: 60,
bearing: 45,
duration: 4000
});
В процессе анимации изменяются:
Параметр duration задаётся в миллисекундах.
map.easeTo({
center: [30.3141, 59.9386],
duration: 5000
});
Значение:
1000 = 1 секунда
3000 = 3 секунды
5000 = 5 секунд
Чрезмерно длинные анимации могут ухудшать пользовательский опыт, поэтому обычно используют диапазон от 500 до 3000 миллисекунд.
Mapbox GL JS позволяет настраивать характер движения камеры через
параметр easing.
Функция получает число от 0 до 1 и возвращает преобразованное значение.
Пример линейного движения:
map.easeTo({
center: [37.6176, 55.7558],
duration: 3000,
easing: t => t
});
map.easeTo({
center: [37.6176, 55.7558],
duration: 3000,
easing: t => 1 - Math.pow(1 - t, 3)
});
Визуально камера быстро стартует и плавно останавливается.
map.easeTo({
center: [37.6176, 55.7558],
duration: 3000,
easing: t => {
return t < 0.5
? 4 * t * t * t
: 1 - Math.pow(-2 * t + 2, 3) / 2;
}
});
Подобные кривые часто используются в интерфейсной анимации.
Метод flyTo() реализует кинематографическое перемещение
камеры.
map.flyTo({
center: [37.6176, 55.7558],
zoom: 12
});
Пользователь наблюдает виртуальный перелёт между текущей и целевой точкой.
map.flyTo({
center: [37.6176, 55.7558],
zoom: 15,
pitch: 70
});
Получается эффект пролёта над городом.
map.flyTo({
center: [37.6176, 55.7558],
zoom: 15,
bearing: 180
});
Во время движения карта дополнительно вращается.
Определяет скорость перелёта.
map.flyTo({
center: [37.6176, 55.7558],
speed: 0.8
});
Стандартное значение обычно находится около единицы.
Управляет кривизной траектории.
map.flyTo({
center: [37.6176, 55.7558],
curve: 1.8
});
Чем больше значение, тем более выраженным становится эффект воздушного полёта.
Используется для поддержки системных настроек доступности.
map.flyTo({
center: [37.6176, 55.7558],
essential: true
});
Если анимация критически важна для интерфейса, рекомендуется явно указывать этот параметр.
Трёхмерные сцены особенно выигрышно смотрятся в сочетании с анимацией камеры.
map.easeTo({
pitch: 60,
duration: 2000
});
Наклон постепенно увеличивается до 60 градусов.
map.easeTo({
pitch: 0,
duration: 2000
});
Камера возвращается в классический режим.
map.easeTo({
zoom: 16,
pitch: 75,
duration: 3000
});
Часто применяется для просмотра 3D-зданий.
Параметр bearing задаёт направление взгляда.
map.easeTo({
bearing: 90,
duration: 2000
});
map.easeTo({
bearing: 180,
duration: 3000
});
map.easeTo({
bearing: map.getBearing() + 45,
duration: 1000
});
Каждый вызов поворачивает карту ещё на 45 градусов.
Для создания автоматической анимации используется цикл.
function rotateCamera(timestamp) {
map.rotateTo(
(timestamp / 100) % 360,
{
duration: 0
}
);
requestAnimationFrame(rotateCamera);
}
requestAnimationFrame(rotateCamera);
Применение:
Для вращения существует специализированный метод.
map.rotateTo(180, {
duration: 3000
});
Преимущества:
Для изменения масштаба можно использовать отдельный метод.
map.zoomTo(14, {
duration: 2000
});
Эквивалентно:
map.easeTo({
zoom: 14,
duration: 2000
});
Перемещает карту к новым координатам.
map.panTo(
[37.6176, 55.7558],
{
duration: 2000
}
);
Подходит для случаев, когда требуется изменить только центр карты.
Mapbox GL JS генерирует события в процессе движения камеры.
Срабатывает при начале перемещения.
map.on('movestart', () => {
console.log('Начало движения');
});
Вызывается во время движения.
map.on('move', () => {
console.log(map.getCenter());
});
Используется для синхронизации интерфейса с положением камеры.
Срабатывает после завершения анимации.
map.on('moveend', () => {
console.log('Перемещение завершено');
});
map.on('zoomstart', () => {
console.log('Начало масштабирования');
});
map.on('zoomend', () => {
console.log('Масштабирование завершено');
});
Несколько переходов можно выполнять поочерёдно.
map.flyTo({
center: [37.6176, 55.7558],
zoom: 10,
duration: 3000
});
map.once('moveend', () => {
map.easeTo({
zoom: 15,
pitch: 60,
duration: 2000
});
});
После завершения перелёта начинается вторая анимация.
Распространённый сценарий — автоматический тур по нескольким точкам.
const locations = [
[37.6176, 55.7558],
[30.3141, 59.9386],
[49.1064, 55.7961]
];
let index = 0;
function showNextLocation() {
map.flyTo({
center: locations[index],
zoom: 12,
duration: 4000
});
index = (index + 1) % locations.length;
map.once('moveend', () => {
setTimeout(showNextLocation, 1000);
});
}
showNextLocation();
Подобная схема используется для:
После клика по маркеру камера может автоматически фокусироваться на объекте.
marker.getElement().addEventListener('click', () => {
map.flyTo({
center: marker.getLngLat(),
zoom: 16,
pitch: 60,
duration: 2500
});
});
Такой подход делает навигацию по карте более наглядной.
Метод особенно полезен при отображении нескольких объектов.
const bounds = [
[37.55, 55.70],
[37.75, 55.85]
];
map.fitBounds(bounds, {
padding: 50,
duration: 2000
});
Параметр padding создаёт внутренние отступы между
границами области и краями карты.
Если часть карты перекрывается боковой панелью, используется параметр
padding.
map.easeTo({
center: [37.6176, 55.7558],
padding: {
left: 400,
top: 20,
right: 20,
bottom: 20
},
duration: 2000
});
Карта автоматически смещает объект интереса в видимую область.
Любое новое движение камеры прерывает предыдущее.
map.flyTo({
center: [37.6176, 55.7558],
duration: 10000
});
setTimeout(() => {
map.jumpTo({
center: [30.3141, 59.9386]
});
}, 2000);
Через две секунды выполняется немедленный переход, который прекращает активный перелёт.
Наиболее подходит для:
Наиболее эффективно для:
Оптимальными считаются значения:
300–700 мс — интерфейсные переходы
1000–2500 мс — навигация
3000–5000 мс — презентационные перелёты
Частые вращения, сильный наклон и длинные перелёты способны ухудшать восприятие карты. В рабочих интерфейсах обычно используются умеренные значения:
zoom: 12-16
pitch: 30-60
bearing: 0-45
Такой диапазон обеспечивает хороший баланс между информативностью, производительностью и визуальной привлекательностью анимации камеры в Mapbox GL JS.