Windows8 Gesture動作
Vivo Tabを買った
Windows8タブレットでの動作確認用にASUSのVivo Tab RTを買った。タブレットとして使う分にはWindows8のメトロUIはなかなか使いやすい。
Gesture関連のイベント
早速、JavaScriptからタッチ等ジェスチャ関連のイベントをどのように扱えるか試してみた。
まず、iOS,Androidのタッチ関連のイベントとはまったく異なる。Windows8ではタッチ関連のイベントにはマウスイベント、ポインタイベント、ジェスチャーイベントの3種類がある。
(a) マウスイベント
従来のマウス操作で使っていたmousedown,mouseup,click等のイベント。これらは、タッチパネル操作でも従来どおりイベント発生するので、PC用のサイトなどでは特に修正をしなくてもタッチパネルから操作できる(このあたりはiOS,Androidも同じ)。ただし、マルチタッチなどに対応するには以下ポインタイベント、ジェスチャーイベントを使う必要がある。
(b) ポインタイベント
タッチパネル上での指の動き(Up/Down/Move)を検出するイベント。MSPointerDown,MSPointerMove,MSPointerUp,MSPointerCancelのようにイベント名はMSPointerで始まる。
iOS,Androidなどでは、touchmoveイベントのevent.touches[]で全ての指の状況を把握できたが、Windows8のポインタイベントでは、指1本毎にポインタIDというものが割り振られて、それぞれのポインタ(指)毎にイベントが発生するため、イベントハンドラではイベントに関連するポインタ(指)の情報しか参照できない。このため、全ての指の状況を把握するには、自分で管理してやる必要がある。
(c) ジェスチャーイベント
タップやホールド等の操作を検出するのに使われるイベント。ポインタイベントでは、単純にUp/Down/Moveしか取得できないので、ホールド等を検出しようとすると、指を降ろしていた時間を監視したりと面倒になるのだが、ジェスチャイベントを使えば簡単にホールド等のジェスチャを検出できる。
なお、iOS,Androidではジェスチャイベントとは複数の指での操作を意味していたが、Windows8では1本指での操作(タップ)等もジェスチャ動作として扱われるので、若干意味が異なる。
ポインタイベントの使い方
ポインタイベントを使うには、まずデバイスがポインタイベントをサポートしているかどうかを確認する必要がある。
デバイスがポインタイベントをサポートしているかどうかは、 window.navigator.msPointerEnabledで判断できる。msPointerEnabledがtrueなら、 window.addEventListener('MSPointerDown', onPointerEvent, false) のようにしてポインタイベントを取得できる。
イベントリスナーの登録
// ポインタイベントのサポート有無チェック if (window.navigator.msPointerEnabled) { // ポインタイベントのリスナー登録 window.addEventListener('MSPointerDown', onPointerEvent, false); window.addEventListener('MSPointerMove', onPointerEvent, false); window.addEventListener('MSPointerUp', onPointerEvent, false); window.addEventListener('MSPointerCancel', onPointerEvent, false); }
イベントリスナー側では以下のようにしてイベントを処理できる。
リスナーの例
function onPointerEvent(e) { var id = e.pointerId; // IDで指を識別する if (e.type == "MSPointerDown") { : } if (e.type == "MSPointerUp") { : } : }
e.pointerIdにはポインタを識別するID値が入っている。ポインタIDはパネルに指を触れた時(MSPointerDown)に新しく割り当てられ、指がパネルに触れている間は同じIDが維持される。Windows8では、iOSのevent.touches[]のように一つのイベントで複数の指の情報は取得できないので、複数の指の情報を参照したい場合は、このポインタIDをキーにして各指の情報をどこかに保存しておく必要がある(ページ下のサンプル参照)。
なお、デバイスが何本の指まで識別できるかは、navigator.msMaxTouchPointsで取得できる。Vivo Tabは5だった。
ジェスチャーイベントの使い方
ジェスチャイベントはポインタイベントと異なり、addEventListener()するだけでは使えない。以下の手順を踏む必要がある。
1. MSGestureオブジェクトを生成
2. 1.で生成したオブジェクトのtargetプロパティに監視対象のDOMノード(document.body等)を登録する。
3. 監視対象にしたいポインタのポインタIDをaddPointer()を使ってMSGestureオブジェクトに明示的に登録する。
1., 2.はアプリケーションの初期化時に行っておけばいいのだが、3.のポインタIDの登録は、ポインタIDの割り当てがMSPointerDown時に行われることから、MSPointerDownのイベントリスナーの中でaddPointer()をする必要がある。addPointer()を忘れると、ポインタが監視対象とならず、ジェスチャーイベントは発生しない。若干ややこしい。
ジェスチャイベントの設定例
var Gesture; function onPointerEvent(e) { : if (e.type == "MSPointerDown") { // ジェスチャーの監視対象にする Gesture.addPointer(e.pointerId); } : } function onInitialize() { : if (window.navigator.msPointerEnabled) { // ポインターイベント登録 window.addEventListener('MSPointerDown', onPointerEvent, false); window.addEventListener('MSPointerMove', onPointerEvent, false); window.addEventListener('MSPointerUp', onPointerEvent, false); window.addEventListener('MSPointerCancel', onPointerEvent, false); // ジェスチャーイベント登録 Gesture = new MSGesture(); Gesture.target = document.body; // targetプロパティを設定する必要がある。 document.body.addEventListener('MSGestureTap', onGestureEvent, false); document.body.addEventListener('MSGestureStart', onGestureEvent, false); document.body.addEventListener('MSGestureChange', onGestureEvent, false); document.body.addEventListener('MSGestureEnd', onGestureEvent, false); document.body.addEventListener('MSGestureHold', onGestureEvent, false); document.body.addEventListener('MSInertiaStart', onGestureEvent, false); } : }
詳細はページ下のサンプル参照。
ジェスチャーイベントのイベントオブジェクトには http://msdn.microsoft.com/ja-jp/library/windows/apps/hh441180.aspx のようなプロパティがあり、回転、拡大(ピンチ)の動作を検出できる。
イベントを使ったサンプル
タッチ関連のイベントの勉強用に作ったサンプル。
http://www.bit-hive.com/~tomita/Win8Gesture/
マウスイベント、ポインタイベント、ジェスチャイベントの発生状況のトレースを出力する。また、タッチした部分にマーカーを表示。
参考ページ
Pointer and gesture events (Windows)