Для работы с жестом pinch (масштабирование двумя пальцами) необходимо подключить библиотеку Interact.js через CDN или npm. Элементы, к которым будет применяться жест, должны быть определены в HTML с уникальными селекторами. Например:
<div id="pinch-box" style="width: 200px; height: 200px; background-color: lightblue;">
</div>
Подключение библиотеки через CDN:
<script src="https://cdn.jsdelivr.net/npm/@interactjs/interactjs/dist/interact.min.js"></script>
Interact.js предоставляет метод .gesturable() для
отслеживания жестов pinch и rotate. Для масштабирования необходимо
использовать события:
gesturestart — начало жестаgesturemove — движение (изменение масштаба)gestureend — завершение жестаПример базовой настройки:
let scale = 1;
interact('#pinch-box')
.gesturable({
listeners: {
start (event) {
event.target.dataset.startScale = scale;
},
move (event) {
scale = parseFloat(event.target.dataset.startScale) * event.scale;
event.target.style.transform = `scale(${scale})`;
}
}
});
Ключевой момент: свойство event.scale
возвращает относительный коэффициент изменения от начала жеста, а не
абсолютный размер. Поэтому необходимо хранить начальный масштаб
элемента, чтобы корректно умножать на текущий коэффициент.
Для предотвращения чрезмерного уменьшения или увеличения элемента применяются ограничения:
const minScale = 0.5;
const maxScale = 3;
interact('#pinch-box')
.gesturable({
listeners: {
move (event) {
scale = Math.max(minScale, Math.min(maxScale, parseFloat(event.target.dataset.startScale) * event.scale));
event.target.style.transform = `scale(${scale})`;
}
}
});
Важное замечание: без ограничения пользователь может случайно увеличить элемент до огромного размера или уменьшить до нуля, что нарушает UX.
Если необходимо масштабировать элемент относительно точки касания
(например, центр между пальцами), используется свойство
event.dsplacement или вычисление центра на основе
event.touches:
interact('#pinch-box')
.gesturable({
listeners: {
move (event) {
const rect = event.target.getBoundingClientRect();
const centerX = rect.left + rect.width / 2;
const centerY = rect.top + rect.height / 2;
scale = parseFloat(event.target.dataset.startScale) * event.scale;
event.target.style.transformOrigin = `${centerX}px ${centerY}px`;
event.target.style.transform = `scale(${scale})`;
}
}
});
Секрет эффективного масштабирования: корректная
установка transform-origin гарантирует, что элемент будет
увеличиваться именно от точки между пальцами, а не смещаться по
экрану.
Interact.js позволяет комбинировать жесты. Пример совместного использования:
let posX = 0;
let posY = 0;
let angle = 0;
interact('#pinch-box')
.draggable({
listeners: {
move(event) {
posX += event.dx;
posY += event.dy;
updateTransform();
}
}
})
.gesturable({
listeners: {
move(event) {
scale = parseFloat(event.target.dataset.startScale) * event.scale;
angle += event.da;
updateTransform();
}
}
});
function updateTransform() {
const el = document.getElementById('pinch-box');
el.style.transform = `translate(${posX}px, ${posY}px) rotate(${angle}deg) scale(${scale})`;
}
Важное: при одновременном drag и pinch необходимо
объединять все трансформации в одну строку transform. Иначе
могут возникнуть неожиданные сдвиги или искажения.
gesturestart используется для инициализации значений:
начальный масштаб, позиция, угол.gestureend часто применяется для сохранения итогового
состояния или плавного возвращения к исходным границам при выходе за
пределы min/max:interact('#pinch-box')
.gesturable({
listeners: {
end(event) {
scale = Math.max(minScale, Math.min(maxScale, scale));
event.target.style.transform = `scale(${scale})`;
}
}
});
Это предотвращает накопление некорректных значений при последовательных жестах.
Interact.js не хранит внутреннее состояние элемента между событиями.
Для надёжной работы часто используют dataset:
event.target.dataset.startScale = scale;
Такой подход позволяет корректно рассчитывать новые значения при
каждом событии gesturemove, не теряя информации о
предыдущем состоянии.
transform.Все эти техники формируют базу для создания интерактивных элементов с масштабированием pinch, обеспечивая стабильное и предсказуемое поведение на любых устройствах.