В Mapbox GL JS управление масштабом карты реализовано через встроенный контрол навигации, который предоставляет пользователю стандартные кнопки увеличения и уменьшения масштаба. Эти элементы являются частью компонента NavigationControl и тесно связаны с состоянием камеры карты.
Zoom-кнопки воздействуют на свойство zoom объекта карты, изменяя уровень детализации тайлов. При увеличении значения zoom карта показывает более детализированную географическую информацию, при уменьшении — агрегированные данные.
Базовая интеграция осуществляется через NavigationControl:
import mapboxgl from 'mapbox-gl';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v12',
center: [37.6173, 55.7558],
zoom: 10
});
map.addControl(new mapboxgl.NavigationControl());
NavigationControl по умолчанию включает:
Контроллер позволяет гибко управлять видимостью отдельных элементов:
map.addControl(new mapboxgl.NavigationControl({
showZoom: true,
showCompass: false
}));
При отключении showZoom управление масштабом остаётся доступным через:
Каждое нажатие изменяет масштаб на фиксированную величину, зависящую от конфигурации карты и текущего zoom:
Фактическая анимация выполняется плавно, с использованием интерполяции камеры.
Компас в NavigationControl отвечает за управление bearing — углом поворота карты относительно севера.
В Mapbox GL JS поворот карты — это часть камеры, а не слоя, что позволяет изменять ориентацию без пересчёта данных.
map.addControl(new mapboxgl.NavigationControl({
showCompass: true
}));
Компас отображается только при наличии ненулевого угла поворота. Если карта ориентирована на север (bearing = 0), элемент может быть скрыт или отображаться в неактивном состоянии.
Кнопка компаса выполняет reset bearing:
map.resetNorth();
или через API камеры:
map.easeTo({
bearing: 0,
pitch: 0
});
Сброс сопровождается анимацией, возвращающей карту в стандартную ориентацию.
Zoom и rotation в Mapbox GL JS работают независимо, но оба влияют на восприятие карты пользователем:
Комбинация этих параметров формирует камеру WebGL-сцены, которая перерисовывается в реальном времени.
Пример комбинированного управления:
map.easeTo({
zoom: 14,
bearing: 45,
pitch: 60,
duration: 2000
});
Хотя zoom-кнопки являются UI-элементами, их функциональность полностью дублируется API:
map.zoomIn();
map.zoomOut();
Существует также контроль перехода к конкретному уровню:
map.setZoom(12);
Эти методы позволяют синхронизировать внешние интерфейсы с состоянием карты.
Для отслеживания взаимодействий используются события карты:
map.on('zoom', () => {
console.log(map.getZoom());
});
map.on('zoomend', () => {
console.log('zoom завершён');
});
map.on('rotate', () => {
console.log(map.getBearing());
});
События позволяют:
NavigationControl можно размещать в любом углу контейнера:
map.addControl(
new mapboxgl.NavigationControl(),
'top-right'
);
Доступные позиции:
Выбор позиции влияет на UX в зависимости от плотности интерфейса.
Стилизация zoom-кнопок возможна через CSS:
.mapboxgl-ctrl button {
width: 36px;
height: 36px;
border-radius: 6px;
}
.mapboxgl-ctrl-zoom-in,
.mapboxgl-ctrl-zoom-out {
font-size: 18px;
}
В Mapbox экосистеме контролы построены на стандартной DOM-структуре, что позволяет переопределять стили без вмешательства в логику.
На мобильных устройствах zoom-кнопки часто считаются вспомогательными, поскольку основной способ управления — жесты:
NavigationControl при этом может быть упрощён или полностью скрыт, чтобы не дублировать естественные жесты.
NavigationControl можно комбинировать с пользовательскими элементами управления:
class CustomZoomControl {
onAdd(map) {
this.map = map;
this.container = document.createElement('div');
const btn = document.createElement('button');
btn.textContent = '+';
btn.oncl ick = () => map.zoomIn();
this.container.appendChild(btn);
return this.container;
}
onRemove() {
this.container.parentNode.removeChild(this.container);
this.map = undefined;
}
}
map.addControl(new CustomZoomControl());
Такая схема позволяет полностью заменить стандартный UI, сохраняя API-совместимость.
Zoom-кнопки поддерживают базовые принципы accessibility:
При разработке интерфейсов важно сохранять семантику кнопок, иначе нарушается взаимодействие с вспомогательными технологиями.
Zoom-кнопки подчиняются ограничениям карты:
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v12',
minZoom: 5,
maxZoom: 18
});
Даже при многократных кликах выход за пределы диапазона невозможен, что предотвращает некорректную загрузку тайлов и перегрузку WebGL-контекста.