NavigationControl

MapLibre GL JS включает набор стандартных UI-контролов, предназначенных для быстрого добавления интерактивных элементов управления картой. Один из базовых и наиболее часто используемых — NavigationControl, отвечающий за масштабирование и вращение карты.

NavigationControl представляет собой компактный виджет интерфейса, который объединяет две ключевые функции:

  • изменение масштаба (zoom in / zoom out)
  • управление поворотом и наклоном карты (bearing / pitch), если соответствующие опции включены

Контрол интегрируется непосредственно в экземпляр карты и работает поверх WebGL-контекста, не вмешиваясь в слой рендеринга данных.

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

Базовая инициализация

NavigationControl добавляется через метод addControl экземпляра карты:

import maplibregl from 'maplibre-gl';

const map = new maplibregl.Map({
  container: 'map',
  style: 'https://demotiles.maplibre.org/style.json',
  center: [30.3, 59.9],
  zoom: 10
});

map.addControl(new maplibregl.NavigationControl());

После добавления в интерфейсе появляются стандартные кнопки увеличения и уменьшения масштаба, а также элементы управления поворотом (в зависимости от конфигурации).

Параметры конфигурации

NavigationControl принимает объект настроек, позволяющий гибко управлять отображаемыми функциями:

const nav = new maplibregl.NavigationControl({
  showCompass: true,
  showZoom: true,
  visualizePitch: true
});

map.addControl(nav);

showZoom

Тип: boolean По умолчанию: true

Определяет, отображаются ли кнопки масштабирования.

  • true — кнопки zoom-in и zoom-out видимы
  • false — управление масштабом скрыто

Используется, когда управление масштабом реализуется внешними элементами интерфейса.

showCompass

Тип: boolean По умолчанию: true

Определяет отображение компаса и кнопки сброса вращения.

Компасс выполняет две функции:

  • визуализация текущего угла поворота карты
  • сброс rotation до 0 при клике

При отключении карта остаётся функционально поворачиваемой (если разрешено), но без визуального индикатора направления.

visualizePitch

Тип: boolean По умолчанию: false

Добавляет визуальный индикатор наклона карты.

Включение этой опции особенно важно при работе с 3D-данными или при активном использовании pitch.

Позиционирование на карте

Контрол можно размещать в одном из стандартных углов карты:

  • top-left
  • top-right
  • bottom-left
  • bottom-right
map.addControl(
  new maplibregl.NavigationControl(),
  'top-right'
);

Выбор позиции влияет на UX: чаще всего NavigationControl размещается в верхнем правом углу, чтобы не конфликтовать с атрибуцией и дополнительными слоями интерфейса.

Поведение при взаимодействии

NavigationControl взаимодействует с картой через публичные методы API:

  • map.zoomIn()
  • map.zoomOut()
  • map.resetNorth()
  • map.resetNorthPitch()

Каждое нажатие кнопки вызывает соответствующую анимацию камеры. Параметры анимации (длительность, easing) наследуются от стандартных настроек карты, если не переопределены.

Пример эквивалентного программного вызова:

map.zoomIn({ duration: 300 });
map.zoomOut({ duration: 300 });
map.resetNorth({ duration: 500 });

Взаимодействие с жестами и устройствами ввода

NavigationControl не заменяет жестовое управление, а дополняет его.

Поддерживаются:

  • колесо мыши для zoom
  • drag для pan
  • shift + drag для rotation (если включено)
  • pinch gestures на touch-устройствах

При этом NavigationControl полезен в сценариях, где:

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

Доступность и семантика

Контрол генерирует DOM-структуру с кнопками, которые имеют стандартные атрибуты доступности:

  • aria-label для описания действия
  • button элементы вместо кастомных div
  • поддержка навигации с клавиатуры (Tab / Enter / Space)

Это позволяет использовать NavigationControl в интерфейсах, ориентированных на WCAG-совместимость.

Стилизация и кастомизация

NavigationControl использует стандартные CSS-классы библиотеки:

  • .maplibregl-ctrl
  • .maplibregl-ctrl-group
  • .maplibregl-ctrl-zoom-in
  • .maplibregl-ctrl-zoom-out
  • .maplibregl-ctrl-compass

Изменение внешнего вида выполняется через переопределение CSS:

.maplibregl-ctrl button {
  width: 32px;
  height: 32px;
}

.maplibregl-ctrl-group {
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.15);
}

В продакшн-системах часто используется полная замена темы, чтобы контролы соответствовали дизайн-системе приложения.

Условное добавление и удаление

NavigationControl можно динамически управлять:

const nav = new maplibregl.NavigationControl();

map.addControl(nav);

// удаление
map.removeControl(nav);

Это важно для интерфейсов, где:

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

Использование в сложных интерфейсах

В приложениях с несколькими слоями управления NavigationControl часто комбинируется с другими контролами:

  • GeolocateControl (определение местоположения)
  • ScaleControl (масштабная линейка)
  • FullscreenControl (полноэкранный режим)

Композиция контролов позволяет собрать полноценную панель навигации:

map.addControl(new maplibregl.NavigationControl(), 'top-right');
map.addControl(new maplibregl.ScaleControl(), 'bottom-left');
map.addControl(new maplibregl.FullscreenControl(), 'top-right');

Поведение при изменении состояния карты

NavigationControl автоматически синхронизируется с состоянием камеры:

  • при программном изменении zoom обновляется UI
  • при вращении карты компас отражает актуальный bearing
  • при сбросе северного направления индикатор возвращается в исходное положение

Синхронизация выполняется через события карты (move, rotate, zoom), которые контрол подписывает при инициализации.

Особенности реализации в WebGL-контексте

NavigationControl не взаимодействует напрямую с WebGL-слоем. Его работа ограничена:

  • DOM-слоем поверх canvas
  • вызовами публичного API карты

Это архитектурное разделение обеспечивает:

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

Ограничения и типичные ошибки использования

При работе с NavigationControl часто встречаются следующие ошибки:

  • дублирование контролов в одном углу, приводящее к перекрытию UI
  • отключение showZoom без альтернативного механизма масштабирования
  • использование кастомных кнопок без синхронизации с состоянием карты
  • попытка стилизовать внутренние элементы без учёта специфичности CSS библиотеки

Корректная интеграция предполагает соблюдение единого источника управления состоянием карты и UI-контролов.