Контролы (Controls) в Google Maps JavaScript API представляют собой элементы пользовательского интерфейса, размещаемые поверх карты. К стандартным контролам относятся кнопки изменения масштаба, переключатель типа карты, управление полноэкранным режимом, инструмент просмотра улиц и другие элементы. Помимо встроенных компонентов API позволяет создавать и размещать собственные пользовательские контролы в любой части карты.
Грамотное позиционирование контролов является важной частью разработки интерфейса картографических приложений. От расположения элементов управления зависит удобство навигации, доступность функций и внешний вид приложения.
Каждая карта содержит набор специальных контейнеров, привязанных к определённым областям интерфейса. Контролы помещаются именно в эти контейнеры.
Для задания позиции используется перечисление
google.maps.ControlPosition.
Пример:
map.controls[google.maps.ControlPosition.TOP_LEFT]
Каждая позиция соответствует определённой области карты.
Схематично расположение выглядит следующим образом:
+--------------------------------------------------+
| TOP_LEFT TOP_CENTER TOP_RIGHT |
| |
| LEFT_TOP RIGHT_TOP |
| |
| LEFT_CENTER RIGHT_CENTER |
| |
| LEFT_BOTTOM RIGHT_BOTTOM |
| |
| BOTTOM_LEFT BOTTOM_CENTER BOTTOM_RIGHT |
+--------------------------------------------------+
Основные позиции контролов:
| Позиция | Расположение |
|---|---|
TOP_LEFT |
Верхний левый угол |
TOP_CENTER |
Верхняя центральная область |
TOP_RIGHT |
Верхний правый угол |
LEFT_TOP |
Левая сторона сверху |
LEFT_CENTER |
Левая сторона по центру |
LEFT_BOTTOM |
Левая сторона снизу |
RIGHT_TOP |
Правая сторона сверху |
RIGHT_CENTER |
Правая сторона по центру |
RIGHT_BOTTOM |
Правая сторона снизу |
BOTTOM_LEFT |
Нижний левый угол |
BOTTOM_CENTER |
Нижняя центральная область |
BOTTOM_RIGHT |
Нижний правый угол |
Каждая из этих позиций представляет отдельный контейнер DOM-элементов.
Большинство стандартных контролов имеют собственные настройки позиции.
Например, контрол масштабирования можно перенести в правый верхний угол:
const map = new google.maps.Map(
document.getElementById("map"),
{
center: { lat: 55.7558, lng: 37.6176 },
zoom: 10,
zoomControl: true,
zoomControlOptions: {
position: google.maps.ControlPosition.TOP_RIGHT
}
}
);
После загрузки карты кнопки масштабирования окажутся в указанной области.
Контрол выбора типа карты (MapTypeControl) также
поддерживает изменение позиции.
const map = new google.maps.Map(
document.getElementById("map"),
{
mapTypeControl: true,
mapTypeControlOptions: {
position: google.maps.ControlPosition.TOP_LEFT
}
}
);
По умолчанию расположение зависит от версии API и используемой темы интерфейса, поэтому явное указание позиции обеспечивает предсказуемое поведение.
Контрол полноэкранного отображения карты можно перемещать аналогичным образом.
const map = new google.maps.Map(
document.getElementById("map"),
{
fullscreenControl: true,
fullscreenControlOptions: {
position: google.maps.ControlPosition.RIGHT_TOP
}
}
);
Такое решение часто используется в приложениях с большим количеством собственных инструментов в верхней части карты.
Инструмент перехода в режим панорам также поддерживает настройку позиции.
const map = new google.maps.Map(
document.getElementById("map"),
{
streetViewControl: true,
streetViewControlOptions: {
position: google.maps.ControlPosition.RIGHT_BOTTOM
}
}
);
Перемещение Street View позволяет избежать пересечения с другими элементами интерфейса.
Несколько встроенных контролов могут быть размещены в разных областях карты.
const map = new google.maps.Map(
document.getElementById("map"),
{
zoomControl: true,
mapTypeControl: true,
streetViewControl: true,
fullscreenControl: true,
zoomControlOptions: {
position: google.maps.ControlPosition.RIGHT_CENTER
},
mapTypeControlOptions: {
position: google.maps.ControlPosition.TOP_LEFT
},
streetViewControlOptions: {
position: google.maps.ControlPosition.RIGHT_BOTTOM
},
fullscreenControlOptions: {
position: google.maps.ControlPosition.TOP_RIGHT
}
}
);
Подобная организация интерфейса позволяет избежать наложения элементов друг на друга.
Пользовательский контрол представляет собой обычный DOM-элемент.
Создадим кнопку сброса масштаба:
const button = document.createElement("button");
button.textContent = "Сбросить масштаб";
button.style.background = "#fff";
button.style.border = "2px solid #ccc";
button.style.padding = "10px";
button.style.cursor = "pointer";
Добавим обработчик:
button.addEventListener("click", () => {
map.setZoom(8);
});
Теперь элемент можно разместить на карте.
Контрол помещается в нужный контейнер через массив
map.controls.
map.controls[
google.maps.ControlPosition.TOP_CENTER
].push(button);
После выполнения кода кнопка появится в верхней центральной части карты.
Свойство controls содержит коллекцию контейнеров для
всех доступных позиций.
Пример доступа:
const topLeftControls =
map.controls[
google.maps.ControlPosition.TOP_LEFT
];
Каждая позиция представляет объект типа MVCArray.
Можно добавлять элементы:
topLeftControls.push(button);
Удалять:
topLeftControls.removeAt(0);
Получать количество элементов:
console.log(topLeftControls.getLength());
Получать элемент по индексу:
console.log(topLeftControls.getAt(0));
Если несколько элементов добавляются в один контейнер, порядок определяется последовательностью вставки.
Пример:
controls.push(button1);
controls.push(button2);
controls.push(button3);
На экране элементы будут расположены следующим образом:
button1
button2
button3
Первый добавленный элемент оказывается ближе к краю контейнера.
Порядок можно изменять программно.
const controls =
map.controls[
google.maps.ControlPosition.TOP_LEFT
];
const control = controls.removeAt(0);
controls.push(control);
После удаления и повторного добавления элемент переместится в конец списка.
Часто несколько кнопок объединяют в единый контейнер.
const panel = document.createElement("div");
panel.style.display = "flex";
panel.style.flexDirection = "column";
Создание кнопок:
const zoomIn = document.createElement("button");
zoomIn.textContent = "+";
const zoomOut = document.createElement("button");
zoomOut.textContent = "-";
panel.appendChild(zoomIn);
panel.appendChild(zoomOut);
Размещение:
map.controls[
google.maps.ControlPosition.LEFT_TOP
].push(panel);
Такой подход позволяет создавать панели инструментов любой сложности.
Контейнер карты определяет только общую область размещения. Более точное расположение можно задавать через CSS.
button.style.marginTop = "15px";
button.style.marginLeft = "10px";
Пример:
const control = document.createElement("div");
control.style.margin = "20px";
control.style.padding = "10px";
control.style.background = "#fff";
После добавления контрол будет смещён относительно стандартного положения контейнера.
На мобильных устройствах пространство ограничено, поэтому часто используется динамическое изменение расположения контролов.
const position =
window.innerWidth < 768
? google.maps.ControlPosition.BOTTOM_CENTER
: google.maps.ControlPosition.TOP_RIGHT;
map.controls[position].push(button);
Подобная техника позволяет улучшить удобство использования интерфейса на смартфонах и планшетах.
Контрол можно удалять из одной области и добавлять в другую.
const oldPosition =
map.controls[
google.maps.ControlPosition.TOP_LEFT
];
const control = oldPosition.removeAt(0);
Добавление:
map.controls[
google.maps.ControlPosition.BOTTOM_RIGHT
].push(control);
Такой механизм используется для адаптации интерфейса под различные режимы работы приложения.
Удаление из контейнера приводит к исчезновению элемента с карты.
const controls =
map.controls[
google.maps.ControlPosition.TOP_RIGHT
];
const control = controls.removeAt(0);
Для возврата:
controls.push(control);
DOM-элемент сохраняется и может использоваться повторно.
Подходит для:
Обычно используется для:
Часто содержат:
Используются редко, поскольку перекрывают карту и ухудшают обзор.
Для большинства картографических приложений хорошо подходит следующая конфигурация:
mapTypeControlOptions: {
position: google.maps.ControlPosition.TOP_LEFT
},
zoomControlOptions: {
position: google.maps.ControlPosition.RIGHT_TOP
},
fullscreenControlOptions: {
position: google.maps.ControlPosition.RIGHT_TOP
},
streetViewControlOptions: {
position: google.maps.ControlPosition.RIGHT_BOTTOM
}
Подобная организация интерфейса соответствует распространённым паттернам современных веб-карт и обеспечивает удобное распределение элементов управления по различным зонам карты.