Типы для событий

MapLibre GL JS строится вокруг событийной модели, унаследованной от архитектуры EventEmitter-подобного интерфейса. Практически все взаимодействие с картой — от загрузки стиля до кликов по слоям — выражается через строго типизированные события, которые формируют основу реактивного управления состоянием карты.

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


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

В основе лежит интерфейс событийного эмиттера, доступный у объекта карты:

map.on('load', () => {
  console.log('Карта загружена');
});

Каждое событие регистрируется через:

  • map.on(type, listener)
  • map.once(type, listener)
  • map.off(type, listener)

Тип события — строковый идентификатор, а обработчик получает объект события, тип которого зависит от категории события.


Жизненный цикл карты

События жизненного цикла фиксируют ключевые стадии готовности карты и её стиля.

load

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

map.on('load', (e) => {
  // карта готова к добавлению слоёв
});

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

idle

Срабатывает, когда карта завершила все рендер-операции и больше не выполняет асинхронных задач.

Используется для:

  • синхронизации состояния UI
  • завершения цепочек загрузки данных
  • тестирования стабильного состояния карты

remove

Срабатывает при уничтожении карты.


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

Рендеринговые события отражают внутренний цикл отрисовки WebGL.

render

Срабатывает при каждом цикле рендера, включая анимации и перемещения.

map.on('render', () => {
  // вызывается очень часто
});

rendercomplete

Фиксирует завершение полного цикла отрисовки.


События перемещения и трансформации карты

Эти события относятся к камере (camera state).

movestart, move, moveend

  • movestart — начало перемещения
  • move — процесс перемещения
  • moveend — завершение

Тип события включает информацию о:

  • центре карты
  • масштабе
  • наклоне
  • азимуте

zoomstart, zoom, zoomend

Отдельный поднабор для масштабирования.

rotatestart, rotate, rotateend

Используются при изменении угла поворота карты.


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

Взаимодействие с картой реализуется через унифицированные pointer-события.

Общие pointer-события

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

Каждое событие содержит объект MapMouseEvent, который расширяет базовый event:

  • координаты на экране
  • географические координаты
  • список объектов под курсором

Пример:

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

Drag-события

  • dragstart
  • drag
  • dragend

Применяются при перетаскивании карты.

Touch-события

  • touchstart
  • touchmove
  • touchend

Используют тип MapTouchEvent, содержащий массив касаний и агрегированную информацию.


События слоёв и объектов

Эти события относятся к интерактивности конкретных слоёв.

click / hover с фильтром слоя

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

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

Тип события расширяется до MapLayerMouseEvent, который включает:

  • features — выбранные геообъекты
  • layerId — идентификатор слоя
  • координаты события

mouseenter / mouseleave слоя

Позволяют отслеживать вход и выход курсора из объектов слоя.


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

Данные в MapLibre GL JS подгружаются асинхронно, и для контроля используются специализированные события.

data

Общее событие изменения данных.

Тип события — MapDataEvent, включает:

  • тип источника (source)
  • состояние загрузки (dataType)
  • флаг завершения

sourcedata

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

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

styledata

Срабатывает при изменении стиля карты.


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

Источник данных (source) может генерировать отдельные события загрузки и обновления.

  • загрузка тайлов
  • обновление GeoJSON
  • изменение векторных данных

Тип события MapSourceDataEvent содержит:

  • sourceId
  • статус загрузки
  • тип данных

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

error

Фиксирует ошибки различного уровня:

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

Тип события содержит объект Error и контекст возникновения.


Типизация событий в TypeScript

Система типов в MapLibre GL JS основана на строгом сопоставлении событий и их payload-типов.

Базовые типы событий

  • MapMouseEvent
  • MapTouchEvent
  • MapLayerMouseEvent
  • MapDataEvent
  • MapSourceDataEvent
  • MapStyleDataEvent
  • MapBoxZoomEvent (в некоторых версиях наследованных API)

Каждый тип расширяет базовый MapEvent, содержащий:

  • type — строка события
  • target — экземпляр карты
  • originalEvent — нативное DOM-событие

Перегрузки обработчиков событий

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

map.on('click', (e: MapMouseEvent) => {});
map.on('click', 'layer-id', (e: MapLayerMouseEvent) => {});

На уровне типов происходит следующее:

  • событие без слоя → MapMouseEvent
  • событие со слоем → MapLayerMouseEvent

Это разделение критично для корректной работы с features.


Пользовательские события

Помимо встроенных событий, доступна генерация собственных:

map.fire('custom-event', { value: 42 });

Такие события не имеют строгого типа по умолчанию и работают через расширение базового интерфейса Evented.


Приоритеты и цепочка обработки

События проходят через систему подписчиков с сохранением порядка регистрации. При этом:

  • once удаляет обработчик после первого вызова
  • off полностью исключает обработчик
  • порядок выполнения соответствует очереди подписки

Особенности производительности

События типа render, mousemove, move могут вызываться десятки раз в секунду. Их обработка требует:

  • минимизации вычислений внутри callback
  • использования throttling при необходимости
  • разделения UI-логики и логики карты

Контекст объектов событий

Все события предоставляют доступ к:

  • экранным координатам (point)
  • географическим координатам (lngLat)
  • текущему состоянию камеры
  • активным слоям и объектам

Это позволяет строить сложные интерактивные системы без прямого доступа к WebGL-слою.


Согласование событий и состояния карты

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

  • перемещение → обновление камеры
  • загрузка данных → обновление источников
  • взаимодействие → выбор feature-объектов
  • рендер → синхронизация визуального слоя

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