Multi-Touch-Webentwicklung

HTML5 Rocks

Einführung

Mobilgeräte wie Smartphones und Tablets verfügen normalerweise über einen kapazitiven berührungssensitiven Bildschirm, der Interaktionen erfassen kann, die die Nutzer mit ihren Fingern ausführen. Die Weiterentwicklung des mobilen Webs ermöglicht zunehmend ausgefeiltere Apps und Webentwickler müssen mit dieser Entwicklung Schritt halten. So können Nutzer beispielsweise bei nahezu jedem schnellen Spiel mehrere Tasten gleichzeitig drücken, was im Kontext eines Touchscreens Multi-Touch voraussetzt.

Apple hat sein Touch Events API in iOS 2.0 eingeführt. Android hat auf diesen faktischen Standard aufgerüstet und die Lücke geschlossen. Kürzlich hat sich eine W3C-Arbeitsgruppe gebildet, um an der Touch Events-Spezifikation zu arbeiten.

In diesem Artikel gehe ich auf das Touch Events API von iOs- und Android-Geräten ein, erkunde, welche Arten von Apps Sie erstellen können, stelle einige Best Practices vor und erläutere nützliche Techniken, die die Entwicklung von Apps mit Touch-Option erleichtern.

Touch-Ereignisse

Drei grundlegende Touch-Ereignisse sind in der Spezifikation erläutert und bei Mobilgeräten weit verbreitet:

  • touchstart: Ein Finger wird auf ein DOM-Element gelegt.
  • touchmove: Ein Finger wird über ein DOM-Element gezogen.
  • touchend: Ein Finger wird von einem DOM-Element entfernt.

Jedes Touch-Ereignis enthält drei Listen von Berührungen:

  • touches: eine Liste aller Finger, die sich derzeit auf dem Bildschirm befinden
  • targetTouches: eine Liste der Finger auf dem aktuellen DOM-Element
  • changedTouches: eine Liste der Finger, die an dem aktuellen Ereignis beteiligt sind. Bei einem Touchend-Ereignis wäre dies zum Beispiel der Finger, der entfernt wurde.
Diese Listen bestehen aus Objekten, die Touch-Informationen enthalten:
  • identifier: eine Nummer, die den aktuellen Finger in der Touch-Sitzung eindeutig identifiziert
  • target: das DOM-Element, das das Ziel der Aktion war
  • client/page/screen-Koordinaten: wo auf dem Bildschirm die Aktion stattgefunden hat
  • radius-Koordinaten und rotationAngle: beschreiben die Ellipse, die ungefähr der Fingerform entspricht

Apps mit Touch-Option

Die Ereignisse touchstart, touchmove, und touchend bieten einen ausreichenden Funktionsumfang, um praktisch alle berührungsbasierten Interaktionen zu unterstützen. Dazu gehören auch alle üblichen Multi-Touch-Gesten wie Pinch & Zoom, Rotation usw.

Mit diesem Snippet kann ein DOM-Element durch die Berührung mit einem einzelnen Finger verschoben werden:

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);

Unten finden Sie ein Beispiel, das alle aktuellen Berührungen auf dem Bildschirm darstellt. Dies ist nützlich, um ein Gefühl für die Reaktionsfähigkeit des Geräts zu bekommen.

// 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);

Demos

Da draußen gibt es bereits eine Reihe interessanter Multi-Touch-Demos, zum Beispiel diese Demo zum Canvas-basierten Zeichnen von Paul Irish und weiteren Autoren.

Oder die Techdemo Browser Ninja, ein Fruit Ninja-Klon, der CSS3-Transformationen und -Übergänge sowie Canvas verwendet:

Best Practices

Zoomen verhindern

Standardeinstellungen funktionieren bei Multi-Touch nicht sehr gut, da die Ziehbewegungen und Gesten oft mit dem Browserverhalten verknüpft sind, zum Beispiel Scrollen und Zoomen.

Richten Sie zum Deaktivieren des Zoomens Ihren Darstellungsbereich mithilfe des folgenden Meta-Tags so ein, dass er nicht vom Nutzer skaliert werden kann:

<meta name="viewport" 
  content="width=device-width, initial-scale=1.0, user-scalable=no">
Weitere Informationen zum Einrichten Ihres Darstellungsbereichs finden Sie in diesem Artikel zu HTML5 für Mobilgeräte.

Scrollen verhindern

Einige Mobilgeräte verfügen über ein Standardverhalten für Touchmove-Ereignisse, wie der klassische Overscroll-Effekt von iOS, bei dem die Ansicht zurückprallt, wenn das Scrollen die Grenzen des Inhalts überschreitet. Dies ist in vielen Multi-Touch-Apps verwirrend und kann leicht deaktiviert werden:

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

Sorgfältig rendern

Wenn Sie eine Multi-Touch-App schreiben, die komplexe Mehrfinger-Gesten beinhaltet, achten Sie genau darauf, wie Sie auf Touch-Ereignisse reagieren, da Sie so viele gleichzeitig verarbeiten werden. Denken Sie an das Beispiel im vorherigen Abschnitt, bei dem alle Berührungen auf dem Bildschirm dargestellt sind. Sie könnten mit der Darstellung beginnen, sobald eine Berührung erfolgt:

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

Diese Technik ist jedoch nicht auf Mehrfingerberührungen ausgerichtet. Stattdessen könnten Sie alle Finger nachverfolgen und in einer Schleife rendern. So erhalten Sie eine viel bessere Leistung:

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

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

Tipp: "setInterval" eignet sich nicht so gut für Animationen, da es die eigene Rendering-Schleife des Browsers nicht berücksichtigt. Moderne Desktop-Browser stellen requestAnimationFrame bereit. Dies stellt im Hinblick auf Leistung und Akkuverbrauch eine weitaus bessere Option dar. Sobald diese Option in mobilen Browsern unterstützt wird, wird sie auch hier zur bevorzugten Methode werden.

"targetTouches" und "changedTouches" verwenden

Denken Sie daran, dass in "event.touches" ALLE Finger aufgeführt sind, die in Kontakt mit dem Bildschirm sind, nicht nur diejenigen auf dem DOM-Element-Ziel. Es ist möglicherweise sinnvoller, stattdessen "event.targetTouches" bzw. "event.changedTouches" zu verwenden.

Da Sie für Mobilgeräte entwickeln, sollten Sie sich mit einigen Best Practices vertraut machen, die in Eric Bidelmans Artikel und in diesem W3C-Dokument beschrieben sind.

Gerätesupport

Leider unterscheiden sich die Implementierungen von Touch-Ereignissen erheblich in Vollständigkeit und Qualität. Ich habe ein Diagnoseskript geschrieben, das einige grundlegende Informationen zur Touch API-Implementierung, wie Angaben zu den unterstützten Ereignissen und zum Auslösen von Touchmove-Ereignissen enthält. Ich habe Android 2.3.3 auf Nexus One- und Nexus S, Android 3.0.1 auf Xoom und iOS 4.2 auf iPad und iPhone getestet.

Kurz gesagt: Alle Browser unterstützen die Ereignisse touchstart, touchend und touchmove.

Die Spezifikation enthält drei weitere Touch-Ereignisse, diese wurden jedoch von keinem der getesteten Browser unterstützt:

  • touchenter: Ein Finger in Bewegung trifft auf ein DOM-Element.
  • touchleave: Ein Finger in Bewegung verlässt ein DOM-Element.
  • touchcancel: Eine Berührung wird unterbrochen (implementierungsspezifisch).

Innerhalb jeder Touch-Liste stellen die getesteten Browser auch die Touch-Listen touches, targetTouches und changedTouches bereit. Keiner der getesteten Browser unterstützt jedoch "radiusX", "radiusY" oder "rotationAngle", die die Form des Fingers beschreiben, der den Bildschirm berührt.

Während eines Touchmove wurden auf allen getesteten Geräten ungefähr 60-mal pro Sekunde Ereignisse ausgelöst.

Android 2.3.3 (Nexus)

Der Android Gingerbread-Browser (getestet auf Nexus One und Nexus S) bietet keinen Multi-Touch-Support. Dies ist ein bekanntes Problem.

Android 3.0.1 (Xoom)

Der Xoom-Browser bietet einen grundlegenden Multi-Touch-Support, der aber nur mit einem einzelnen DOM-Element funktioniert. Der Browser reagiert nicht ordnungsgemäß auf zwei gleichzeitige Berührungen auf verschiedenen DOM-Elementen. Anders ausgedrückt: In folgendem Fall wird auf zwei gleichzeitige Berührungen reagiert:

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

Aber in diesem Fall nicht:

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)

iOS-Geräte unterstützen Multi-Touch vollständig, können mehrere Fingerbewegungen verfolgen und bieten ein äußerst reaktionsfähiges Berührungserlebnis im Browser.

Entwickler-Tools

In der mobilen Entwicklung ist es oft einfacher, zunächst auf einem Desktop-Computer einen Prototyp zu erstellen und dann die mobilspezifischen Herausforderungen auf den Geräten anzugehen, die unterstützt werden sollen. Multi-Touch ist eine der Funktionen, die auf dem PC schwierig zu testen sind, da die meisten PCs nicht über eine Touch-Eingabe verfügen.

Das Testen auf Mobilgeräten kann Ihren Entwicklungszyklus in die Länge ziehen, da jede Änderung auf einen Server übertragen und dann auf das Gerät geladen werden muss. Sobald die Funktion ausgeführt wird, haben Sie nicht mehr viele Debugging-Möglichkeiten, da Tablets und Smartphones keine Webentwickler-Tools bereitstellen.

Sie können dieses Problem lösen, indem Sie Touch-Ereignisse auf Ihrem Entwicklungscomputer simulieren. Single-Touch-Ereignisse können auf der Grundlage von Mausereignissen simuliert werden. Multi-Touch-Ereignisse können simuliert werden, wenn Sie über ein Gerät mit Touch-Eingabe verfügen, zum Beispiel ein modernes Apple MacBook.

Single-Touch-Ereignisse

Falls Sie Single-Touch-Ereignisse auf Ihrem Desktop-Computer simulieren möchten, testen Sie Phantom Limb, das Touch-Ereignisse auf Seiten simuliert und außerdem eine überdimensionale Hand zum Starten bereitstellt.

Mit dem Touchable-jQuery-Plug-in können Touch- und Maus-Ereignisse über Plattformen hinweg vereinheitlicht werden.

Multi-Touch-Ereignisse

Mit meinem MagicTouch.js-Polyfill können Sie Ihre Multi-Touch-Web-App in Ihrem Browser mit Ihrem Multi-Touch-Touchpad (z. B. Apple MacBook oder MagicPad) ausführen. Touch-Ereignisse auf Ihrem Touchpad werden erfasst und in standardkompatible Touch-Ereignisse umgewandelt.

  1. Laden Sie das npTuioClient NPAPI-Plug-in herunter und installieren Sie es unter ~/Library/Internet Plug-Ins/.
  2. Laden Sie die TongSeng TUIO-App für das Mac MagicPad herunter und starten Sie den Server.
  3. Laden Sie MagicTouch.js herunter, eine JavaScript-Bibliothek zur Simulation spezifikationskompatibler Touch-Ereignisse auf der Grundlage von npTuioClient-Rückrufen.
  4. Fügen Sie das "magictouch.js"-Skript und das "npTuioClient"-Plug-in wie folgt in Ihre App ein:
<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>

Ich habe diesen Ansatz nur mit Chrome 10 getestet, das Ganze sollte jedoch mit minimalen Anpassungen in anderen modernen Browsern ebenfalls funktionieren.

Falls Ihr Computer keine Multi-Touch-Eingabe ermöglicht, können Sie Touch-Ereignisse mithilfe anderer TUIO-Tracker wie reacTIVision simulieren. Weitere Informationen finden Sie auf der TUIO-Projektseite.

Beachten Sie, dass Ihre Gesten möglicherweise mit Multi-Touch-Gesten auf Betriebssystemebene identisch sind. In OS X können Sie systemweite Ereignisse konfigurieren, indem Sie in den Systemeinstellungen die Trackpad-Einstellungen aufrufen.

Multi-Touch-Funktionen werden in mobilen Browsern immer stärker unterstützt und ich freue mich schon auf neue Web-Apps, die die Vorteile dieses vielfältigen APIs nutzen.

Comments

0