В Mapbox GL JS контролы представляют собой готовые элементы пользовательского интерфейса, которые добавляются прямо на карту и обеспечивают стандартные функции взаимодействия: навигацию, поиск, геолокацию, масштабирование, отображение атрибуции и переключение стилей. Контролы реализованы как независимые компоненты, подключаемые через API карты и работающие поверх WebGL-рендера.
Архитектура контролов унифицирована: каждый контрол реализует
минимальный интерфейс с методами onAdd(map) и
onRemove(), что позволяет интегрировать как встроенные, так
и кастомные элементы управления.
Контролы подключаются через метод:
map.addControl(control, position);
Где control — объект, реализующий интерфейс контроля, а
position задаёт расположение на карте:
top-lefttop-rightbottom-leftbottom-rightПример добавления стандартного управления навигацией:
map.addControl(new mapboxgl.NavigationControl(), 'top-right');
Каждый контрол автоматически помещается в контейнер карты и получает
доступ к экземпляру map.
Контрол навигации обеспечивает базовые функции управления картой:
map.addControl(new mapboxgl.NavigationControl());
Контрол можно настроить:
const nav = new mapboxgl.NavigationControl({
showZoom: true,
showCompass: true,
visualizePitch: true
});
map.addControl(nav);
showZoom отвечает за кнопки масштабирования, showCompass включает вращение и сброс направления, visualizePitch отображает управление наклоном.
Контрол геолокации позволяет получать текущее местоположение пользователя и отслеживать его перемещение.
map.addControl(new mapboxgl.GeolocateControl({
positionOptions: {
enableHighAccuracy: true
},
trackUserLocation: true
}));
Контрол поддерживает два основных режима:
geolocatetrackuserlocationstarttrackuserlocationenderrorconst geolocate = new mapboxgl.GeolocateControl();
geolocate.on('geolocate', (e) => {
console.log(e.coords.latitude, e.coords.longitude);
});
Контрол полноэкранного режима переключает контейнер карты в fullscreen.
map.addControl(new mapboxgl.FullscreenControl());
Контрол не требует дополнительной конфигурации и работает в стандартной реализации.
Контрол масштаба отображает линейку расстояний в выбранных единицах измерения.
map.addControl(new mapboxgl.ScaleControl({
maxWidth: 120,
unit: 'metric'
}));
metric — метры и километрыimperial — футы и милиnautical — морские милиМасштаб автоматически пересчитывается при:
Контрол атрибуции отображает обязательные ссылки на источники данных карты.
map.addControl(new mapboxgl.AttributionControl({
compact: true
}));
Контрол является обязательным в большинстве случаев использования Mapbox GL JS, так как обеспечивает соблюдение лицензии данных.
Контрол логотипа отображает брендинг Mapbox в интерфейсе карты.
map.addControl(new mapboxgl.LogoControl());
В современных версиях SDK его поведение ограничено условиями лицензирования, и он часто интегрирован в AttributionControl.
ScaleControl использует геодезические вычисления для отображения реальных расстояний на плоскости Web Mercator. Пересчёт происходит при каждом изменении состояния камеры карты.
Модель вычисления учитывает:
Это обеспечивает корректность отображения масштаба на разных широтах, где искажения карты различаются.
Контролы группируются в контейнеры DOM в зависимости от позиции:
top-left
top-right
bottom-left
bottom-right
Каждый контейнер представляет собой независимый стек элементов. Порядок добавления контролов внутри одного контейнера определяет их вертикальное расположение.
map.addControl(new mapboxgl.NavigationControl(), 'top-right');
map.addControl(new mapboxgl.FullscreenControl(), 'top-right');
В этом случае fullscreen-контрол окажется ниже навигационного.
Любой контрол можно удалить динамически:
map.removeControl(control);
Удаление вызывает:
onRemove()Контролы не удаляются автоматически при уничтожении карты, если они были добавлены вручную вне жизненного цикла.
Интерфейс контролов предельно минимален:
class CustomControl {
onAdd(map) {
this.map = map;
this.container = document.createElement('div');
this.container.className = 'custom-control';
this.container.textContent = 'Action';
return this.container;
}
onRemove() {
this.container.parentNode.removeChild(this.container);
this.map = undefined;
}
}
Добавление:
map.addControl(new CustomControl());
onAdd должен возвращать DOM-элементonRemove обязан освобождать ресурсыthis.mapКонтролы часто используются для инкапсуляции логики взаимодействия с картой:
Пример контролируемого изменения масштаба:
class ZoomControl {
onAdd(map) {
this.map = map;
this.container = document.createElement('div');
const btn = document.createElement('button');
btn.textContent = 'Zoom +';
btn.oncl ick = () => {
this.map.zoomIn();
};
this.container.appendChild(btn);
return this.container;
}
onRemove() {
this.container.remove();
this.map = undefined;
}
}
Контролы подключаются после создания карты и привязываются к её экземпляру.
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v12'
});
map.on('load', () => {
map.addControl(new mapboxgl.NavigationControl());
});
Хотя добавление возможно и до события load, большинство
сложных контролов используют готовую структуру карты, которая становится
доступной после инициализации.
Контролы работают независимо, но могут влиять на одно и то же состояние карты:
Конфликты возникают только при одновременном управлении камерой разными контролами, что требует аккуратного управления событиями карты.
Контролы используют стандартные CSS классы Mapbox:
.mapboxgl-ctrl.mapboxgl-ctrl-group.mapboxgl-ctrl-iconПереопределение стилей:
.mapboxgl-ctrl button {
width: 36px;
height: 36px;
}
Контролы можно полностью переоформить, сохраняя DOM-структуру.
В мобильных интерфейсах контролы часто перераспределяются:
ScaleControl и AttributionControl автоматически адаптируются к ширине экрана.
При изменении style (map.setStyle) все контролы
сохраняются, но:
NavigationControl и FullscreenControl не зависят от стиля и продолжают работать без изменений.
Контролы практически не влияют на производительность карты, так как:
Исключение составляют кастомные контролы с частыми обновлениями
интерфейса или подписками на события move и
render.
Контролы часто используются как контейнеры для сложных UI-компонентов:
Их роль выходит за рамки простых кнопок и становится частью архитектуры пользовательского взаимодействия с картой.