Управление жестами на мобильных

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


Базовые жесты и их поведение

В стандартной конфигурации карты на мобильных устройствах поддерживаются следующие жесты:

  • Pan (перетаскивание) — перемещение карты одним пальцем
  • Pinch-to-zoom (щипок) — изменение масштаба двумя пальцами
  • Double tap zoom — увеличение масштаба двойным касанием
  • Inertia scrolling — инерционное движение после свайпа
  • Rotate (ограниченно) — поворот карты при включённой поддержке жестов

Каждый из этих жестов может быть включён, ограничен или полностью отключён через параметры и CSS/DOM-обработчики.


Параметр gestureHandling

Ключевая настройка управления жестами — gestureHandling. Она определяет, как карта реагирует на касания и взаимодействие с прокруткой страницы.

const map = new google.maps.Map(document.getElementById("map"), {
  center: { lat: 50.4501, lng: 30.5234 },
  zoom: 10,
  gestureHandling: "auto"
});

Режимы gestureHandling

auto

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

  • на мобильных устройствах чаще переходит в режим cooperative
  • на десктопе позволяет свободное взаимодействие
  • учитывает прокрутку страницы

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


greedy

Карта перехватывает все жесты пользователя:

  • прокрутка страницы блокируется при взаимодействии с картой
  • pinch-to-zoom всегда активен
  • scroll страницы внутри контейнера карты невозможен

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

gestureHandling: "greedy"

cooperative

Жесты масштабирования и прокрутки разделяются между страницей и картой:

  • для масштабирования требуется Ctrl / Cmd (на десктопе)
  • на мобильных используется более осторожная модель взаимодействия
  • предотвращает случайные зумы при скролле страницы

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

gestureHandling: "cooperative"

none

Полное отключение всех жестов:

  • карта статична
  • взаимодействие возможно только через программные методы API
  • жесты пользователя игнорируются
gestureHandling: "none"

Дополнительные параметры управления жестами

Помимо gestureHandling, важную роль играют отдельные настройки карты.

Отключение перетаскивания

draggable: false

Полностью блокирует перемещение карты пальцем или мышью.


Управление масштабированием колесом и жестами

scrollwheel: false

На мобильных напрямую не используется, но влияет на поведение гибридных устройств и браузеров с эмуляцией мыши.


Контроль UI-элементов

zoomControl: true,
fullscreenControl: false,
mapTypeControl: false

Эти элементы часто заменяют жесты в сценариях с ограниченным взаимодействием.


Особенности мобильных сенсорных событий

На мобильных устройствах карта взаимодействует с системой через Touch Events и Pointer Events. Основная сложность заключается в конфликте между прокруткой страницы и обработкой жестов карты.

Passive listeners

Современные браузеры используют passive: true для улучшения производительности прокрутки. Это ограничивает возможность вызова preventDefault() и влияет на обработку жестов внутри контейнера карты.

Конфликт прокрутки страницы

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

Решения:

  • использование gestureHandling: cooperative
  • ограничение высоты контейнера карты
  • добавление padding вокруг карты
  • отключение draggable в текстовых блоках

Перехват жестов и overlay-элементы

Интерактивные элементы поверх карты (маршруты, карточки, фильтры) могут блокировать жесты карты.

Пример проблемы

<div id="map"></div>
<div class="overlay"></div>

Если overlay перекрывает карту и не пропускает события, жесты перестают работать.

Решение через pointer-events

.overlay {
  pointer-events: none;
}

Либо точечная активация:

.overlay button {
  pointer-events: auto;
}

Программное управление жестами

Некоторые сценарии требуют динамического изменения поведения карты.

Включение/выключение drag

map.setOptions({ draggable: false });

Изменение режима жестов на лету

map.setOptions({ gestureHandling: "greedy" });

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

function openModal() {
  map.setOptions({
    gestureHandling: "none",
    draggable: false
  });
}

UX-паттерны для мобильных карт

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

Используется режим greedy:

  • приложения доставки
  • навигационные сервисы
  • трекинг объектов

Главный принцип — минимизация препятствий между жестом и реакцией карты.


Карта как вспомогательный элемент

Используется cooperative:

  • статьи и справочные страницы
  • каталоги
  • аналитические панели

Основной акцент — сохранение естественного скролла страницы.


Статическая карта

Используется none:

  • превью
  • мини-карты
  • изображения маршрутов без интерактивности

Поведение жестов в сложных DOM-структурах

При размещении карты внутри:

  • модальных окон
  • вкладок (tabs)
  • scrollable контейнеров

возникают особенности обработки сенсорных событий.

Scroll внутри контейнера

Если родительский контейнер имеет overflow: scroll, жесты могут конфликтовать с картой.

Решение:

.map-container {
  touch-action: manipulation;
}

Lazy loading и жесты

При инициализации карты в скрытом блоке (display: none) жесты могут работать некорректно до первого ресайза.

Корректная инициализация:

google.maps.event.trigger(map, "resize");
map.setCenter({ lat: 50.4501, lng: 30.5234 });

Адаптация жестов под разные устройства

Поведение жестов зависит от:

  • плотности пикселей (DPR)
  • наличия аппаратного мультитача
  • режима браузера (mobile/desktop emulation)

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


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

Жесты напрямую влияют на нагрузку:

  • частые события touchmove
  • пересчёт тайлов карты
  • перерасчёт векторных слоёв

Оптимизация включает:

  • ограничение кастомных overlay-анимаций
  • минимизацию DOM-слоёв поверх карты
  • отключение лишних контролов UI
  • использование debounce при синхронизации состояния карты