Pengembangan web multi-sentuh

Pengantar

Perangkat seluler seperti smartphone dan tablet biasanya memiliki layar yang peka sentuhan kapasitif untuk menangkap interaksi yang dilakukan dengan jari pengguna. Seiring berkembangnya web seluler untuk menyediakan aplikasi yang semakin canggih, developer web memerlukan cara untuk menangani peristiwa ini. Misalnya, hampir semua game bertempo cepat mengharuskan pemain menekan beberapa tombol sekaligus, yang dalam konteks layar sentuh, menyiratkan multi-sentuh.

Apple memperkenalkan API peristiwa sentuh di iOS 2.0. Android telah menerapkan standar de-facto ini dan menutup kesenjangan. Baru-baru ini, grup kerja W3C bersama-sama mengerjakan spesifikasi peristiwa sentuh ini.

Dalam artikel ini, saya akan mempelajari API peristiwa sentuh yang disediakan oleh perangkat iOS dan Android, serta Chrome desktop di hardware yang mendukung sentuhan, dan mengeksplorasi jenis aplikasi apa yang dapat Anda buat, menyajikan beberapa praktik terbaik, dan membahas teknik berguna yang mempermudah pengembangan aplikasi yang mendukung sentuhan.

Peristiwa sentuh

Tiga peristiwa sentuh dasar diuraikan dalam spesifikasi dan diterapkan secara luas di seluruh perangkat seluler:

  • touchstart: jari ditempatkan di elemen DOM.
  • touchmove: jari ditarik di sepanjang elemen DOM.
  • touchend: jari dihapus dari elemen DOM.

Setiap peristiwa sentuh menyertakan tiga daftar sentuhan:

  • sentuhan: daftar semua jari yang saat ini ada di layar.
  • targetTouches: daftar jari di elemen DOM saat ini.
  • changedTouches: daftar jari yang terlibat dalam peristiwa saat ini. Misalnya, dalam peristiwa sentuh, ini akan menjadi jari yang telah dihapus.

Daftar ini terdiri dari objek yang berisi informasi sentuh:

  • identifier: nomor yang secara unik mengidentifikasi jari saat ini dalam sesi sentuh.
  • target: elemen DOM yang merupakan target tindakan.
  • koordinat klien/halaman/layar: tempat tindakan tersebut terjadi di layar.
  • Koordinat radius dan rotationAngle: mendeskripsikan elips yang mendekati bentuk jari.

Aplikasi yang mendukung sentuhan

Peristiwa touchstart, touchmove, dan touchend menyediakan set fitur yang cukup kaya untuk mendukung hampir semua jenis interaksi berbasis sentuh – termasuk semua gestur multi-kontrol biasa seperti cubit untuk zoom, rotasi, dan sebagainya.

Cuplikan ini memungkinkan Anda menarik elemen DOM di sekitar menggunakan sentuhan satu jari:

var obj = document.getElementById('id');
obj.addEventListener('touchmove', function(event) {
  // If there's exactly one finger inside this element
  if (event.targetTouches.length == 1) {
    var touch = event.targetTouches[0];
    // Place element where the finger is
    obj.style.left = touch.pageX + 'px';
    obj.style.top = touch.pageY + 'px';
  }
}, false);

Berikut adalah contoh yang menampilkan semua sentuhan saat ini di layar. Ini berguna untuk merasakan responsivitas perangkat.

Pelacakan jari.
// Setup canvas and expose context via ctx variable
canvas.addEventListener('touchmove', function(event) {
  for (var i = 0; i < event.touches.length; i++) {
    var touch = event.touches[i];
    ctx.beginPath();
    ctx.arc(touch.pageX, touch.pageY, 20, 0, 2*Math.PI, true);
    ctx.fill();
    ctx.stroke();
  }
}, false);

Demo

Sejumlah demo multi-sentuh yang menarik sudah diluncurkan, seperti demo gambar berbasis kanvas oleh Paul Irish dan lainnya.

Screenshot gambar

Dan Browser Ninja, demo teknologi yang merupakan clone Buah Ninja menggunakan transformasi dan transisi CSS3, serta kanvas:

Ninja browser

Praktik terbaik

Mencegah zoom

Setelan default tidak berfungsi dengan baik untuk multi-sentuh, karena gestur geser dan gestur sering dikaitkan dengan perilaku browser, seperti men-scroll dan zoom.

Untuk menonaktifkan zoom, siapkan area pandang agar tidak dapat diskalakan oleh pengguna menggunakan tag meta berikut:

<meta name="viewport" 
  content="width=device-width, initial-scale=1.0, user-scalable=no>

Baca artikel HTML5 seluler ini untuk informasi selengkapnya tentang cara menyetel area pandang Anda.

Mencegah scroll

Beberapa perangkat seluler memiliki perilaku default untuk touchmove, seperti efek overscroll iOS klasik, yang menyebabkan tampilan memantul kembali saat scrolling melebihi batas konten. Hal ini membingungkan di banyak aplikasi multi-sentuh, dan dapat dengan mudah dinonaktifkan:

document.body.addEventListener('touchmove', function(event) {
  event.preventDefault();
}, false); 

Render dengan hati-hati

Jika Anda menulis aplikasi multi-sentuh yang melibatkan gestur multi-jari yang rumit, berhati-hatilah saat merespons peristiwa sentuh, karena Anda akan menangani banyak sekali jari sekaligus. Perhatikan contoh di bagian sebelumnya yang menggambar semua sentuhan di layar. Anda dapat menggambar segera setelah ada input sentuh:

canvas.addEventListener('touchmove', function(event) {
  renderTouches(event.touches);
}, false);

Namun, teknik ini tidak diskalakan dengan jumlah jari di layar. Sebagai gantinya, Anda dapat melacak semua jari, dan merender secara berulang untuk mendapatkan performa yang jauh lebih baik:

var touches = []
canvas.addEventListener('touchmove', function(event) {
  touches = event.touches;
}, false);

// Setup a 60fps timer
timer = setInterval(function() {
  renderTouches(touches);
}, 15);

Memanfaatkan targetTouches dan changedTouches

Perlu diingat bahwa event.touches adalah array SEMUA jari yang bersentuhan dengan layar, bukan hanya jari yang ada di target elemen DOM. Mungkin akan jauh lebih berguna jika Anda menggunakan event.targetTouches atau event.ChangesTouches.

Terakhir, karena Anda mengembangkan aplikasi untuk perangkat seluler, Anda sebaiknya memahami praktik terbaik seluler umum, yang dibahas dalam artikel Eric Bidelman, serta dokumen W3C ini.

Dukungan perangkat

Sayangnya, implementasi peristiwa sentuh sangat bervariasi dalam hal kelengkapan dan kualitas. Saya menulis skrip diagnostik yang menampilkan beberapa informasi dasar tentang implementasi touch API, termasuk peristiwa yang didukung, dan resolusi pengaktifan touchmove. Saya menguji Android 2.3.3 di hardware Nexus One dan Nexus S, Android 3.0.1 di Xoom, serta iOS 4.2 di iPad dan iPhone.

Secara ringkas, semua browser yang diuji mendukung peristiwa touchstart, touchend, dan touchmove.

Spesifikasi ini menyediakan tiga peristiwa sentuh tambahan, tetapi tidak ada browser teruji yang mendukungnya:

  • touchenter: jari yang bergerak memasuki elemen DOM.
  • touchleave: jari yang bergerak keluar dari elemen DOM.
  • touchcancel: sentuhan terganggu (khusus implementasi).

Dalam setiap daftar sentuh, browser yang diuji juga menyediakan daftar sentuh sentuhan, targetTouches, dan perubahanTouches. Namun, tidak ada browser yang diuji yang mendukung radiusX, radiusY, atau rotationAngle, yang menentukan bentuk jari yang menyentuh layar.

Selama gestur sentuh, peristiwa dipicu sekitar 60 kali per detik di semua perangkat yang diuji.

Android 2.3.3 (Nexus)

Browser Gingerbread Android (diuji pada Nexus One dan Nexus S), tidak memiliki dukungan multi-sentuh. Ini adalah masalah umum.

Android 3.0.1 (Xoom)

Di browser Xoom, ada dukungan multi-sentuh dasar, tetapi hanya berfungsi pada satu elemen DOM. Browser tidak merespons dua sentuhan bersamaan pada elemen DOM yang berbeda. Dengan kata lain, hal berikut akan bereaksi terhadap dua sentuhan simultan:

obj1.addEventListener('touchmove', function(event) {
  for (var i = 0; i < event.targetTouches; i++) {
    var touch = event.targetTouches[i];
    console.log('touched ' + touch.identifier);
  }
}, false);

Namun, hal berikut tidak akan:

var objs = [obj1, obj2];
for (var i = 0; i < objs.length; i++) {
  var obj = objs[i];
  obj.addEventListener('touchmove', function(event) {
    if (event.targetTouches.length == 1) {
      console.log('touched ' + event.targetTouches[0].identifier);
    }
  }, false);
}

iOS 4.x (iPad, iPhone)

Perangkat iOS sepenuhnya mendukung multi-sentuh, mampu melacak beberapa jari, dan memberikan pengalaman sentuh yang sangat responsif di browser.

Developer tools

Dalam pengembangan seluler, sering kali lebih mudah untuk memulai pembuatan prototipe di desktop lalu menangani bagian khusus seluler pada perangkat yang ingin Anda dukung. Multi-sentuh adalah salah satu fitur yang sulit diuji di PC karena sebagian besar PC tidak memiliki input sentuh.

Melakukan pengujian di perangkat seluler dapat memperpanjang siklus pengembangan, karena setiap perubahan yang Anda buat harus dikirimkan ke server, lalu dimuat di perangkat. Kemudian, setelah berjalan, tidak banyak hal yang dapat Anda lakukan untuk men-debug aplikasi Anda, karena tablet dan smartphone tidak memiliki alat developer web.

Solusi dari masalah ini adalah menyimulasikan peristiwa sentuh pada mesin pengembangan Anda. Untuk sekali sentuh, peristiwa sentuh dapat disimulasikan berdasarkan peristiwa mouse. Peristiwa multi-sentuh dapat disimulasikan jika Anda memiliki perangkat dengan input sentuh, seperti Apple MacBook modern.

Peristiwa sekali sentuh

Jika Anda ingin menyimulasikan peristiwa sekali sentuh di desktop, Chrome menyediakan emulasi peristiwa sentuh dari alat developer. Buka Developer Tools, lalu pilih roda gigi Setelan, lalu "Overrides" atau "Emulation", dan aktifkan "Emulate touch events".

Untuk browser lain, Anda mungkin ingin mencoba Phantom Limb, yang menyimulasikan peristiwa sentuh pada halaman dan juga memberikan tangan yang sangat besar untuk melakukan booting.

Ada juga plugin jQuery Touchable yang menyatukan peristiwa sentuh dan mouse di seluruh platform.

Peristiwa multi-sentuh

Agar aplikasi web multi-sentuh Anda berfungsi di browser pada trackpad multi-sentuh (seperti Apple MacBook atau MagicPad), saya telah membuat polyfill MagicTouch.js. Fitur ini menangkap peristiwa sentuh dari trackpad dan mengubahnya menjadi peristiwa sentuh yang kompatibel dengan standar.

  1. Download dan instal plugin enable npTuioClient ke ~/Library/Internet Plugin/.
  2. Download aplikasi TongSeng TUIO untuk MagicPad Mac dan mulai server.
  3. Download MagicTouch.js, library javascript untuk menyimulasikan peristiwa sentuh yang kompatibel dengan spesifikasi berdasarkan callback npTuioClient.
  4. Sertakan skrip magictouch.js dan plugin npTuioClient dalam aplikasi Anda sebagai berikut:
<head>
  ...
  <script src="/path/to/magictouch.js"></script>
</head>

<body>
  ...
  <object id="tuio" type="application/x-tuio" style="width: 0px; height: 0px;">
    Touch input plugin failed to load!
  </object>
</body>

Anda mungkin perlu mengaktifkan plugin.

Demo langsung dengan magictouch.js tersedia di paulirish.com/demo/multi:

Saya menguji pendekatan ini hanya dengan Chrome 10, tetapi pendekatan ini seharusnya berfungsi pada browser modern lainnya dengan hanya sedikit penyesuaian.

Jika komputer tidak memiliki input multisentuh, Anda dapat menyimulasikan peristiwa sentuh menggunakan pelacak TUIO lainnya, seperti reacTIVision. Untuk mengetahui informasi selengkapnya, lihat halaman project TUIO.

Perlu diperhatikan bahwa gestur Anda mungkin identik dengan gestur multi-kontrol tingkat OS. Di OS X, Anda dapat mengonfigurasi peristiwa di seluruh sistem dengan membuka panel preferensi Trackpad di System Preferences.

Karena fitur multi-sentuh semakin banyak didukung di seluruh browser seluler, saya sangat senang melihat aplikasi web baru yang memanfaatkan API yang kaya ini secara maksimal.