Hammer.js представляет собой библиотеку для обработки жестов касания и мыши в веб-приложениях. Она обеспечивает единый слой абстракции над событиями pointer/touch/mouse, позволяя работать с такими взаимодействиями, как swipe, pan, pinch и rotate без необходимости вручную обрабатывать низкоуровневые события браузера.
Библиотека строится вокруг концепции распознавателей жестов (recognizers). Каждый recognizer отвечает за определённый тип взаимодействия:
Каждый распознаватель подключается к единому менеджеру, который отслеживает входящие события и маршрутизирует их в соответствующие обработчики.
В основе лежит система state machine, где каждое касание проходит стадии:
Эта модель позволяет точно контролировать поведение жестов и комбинировать их.
npm install hammerjs
После установки библиотека импортируется в проект:
import Hammer from 'hammerjs';
При использовании сборщиков (Webpack, Vite, Rollup) Hammer.js корректно включается в бандл без дополнительной настройки.
<script src="https://cdn.jsdelivr.net/npm/hammerjs@2.0.8/hammer.min.js"></script>
После подключения глобальный объект Hammer становится
доступен в window.
Инициализация начинается с привязки к DOM-элементу:
const element = document.getElementById('canvas-area');
const hammer = new Hammer(element);
С этого момента элемент начинает отслеживать жесты касания и мыши.
Каждый экземпляр управляет собственным контекстом событий, не влияя на другие элементы страницы.
По умолчанию активирован базовый набор жестов. Для точного контроля
конфигурация изменяется через get и set:
hammer.get('pan').set({ direction: Hammer.DIRECTION_ALL });
hammer.get('pinch').set({ enable: true });
Возможные направления pan:
Отключение ненужных жестов снижает нагрузку на обработку событий:
hammer.get('rotate').set({ enable: false });
События подписываются через метод on:
hammer.on('panmove', function (event) {
console.log(event.deltaX, event.deltaY);
});
Основные события:
Объект события содержит параметры:
Hammer.js позволяет комбинировать recognizers, но требует явного управления зависимостями:
const pinch = new Hammer.Pinch();
const pan = new Hammer.Pan();
pinch.recognizeWith(pan);
Такое связывание позволяет одновременно обрабатывать масштабирование и перемещение.
При работе с canvas-сценами жесты часто используются для управления камерой, графиками или интерактивными элементами.
Пример базовой схемы управления трансформацией:
let scale = 1;
let offsetX = 0;
let offsetY = 0;
hammer.on('pinchmove', function (e) {
scale = e.scale;
render();
});
hammer.on('panmove', function (e) {
offsetX += e.deltaX;
offsetY += e.deltaY;
render();
});
Функция render применяет трансформации к контексту canvas:
function render() {
ctx.setTransform(scale, 0, 0, scale, offsetX, offsetY);
}
Chart.js не имеет встроенной полноценной системы жестов, поэтому Hammer.js часто используется как внешний слой интерактивности.
Типовой сценарий — управление масштабированием и панорамированием графика.
const canvas = document.getElementById('chart');
const hammer = new Hammer(canvas);
let chartOffsetX = 0;
hammer.on('panmove', (e) => {
chartOffsetX += e.deltaX;
chart.update();
});
В реальных приложениях offset связывается с пользовательскими плагинами или кастомной логикой осей.
let chartScale = 1;
hammer.get('pinch').set({ enable: true });
hammer.on('pinchmove', (e) => {
chartScale = e.scale;
chart.update();
});
Для корректной интеграции масштаб обычно применяется через обновление диапазона осей:
chart.options.scales.x.min *= chartScale;
chart.options.scales.x.max *= chartScale;
Hammer.js позволяет управлять порогами распознавания:
hammer.get('pan').set({
threshold: 5,
pointers: 1
});
Основные параметры:
Настройка влияет на отзывчивость интерфейса и точность жестов.
При одновременной работе нескольких recognizers возможны конфликты. Для их решения применяется:
pan.requireFailure(pinch);
Это означает, что pan активируется только при отсутствии pinch.
В современных браузерах Hammer.js использует Pointer Events как основной источник данных. Это обеспечивает поддержку:
Абстракция унифицирует различия между устройствами и приводит все события к единому формату.
При высокой частоте событий важно контролировать нагрузку:
let ticking = false;
hammer.on('panmove', (e) => {
if (!ticking) {
requestAnimationFrame(() => {
updateState(e);
ticking = false;
});
ticking = true;
}
});
На мобильных устройствах возможны системные жесты браузера (scroll, zoom страницы), которые конфликтуют с Hammer.js. Для предотвращения применяется CSS:
touch-action: none;
Это отключает стандартную обработку касаний и передаёт управление библиотеке.
Hammer.js поддерживает создание кастомных recognizers:
const mc = new Hammer.Manager(element);
mc.add(new Hammer.Pan({ direction: Hammer.DIRECTION_HORIZONTAL }));
mc.add(new Hammer.Swipe());
Такой подход позволяет строить специализированные системы взаимодействия, адаптированные под конкретные интерфейсы.
Интерактивные приложения часто используют жесты как входные данные для изменения состояния:
Hammer.js выступает промежуточным слоем между физическим взаимодействием пользователя и логикой приложения, обеспечивая единообразную модель обработки событий.