В основе обработки жестов в OpenLayers лежит подсистема взаимодействий (Interactions). Она определяет, каким образом пользователь управляет картой: перемещение, масштабирование, поворот, выделение объектов и комбинированные сценарии ввода. Каждое взаимодействие представляет собой отдельный модуль, который подключается к объекту карты и перехватывает события указателя, мыши или сенсорного ввода.
Архитектура построена вокруг класса
ol/interaction/Interaction, от которого наследуются все
стандартные жесты. Такой подход позволяет гибко комбинировать поведение
карты, добавлять собственные механики и управлять приоритетами обработки
событий.
OpenLayers включает набор готовых взаимодействий, которые покрывают большинство сценариев работы с картой.
Жест перемещения реализован через взаимодействие перетаскивания карты.
Основные особенности:
Класс: ol/interaction/DragPan
Ключевая логика основана на вычислении смещения указателя между
событиями pointerdown и pointermove, после
чего пересчитывается центр карты в координатах проекции.
Колёсная прокрутка преобразуется в изменение масштаба карты.
Особенности:
Класс: ol/interaction/MouseWheelZoom
Внутри взаимодействия используется накопление дельты прокрутки и преобразование её в коэффициент масштабирования с экспоненциальной функцией.
Двойной клик выполняет приближение к точке курсора.
Особенности:
Класс: ol/interaction/DoubleClickZoom
Данный жест полезен в сценариях быстрого навигационного приближения без использования колесика мыши.
Для сенсорных устройств применяется pinch-жест (сведение/разведение пальцев).
Особенности:
Класс: ol/interaction/PinchZoom
Механизм основан на геометрии треугольника между двумя pointer-событиями, где расстояние используется как коэффициент масштабирования.
Часто совмещается с pinch-zoom.
Особенности:
Класс: ol/interaction/PinchRotate
В OpenLayers набор взаимодействий задаётся при создании карты.
import Map from 'ol/Map.js';
import View from 'ol/View.js';
import {defaults as defaultInteractions} from 'ol/interaction/defaults.js';
const map = new Map({
target: 'map',
view: new View({
center: [0, 0],
zoom: 2
}),
interactions: defaultInteractions()
});
Функция defaultInteractions() возвращает стандартный
набор жестов:
Контроль над поведением осуществляется путём явного задания списка взаимодействий.
Пример отключения вращения:
import {defaults as defaultInteractions, MouseWheelZoom, DragPan} from 'ol/interaction.js';
const map = new Map({
target: 'map',
interactions: defaultInteractions({
mouseWheelZoom: true,
doubleClickZoom: true,
pinchRotate: false
})
});
Другой подход — полное переопределение набора:
const map = new Map({
interactions: [
new DragPan(),
new MouseWheelZoom()
]
});
Такой способ используется в интерфейсах, где требуется строго контролируемое поведение карты без лишних жестов.
Каждое взаимодействие поддерживает функцию condition,
которая определяет, когда жест должен срабатывать.
Пример ограничения DragPan только при зажатом Shift:
import DragPan from 'ol/interaction/DragPan.js';
import {shiftKeyOnly} from 'ol/events/condition.js';
const dragPan = new DragPan({
condition: shiftKeyOnly
});
Функции условий:
singleClickdoubleClickshiftKeyOnlyaltKeyOnlyplatformModifierKeyOnlyМеханизм основан на анализе объекта события pointer/keyboard и позволяет строить сложные комбинации управления.
Если несколько жестов реагируют на одно и то же событие, используется система приоритетов.
Каждое взаимодействие имеет:
priority (внутренний порядок обработки)active)stopPropagation)Например, PinchZoom имеет более высокий приоритет, чем DragPan, чтобы мультитач не интерпретировался как перемещение карты.
Современная реализация OpenLayers опирается на Pointer Events.
Основной поток событий:
pointerdown — начало жестаpointermove — изменение положенияpointerup — завершение жестаpointercancel — прерывание системойКаждое взаимодействие подписывается на эти события через единый диспетчер и получает унифицированный объект события, содержащий:
Создание собственного жеста выполняется через наследование от базового класса Interaction.
import Interaction from 'ol/interaction/Interaction.js';
class CustomDrag extends Interaction {
constructor() {
super();
}
handleEvent(mapBrowserEvent) {
if (mapBrowserEvent.type === 'pointerdrag') {
const deltaX = mapBrowserEvent.pixel[0];
const deltaY = mapBrowserEvent.pixel[1];
// пользовательская логика обработки
}
return true;
}
}
Метод handleEvent является центральной точкой обработки
событий. Он может:
Многие жесты используют внутреннюю систему анимации view.
При DragPan после отпускания указателя может применяться инерция:
Параметры:
decay — коэффициент затуханияduration — длительность анимацииeasing — функция плавностиНа мобильных устройствах жесты обрабатываются через комбинацию pointer-идентификаторов.
Основные сценарии:
Система отслеживает:
Любое взаимодействие может быть временно отключено:
interaction.setActive(false);
Это используется при:
Также возможно динамическое включение/выключение отдельных жестов в зависимости от состояния приложения.
При добавлении взаимодействий рисования (Draw, Select) важно учитывать конфликт жестов.
Типичная конфигурация:
Система разрешения конфликтов строится на:
conditionПри интенсивном взаимодействии критичны:
Особенно нагруженными являются:
Оптимизация достигается через ограничение частоты обновлений и упрощение математических операций внутри обработчиков.