Touch-события представляют собой механизм взаимодействия с сенсорными экранами и позволяют отслеживать касания, перемещения пальцев и их завершение. В отличие от классических событий мыши, они поддерживают множественные точки контакта, что делает возможным реализацию жестов: свайпов, пинчей, вращений.
Основные типы touch-событий:
Каждое событие содержит список касаний (TouchList), где
можно получить координаты (clientX, clientY),
идентификатор касания и другие параметры.
Библиотека anime.js не имеет встроенной абстракции для touch-жестов, однако отлично интегрируется с ними через стандартные обработчики событий. Основной подход — использование touch-событий для управления параметрами анимации в реальном времени.
Ключевая идея: touch-событие управляет состоянием анимации, а anime.js отвечает за визуальное представление.
Простейший сценарий — запуск анимации при касании элемента.
const element = document.querySelector('.box');
element.addEventListener('touchstart', () => {
anime({
targets: element,
scale: 1.2,
duration: 300,
easing: 'easeOutQuad'
});
});
element.addEventListener('touchend', () => {
anime({
targets: element,
scale: 1,
duration: 300,
easing: 'easeOutQuad'
});
});
В этом примере создаётся эффект «нажатия», аналогичный кнопке.
Для более сложных взаимодействий используется событие
touchmove. Оно позволяет изменять параметры анимации в
зависимости от позиции пальца.
const element = document.querySelector('.box');
element.addEventListener('touchmove', (e) => {
const touch = e.touches[0];
anime({
targets: element,
translateX: touch.clientX,
translateY: touch.clientY,
duration: 0
});
});
Здесь анимация фактически используется как средство мгновенного обновления состояния.
Прямое присваивание координат может выглядеть резко. Для сглаживания движения применяется анимация с короткой длительностью.
element.addEventListener('touchmove', (e) => {
const touch = e.touches[0];
anime({
targets: element,
translateX: touch.clientX,
translateY: touch.clientY,
duration: 200,
easing: 'easeOutQuad'
});
});
Это создаёт эффект инерции и плавности.
Свайп определяется как быстрое перемещение пальца в определённом направлении. Для его реализации необходимо:
touchstart)touchend)let startX = 0;
element.addEventListener('touchstart', (e) => {
startX = e.touches[0].clientX;
});
element.addEventListener('touchend', (e) => {
const endX = e.changedTouches[0].clientX;
const diff = endX - startX;
if (diff > 50) {
anime({
targets: element,
translateX: 200,
duration: 500
});
} else if (diff < -50) {
anime({
targets: element,
translateX: -200,
duration: 500
});
}
});
Порог в 50 пикселей предотвращает случайные срабатывания.
Для более естественного поведения используется скорость движения пальца. Это позволяет реализовать «бросок» объекта.
let lastX = 0;
let lastTime = 0;
element.addEventListener('touchmove', (e) => {
const touch = e.touches[0];
const now = Date.now();
const deltaX = touch.clientX - lastX;
const deltaTime = now - lastTime;
const velocity = deltaX / deltaTime;
lastX = touch.clientX;
lastTime = now;
anime({
targets: element,
translateX: `+=${deltaX}`,
duration: 0
});
element.dataset.velocity = velocity;
});
element.addEventListener('touchend', () => {
const velocity = parseFloat(element.dataset.velocity) || 0;
anime({
targets: element,
translateX: `+=${velocity * 200}`,
duration: 800,
easing: 'easeOutExpo'
});
});
Так создаётся эффект продолжения движения после отпускания.
Touch API поддерживает несколько точек касания. Это позволяет реализовать масштабирование и вращение.
let initialDistance = null;
function getDistance(touches) {
const dx = touches[0].clientX - touches[1].clientX;
const dy = touches[0].clientY - touches[1].clientY;
return Math.sqrt(dx * dx + dy * dy);
}
element.addEventListener('touchmove', (e) => {
if (e.touches.length === 2) {
const distance = getDistance(e.touches);
if (!initialDistance) {
initialDistance = distance;
}
const scale = distance / initialDistance;
anime({
targets: element,
scale: scale,
duration: 0
});
}
});
element.addEventListener('touchend', () => {
initialDistance = null;
});
На мобильных устройствах браузер может перехватывать жесты (например,
скролл). Для корректной работы анимаций используется
preventDefault().
element.addEventListener('touchmove', (e) => {
e.preventDefault();
}, { passive: false });
Важно указывать { passive: false }, иначе браузер
игнорирует запрет.
Работа с touch-событиями требует высокой частоты обновлений, поэтому важно учитывать:
duration: 0 для мгновенных
обновленийЭффективный подход — использовать одну анимацию и обновлять её
параметры через .seek() или .pause() /
.play().
anime.js позволяет объединять анимации в timeline, который можно контролировать через touch.
const timeline = anime.timeline({
autoplay: false
})
.add({
targets: element,
translateX: 300,
duration: 1000
});
element.addEventListener('touchmove', (e) => {
const touch = e.touches[0];
const progress = touch.clientX / window.innerWidth;
timeline.seek(timeline.duration * progress);
});
Так реализуется «перемотка» анимации пальцем.
При построении сложных интерфейсов полезно разделять:
Такое разделение упрощает поддержку и масштабирование.
touchcancel, что приводит к «зависшим»
состояниямtouchmoveСовременные браузеры поддерживают Pointer Events,
которые объединяют мышь, touch и стилус. В некоторых случаях
целесообразно использовать их вместо touch-событий, сохраняя
совместимость.
Однако anime.js одинаково хорошо работает с любым типом событий, поскольку не зависит от источника ввода.
Интеграция touch-событий с anime.js используется для:
Гибкость библиотеки позволяет реализовывать как простые реакции на касание, так и сложные физические взаимодействия с инерцией и жестами.