Pengembangan web multi-sentuh

Pengantar

Perangkat seluler seperti smartphone dan tablet biasanya memiliki layar sensitif sentuh kapasitif untuk menangkap interaksi yang dilakukan dengan jari pengguna. Seiring web seluler berkembang untuk memungkinkan aplikasi yang semakin canggih, developer web memerlukan cara untuk menangani peristiwa ini. Misalnya, hampir semua game 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 mengejar standar de facto ini dan menutup kesenjangan. Baru-baru ini, grup kerja W3C telah berkumpul untuk mengerjakan spesifikasi peristiwa sentuh ini.

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

Peristiwa sentuh

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

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

Setiap peristiwa sentuh menyertakan tiga daftar sentuh:

  • touches: daftar semua jari yang saat ini berada di layar.
  • targetTouches: daftar jari pada elemen DOM saat ini.
  • changedTouches: daftar jari yang terlibat dalam peristiwa saat ini. Misalnya, dalam peristiwa touchend, ini akan menjadi jari yang dihapus.

Daftar ini terdiri dari objek yang berisi informasi sentuh:

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

Aplikasi yang mendukung sentuh

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

Cuplikan ini memungkinkan Anda menarik elemen DOM menggunakan sentuhan jari tunggal:

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. Hal ini berguna untuk mendapatkan perasaan 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 tersedia, seperti demo gambar berbasis kanvas ini oleh Paul Irish dan lainnya.

Menggambar screenshot

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

Ninja browser

Praktik terbaik

Mencegah zoom

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

Untuk menonaktifkan zoom, siapkan area pandang agar tidak skalabel 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 mengetahui informasi selengkapnya tentang cara menetapkan area pandang.

Mencegah scroll

Beberapa perangkat seluler memiliki perilaku default untuk touchmove, seperti efek overscroll iOS klasik, yang menyebabkan tampilan kembali ke posisi semula saat scroll 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 kompleks, berhati-hatilah dengan cara Anda bereaksi terhadap peristiwa sentuh, karena Anda akan menangani begitu banyak peristiwa sekaligus. Pertimbangkan 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 dalam loop 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);

Menggunakan targetTouches dan changedTouches

Ingat bahwa event.touches adalah array dari SEMUA jari yang bersentuhan dengan layar, bukan hanya jari yang berada di target elemen DOM. Anda mungkin merasa lebih berguna untuk menggunakan event.targetTouches atau event.changedTouches.

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

Dukungan perangkat

Sayangnya, penerapan peristiwa sentuh sangat bervariasi dalam kelengkapan dan kualitasnya. Saya menulis skrip diagnostik yang menampilkan beberapa informasi dasar tentang penerapan API sentuh, termasuk peristiwa yang didukung, dan resolusi pengaktifan touchmove. Saya menguji Android 2.3.3 di perangkat keras Nexus One dan Nexus S, Android 3.0.1 di Xoom, dan iOS 4.2 di iPad dan iPhone.

Pada dasarnya, semua browser yang diuji mendukung peristiwa touchstart, touchend, dan touchmove.

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

  • touchenter: jari yang bergerak memasuki elemen DOM.
  • touchleaf: jari yang bergerak meninggalkan elemen DOM.
  • touchcancel: sentuhan terganggu (khusus implementasi).

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

Selama touchmove, peristiwa diaktifkan sekitar 60 kali per detik di semua perangkat yang diuji.

Android 2.3.3 (Nexus)

Di Browser Android Gingerbread (diuji di Nexus One dan Nexus S), tidak ada dukungan multi-sentuh. Masalah ini merupakan 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 dengan benar dua sentuhan serentak pada elemen DOM yang berbeda. Dengan kata lain, kode berikut akan bereaksi terhadap dua sentuhan serentak:

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 dihapus:

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 cukup banyak jari, dan memberikan pengalaman sentuh yang sangat responsif di browser.

Developer tools

Dalam pengembangan seluler, biasanya 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, ada sedikit hal yang dapat Anda lakukan untuk men-debug aplikasi, karena tablet dan smartphone tidak memiliki alat developer web.

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

Peristiwa sentuh tunggal

Jika Anda ingin menyimulasikan peristiwa satu sentuhan pada desktop, Chrome menyediakan emulasi peristiwa sentuh dari alat developer. Buka Developer tools, lalu pilih roda gigi Setelan, kemudian "Ganti" atau "Emulasi", kemudian aktifkan "Emulasikan peristiwa sentuh".

Untuk browser lain, Anda dapat mencoba Phantom Limb, yang menyimulasikan peristiwa sentuh di halaman dan juga memberikan bantuan besar untuk memulai.

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

Peristiwa multi-sentuh

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

  1. Download dan instal plugin NPAPI npTuioClient ke ~/Library/Internet Plug-Ins/.
  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 live dengan magictouch.js tersedia di paulirish.com/demo/multi:

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

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

Perhatikan bahwa gestur Anda mungkin sama dengan gestur multi-kontrol level OS. Di OS X, Anda dapat mengonfigurasi peristiwa seluruh sistem dengan membuka panel preferensi Trackpad di System Preferences.

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