Типы событий карты

События в Mapbox GL JS представляют собой механизм взаимодействия с картой и её состоянием. Они позволяют реагировать на действия пользователя, изменения данных, завершение отрисовки, загрузку ресурсов и внутренние процессы рендеринга. Архитектура событий построена по модели, схожей с DOM Events, но адаптирована под WebGL-контекст карты.

Все события регистрируются через методы экземпляра карты:

map.on('тип-события', handler);
map.off('тип-события', handler);
map.once('тип-события', handler);

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


Классификация событий

События Mapbox GL JS можно разделить на несколько крупных категорий:

  • события взаимодействия пользователя (pointer / mouse / touch)
  • события состояния карты (load, idle, remove)
  • события рендеринга (render, renderstart, renderend)
  • события данных (data, sourcedata, styledataloading)
  • события слоёв и источников
  • события ошибок

Такая классификация отражает внутреннюю архитектуру карты: от источников данных до финального кадра WebGL.


События взаимодействия с пользователем

События этого типа возникают при работе пользователя с картой. Они привязаны к координатам, пикселям и объектам слоёв.

Основные события мыши и указателя

  • click
  • dblclick
  • mousedown
  • mouseup
  • mousemove
  • mouseenter
  • mouseleave
  • mouseover
  • mouseout
  • contextmenu

Пример регистрации события клика:

map.on('click', (e) => {
    console.log(e.lngLat);
});

Объект события содержит ключевые поля:

  • lngLat — географические координаты точки
  • point — экранные координаты (x, y)
  • originalEvent — нативное DOM-событие
  • features — объекты слоёв, попавшие под курсор (если используется queryRenderedFeatures)

События слоёв (layer events)

События можно привязывать к конкретным слоям:

map.on('click', 'cities-layer', (e) => {
    console.log(e.features);
});

Поддерживаемые типы аналогичны базовым pointer-событиям: click, mouseenter, mouseleave, mousemove.

Это позволяет реализовывать интерактивные карты без ручного поиска объектов.


События touch и жестов

На мобильных устройствах используются сенсорные события, которые Mapbox GL JS абстрагирует:

  • touchstart
  • touchend
  • touchcancel

Однако большинство жестов (zoom, rotate, pitch) не требуют прямой обработки touch-событий, поскольку управляются встроенными контроллерами карты.


События состояния карты

События состояния отражают жизненный цикл карты и её готовность к работе.

load

Срабатывает один раз после полной загрузки стиля и всех необходимых ресурсов.

map.on('load', () => {
    console.log('карта готова');
});

remove

Вызывается при удалении карты из DOM:

map.on('remove', () => {
    console.log('карта уничтожена');
});

idle

Срабатывает, когда карта завершила все операции рендеринга и загрузки:

  • нет ожидающих тайлов
  • нет активных анимаций
  • нет изменений стиля
map.on('idle', () => {
    console.log('карта в состоянии покоя');
});

События рендеринга

Эти события отражают процесс отрисовки WebGL-сцены.

renderstart

Возникает при начале нового цикла рендеринга.

render

Срабатывает на каждом кадре рендеринга. Может вызываться многократно в секунду.

map.on('render', () => {
    console.log('кадр отрисован');
});

renderend

Возникает после завершения текущего цикла рендеринга.

Рендер-события особенно важны при создании анимаций и синхронизации внешних интерфейсов с картой.


События данных

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

data

Срабатывает при изменении состояния любого источника данных.

sourcedata

Событие, связанное с конкретным source:

map.on('sourcedata', (e) => {
    console.log(e.sourceId);
});

dataloading

Возникает при начале загрузки данных.

styledataloading

Срабатывает при загрузке стиля или его частей.


События источников данных

Источники (sources) имеют собственный жизненный цикл загрузки:

  • начало загрузки тайлов
  • завершение загрузки
  • ошибки загрузки

События позволяют отслеживать состояние каждого слоя данных независимо.

map.on('data', (e) => {
    if (e.sourceId === 'cities') {
        console.log('обновились данные cities');
    }
});

События ошибок

error

Универсальное событие для всех типов ошибок:

  • загрузка тайлов
  • ошибки стиля
  • сетевые сбои
  • ошибки источников данных
map.on('error', (e) => {
    console.error(e.error);
});

Объект ошибки обычно содержит:

  • error.message
  • error.status
  • error.sourceId (если применимо)

Особенности работы с событиями

Контекст исполнения

В обработчиках событий this указывает на экземпляр карты:

map.on('load', function () {
    this.addSource(...);
});

Однократные события

Метод once используется для одноразового реагирования:

map.once('load', () => {
    console.log('выполнится один раз');
});

Удаление обработчиков

function handler(e) {
    console.log(e);
}

map.on('click', handler);
map.off('click', handler);

Если обработчик не указан, удаляются все слушатели данного события.


Приоритет и взаимодействие событий

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

Пример при клике:

  1. mousedown
  2. mouseup
  3. click
  4. возможные render
  5. возможные data при запросе объектов

Понимание этой цепочки важно для прогнозирования поведения интерфейса.


События и слои

Слои в Mapbox GL JS имеют собственную модель интерактивности. При наличии нескольких слоёв под курсором события обрабатываются в порядке z-index.

map.on('click', (e) => {
    const features = map.queryRenderedFeatures(e.point);
});

Каждый объект feature содержит:

  • layer
  • geometry
  • properties
  • source

События движения карты

Хотя они не относятся напрямую к pointer-событиям, они критически важны для интерактивности:

  • movestart
  • move
  • moveend
  • zoomstart
  • zoom
  • zoomend
  • rotatestart
  • rotate
  • rotateend
  • pitchstart
  • pitch
  • pitchend

Эти события позволяют отслеживать трансформации камеры карты.

map.on('move', () => {
    console.log(map.getCenter());
});

Связь событий с рендерингом WebGL

Каждое изменение состояния карты инициирует перерасчёт сцены:

  • изменение центра
  • изменение масштаба
  • добавление источников
  • фильтрация слоёв

Это приводит к цепочке:

move/zoom/pitch → renderstart → render → renderend → idle

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