Управление жестами

В HERE Maps JavaScript API обработка пользовательских взаимодействий строится вокруг системы событий и поведения карты. Базовый слой отвечает за визуализацию карты, а управление жестами реализуется через модуль событий карты (mapevents) и поведенческий слой (Behavior), который интерпретирует низкоуровневые события мыши и сенсорного ввода в высокоуровневые действия: панорамирование, масштабирование, вращение и инерционные перемещения.

Ключевая идея архитектуры заключается в разделении:

  • H.Map — контейнер и рендер карты;
  • H.mapevents.MapEvents — генератор унифицированных событий ввода;
  • H.mapevents.Behavior — интерпретатор жестов и управляющий слой взаимодействия.

Инициализация системы обработки жестов

Для включения жестов требуется связать карту с системой событий и поведением. Без этого карта остаётся статичной и не реагирует на пользовательский ввод.

const platform = new H.service.Platform({
  apikey: 'YOUR_API_KEY'
});

const defaultLayers = platform.createDefaultLayers();

const map = new H.Map(
  document.getElementById('map'),
  defaultLayers.vector.normal.map,
  {
    center: { lat: 52.52, lng: 13.405 },
    zoom: 10,
    pixelRatio: window.devicePixelRatio || 1
  }
);

const mapEvents = new H.mapevents.MapEvents(map);
const beh * avior = new H.mapevents.Behavior(mapEvents);

Именно объект H.mapevents.Behavior активирует стандартный набор жестов, включая перетаскивание, масштабирование колесом мыши, pinch-жесты на сенсорных устройствах и двойной тап.

Базовые жесты и их интерпретация

Поведение карты агрегирует низкоуровневые события в логические действия:

  • Pan (перемещение) — реализуется через drag мышью или касанием.
  • Zoom (масштабирование) — колесо мыши, pinch-жест, двойной тап.
  • Inertia (инерция) — продолжение движения после отпускания пальца или кнопки мыши.
  • Double tap zoom — быстрое увеличение масштаба в точке касания.

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

Управление поведением карты

Объект Behavior предоставляет методы для включения и отключения групп жестов. Управление осуществляется через набор флагов поведения.

behavior.disable();
behavior.enable();

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

Более точечное управление осуществляется через параметры:

behavior.setOptions({
  pan: true,
  zoom: true,
  pinchZoom: true,
  scrollWheelZoom: false,
  kineticPan: true
});

Управление прокруткой и масштабированием

Колесо мыши (scrollWheelZoom)

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

behavior.setOptions({
  scrollWheelZoom: false
});

При включённом режиме карта захватывает событие колесика мыши, что может конфликтовать с прокруткой страницы.

Pinch Zoom

Pinch-жест применяется на сенсорных экранах и позволяет изменять масштаб двумя пальцами.

behavior.setOptions({
  pinchZoom: true
});

При отключении pinch взаимодействие на мобильных устройствах ограничивается только панорамированием.

Панорамирование и инерция движения

Панорамирование реализуется через drag-события. Дополнительно применяется кинетическая модель движения, создающая эффект инерции.

behavior.setOptions({
  kineticPan: true
});

Инерция рассчитывается на основе скорости последнего перемещения. При отключении движение карты резко останавливается сразу после завершения жеста.

Управление двойным тапом и масштабированием по центру

Двойной тап является стандартным жестом быстрого увеличения масштаба в точке взаимодействия.

behavior.setOptions({
  doubleTapZoom: true
});

При отключении этого режима управление масштабом остаётся только через колесо мыши или pinch.

Ограничение жестов через уровень карты

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

map.setZoomRange(5, 18);

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

Обработка событий жестов

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

map.addEventListener('dragstart', (evt) => {
  console.log('Начало перемещения карты');
});

map.addEventListener('drag', (evt) => {
  console.log('Перемещение в процессе');
});

map.addEventListener('dragend', (evt) => {
  console.log('Перемещение завершено');
});

Аналогичная структура применяется для масштабирования:

map.addEventListener('mapviewchange', (evt) => {
  console.log('Изменение состояния карты');
});

Событие mapviewchange агрегирует все изменения состояния: zoom, center, tilt, bearing.

Сенсорные события и multi-touch обработка

На устройствах с поддержкой multitouch жесты обрабатываются через объединение касаний в единые действия:

  • два пальца — масштабирование;
  • один палец — перемещение;
  • вращение (при включённой поддержке) — изменение угла карты.

Расширенное управление позволяет включать или отключать отдельные сенсорные режимы:

behavior.setOptions({
  pinchRotate: true
});

Отключение всех интерактивных жестов

В сценариях статических карт поведение полностью деактивируется, оставляя только визуализацию.

mapEvents.disable();
behavior.disable();

Такой режим используется при генерации изображений карты или при кастомных системах управления поверх API.

Кастомизация взаимодействий

Поведенческий слой может быть заменён или расширен собственной логикой через перехват событий. Это позволяет реализовать альтернативные схемы управления:

  • фиксированное центрирование карты;
  • запрет перемещения за пределы региона;
  • кастомные жесты (например, удержание + drag для изменения параметров слоя).
map.addEventListener('drag', (evt) => {
  const pointer = evt.currentPointer;
  if (pointer.type === 'touch') {
    // кастомная логика обработки
  }
});

Приоритеты жестов и конфликт событий

При одновременном использовании нескольких типов ввода возникает приоритетная обработка:

  1. Touch-события
  2. Mouse события
  3. Keyboard события

Конфликты чаще всего возникают между:

  • scroll страницы и scrollWheelZoom;
  • drag карты и drag DOM-элементов поверх карты;
  • pinch zoom и кастомными multi-touch обработчиками.

Решение заключается в блокировке стандартного поведения через stopPropagation и отключение соответствующих опций поведения.

map.getElement().addEventListener('wheel', (evt) => {
  evt.stopPropagation();
}, true);