Mapbox GL JS использует событийно-ориентированную модель взаимодействия с картой, где графические примитивы и пользовательские действия обрабатываются через набор режимов редактирования. В экосистеме Mapbox GL Draw режимы определяют поведение инструмента при создании, изменении и выделении геометрии, формируя конечный пользовательский опыт работы с пространственными объектами.
Система режимов основана на конечном автомате, где текущее состояние определяет допустимые действия пользователя и реакцию интерфейса. Каждый режим представляет собой объект с набором методов жизненного цикла и обработчиков событий.
Ключевая идея заключается в разделении логики:
Режим не существует изолированно: он работает в связке с состоянием
FeatureCollection, которое хранит все геометрические
объекты.
Стандартный набор режимов охватывает основные сценарии редактирования.
Режим выбора объектов без активного редактирования геометрии. Используется как базовое состояние взаимодействия.
Характерные особенности:
Поведение определяется тем, какие объекты находятся в состоянии
selected.
Режим точечного редактирования геометрии.
Позволяет:
Внутренне режим работает с индексами координат, изменяя структуру
массива coordinates в GeoJSON.
Режим создания точечных объектов.
Основные характеристики:
PointИспользуется для маркеров, событийных точек и объектов без геометрической сложности.
Режим построения линий с последовательным добавлением координат.
Поведение:
Линия формируется как массив координат, который динамически расширяется.
Режим построения полигонов с замыканием контура.
Особенности:
Полигон хранит структуру:
coordinates: [
[ [lng, lat], [lng, lat], ... , [lng, lat] ]
]
Каждый режим реализует стандартный набор методов, определяющих его поведение в ответ на действия пользователя.
Инициализация состояния режима. Вызывается при активации режима.
Используется для:
Обработка кликов по карте.
Зависит от режима:
Отвечает за интерактивное обновление геометрии.
Типичное применение:
Обработка клавиатурных событий:
Вызывается при выходе из режима.
Используется для:
Обработка удаления объектов.
Позволяет централизованно управлять удалением выбранных feature.
Режимы активно используют feature-state Mapbox GL JS для
хранения метаданных объектов.
Типичные состояния:
active: true — объект редактируетсяmeta: "vertex" — вершина линии/полигонаselected: true — объект выделенЭти состояния не входят в GeoJSON напрямую, но влияют на отрисовку слоя.
Смена режима осуществляется через changeMode, что
является центральным механизмом управления состоянием.
Пример:
mapboxDraw.changeMode('simple_select');
mapboxDraw.changeMode('draw_polygon');
mapboxDraw.changeMode('direct_select', { featureId: '123' });
Параметры передаются через объект аргументов, позволяя передавать идентификаторы объектов и дополнительные настройки.
Архитектура позволяет расширять стандартный набор режимов, реализуя собственные сценарии взаимодействия.
Структура кастомного режима:
const customMode = {
onSetup() {
return {
active: true
};
},
onClick(state, e) {
state.count = (state.count || 0) + 1;
return state;
},
onMouseMove(state, e) {
state.lastPosition = [e.lngLat.lng, e.lngLat.lat];
return state;
},
onKeyUp(state, e) {
if (e.key === 'Escape') {
return this.changeMode('simple_select');
}
}
};
Кастомные режимы позволяют реализовать:
Во время рисования создаются промежуточные объекты:
currentVertexhotPointmidPointactiveLineОни не сохраняются в итоговом GeoJSON, но используются для визуализации и взаимодействия.
Режимы тесно связаны с GeoJSONSource, который
обновляется при каждом изменении состояния.
Механизм работы:
Mapbox GL JS использует WebGL-рендеринг, поэтому обновления происходят эффективно через diff состояния, а не полную перерисовку сцены.
direct_select реализует сложную систему манипуляции
вершинами.
Основные операции:
Каждая вершина имеет индекс в массиве координат, что позволяет точно изменять структуру геометрии без пересоздания объекта.
Режимы используют унифицированную модель pointer events:
mousedownmousemovemouseupclickСобытия преобразуются в географические координаты через
map.project и map.unproject, что обеспечивает
синхронизацию экранных и географических координат.
Во время активного режима используются специальные слои:
Каждый слой зависит от состояния feature-state, что позволяет динамически изменять стили без пересоздания источника данных.
Завершение режима зависит от типа геометрии:
После завершения режим переключается в simple_select, а
объект фиксируется в источнике данных.
Режимы не взаимодействуют напрямую с DOM-элементами геометрии. Вся логика построена на:
Это обеспечивает высокую производительность при большом количестве объектов и сложных сценах редактирования.