В экосистеме HERE Technologies управление курсором в JavaScript API является частью более широкого слоя взаимодействия пользователя с картой, где DOM-события, слой рендеринга WebGL/Canvas и поведенческие модели карты работают совместно. Курсор выступает не просто визуальным индикатором, а сигналом состояния интерфейса: наведение на интерактивный объект, начало перетаскивания, режим выделения, блокировка взаимодействий или работа с пользовательскими слоями.
Карта в HERE Maps JS API рендерится внутри DOM-элемента, который инкапсулирует WebGL/Canvas поверхность. Управление курсором осуществляется через стиль этого контейнера или через события взаимодействия:
map.getElement() — основной DOM-контейнер картыmap.getViewPort().getElement() — слой viewport, часто
используется для стилизацииpointerdown, pointermove,
pointerupH.mapevents.BehaviorКурсор в этом контексте не привязан к географическим координатам напрямую, а изменяется в зависимости от состояния взаимодействия с пиксельной поверхностью карты.
Наиболее прямой способ управления курсором — модификация CSS свойства
cursor у контейнера карты:
const mapContainer = map.getElement();
mapContainer.style.cursor = 'default';
Поддерживаются стандартные значения CSS:
defaultpointergrabgrabbingcrosshairmoveДля более точного контроля часто используется переключение состояний:
map.addEventListener('pointerdown', () => {
map.getElement().style.cursor = 'grabbing';
});
map.addEventListener('pointerup', () => {
map.getElement().style.cursor = 'grab';
});
map.addEventListener('pointermove', () => {
map.getElement().style.cursor = 'grab';
});
Такой подход особенно важен при реализации кастомного drag-поведения,
когда стандартный Behavior отключён или расширен.
При использовании слоя взаимодействия
H.mapevents.Behavior управление курсором часто становится
автоматическим, поскольку библиотека сама переключает состояния при зуме
и перетаскивании карты.
const beh * avior = new H.mapevents.Behavior(
new H.mapevents.MapEvents(map)
);
В этом режиме:
grabbingpointerОднако разработчики часто переопределяют это поведение, чтобы синхронизировать курсор с бизнес-логикой интерфейса.
Карта состоит из интерактивных слоёв (markers, polylines, polygons), каждый из которых может иметь события:
pointerenterpointerleavetappointerdownПример изменения курсора при наведении на маркер:
marker.addEventListener('pointerenter', () => {
map.getElement().style.cursor = 'pointer';
});
marker.addEventListener('pointerleave', () => {
map.getElement().style.cursor = 'default';
});
Этот механизм позволяет визуально отделять интерактивные объекты от фоновой карты.
Низкоуровневая система событий H.map.Event позволяет
перехватывать глобальные события карты:
map.addEventListener('pointermove', function (evt) {
const target = evt.target;
if (target instanceof H.map.Marker) {
map.getElement().style.cursor = 'pointer';
} else {
map.getElement().style.cursor = 'default';
}
});
Здесь важным является анализ evt.target, который
указывает на объект сцены, находящийся под курсором.
В сложных интерфейсах курсор используется как индикатор режима:
map.getElement().style.cursor = 'grab';
При удержании:
map.getElement().style.cursor = 'grabbing';
map.getElement().style.cursor = 'crosshair';
map.getElement().style.cursor = 'not-allowed';
map.setInteractive(false);
Хотя метод setInteractive не является универсальным API,
часто используется логическое отключение поведения через
H.mapevents.Behavior.disable() или удаление
обработчиков.
Курсор может быть заменён на изображение:
map.getElement().style.cursor = 'url(cursor.png) 12 12, auto';
Особенности:
auto)Кастомные курсоры часто применяются в:
При использовании DOM-оверлеев поверх карты курсор может
конфликтовать между слоями. В таких случаях важно контролировать
pointer-events:
.overlay {
pointer-events: none;
}
Или наоборот:
.overlay {
pointer-events: auto;
}
Это влияет на то, какой слой получает события, а следовательно — какой стиль курсора применяется.
Хотя курсор существует в экранных координатах, его положение можно преобразовать в географические:
map.addEventListener('pointermove', (evt) => {
const coord = map.screenToGeo(
evt.currentPointer.viewportX,
evt.currentPointer.viewportY
);
console.log(coord.lat, coord.lng);
});
На основе этих данных можно динамически менять курсор в зависимости от зоны карты (например, разные регионы или полигоны).
Частое изменение cursor через прямое обновление DOM
может приводить к лишним reflow/repaint. Оптимизация включает:
function setCursor(cursor) {
const el = map.getElement();
if (el.style.cursor !== cursor) {
el.style.cursor = cursor;
}
}
На практике часто возникают ситуации, когда курсор “залипает”. Основные причины:
pointeruppointer-events: autoBehavior и кастомный handler одновременноРешение обычно сводится к централизованному управлению состоянием курсора через единый контроллер, который синхронизирует события карты и UI-инструментов.