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

Google Maps JavaScript API предоставляет несколько способов размещения пользовательских элементов поверх карты. Помимо стандартных маркеров, полигонов и информационных окон, часто возникает необходимость отображать полноценные HTML-блоки: карточки объектов, панели управления, подписи, всплывающие окна, индикаторы состояния, элементы интерфейса и интерактивные компоненты.

Использование HTML позволяет:

  • применять обычную HTML-разметку;
  • использовать CSS для оформления;
  • подключать JavaScript-обработчики событий;
  • создавать сложные пользовательские интерфейсы;
  • интегрировать сторонние библиотеки визуализации.

Основным инструментом для размещения HTML поверх карты является механизм наложений (Overlay).


Способы отображения HTML на карте

В Google Maps JavaScript API существует несколько подходов:

  1. Использование элементов управления карты (Controls).
  2. Использование информационных окон (InfoWindow).
  3. Использование пользовательских наложений через OverlayView.
  4. Использование современных кастомных маркеров (AdvancedMarkerElement).

Каждый вариант подходит для разных задач.


Размещение HTML через элементы управления карты

Элементы управления располагаются по краям карты и не привязаны к координатам.

Создание HTML-блока

<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 через InfoWindow

Информационные окна поддерживают 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 внутри окна может содержать:

  • изображения;
  • таблицы;
  • кнопки;
  • формы;
  • ссылки;
  • встроенные компоненты.

Использование сложного HTML в InfoWindow

Пример карточки объекта недвижимости:

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.

Для полного контроля обычно используют пользовательские наложения.


Пользовательские HTML-наложения через OverlayView

Класс OverlayView предоставляет прямой доступ к слоям карты и позволяет размещать любые DOM-элементы в географических координатах.

Это основной механизм для создания:

  • пользовательских маркеров;
  • ценников;
  • подписей;
  • карточек объектов;
  • индикаторов;
  • всплывающих панелей;
  • анимированных элементов.

Структура OverlayView

Для создания наложения необходимо наследоваться от OverlayView.

Минимальная структура:

class CustomOverlay
    extends google.maps.OverlayView {

    onAdd() {

    }

    draw() {

    }

    onRemove() {

    }
}

Каждый метод отвечает за отдельный этап жизненного цикла.


Метод onAdd()

Вызывается после добавления наложения на карту.

В этом методе обычно:

  • создаётся HTML;
  • назначаются стили;
  • добавляются обработчики событий.

Пример:

onAdd() {

    this.div =
        document.createElement("div");

    this.div.className =
        "custom-overlay";

    this.div.innerHTML =
        "<strong>Объект</strong>";

}

Метод draw()

Метод отвечает за позиционирование элемента на карте.

Для вычисления координат используется проекция карты.

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";
}

Каждый раз при изменении масштаба или перемещении карты метод вызывается повторно.


Метод onRemove()

Удаляет элемент из DOM.

onRemove() {

    if (this.div) {

        this.div.remove();

        this.div = null;
    }

}

Полноценный пример HTML-наложения

Создание класса

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);

Слои карты (Map Panes)

Google Maps использует несколько уровней отображения.

Получить их можно через:

const panes =
    this.getPanes();

Доступны следующие панели:

panes.mapPane
panes.overlayLayer
panes.overlayShadow
panes.overlayImage
panes.overlayMouseTarget
panes.floatPane

mapPane

Базовый слой карты.

Используется редко.

panes.mapPane

overlayLayer

Слой для графических наложений.

panes.overlayLayer

overlayMouseTarget

Поддерживает взаимодействие мышью.

panes.overlayMouseTarget

Для большинства HTML-компонентов используется именно этот слой.


floatPane

Находится поверх остальных.

В нём отображаются информационные окна.

panes.floatPane

Подходит для всплывающих панелей.


Создание интерактивного HTML-элемента

Поскольку используется обычный 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("Открытие");
        }
    );

Использование CSS-анимаций

HTML-наложения поддерживают любые CSS-анимации.

.overlay {
    animation:
        pulse 1s infinite;
}

@keyframes pulse {

    0% {
        transform: scale(1);
    }

    50% {
        transform: scale(1.2);
    }

    100% {
        transform: scale(1);
    }

}

Это позволяет создавать:

  • мигающие индикаторы;
  • подсветку объектов;
  • эффекты появления;
  • анимированные подсказки.

Привязка HTML к географическим координатам

Каждый элемент может отображаться в конкретной точке карты.

new google.maps.LatLng(
    55.7558,
    37.6176
);

или

{
    lat: 55.7558,
    lng: 37.6176
}

При перемещении карты элемент автоматически перемещается вместе с координатой.


Смещение HTML-элемента относительно точки

Обычно элемент необходимо располагать над координатой.

this.div.style.transform =
    "translate(-50%, -100%)";

Такой подход позволяет:

  • центрировать элемент;
  • размещать карточку над маркером;
  • создавать пользовательские подписи.

Современный способ: AdvancedMarkerElement

В новых версиях 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
        });

Преимущества AdvancedMarkerElement

По сравнению с классическим Marker:

  • поддерживает HTML;
  • поддерживает CSS;
  • обеспечивает более гибкую стилизацию;
  • лучше подходит для современных интерфейсов;
  • интегрируется с DOM напрямую.

Создание карточек объектов через AdvancedMarkerElement

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-блок.


Управление видимостью 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.


Удаление HTML-элементов

Для пользовательских наложений:

overlay.setMap(null);

После вызова автоматически выполнится:

onRemove()

Для современных маркеров:

marker.map = null;

Производительность при большом количестве HTML-элементов

HTML-элементы значительно тяжелее обычных маркеров.

При разработке крупных карт рекомендуется:

  • минимизировать количество DOM-узлов;
  • избегать сложных CSS-эффектов;
  • использовать кластеризацию объектов;
  • удалять невидимые элементы;
  • применять виртуализацию при больших объёмах данных;
  • использовать 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-компоненты, создавая интерфейсы любой сложности — от простых подписей до полноценных интерактивных приложений с динамическими карточками, фильтрами и визуальными панелями управления.