Google Maps JavaScript API предоставляет несколько способов размещения пользовательских элементов поверх карты. Помимо стандартных маркеров, полигонов и информационных окон, часто возникает необходимость отображать полноценные HTML-блоки: карточки объектов, панели управления, подписи, всплывающие окна, индикаторы состояния, элементы интерфейса и интерактивные компоненты.
Использование HTML позволяет:
Основным инструментом для размещения HTML поверх карты является механизм наложений (Overlay).
В Google Maps JavaScript API существует несколько подходов:
OverlayView.AdvancedMarkerElement).Каждый вариант подходит для разных задач.
Элементы управления располагаются по краям карты и не привязаны к координатам.
<div id="map"></div>
<div id="panel">
<h3>Панель управления</h3>
<button>Обновить данные</button>
</div>
const map = new google.maps.Map(
document.getElementById("map"),
{
center: {
lat: 55.7558,
lng: 37.6176
},
zoom: 12
}
);
const panel = document.getElementById("panel");
map.controls[
google.maps.ControlPosition.TOP_LEFT
].push(panel);
После выполнения кода HTML-блок становится частью интерфейса карты.
Объекты можно размещать в различных областях карты.
google.maps.ControlPosition.TOP_LEFT
google.maps.ControlPosition.TOP_CENTER
google.maps.ControlPosition.TOP_RIGHT
google.maps.ControlPosition.LEFT_TOP
google.maps.ControlPosition.LEFT_CENTER
google.maps.ControlPosition.LEFT_BOTTOM
google.maps.ControlPosition.RIGHT_TOP
google.maps.ControlPosition.RIGHT_CENTER
google.maps.ControlPosition.RIGHT_BOTTOM
google.maps.ControlPosition.BOTTOM_LEFT
google.maps.ControlPosition.BOTTOM_CENTER
google.maps.ControlPosition.BOTTOM_RIGHT
Пример:
map.controls[
google.maps.ControlPosition.BOTTOM_RIGHT
].push(panel);
Поскольку используется обычный HTML, оформление выполняется средствами CSS.
#panel {
background: white;
padding: 15px;
border-radius: 8px;
box-shadow: 0 3px 10px rgba(0,0,0,0.2);
font-family: Arial, sans-serif;
}
#panel button {
margin-top: 10px;
width: 100%;
}
Подобный подход позволяет создавать панели фильтрации, навигационные меню, легенды карты и инструменты поиска.
Информационные окна поддерживают HTML-содержимое.
const infoWindow =
new google.maps.InfoWindow({
content: `
<div class="card">
<h3>Москва</h3>
<p>Столица России</p>
</div>
`
});
marker.addListener("click", () => {
infoWindow.open({
anchor: marker,
map
});
});
HTML внутри окна может содержать:
Пример карточки объекта недвижимости:
const infoWindow =
new google.maps.InfoWindow({
content: `
<div class="property-card">
<img
src="house.jpg"
width="250"
>
<h2>Дом у озера</h2>
<p>
Площадь: 180 м²
</p>
<button>
Подробнее
</button>
</div>
`
});
Такой способ удобен для отображения информации, однако окно ограничено стандартным поведением Google Maps.
Для полного контроля обычно используют пользовательские наложения.
Класс OverlayView предоставляет прямой доступ к слоям
карты и позволяет размещать любые DOM-элементы в географических
координатах.
Это основной механизм для создания:
Для создания наложения необходимо наследоваться от
OverlayView.
Минимальная структура:
class CustomOverlay
extends google.maps.OverlayView {
onAdd() {
}
draw() {
}
onRemove() {
}
}
Каждый метод отвечает за отдельный этап жизненного цикла.
Вызывается после добавления наложения на карту.
В этом методе обычно:
Пример:
onAdd() {
this.div =
document.createElement("div");
this.div.className =
"custom-overlay";
this.div.innerHTML =
"<strong>Объект</strong>";
}
Метод отвечает за позиционирование элемента на карте.
Для вычисления координат используется проекция карты.
draw() {
const projection =
this.getProjection();
const position =
projection.fromLatLngToDivPixel(
this.position
);
this.div.style.left =
position.x + "px";
this.div.style.top =
position.y + "px";
}
Каждый раз при изменении масштаба или перемещении карты метод вызывается повторно.
Удаляет элемент из DOM.
onRemove() {
if (this.div) {
this.div.remove();
this.div = null;
}
}
class CustomOverlay
extends google.maps.OverlayView {
constructor(position, text) {
super();
this.position = position;
this.text = text;
}
onAdd() {
this.div =
document.createElement("div");
this.div.className =
"overlay";
this.div.innerHTML =
this.text;
const panes =
this.getPanes();
panes.overlayMouseTarget
.appendChild(this.div);
}
draw() {
const projection =
this.getProjection();
const pixel =
projection
.fromLatLngToDivPixel(
this.position
);
this.div.style.left =
pixel.x + "px";
this.div.style.top =
pixel.y + "px";
}
onRemove() {
this.div.remove();
}
}
const overlay =
new CustomOverlay(
{
lat: 55.7558,
lng: 37.6176
},
"Москва"
);
overlay.setMap(map);
Google Maps использует несколько уровней отображения.
Получить их можно через:
const panes =
this.getPanes();
Доступны следующие панели:
panes.mapPane
panes.overlayLayer
panes.overlayShadow
panes.overlayImage
panes.overlayMouseTarget
panes.floatPane
Базовый слой карты.
Используется редко.
panes.mapPane
Слой для графических наложений.
panes.overlayLayer
Поддерживает взаимодействие мышью.
panes.overlayMouseTarget
Для большинства HTML-компонентов используется именно этот слой.
Находится поверх остальных.
В нём отображаются информационные окна.
panes.floatPane
Подходит для всплывающих панелей.
Поскольку используется обычный DOM, можно подключать обработчики событий.
this.div.addEventListener(
"click",
() => {
console.log(
"Клик по элементу"
);
}
);
Также доступны:
mouseenter
mouseleave
mousedown
mouseup
dblclick
contextmenu
this.div.innerHTML = `
<div class="card">
<h3>Магазин</h3>
<button id="show">
Открыть
</button>
</div>
`;
После вставки элемента можно назначить обработчик:
this.div
.querySelector("#show")
.addEventListener(
"click",
() => {
alert("Открытие");
}
);
HTML-наложения поддерживают любые CSS-анимации.
.overlay {
animation:
pulse 1s infinite;
}
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.2);
}
100% {
transform: scale(1);
}
}
Это позволяет создавать:
Каждый элемент может отображаться в конкретной точке карты.
new google.maps.LatLng(
55.7558,
37.6176
);
или
{
lat: 55.7558,
lng: 37.6176
}
При перемещении карты элемент автоматически перемещается вместе с координатой.
Обычно элемент необходимо располагать над координатой.
this.div.style.transform =
"translate(-50%, -100%)";
Такой подход позволяет:
В новых версиях API рекомендуется использовать HTML внутри современных маркеров.
const content =
document.createElement("div");
content.className =
"marker";
content.innerHTML =
"<strong>Кафе</strong>";
const marker =
new google.maps.marker
.AdvancedMarkerElement({
map,
position: {
lat: 55.7558,
lng: 37.6176
},
content
});
По сравнению с классическим Marker:
const card =
document.createElement("div");
card.innerHTML = `
<div class="place-card">
<h4>Ресторан</h4>
<span>Рейтинг: 4.8</span>
</div>
`;
new google.maps.marker
.AdvancedMarkerElement({
map,
position: {
lat: 55.76,
lng: 37.61
},
content: card
});
В результате вместо обычного маркера отображается полноценный HTML-блок.
Скрытие:
this.div.style.display =
"none";
Отображение:
this.div.style.display =
"block";
Для AdvancedMarkerElement:
marker.content.style.display =
"none";
HTML можно изменять в любой момент.
this.div.innerHTML =
"<b>Новые данные</b>";
Либо:
card.querySelector(".title")
.textContent =
"Новое название";
Это полезно при обновлении данных через AJAX или WebSocket.
Для пользовательских наложений:
overlay.setMap(null);
После вызова автоматически выполнится:
onRemove()
Для современных маркеров:
marker.map = null;
HTML-элементы значительно тяжелее обычных маркеров.
При разработке крупных карт рекомендуется:
AdvancedMarkerElement вместо сложных
пользовательских наложений там, где это возможно.Особенно заметно снижение производительности при одновременном отображении нескольких тысяч HTML-компонентов.
<div class="price-tag">
15 000 000 ₽
</div>
<div class="shop-marker">
Магазин
</div>
<div class="bus-marker">
Автобус №42
</div>
<div class="popup-card">
<h3>Объект</h3>
<p>Описание</p>
</div>
<div class="filter-panel">
...
</div>
<div class="legend">
...
</div>
Благодаря сочетанию OverlayView,
AdvancedMarkerElement, стандартного DOM и CSS Google Maps
JavaScript API позволяет размещать на карте практически любые
HTML-компоненты, создавая интерфейсы любой сложности — от простых
подписей до полноценных интерактивных приложений с динамическими
карточками, фильтрами и визуальными панелями управления.