Управление видимостью элементов интерфейса

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

Элементы управления картой (controls) представляют собой предопределённые UI-компоненты: масштабирование, переключение типа карты, Street View, полноэкранный режим, масштабная линейка. Их видимость регулируется через конфигурацию объекта карты при инициализации и через метод обновления опций.

Основной механизм — свойство mapOptions.controls и набор специализированных флагов:

const map = new google.maps.Map(document.getElementById("map"), {
  center: { lat: 40.73061, lng: -73.935242 },
  zoom: 12,
  zoomControl: true,
  mapTypeControl: true,
  streetViewControl: true,
  fullscreenControl: true,
  scaleControl: true
});

Каждый из флагов управляет отдельным элементом интерфейса. Изменение состояния после инициализации выполняется через setOptions:

map.setOptions({
  zoomControl: false,
  mapTypeControl: false
});

Такой подход позволяет динамически адаптировать интерфейс в зависимости от режима работы приложения, например при переходе в режим аналитики или минималистичного отображения.

Управление позиционированием элементов управления

Видимость элементов часто дополняется их расположением. Google Maps предоставляет механизм ControlPosition, позволяющий закреплять элементы в разных углах карты.

map.setOptions({
  zoomControlOptions: {
    position: google.maps.ControlPosition.RIGHT_CENTER
  },
  mapTypeControlOptions: {
    position: google.maps.ControlPosition.TOP_LEFT
  }
});

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

Видимость маркеров

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

const marker = new google.maps.Marker({
  position: { lat: 40.73061, lng: -73.935242 },
  map: map,
  title: "Точка интереса",
  visible: true
});

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

marker.setVisible(false);

Такой подход важен для производительности, поскольку повторное создание маркеров требует перерасчёта слоёв и перерисовки карты. При этом сохранение экземпляра позволяет быстро восстановить отображение.

Для групп маркеров часто используется внешняя логика фильтрации:

markers.forEach(m => {
  if (m.type === "restaurant") {
    m.setVisible(true);
  } else {
    m.setVisible(false);
  }
});

Оверлеи и пользовательские слои

Оверлеи (overlays) включают полилинии, полигоны, окружности и кастомные элементы, привязанные к географическим координатам. Их видимость также управляется через setMap и setVisible (в зависимости от типа объекта).

Полигон:

const polygon = new google.maps.Polygon({
  paths: coordinates,
  strokeColor: "#FF0000",
  fillColor: "#FF0000",
  map: map
});

Скрытие:

polygon.setMap(null);

Возврат на карту:

polygon.setMap(map);

Такой механизм полностью отключает объект от рендеринга, освобождая ресурсы.

Для более тонкого управления используется изменение стилей:

polygon.setOptions({
  strokeOpacity: 0,
  fillOpacity: 0
});

Это позволяет сохранять объект в DOM-сцене карты, но визуально скрывать его.

Информационные окна

InfoWindow является динамическим элементом интерфейса, отображающим контекстную информацию. Его видимость управляется через методы open и close.

const infoWindow = new google.maps.InfoWindow({
  content: "<div>Информация о точке</div>"
});

Открытие:

infoWindow.open({
  anchor: marker,
  map: map
});

Закрытие:

infoWindow.close();

В сложных интерфейсах применяется логика единственного активного окна, где перед открытием нового экземпляра закрывается предыдущий.

Управление слоями карты

Слои (layers) определяют дополнительные информационные надстройки: трафик, транспорт, границы, велодорожки. Их видимость регулируется через методы setMap.

const trafficLayer = new google.maps.TrafficLayer();
trafficLayer.setMap(map);

Скрытие слоя:

trafficLayer.setMap(null);

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

Контроль видимости через состояние карты

Состояние карты влияет на отображение элементов интерфейса косвенно. Например, изменение масштаба может скрывать или группировать маркеры, а изменение границ карты — фильтровать данные.

map.addListener("zoom_changed", () => {
  const zoom = map.getZoom();

  markers.forEach(marker => {
    marker.setVisible(zoom > 10);
  });
});

Такой подход используется для кластеризации и оптимизации визуальной плотности данных.

Аналогично, изменение границ:

map.addListener("bounds_changed", () => {
  const bounds = map.getBounds();

  markers.forEach(marker => {
    if (bounds.contains(marker.getPosition())) {
      marker.setVisible(true);
    } else {
      marker.setVisible(false);
    }
  });
});

Управление пользовательскими контролами

Кастомные элементы управления добавляются в массив controls, где каждая позиция соответствует области интерфейса.

const controlDiv = document.createElement("div");
controlDiv.innerHTML = "Фильтр";

map.controls[google.maps.ControlPosition.TOP_RIGHT].push(controlDiv);

Видимость таких элементов управляется напрямую через DOM:

controlDiv.style.display = "none";

или

controlDiv.style.visibility = "hidden";

Выбор между display и visibility влияет на перерасчёт layout карты и поведение соседних элементов.

Динамическое переключение режимов интерфейса

Комплексные приложения используют набор состояний интерфейса, где видимость элементов определяется режимом работы: просмотр, редактирование, аналитика.

function setEditMode(enabled) {
  map.setOptions({
    draggable: !enabled,
    zoomControl: !enabled,
    streetViewControl: !enabled
  });

  markers.forEach(m => m.setVisible(enabled));
}

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

Оптимизация при массовом изменении видимости

При работе с большим количеством объектов изменение видимости должно минимизировать количество перерисовок. Используются пакетные операции и временное отключение обновлений.

function hideAllMarkers() {
  for (let i = 0; i < markers.length; i++) {
    markers[i].setVisible(false);
  }
}

Для сложных сцен применяется временное удаление слоя:

map.data.setStyle({ visible: false });

или полное отключение Data Layer:

map.data.forEach(feature => {
  map.data.remove(feature);
});

Видимость элементов Data Layer

Data Layer позволяет работать с геоданными в формате GeoJSON. Управление видимостью осуществляется через стилизацию.

map.data.setStyle(feature => {
  return {
    visible: feature.getProperty("active") === true
  };
});

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

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

Видимость элементов может зависеть от размеров контейнера. При динамическом изменении DOM необходимо инициировать перерасчёт:

google.maps.event.trigger(map, "resize");
map.setCenter({ lat: 40.73061, lng: -73.935242 });

Без этого UI-элементы могут смещаться или скрываться за пределами видимой области.

Управление прозрачностью как альтернативный способ скрытия

Вместо полного скрытия объектов применяется изменение прозрачности:

marker.setOpacity(0);

или для линий и полигонов:

polyline.setOptions({
  strokeOpacity: 0
});

Такой метод сохраняет интерактивность объекта, позволяя обрабатывать события даже при визуальной невидимости.

Приоритет отображения элементов интерфейса

Видимость также определяется порядком наложения слоёв. Z-index контролируется автоматически, но может быть частично переопределён через кастомные overlay.

class CustomOverlay extends google.maps.OverlayView {
  draw() {
    this.getPanes().overlayLayer.style.zIndex = 999;
  }
}

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

Синхронизация видимости с пользовательскими событиями

Интерфейс часто реагирует на события клика, наведения и перетаскивания:

marker.addListener("click", () => {
  marker.setVisible(false);
});

Такой подход используется для интерактивных карт, где элементы исчезают или появляются в ответ на действия пользователя.

map.addListener("click", () => {
  markers.forEach(m => m.setVisible(true));
});

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