Клавиатурные shortcuts

Клавиатурное управление в Mapbox GL JS реализовано через встроенный механизм взаимодействия карты с DOM-событиями клавиатуры. Оно обеспечивает базовую навигацию по карте без использования мыши или сенсорного ввода и является частью стандартного набора интерактивных контроллеров, подключаемых к экземпляру карты.

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

KeyboardHandler и модель обработки событий

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

Обработка событий строится вокруг преобразования нажатий клавиш в изменения параметров камеры:

  • центр карты (center)
  • масштаб (zoom)
  • угол поворота (bearing)
  • наклон (pitch)

Каждое действие приводит к вызову внутреннего метода обновления камеры с анимацией или без неё в зависимости от конфигурации.

Базовые клавиатурные действия

Стандартный набор клавиатурных команд в Mapbox GL JS ориентирован на навигацию и масштабирование карты.

Перемещение карты

Перемещение осуществляется через клавиши стрелок:

  • ArrowUp — смещение карты вверх
  • ArrowDown — смещение карты вниз
  • ArrowLeft — смещение карты влево
  • ArrowRight — смещение карты вправо

Смещение вычисляется в пикселях экрана с последующей трансформацией в географические координаты с учётом текущего масштаба. Это означает, что при большом зуме шаг перемещения соответствует меньшей географической дистанции.

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

Масштабирование

Клавиатурное масштабирование реализуется через стандартные клавиши:

  • + или = — увеличение масштаба (zoom in)
  • - — уменьшение масштаба (zoom out)

Изменение масштаба происходит дискретно, с шагом, определённым параметром zoomDelta, который по умолчанию равен фиксированному значению, обеспечивающему плавную навигацию без резких скачков.

Масштабирование может сопровождаться анимацией, если включены переходы камеры.

Фокусировка и управление контекстом клавиатуры

Клавиатурные события активируются только при наличии фокуса у контейнера карты. Контейнер Mapbox GL JS обычно получает атрибут tabindex, позволяющий включать его в последовательность фокусировки страницы.

const map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/streets-v12',
  center: [0, 0],
  zoom: 2
});

map.getContainer().setAttribute('tabindex', '0');

Фокусировка контейнера приводит к активации обработчиков клавиатуры. Потеря фокуса отключает обработку событий, предотвращая конфликт с другими элементами интерфейса.

Конфигурация клавиатурного управления

Клавиатурное управление может быть включено или отключено через параметры карты:

const map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/streets-v12',
  keyboard: true
});

При установке keyboard: false обработка всех клавиатурных событий полностью отключается, включая стандартные действия перемещения и масштабирования.

Дополнительно возможна точечная настройка поведения через взаимодействие с handler API:

map.keyboard.disable();
map.keyboard.enable();

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

Клавиатурное управление функционирует совместно с другими системами взаимодействия:

  • dragPan — перетаскивание мышью
  • scrollZoom — масштабирование колесом мыши
  • boxZoom — выделение области
  • dragRotate — вращение карты

Приоритет обработки событий регулируется внутренней системой Mapbox GL JS, где клавиатурные события имеют более низкий приоритет по сравнению с активными drag-событиями, но более высокий по сравнению с неактивными состояниями карты.

Кастомизация клавиатурных shortcuts

Пользовательская логика клавиатурных сочетаний реализуется через перехват DOM-событий keydown на контейнере карты.

map.getContainer().addEventListener('keydown', (e) => {
  if (e.key === 'r') {
    map.resetNorth();
  }

  if (e.key === '0') {
    map.flyTo({ zoom: 0, center: [0, 0] });
  }
});

Такой подход позволяет расширять стандартный набор взаимодействий, включая:

  • сброс ориентации карты
  • переход к предустановленным позициям
  • активацию пользовательских режимов отображения

При добавлении кастомных обработчиков учитывается необходимость предотвращения конфликтов с системными сочетаниями браузера через preventDefault().

Перехват и подавление стандартного поведения

Для предотвращения стандартного поведения клавиш браузера применяется механизм перехвата событий:

map.getContainer().addEventListener('keydown', (e) => {
  if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
    e.preventDefault();
  }
});

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

Доступность и клавиатурная навигация

Клавиатурная поддержка в Mapbox GL JS тесно связана с требованиями доступности интерфейсов. Контейнер карты должен быть доступен для фокусировки и не должен блокироваться другими DOM-элементами.

Основные аспекты доступности:

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

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

Конфликты клавиш и стратегия разрешения

В сложных веб-приложениях клавиатурные shortcuts карты могут конфликтовать с глобальными горячими клавишами интерфейса. Для устранения конфликтов применяется несколько стратегий:

  • проверка активного фокуса перед обработкой событий
  • использование модификаторов клавиш (Ctrl, Alt)
  • локальная изоляция событий внутри контейнера карты
  • динамическое включение/выключение keyboard handler при открытии модальных окон
const disableMapKeyboard = () => map.keyboard.disable();
const enableMapKeyboard = () => map.keyboard.enable();

modal.ono pen = disableMapKeyboard;
modal.oncl ose = enableMapKeyboard;

Поведение при потере фокуса

При потере фокуса контейнером карты все клавиатурные события автоматически игнорируются. Это предотвращает непреднамеренное управление картой при взаимодействии с другими элементами интерфейса, такими как формы, панели управления или редакторы.

Состояние фокуса может использоваться как триггер для изменения визуального оформления карты, например подсветки активного режима управления, что реализуется через CSS-селекторы :focus или программное добавление классов состояния.

Производительность обработки клавиатурных событий

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

  • throttling повторных событий keydown
  • объединение нескольких последовательных изменений камеры в один render cycle
  • использование requestAnimationFrame для синхронизации обновлений

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