В MapLibre GL JS попапы являются DOM-элементами, привязанными к координатам карты или к конкретным объектам слоя. Их позиционирование определяется системой экранных координат, преобразуемых из географических, а также набором параметров якоря, смещения и поведения при изменении состояния карты. Корректная работа с попапами требует понимания того, как библиотека рассчитывает их размещение относительно слоя тайлов и текущего матричного преобразования карты.
Каждый popup существует в двух системах координат:
При добавлении popup через setLngLat([lng, lat])
происходит преобразование в пиксельную систему с учётом текущего
масштаба, центра карты, наклона и вращения.
new maplibregl.Popup()
.setLngLat([30.5, 50.45])
.setText('Точка интереса')
.addTo(map);
В момент рендеринга карта вычисляет позицию якоря, после чего DOM-элемент popup помещается в overlay-контейнер поверх canvas.
Ключевым механизмом управления расположением popup является свойство
anchor. Оно определяет, какой точкой всплывающего окна
будет привязка к координате.
Основные значения:
center — центр popup привязан к координатеtop — нижняя часть popup находится над точкойbottom — верхняя часть popup находится под точкойleft — правый край popup указывает на точкуright — левый край popup указывает на точкуtop-left, top-right,
bottom-left, bottom-right)new maplibregl.Popup({
anchor: 'bottom',
})
.setLngLat([30.5, 50.45])
.setText('Anchored popup')
.addTo(map);
Механизм anchor влияет не только на визуальное положение, но и на расчёт автоматического смещения при приближении к границам viewport.
Если anchor не задан, библиотека выполняет
автоматический выбор на основе доступного пространства вокруг точки.
Алгоритм анализирует:
В результате popup стремится оставаться полностью видимым без выхода за границы экрана.
Это поведение особенно заметно при размещении точек рядом с краями карты, где popup может «переворачиваться» вверх или вниз.
Параметр offset позволяет вручную корректировать позицию
popup относительно точки привязки. Он может быть задан:
new maplibregl.Popup({
offset: 20
})
.setLngLat([30.5, 50.45])
.setText('Offset popup')
.addTo(map);
Более точная форма управления:
new maplibregl.Popup({
offset: {
top: [0, 10],
bottom: [0, -10],
left: [10, 0],
right: [-10, 0]
}
});
Каждое значение задаёт смещение относительно конкретного anchor-состояния. Это важно при создании кастомных popup с нестандартной геометрией (например, с хвостом или асимметричным блоком).
Popup может быть привязан как к произвольной координате, так и к feature слоя:
map.on('click', 'cities-layer', (e) => {
const coordinates = e.features[0].geometry.coordinates.slice();
new maplibregl.Popup()
.setLngLat(coordinates)
.setHTML('<strong>Город</strong>')
.addTo(map);
});
При работе с GeoJSON слоями важно учитывать, что координаты могут быть копиями массива, особенно при работе с многополигональными структурами.
Popup автоматически пересчитывает своё положение при:
Каждое изменение матрицы карты вызывает перерасчёт screen projection.
Это означает, что popup не фиксируется в DOM относительно окна браузера, а привязан к географической точке через постоянную трансформацию.
При резких изменениях масштаба возможны кратковременные смещения, связанные с пересчётом тайлового слоя.
Если popup выходит за пределы viewport, библиотека применяет алгоритм auto-padding и repositioning. Он включает:
Это поведение контролируется через параметры карты
(padding), которые влияют на допустимую область размещения
UI-элементов.
При включённом наклоне карты (pitch) и вращении
(bearing) popup остаётся ориентированным к экрану, а не к
географической плоскости.
Это означает:
Особенно важно при больших значениях pitch, когда перспектива сильно искажает расстояния.
Popup в MapLibre GL JS представляет собой DOM-узел со следующей структурой:
Можно переопределить содержимое:
new maplibregl.Popup({ closeButton: false })
.setHTML(`
<div class="custom-popup">
<h3>Объект</h3>
<p>Описание точки</p>
</div>
`)
.setLngLat([30.5, 50.45])
.addTo(map);
Стилизация влияет на расчёт размеров, а значит и на автоматический выбор anchor.
При изменении содержимого popup через setHTML или
setText происходит:
Это особенно критично при асинхронной подгрузке данных (например, API-запросах), когда размеры popup неизвестны заранее.
Одновременное отображение нескольких popup требует учёта перекрытий. В стандартной конфигурации каждый popup:
Для управления слоями используются CSS z-index и стратегия группировки UI-элементов поверх карты.
Позиционирование popup связано с постоянными recalculation циклами при движении карты. Основные источники нагрузки:
При большом количестве popup рекомендуется:
При использовании бесшовного мира карта создаёт копии координат по оси longitude. Popup всегда привязывается к ближайшей копии координаты, чтобы избежать резких скачков при переходе через ±180°.
Это поведение обеспечивает визуальную стабильность при глобальном масштабировании и перемещении.
Popup может участвовать в автоцентрировании карты, если включено
соответствующее поведение (map.easeTo, flyTo в
связке с popup). В таких случаях:
Это используется при сценариях «показать объект и сразу выделить его информацией».
Выбор anchor напрямую зависит от:
Неправильная конфигурация anchor часто приводит к:
Поэтому фиксированный anchor предпочтителен в интерфейсах с предсказуемым layout, тогда как auto-anchor — в интерактивных аналитических картах.
Механизм позиционирования popup в MapLibre GL JS можно рассматривать как комбинацию трёх слоёв:
Эти уровни работают синхронно, обеспечивая стабильное отображение popup в условиях постоянного изменения матрицы карты и пользовательских взаимодействий.