Класс Popup

Popup в Mapbox GL JS представляет собой всплывающее окно, привязанное к координатам карты или к объектам слоя. Оно используется для отображения дополнительной информации поверх карты без изменения её состояния. Архитектурно Popup является DOM-элементом, управляемым через API библиотеки и интегрированным в систему координат Web Mercator, используемую Mapbox GL JS.

Создание экземпляра Popup выполняется через конструктор:

const popup = new mapboxgl.Popup(options);

Параметр options управляет поведением и внешним видом окна. Наиболее значимые поля конфигурации:

  • closeButton — отображение кнопки закрытия
  • closeOnClick — закрытие при клике по карте
  • closeOnMove — закрытие при перемещении карты
  • offset — смещение относительно точки привязки
  • anchor — автоматическое позиционирование (top, bottom, left, right и др.)
  • className — пользовательский CSS-класс
  • maxWidth — максимальная ширина окна
  • focusAfterOpen — фокусировка после открытия

Каждый параметр влияет на взаимодействие Popup с картой и DOM-структурой.

Привязка к координатам

Ключевая операция Popup — закрепление на географической позиции:

popup.setLngLat([longitude, latitude]);

Координаты задаются в формате [lng, lat], соответствующем стандарту GeoJSON и внутренней системе Mapbox GL JS. После установки позиции Popup становится геопривязанным элементом, синхронизированным с трансформацией карты (zoom, pitch, bearing).

Добавление на карту

Отображение Popup выполняется через привязку к объекту карты:

popup.addTo(map);

Метод addTo интегрирует Popup в слой интерфейса карты, создавая соответствующий DOM-узел внутри контейнера Mapbox. При этом Popup не является частью слоя данных — он относится к UI-слою (overlay layer).

Удаление выполняется методом:

popup.remove();

После удаления DOM-узел уничтожается или деактивируется в зависимости от внутреннего состояния экземпляра.

Управление содержимым

Popup поддерживает несколько способов задания содержимого.

HTML-содержимое

popup.setHTML("<strong>Точка интереса</strong><br>Описание объекта");

Метод setHTML интерпретирует строку как HTML-разметку и вставляет её внутрь контейнера Popup. Это наиболее гибкий, но потенциально рискованный способ из-за возможности инъекций при работе с внешними данными.

Текстовое содержимое

popup.setText("Точка интереса");

setText экранирует HTML-символы и гарантирует безопасный вывод строки без интерпретации разметки.

DOM-элемент

const container = document.createElement("div");
container.innerText = "Информация";

popup.setDOMContent(container);

Метод setDOMContent позволяет передать готовый DOM-узел, обеспечивая полный контроль над структурой и поведением содержимого, включая вложенные события и компоненты.

Позиционирование и якоря

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

  • top
  • bottom
  • left
  • right
  • top-left
  • top-right
  • bottom-left
  • bottom-right

При использовании anchor: "auto" библиотека самостоятельно выбирает оптимальное расположение, избегая выхода за границы viewport.

Дополнительно применяется offset, который может задаваться числом или массивом:

offset: 10

или

offset: [0, -20]

Смещение позволяет адаптировать Popup под маркеры или сложные визуальные композиции.

Поведение при взаимодействии с картой

Popup может реагировать на изменения состояния карты:

  • closeOnClick: true — закрытие при клике по карте
  • closeOnMove: true — закрытие при панорамировании или масштабировании

Эти параметры используются для управления жизненным циклом всплывающих окон в динамических интерфейсах.

Пример сценария:

const popup = new mapboxgl.Popup({
  closeOnClick: true,
  closeOnMove: false
});

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

Привязка к маркерам

Наиболее распространённый сценарий — связывание Popup с маркером:

const marker = new mapboxgl.Marker()
  .setLngLat([30.5, 50.5])
  .setPopup(
    new mapboxgl.Popup().setText("Маркер на карте")
  )
  .addTo(map);

В этом случае Popup автоматически открывается при взаимодействии с маркером. Внутренне Mapbox GL JS синхронизирует события DOM-слоя маркера с состоянием Popup.

Методы управления состоянием

toggle()

Popup не имеет явного метода toggle, но подобная логика реализуется вручную:

if (popup.isOpen()) {
  popup.remove();
} else {
  popup.addTo(map);
}

getLngLat()

const lngLat = popup.getLngLat();

Возвращает текущие координаты привязки, что важно при динамическом перемещении объектов.

isOpen()

Некоторые реализации используют проверку состояния через внутренние флаги экземпляра или DOM-проверку.

Трекинг курсора

Опция trackPointer позволяет привязать Popup к положению курсора мыши:

const popup = new mapboxgl.Popup({
  trackPointer: true
});

В этом режиме координаты обновляются в реальном времени при движении мыши по карте. Это используется для интерактивных подсказок и hover-информации.

Стилизация Popup

Визуальное оформление контролируется через CSS. Базовая структура включает:

  • .mapboxgl-popup
  • .mapboxgl-popup-content
  • .mapboxgl-popup-tip
  • .mapboxgl-popup-close-button

Пример переопределения:

.mapboxgl-popup-content {
  background: #1e1e1e;
  color: #ffffff;
  border-radius: 8px;
  padding: 12px;
}

Изменение стилей позволяет интегрировать Popup в дизайн интерфейса без ограничения стандартной темы.

Жизненный цикл экземпляра

Popup проходит несколько стадий:

  1. Создание экземпляра через конструктор
  2. Привязка координат через setLngLat
  3. Добавление на карту через addTo
  4. Отображение в DOM
  5. Обновление позиции при трансформациях карты
  6. Удаление через remove

Каждый этап синхронизирован с внутренним event-loop Mapbox GL JS и системой рендеринга WebGL-карты.

Ограничения и особенности поведения

Popup не является частью WebGL-слоя и не рендерится через GPU. Он накладывается поверх canvas как HTML-элемент, что определяет ряд особенностей:

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

Эти особенности влияют на архитектуру интерфейсов с большим количеством интерактивных точек.