Событийная модель построена на расширенной реализации
Evented, аналогичной DOM-событиям, но специализированной
для состояния карты и графического слоя WebGL.
Каждый экземпляр карты предоставляет методы:
on(type, listener) — подписка на событиеoff(type, listener) — удаление обработчикаonce(type, listener) — одноразовая подпискаТип события может включать пространство имён через точку, что позволяет структурировать обработчики:
map.on('click', (e) => {
console.log(e.lngLat);
});
map.on('moveend', handleMoveEnd);
map.once('load', initLayers);
Пространства имён применяются для группового управления:
map.on('click.markers', handler);
map.off('click.markers');
Срабатывает после полной загрузки ресурсов карты, включая стиль, источники и базовые тайлы.
map.on('load', () => {
map.addLayer({
id: 'points',
type: 'circle',
source: 'points-source'
});
});
Особенность: событие не гарантирует готовность всех динамически добавленных ресурсов после инициализации, особенно при смене стиля.
Более узкое событие, срабатывающее при загрузке нового стиля, включая
setStyle.
map.on('style.load', () => {
console.log('Стиль загружен');
});
Используется для реактивации слоёв после смены визуальной темы карты.
Состояние камеры контролируется через изменения центра, масштаба, наклона и поворота.
Срабатывает при любом изменении положения камеры.
map.on('move', () => {
const center = map.getCenter();
});
Используется для синхронизации UI в реальном времени, но требует осторожности из-за высокой частоты вызова.
Разделяют процесс перемещения на начало и конец.
map.on('movestart', () => {
console.log('Начало движения');
});
map.on('moveend', () => {
console.log('Движение завершено');
});
moveend часто используется для загрузки данных по новому
экстенту карты.
Отслеживание масштабирования:
map.on('zoom', () => {
console.log(map.getZoom());
});
Отслеживают изменение угла вращения и наклона:
map.on('rotate', () => {});
map.on('pitch', () => {});
Срабатывает при каждом кадре перерисовки WebGL-сцены.
Используется для анимаций и синхронизации внешних слоёв:
map.on('render', () => {
// вызывается часто
});
Важно учитывать, что событие может вызываться десятки раз в секунду.
Срабатывает, когда карта полностью «успокаивается»: нет движения, загрузки тайлов и перерисовки.
map.on('idle', () => {
console.log('Карта стабилизировалась');
});
Это ключевое событие для определения завершения всех асинхронных процессов.
Основное событие выбора объектов:
map.on('click', (e) => {
const features = map.queryRenderedFeatures(e.point);
});
Объект события содержит:
lngLat — географические координатыpoint — координаты в пикселяхfeatures — пересечённые объекты слоя (при запросе)Используются для интерактивных подсказок:
map.on('mousemove', 'layer-id', (e) => {
map.getCanvas().style.cursor = 'pointer';
});
Особенность: события могут привязываться к конкретному слою.
Низкоуровневое управление взаимодействием:
map.on('mousedown', (e) => {});
map.on('mouseup', (e) => {});
Применяется при реализации кастомного drag-логики.
Срабатывает при загрузке или обновлении данных любого источника.
map.on('data', (e) => {
if (e.sourceId === 'cities') {
console.log('Обновление источника cities');
}
});
Позволяют отслеживать состояние конкретных источников:
map.on('sourcedata', (e) => {
if (e.isSourceLoaded) {
console.log('Источник загружен');
}
});
Универсальное событие для всех ошибок карты:
map.on('error', (e) => {
console.error(e.error);
});
Ошибки могут быть связаны с:
Состояние карты представляет собой совокупность параметров камеры, стиля и загрузки ресурсов.
Основные параметры:
Получение значений:
map.getCenter();
map.getZoom();
map.getBearing();
map.getPitch();
Установка состояния:
map.setCenter([30.5, 50.4]);
map.setZoom(10);
map.setBearing(45);
map.setPitch(30);
const bounds = map.getBounds();
Используется для:
map.loaded();
map.isStyleLoaded();
loaded() возвращает состояние готовности всех
ресурсов.
Анимационный переход:
map.flyTo({
center: [30, 50],
zoom: 12,
speed: 1.2
});
Более мягкая анимация без резких ускорений:
map.easeTo({
center: [30, 50],
duration: 800
});
Мгновенное изменение состояния:
map.jumpTo({
center: [30, 50],
zoom: 10
});
Часто состояние карты синхронизируют с URL или внешним состоянием приложения.
map.on('moveend', () => {
const center = map.getCenter();
const zoom = map.getZoom();
location.hash = `${zoom}/${center.lng}/${center.lat}`;
});
При инициализации:
const [zoom, lng, lat] = location.hash.slice(1).split('/');
map.setView([lng, lat], zoom);
События движения (move, render,
zoom) могут генерироваться с высокой частотой.
Типичные подходы оптимизации:
requestAnimationFramemoveendlet ticking = false;
map.on('move', () => {
if (!ticking) {
requestAnimationFrame(() => {
updateUI();
ticking = false;
});
ticking = true;
}
});
Долгоживущие приложения требуют явного удаления обработчиков:
function handler() {}
map.on('click', handler);
map.off('click', handler);
При использовании пространств имён:
map.off('click.layerHandlers');
События могут быть привязаны к конкретным слоям:
map.on('click', 'cities-layer', (e) => {
console.log(e.features);
});
Это позволяет:
Карта в Mapbox GL JS рассматривается как трансформируемая сцена WebGL, где текущее состояние определяется комбинацией:
Любое событие либо изменяет это состояние, либо сигнализирует о его изменении, формируя непрерывный поток обновлений, на котором строится интерактивность и реактивная логика приложения.