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

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

Стилизация влияет на отображение:

  • дорог;
  • водоёмов;
  • парков;
  • административных границ;
  • подписей объектов;
  • транспортной инфраструктуры;
  • пользовательских слоёв.

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


Зачем необходимо переключение стилей

Динамическая смена оформления применяется в различных типах приложений.

Поддержка светлой и тёмной темы

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

Например:

  • светлый интерфейс — стандартная карта;
  • тёмный интерфейс — карта с приглушёнными цветами и контрастными подписями.

Отображение специализированных данных

При работе с логистикой, транспортом или аналитикой акцент необходимо переносить на определённые объекты карты.

Например:

  • скрыть туристические объекты;
  • уменьшить насыщенность второстепенных дорог;
  • выделить магистрали;
  • сделать фон менее заметным.

Улучшение читаемости

При большом количестве маркеров или геометрических объектов яркие элементы карты могут отвлекать внимание. В таких случаях используется минималистичный стиль.

Контекстное изменение интерфейса

Стиль может изменяться автоматически:

  • днём и ночью;
  • при смене масштаба;
  • при выборе определённого режима работы приложения;
  • при активации специальных фильтров.

Принцип работы стилизации

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

Простейшая структура выглядит следующим образом:

const styles = [
  {
    featureType: "water",
    elementType: "geometry",
    stylers: [
      {
        color: "#1a73e8"
      }
    ]
  }
];

Каждый объект содержит:

Свойство Назначение
featureType Тип объекта карты
elementType Конкретный элемент объекта
stylers Набор визуальных настроек

Создание нескольких наборов стилей

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

Светлая тема

const lightStyle = [
  {
    featureType: "water",
    elementType: "geometry",
    stylers: [
      { color: "#c9e6ff" }
    ]
  }
];

Тёмная тема

const darkStyle = [
  {
    featureType: "all",
    elementType: "geometry",
    stylers: [
      { color: "#242f3e" }
    ]
  },
  {
    featureType: "road",
    elementType: "geometry",
    stylers: [
      { color: "#38414e" }
    ]
  },
  {
    featureType: "water",
    elementType: "geometry",
    stylers: [
      { color: "#17263c" }
    ]
  }
];

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


Переключение стиля через setOptions

Самый распространённый способ изменения оформления — вызов метода setOptions().

Создание карты:

const map = new google.maps.Map(
  document.getElementById("map"),
  {
    center: { lat: 55.7558, lng: 37.6173 },
    zoom: 10,
    styles: lightStyle
  }
);

Изменение стиля:

map.setOptions({
  styles: darkStyle
});

После выполнения карта мгновенно перерисуется с новым оформлением.


Переключение по нажатию кнопки

Часто стиль меняется через пользовательский интерфейс.

HTML:

<button id="toggleStyle">
    Сменить тему
</button>

Jav * aScript:

let darkMode = false;

document
  .getElementById("toggleStyle")
  .addEventListener("click", () => {

    darkMode = !darkMode;

    map.setOptions({
      styles: darkMode
        ? darkStyle
        : lightStyle
    });
});

Каждое нажатие переключает оформление между двумя вариантами.


Использование флажка переключения

Более современный вариант — чекбокс.

HTML:

<label>
    <input type="checkbox" id="theme">
    Тёмная тема
</label>

Jav * aScript:

const checkbox =
  document.getElementById("theme");

checkbox.addEventListener("change", () => {

  map.setOptions({
    styles: checkbox.checked
      ? darkStyle
      : lightStyle
  });

});

Такой подход особенно удобен при интеграции с системами настроек.


Автоматическая смена темы по системным настройкам

Браузер предоставляет информацию о текущей теме операционной системы.

Получение состояния:

const mediaQuery =
  window.matchMedia(
    "(prefers-color-scheme: dark)"
  );

Установка начального стиля:

map.setOptions({
  styles: mediaQuery.matches
    ? darkStyle
    : lightStyle
});

Отслеживание изменений:

mediaQuery.addEventListener(
  "change",
  event => {

    map.setOptions({
      styles: event.matches
        ? darkStyle
        : lightStyle
    });

  }
);

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


Смена стиля по времени суток

Иногда требуется автоматически менять оформление в зависимости от времени.

Получение текущего часа:

const hour = new Date().getHours();

Выбор стиля:

if (hour >= 18 || hour < 6) {

  map.setOptions({
    styles: darkStyle
  });

} else {

  map.setOptions({
    styles: lightStyle
  });

}

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


Минималистичный режим карты

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

Пример минималистичного стиля:

const minimalStyle = [
  {
    featureType: "poi",
    stylers: [
      { visibility: "off" }
    ]
  },
  {
    featureType: "transit",
    stylers: [
      { visibility: "off" }
    ]
  }
];

Активация:

map.setOptions({
  styles: minimalStyle
});

В результате карта становится менее перегруженной визуально.


Переключение между несколькими стилями

Количество вариантов оформления не ограничено двумя темами.

Например:

const stylesCollection = {
  default: defaultStyle,
  dark: darkStyle,
  minimal: minimalStyle,
  navigation: navigationStyle
};

Функция применения:

function applyStyle(name) {

  map.setOptions({
    styles: stylesCollection[name]
  });

}

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

applyStyle("dark");
applyStyle("minimal");
applyStyle("navigation");

Подобная архитектура упрощает масштабирование проекта.


Изменение стиля через выпадающий список

HTML:

<select id="styleSelect">
    <option value="default">
        Стандартный
    </option>
    <option value="dark">
        Тёмный
    </option>
    <option value="minimal">
        Минималистичный
    </option>
</select>

Jav * aScript:

const select =
  document.getElementById(
    "styleSelect"
  );

select.addEventListener(
  "change",
  event => {

    map.setOptions({
      styles:
        stylesCollection[
          event.target.value
        ]
    });

  }
);

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


Скрытие объектов при переключении

Стиль может использоваться не только для изменения цвета.

Скрытие бизнес-объектов:

const hideBusinessStyle = [
  {
    featureType: "poi.business",
    stylers: [
      { visibility: "off" }
    ]
  }
];

Применение:

map.setOptions({
  styles: hideBusinessStyle
});

После переключения коммерческие объекты исчезнут с карты.


Выделение дорожной сети

Для навигационных сервисов часто требуется сделать дороги более заметными.

Пример:

const navigationStyle = [
  {
    featureType: "road",
    elementType: "geometry",
    stylers: [
      {
        color: "#ff9800"
      },
      {
        weight: 2
      }
    ]
  }
];

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

map.setOptions({
  styles: navigationStyle
});

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


Смена стиля при изменении масштаба

Иногда детализация должна зависеть от уровня приближения.

Отслеживание изменения масштаба:

map.addListener(
  "zoom_changed",
  () => {

    const zoom =
      map.getZoom();

    if (zoom < 8) {

      map.setOptions({
        styles: minimalStyle
      });

    } else {

      map.setOptions({
        styles: defaultStyle
      });

    }

  }
);

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


Централизованное управление стилями

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

Пример класса:

class MapStyleManager {

  constructor(map) {
    this.map = map;
    this.styles = {};
  }

  register(name, style) {
    this.styles[name] = style;
  }

  apply(name) {

    if (!this.styles[name]) {
      return;
    }

    this.map.setOptions({
      styles: this.styles[name]
    });

  }

}

Регистрация:

const manager =
  new MapStyleManager(map);

manager.register(
  "dark",
  darkStyle
);

manager.register(
  "minimal",
  minimalStyle
);

Применение:

manager.apply("dark");

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


Производительность при переключении стилей

При работе со стилями рекомендуется соблюдать несколько правил.

Не создавать массивы стилей внутри обработчиков событий

Плохо:

button.oncl ick = () => {

  map.setOptions({
    styles: [
      ...
    ]
  });

};

Хорошо:

const darkStyle = [...];

button.oncl ick = () => {

  map.setOptions({
    styles: darkStyle
  });

};

Использовать заранее подготовленные конфигурации

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

Не выполнять переключение слишком часто

Постоянная перерисовка карты может вызывать визуальные артефакты и лишнюю нагрузку на браузер.


Типичные сценарии использования

Навигационные системы

  • дневная карта;
  • ночная карта;
  • выделение дорожной сети.

CRM и логистические платформы

  • минималистичное отображение;
  • скрытие второстепенных объектов;
  • акцент на маршрутах доставки.

Аналитические панели

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

Геоинформационные системы

  • специальные режимы отображения данных;
  • переключение между тематическими картами;
  • визуальная фильтрация объектов через стили.

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