Сенсорное взаимодействие в HERE Maps API строится вокруг унифицированной модели событий, которая объединяет касания (touch), указательные события (pointer events) и высокоуровневые жесты карты. Архитектура взаимодействия рассчитана на работу как в мобильных браузерах, так и на десктопных устройствах с тачскринами и мышью, обеспечивая единый поток событий для обработки пользовательских действий.
В основе интерактивности карты лежат три слоя обработки:
H.mapevents)tap,
drag, longpress,
pointermove)Такое разделение позволяет абстрагироваться от различий между устройствами ввода и сосредоточиться на логике взаимодействия с картой.
Ключевым компонентом является модуль:
const mapEvents = new H.mapevents.MapEvents(map);
Он подключает обработку сенсорных и указательных событий к экземпляру карты.
Далее создаётся поведенческий слой:
const beh * avior = new H.mapevents.Behavior(mapEvents);
Behavior отвечает за стандартные жесты: панорамирование,
масштабирование, вращение и инерцию движения.
После подключения H.mapevents.Behavior карта начинает
автоматически обрабатывать стандартные жесты:
Эти жесты реализуются внутри Behavior и не требуют
ручной обработки DOM-событий.
HERE Maps API предоставляет набор событий уровня карты, которые абстрагированы от конкретного устройства ввода:
tap — одиночное касание или кликlongpress — длительное удержаниеdragstart, drag, dragend —
перетаскиваниеpointermove — движение указателяpointerdown, pointerup — начало и конец
взаимодействияwheel — масштабирование колесом мышиПример регистрации события касания:
map.addEventListener('tap', function (evt) {
const coord = map.screenToGeo(
evt.currentPointer.viewportX,
evt.currentPointer.viewportY
);
console.log('Координаты точки:', coord.lat, coord.lng);
});
Событие содержит данные о позиции указателя и контекст взаимодействия.
Каждое сенсорное событие содержит объект PointerEvent,
включающий:
viewportX, viewportY — координаты на
экранеtarget — объект карты или слойtype — тип событияcurrentPointer — активный указательpointers — список всех активных касанийПреобразование экранных координат в географические выполняется через:
map.screenToGeo(viewportX, viewportY);
Обратное преобразование:
map.geoToScreen(latitude, longitude);
Это ключевой механизм связывания UI-событий с географической логикой.
Событие tap используется для выбора объектов карты,
установки маркеров и получения координат точки касания.
map.addEventListener('tap', function (evt) {
const position = map.screenToGeo(
evt.currentPointer.viewportX,
evt.currentPointer.viewportY
);
const marker = new H.map.Marker(position);
map.addObject(marker);
});
При использовании слоёв объектов событие может возвращать дополнительные данные:
map.addEventListener('tap', function (evt) {
const object = evt.target;
if (object instanceof H.map.Marker) {
object.setVisibility(false);
}
});
Событие longpress возникает при удержании точки контакта
в течение заданного времени.
map.addEventListener('longpress', function (evt) {
const coord = map.screenToGeo(
evt.currentPointer.viewportX,
evt.currentPointer.viewportY
);
console.log('Контекстное действие в точке:', coord);
});
longpress часто используется для вызова контекстного
меню, добавления объектов или запуска вспомогательных инструментов.
События dragstart, drag,
dragend позволяют отслеживать движение карты:
map.addEventListener('dragstart', function () {
console.log('Начало перемещения карты');
});
map.addEventListener('drag', function (evt) {
const deltaX = evt.currentPointer.viewportX - evt.startX;
const deltaY = evt.currentPointer.viewportY - evt.startY;
console.log('Смещение:', deltaX, deltaY);
});
map.addEventListener('dragend', function () {
console.log('Завершение перемещения');
});
Эти события полезны для синхронизации UI-элементов с движением карты.
Масштабирование двумя пальцами обрабатывается автоматически, однако его параметры могут быть перехвачены через события указателей.
map.addEventListener('pointermove', function (evt) {
if (evt.pointers.length === 2) {
console.log('Мультисенсорный жест масштабирования');
}
});
Механизм Behavior интерпретирует расстояние между
касаниями как коэффициент масштабирования.
Иногда требуется подавление стандартных жестов карты для реализации кастомной логики взаимодействия.
behavior.disable(H.mapevents.Behavior.Feature.PANNING);
behavior.disable(H.mapevents.Behavior.Feature.ZOOMING);
behavior.disable(H.mapevents.Behavior.Feature.ROTATING);
После отключения стандартных обработчиков события начинают поступать в сыром виде, что позволяет полностью контролировать обработку касаний.
Низкоуровневые события указателей дают полный контроль над взаимодействием.
map.addEventListener('pointerdown', function (evt) {
console.log('Pointer down:', evt.pointerId);
});
map.addEventListener('pointerup', function (evt) {
console.log('Pointer up:', evt.pointerId);
});
При необходимости можно реализовать собственную систему жестов поверх этих событий.
Сенсорные события практически всегда требуют преобразования координат:
map.addEventListener('tap', function (evt) {
const geo = map.screenToGeo(
evt.currentPointer.viewportX,
evt.currentPointer.viewportY
);
const screen = map.geoToScreen(geo.lat, geo.lng);
console.log('Geo:', geo, 'Screen:', screen);
});
Такое двустороннее преобразование используется при создании интерактивных слоёв, визуализаций и пользовательских объектов.
Система pointer events поддерживает несколько одновременных точек взаимодействия:
map.addEventListener('pointermove', function (evt) {
evt.pointers.forEach(function (pointer) {
console.log(pointer.pointerId, pointer.viewportX, pointer.viewportY);
});
});
Это важно для реализации кастомных жестов, таких как масштабирование по расстоянию между пальцами или вращение по углу между точками касания.
При активном Behavior часть событий может
перехватываться встроенной логикой карты. Для предотвращения конфликта
используется контроль propagation:
map.addEventListener('tap', function (evt) {
evt.stopPropagation();
});
Это позволяет блокировать дальнейшую обработку события другими слоями.
Частые события pointermove и drag могут
вызывать нагрузку на основной поток. Для оптимизации применяется:
requestAnimationFramelet lastTime = 0;
map.addEventListener('pointermove', function (evt) {
const now = Date.now();
if (now - lastTime < 16) return;
lastTime = now;
// обработка движения
});
События могут быть привязаны к графическим объектам:
const marker = new H.map.Marker({ lat: 52.5, lng: 13.4 });
marker.addEventListener('tap', function () {
console.log('Маркер активирован');
});
map.addObject(marker);
Это позволяет строить интерактивные слои с независимой логикой поведения для каждого объекта.
Сенсорные события тесно связаны с состоянием карты:
dragОтслеживание состояния:
map.addEventListener('mapviewchange', function () {
console.log(map.getCenter(), map.getZoom());
});
Это позволяет синхронизировать внешние компоненты интерфейса с действиями пользователя на карте.