Українська

Досліджуйте світ сенсорних жестів та навчіться реалізовувати їх у своїх проєктах на JavaScript. Цей посібник охоплює все, від базових подій дотику до складних технік розпізнавання жестів.

Сенсорні жести: вичерпний посібник з реалізації на JavaScript

У сучасному світі, орієнтованому на мобільні пристрої, сенсорні жести стали невід'ємною частиною користувацького досвіду. Від простих натискань до складних взаємодій кількома пальцями, сенсорні жести забезпечують природний та інтуїтивно зрозумілий спосіб взаємодії користувачів з веб-додатками. Цей вичерпний посібник досліджує світ сенсорних жестів і пропонує покроковий підхід до їх реалізації у ваших проєктах на JavaScript.

Розуміння подій дотику

Перш ніж занурюватися в розпізнавання жестів, важливо зрозуміти основні події дотику, які лежать в основі цих взаємодій. JavaScript надає набір подій, які спрацьовують, коли користувач торкається екрана. Ці події надають інформацію про дотик, таку як його місцезнаходження та стан.

Основні події дотику:

Кожна з цих подій містить властивість `touches`, яка є списком об'єктів `Touch`. Кожен об'єкт `Touch` представляє одну точку контакту на екрані та містить таку інформацію, як:

Приклад: логування координат дотику

Цей простий приклад демонструє, як логувати координати точки дотику, коли користувач торкається екрана:


 document.addEventListener('touchstart', function(event) {
  event.preventDefault(); // Запобігає стандартній поведінці браузера (наприклад, прокрутці)
  let touch = event.touches[0];
  console.log('Дотик розпочався в X: ' + touch.clientX + ', Y: ' + touch.clientY);
 });

Примітка: Метод `preventDefault()` часто використовується для запобігання виконанню браузером стандартної поведінки при дотику, такої як прокрутка або масштабування.

Реалізація базових жестів

Маючи тверде розуміння подій дотику, ми тепер можемо реалізувати базові жести. Розглянемо приклади, такі як натискання (tap), свайп (swipe) та перетягування (drag). Спочатку ми дамо їм визначення, а потім наведемо приклади на JavaScript.

Жест натискання (Tap)

Жест натискання — це швидкий дотик та відпускання екрана. Щоб реалізувати жест натискання, ми можемо відстежувати події `touchstart` та `touchend` і вимірювати різницю в часі між ними. Якщо різниця в часі менша за певний поріг (наприклад, 200 мілісекунд), ми вважаємо це натисканням.


 let tapStartTime = null;

 document.addEventListener('touchstart', function(event) {
  tapStartTime = new Date().getTime();
 });

 document.addEventListener('touchend', function(event) {
  let tapEndTime = new Date().getTime();
  let tapDuration = tapEndTime - tapStartTime;

  if (tapDuration < 200) {
   console.log('Натискання виявлено!');
  }
 });

Жест свайпу (Swipe)

Жест свайпу — це швидкий, спрямований рух по екрану. Щоб виявити свайп, нам потрібно відстежувати початкові та кінцеві позиції дотику та обчислювати відстань і напрямок руху. Нам також потрібно враховувати тривалість свайпу.


 let swipeStartX = null;
 let swipeStartY = null;

 document.addEventListener('touchstart', function(event) {
  swipeStartX = event.touches[0].clientX;
  swipeStartY = event.touches[0].clientY;
 });

 document.addEventListener('touchend', function(event) {
  let swipeEndX = event.changedTouches[0].clientX;
  let swipeEndY = event.changedTouches[0].clientY;
  let deltaX = swipeEndX - swipeStartX;
  let deltaY = swipeEndY - swipeStartY;
  let swipeDistance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);

  if (swipeDistance > 50) { // За потреби налаштуйте порогове значення
   let angle = Math.atan2(deltaY, deltaX) * 180 / Math.PI;

   if (angle > -45 && angle <= 45) {
    console.log('Свайп вправо!');
   } else if (angle > 45 && angle <= 135) {
    console.log('Свайп вниз!');
   } else if (angle > 135 || angle <= -135) {
    console.log('Свайп вліво!');
   } else {
    console.log('Свайп вгору!');
   }
  }
 });

Жест перетягування (Drag)

Жест перетягування полягає у дотику до елемента та переміщенні його по екрану. Щоб реалізувати жест перетягування, нам потрібно відстежувати подію `touchmove` і відповідно оновлювати позицію елемента.


 let dragging = false;
 let offsetX, offsetY;
 let element = document.getElementById('draggableElement');

 element.addEventListener('touchstart', function(event) {
  dragging = true;
  offsetX = event.touches[0].clientX - element.offsetLeft;
  offsetY = event.touches[0].clientY - element.offsetTop;
 });

 document.addEventListener('touchmove', function(event) {
  if (dragging) {
   element.style.left = (event.touches[0].clientX - offsetX) + 'px';
   element.style.top = (event.touches[0].clientY - offsetY) + 'px';
  }
 });

 document.addEventListener('touchend', function(event) {
  dragging = false;
 });

Переконайтеся, що у вашому HTML є елемент з id "draggableElement":


 
Перетягни мене!

Жести мультитач

Жести мультитач передбачають використання кількох пальців для взаємодії з екраном. Це дозволяє створювати більш складні та виразні взаємодії, такі як зведення/розведення пальців для масштабування (pinch-to-zoom) та обертання.

Зведення/розведення для масштабування (Pinch-to-Zoom)

Зведення/розведення пальців — це поширений жест, що використовується для збільшення та зменшення масштабу зображення або карти. Щоб реалізувати цей жест, нам потрібно відстежувати відстань між двома точками дотику та відповідно регулювати масштаб елемента.


 let initialDistance = null;
 let currentScale = 1;
 let element = document.getElementById('zoomableImage');

 function getDistance(event) {
  let touch1 = event.touches[0];
  let touch2 = event.touches[1];
  let x = touch2.clientX - touch1.clientX;
  let y = touch2.clientY - touch1.clientY;
  return Math.sqrt(x * x + y * y);
 }

 element.addEventListener('touchstart', function(event) {
  if (event.touches.length === 2) {
   initialDistance = getDistance(event);
  }
 });

 element.addEventListener('touchmove', function(event) {
  if (event.touches.length === 2) {
   event.preventDefault();
   let currentDistance = getDistance(event);
   let scaleFactor = currentDistance / initialDistance;
   currentScale *= scaleFactor; // Накопичуємо масштабування
   element.style.transform = 'scale(' + currentScale + ')';
   initialDistance = currentDistance; // Скидаємо для наступного руху
  }
 });

 element.addEventListener('touchend', function(event) {
  initialDistance = null;
 });

Переконайтеся, що у вашому HTML є зображення з id "zoomableImage":


 

Обертання

Обертання полягає в обертанні елемента за допомогою двох пальців. Щоб реалізувати обертання, нам потрібно відстежувати кут між двома точками дотику та відповідно обертати елемент.


 let initialAngle = null;
 let currentRotation = 0;
 let element = document.getElementById('rotatableImage');

 function getAngle(event) {
  let touch1 = event.touches[0];
  let touch2 = event.touches[1];
  return Math.atan2(touch2.clientY - touch1.clientY, touch2.clientX - touch1.clientX) * 180 / Math.PI;
 }

 element.addEventListener('touchstart', function(event) {
  if (event.touches.length === 2) {
   initialAngle = getAngle(event);
  }
 });

 element.addEventListener('touchmove', function(event) {
  if (event.touches.length === 2) {
   event.preventDefault();
   let currentAngle = getAngle(event);
   let rotation = currentAngle - initialAngle;
   currentRotation += rotation; // Накопичуємо обертання
   element.style.transform = 'rotate(' + currentRotation + 'deg)';
   initialAngle = currentAngle; // Скидаємо для наступного руху
  }
 });

 element.addEventListener('touchend', function(event) {
  initialAngle = null;
 });

Переконайтеся, що у вашому HTML є зображення з id "rotatableImage":


 

Бібліотеки для розпізнавання жестів

Реалізація складних жестів з нуля може бути складною та займати багато часу. На щастя, існує кілька бібліотек JavaScript, які можуть спростити процес розпізнавання жестів. Ці бібліотеки надають готові розпізнавачі жестів та утиліти для обробки подій дотику.

Hammer.js

Hammer.js — це популярна бібліотека JavaScript для розпізнавання жестів. Вона підтримує широкий спектр жестів, включаючи натискання, подвійне натискання, свайп, зведення/розведення, обертання та панорамування. Вона легка, проста у використанні та має широкі можливості для налаштування. Hammer.js працює, прослуховуючи події дотику, а потім визначаючи, яку дію виконує користувач, на основі розташування та тривалості точок дотику.


 // Підключіть Hammer.js у вашому HTML
 // 

 let element = document.getElementById('myElement');
 let hammer = new Hammer(element);

 hammer.on('tap', function(event) {
  console.log('Виявлено подію натискання');
 });

 hammer.on('swipe', function(event) {
  console.log('Виявлено подію свайпу');
  console.log('Напрямок свайпу: ' + event.direction);
 });

 hammer.get('pinch').set({ enable: true });
 hammer.get('rotate').set({ enable: true });

 hammer.on('pinch', function(event) {
  console.log('Виявлено подію зведення/розведення');
  element.style.transform = 'scale(' + event.scale + ')';
 });

 hammer.on('rotate', function(event) {
  console.log('Виявлено подію обертання');
  element.style.transform = 'rotate(' + event.rotation + 'deg)';
 });

AlloyFinger

AlloyFinger — це ще одна популярна бібліотека JavaScript, що спеціалізується на розпізнаванні жестів, особливо для мобільних пристроїв. Вона відома своїм невеликим розміром та хорошою продуктивністю. Вона зосереджена на поширених сенсорних жестах, таких як натискання, свайп, зведення/розведення, обертання та утримання. Вона надає простий у використанні API для прив'язки жестів до елементів.


 // Підключіть AlloyFinger у вашому HTML
 //  // Замініть на ваш шлях до AlloyFinger

 let element = document.getElementById('myElement');
 let af = new AlloyFinger(element, {
  tap: function() {
   console.log('Виявлено подію натискання');
  },
  swipe: function(evt) {
   console.log('Виявлено подію свайпу');
   console.log('Напрямок свайпу: ' + evt.direction); // вгору, вниз, вліво, вправо
  },
  pinch: function(evt) {
   console.log('Виявлено подію зведення/розведення');
   element.style.transform = 'scale(' + evt.scale + ')';
  },
  rotate: function(evt) {
   console.log('Виявлено подію обертання');
   element.style.transform = 'rotate(' + evt.angle + 'deg)';
  }
 });

Аспекти доступності

При реалізації сенсорних жестів важливо враховувати доступність для користувачів з обмеженими можливостями. Деякі користувачі можуть бути не в змозі використовувати сенсорні жести через рухові порушення. Надання альтернативних методів введення, таких як керування з клавіатури або голосові команди, гарантує, що ваш додаток буде доступним для ширшої аудиторії.

Оптимізація продуктивності

Події дотику можуть бути обчислювально затратними, особливо при обробці складних жестів. Оптимізація вашого коду для підвищення продуктивності є вирішальною для забезпечення плавного та чутливого користувацького досвіду.

Кросбраузерна сумісність

Підтримка подій дотику відрізняється в різних браузерах та на різних пристроях. Важливо тестувати ваш код на різноманітних браузерах та пристроях, щоб забезпечити кросбраузерну сумісність. Розгляньте можливість використання поліфілів або бібліотек, які абстрагують відмінності між браузерами.

Аспекти інтернаціоналізації (i18n)

При реалізації сенсорних жестів не забувайте враховувати інтернаціоналізацію (i18n). Хоча самі взаємодії дотиком зазвичай не залежать від мови, навколишні елементи інтерфейсу та механізми зворотного зв'язку повинні бути локалізовані для різних мов та регіонів.

Глобальні приклади та міркування

Розглянемо, як сенсорні жести можуть застосовуватися по-різному в різних глобальних контекстах:

Висновок

Сенсорні жести — це потужний інструмент для створення захоплюючого та інтуїтивно зрозумілого користувацького досвіду. Розуміючи основні події дотику та використовуючи відповідні техніки розпізнавання жестів, ви можете реалізувати широкий спектр жестів у своїх проєктах на JavaScript. Не забувайте враховувати доступність, продуктивність та кросбраузерну сумісність, щоб ваш додаток добре працював для всіх користувачів. З розвитком технологій очікуйте появи нових типів жестів та взаємодій; продовжуйте навчатися, щоб залишатися на передньому краї цифрових технологій.