次の方法で共有


scriptjunkie{}

タッチ操作とマウス操作の統一: Pointer Events を使用してクロスブラウザー タッチを実現する方法

David Rousset | 2013 年 3 月 22 日

開発者の方から「携帯端末やタブレットにはタッチ対応のデバイスがたくさんあるが、どこから手を付けたらよいでしょう」とか、「タッチ入力への対応を最も簡単にビルドする方法を教えてください」といった質問がよく寄せられます。手短に答えると、複雑ですが、Web 上のマルチタッチ入力を処理する統一性の高い方法が確かにあります。つまり、最新のタッチ対応ブラウザーではマルチタッチ入力を処理し、以前のブラウザーではフォールバックを提供します。今回は、 MSPointer (新しいマルチタッチ テクノロジ) と、クロスブラウザー サポートを適切かつ簡潔にするポリフィルを使ってブラウザー上でいくつか実験を行います。今回紹介するのは、実験が可能で、自分のサイトに簡単に流用できるようなコードです。

まず、Web では多くのタッチ テクノロジが進化しています。ブラウザー サポートの場合、すべてのブラウザーをサポートするには、 MSPointer 以外にも、 iOS タッチ イベント モデルや W3C マウス イベント モデルを参考にする必要があります。また、標準化に向けて (積極的で) 進化中のサポートもあります。2012 年 9 月、Microsoft は MSPointer を標準として W3C に提出し、ようやく最終草案にこぎつけています ( http://www.w3.org/TR/pointerevents、英語)。また、 MS Open Tech チームも最近、 Webkit 向けに Pointer Events の初期プロトタイプをリリースしました。

MSPointer を試すのはデバイスのシェアを拡大しようというのが理由ではありません。基本入力処理への Microsoft のアプローチが、Web で現状利用できるアプローチとはまったく異なり、一度見ておくにふさわしいアプローチであるためです。他のアプローチと異なるのは、開発者がポインターという抽象的な入力形式を記述できる点です。ポインターは、マウス カーソル、ペン、指、複数の指などを使って画面上で行われるすべてのコンタクト ポイントを表します。したがって、入力の種類ごとに別々にコーディングする手間がかかりません。

コンセプト

まず、MSPointer のイベント API を公開する Internet Explorer 10 の内部で実行されるアプリについて説明してから、すべてのブラウザーをサポートするソリューションを確認します。その後、JavaScript コードで簡単にタッチ操作を処理できる、Internet Explorer 10 のジェスチャー サービスを利用する方法を見ていきます。Windows 8 と Windows Phone 8 は同じブラウザー エンジンを共有しているため、どちらのプラットフォームでもコードや考え方は同じです。さらに、今回説明するタッチに関するすべての内容は、HTML5 と JS を使ってビルドされる Windows ストア アプリ でもまったく同じことを実現できます。これは、やはり同じエンジンが使用されているためです。

MSPointer の基盤となっている考え方は、単一コード ベースを使ってマウス、ペン、およびタッチ デバイスに対処できるようにすることです。このコード ベースでは、これまでに理解してきた従来のマウス イベントに相当するパターンを使用します。実際、マウス、ペン、およびタッチには共通のプロパティがいくつかあります (図 1 参照)。たとえば、マウス、ペン、タッチを使ってポインターを移動し、要素をクリックできます。そこで、まったく同じコードを使用してこのようなシナリオに対処してみることにします。MSPointer はこのような共通プロパティを集約し、マウス イベントと同様の方法でこの共通プロパティを公開します。


図 1. マウス、ペン、およびタッチには共通するプロパティがある

最も明白に共通するイベントは MSPointerDownMSPointerMove、および MSPointerUp で、これらは同等のマウス イベントに直接対応しています。これらのイベントの出力として、画面上の X 座標と Y 座標を受け取ることになります。

また、 MSPointerOverMSPointerOutMSPointerHoverMSPointerCancel といったマウスにはない固有のイベントもあります。

とは言え、既定のマウス動作とは異なる方法でタッチに対処して、異なるユーザー エクスペリエンスを提供することを考えるのも当然です。また、マルチタッチ画面であれば、ユーザーが要素を簡単に回転、ズーム、パンできます。ペンやスタイラスであれば、筆圧の情報も提供されます。この情報はマウスでは提供できません。Pointer Events はこのような違いを集約して、各デバイス固有のカスタム コードをビルドできるようにします。

注: タッチ画面を装備する Windows 8/RT デバイスや Windows Phone 8 を使用できる場合は、この後ページに埋め込んだサンプルをテストしてみることをお勧めします。このようなデバイスを利用できない場合でも、次のようなオプションがあります。

  1. 無料の Visual Studio 2012 Express 開発ツールに付属する Windows 8 Simulator を使用すれば基本レベルのエクスペリエンスを体験できます。このしくみの詳細については、「 Using the Windows 8 Simulator & VS 2012 to debug the IE10 touch events & your responsive design」(Windows 8 Simulator と VS 2012 を使用して IE10 のタッチ イベントとレスポンシブ デザインをデバッグする、英語) のブログ記事を参照してください。
  2. このビデオ (英語) を視聴します (このビデオを別の形式で視聴する場合は本稿の末尾を参照してください)。 このビデオ (英語) では、Windows 8 タブレットでタッチ、ペン、およびマウスをサポートするサンプル (後ほど説明) をデモしています。
  3. Windows 8 デバイスを利用できない場合は、 BrowserStack (英語) のような仮想クロスブラウズ テストを使用して対話形式でテストします。Internet Explorer チームの厚意により、 modern.IEBrowserStack を 3 か月間無料で使用できます。

シンプルなタッチ イベントを処理する

手順 1: JS には手を付けずに、CSS に行を追加する

基本から始めましょう。既存の JavaScript コードでマウス イベントを処理していれば、そのコードを簡単に利用できます。Internet Explorer 10 でペンやタッチ デバイスを操作しても、コードはそのまま動作します。つまり、コードで Pointer Events を処理していなければ、Internet Explorer 10 は最後の手段としてマウス イベントを発生します。利用者が指でクリック操作する日が来ることを開発者がまったく想定していなかったとしても、Web ページ上のボタンなどの要素を指で "クリック" できるのは、このためです。したがって、mousedown イベントまたは mouseup イベントを登録するコードは、まったく変更することなく動作します。では、mousemove についてはどうでしょう。

既定の動作を調べて、この疑問の答えを考えてみます。たとえば、次のコードがあるとします。

<!DOCTYPE html> 
<html> 
<head> 
  <title>Touch article sample 1</title> 
</head> 
<body> 
  <canvas id="drawSurface" width="400px" height="400px" 
    style="border: 1px dashed black;"> 
  </canvas> 
  <script> 
    var canvas = document.getElementById("drawSurface"); 
    var context = canvas.getContext("2d"); 
    context.fillStyle = "rgba(0, 0, 255, 0.5)"; 
  
    canvas.addEventListener("mousemove", paint, false); 
  
    function paint(event) { 
      context.fillRect(event.clientX, event.clientY, 10, 10); 
    } 
  </script> 
</body> 
</html>

このコードでは、マウスの動きを追跡して、HTML5 のキャンバス要素内に 10 ピクセル x 10 ピクセルの青色の四角形を単純に描画します。これをテストするには、ボックス内でマウスを動かします (図 2 参照)。タッチ画面を使用している場合は、キャンバスとの対話操作を試みて現状の動作をチェックしてください。

図 2. MouseDown/Up/Click だけがタッチ操作に反応し、画面上を指でドラッグしても青い四角形は追随して描画されない

キャンバス要素内でマウスを動かすと、一連の青い四角形が描画されます。しかし、タッチ操作を使用すると、キャンバス要素をタップした位置だけに四角形が 1 つ描画されます。キャンバス要素内で指を動かそうとすると、ブラウザーはページのパンを試みます。これは、パンが既定の動作として定義されているためです。

そこで、ブラウザーの既定動作をオーバーライドすることを指定する必要があります。つまり、ブラウザーにタッチ イベントを解釈させずに、このイベントを JavaScript コードにリダイレクトするよう指示します。そのためには、既定の動作をオーバーライドするページ要素をターゲットに指定して、以下の CSS ルールを適用します。

-ms-touch-action: auto | none | manipulation | double-tap-zoom | inherit;

どの動作にフィルターをかけるかに応じて、さまざまな値を使用できます。今回使用する値は「 Guidelines for Building Touch-friendly Sites」(タッチ対応のサイトをビルドするためのガイドライン、英語) で確認できます。

このルールがよく見受けられるのは、ページ上に地図コントロールがある場合です。地図の中ではパンやズームを行えるようになっていますが、他の部分では既定の動作が保持されます。この場合は、地図を表示する HTML コンテナーだけに CSS ルール (-ms-touch-action: manipulation) を適用しています。

今回の場合は、以下の CSS ブロックを追加します。

<style> 
  #drawSurface 
  { 
    /* Disable touch behaviors, like pan and zoom */ 
    -ms-touch-action: none; 
  } 
</style>

すると、図 3 に示す結果が生成されるようになります。

図 3. –ms-touch-action: none を追加すると、ブラウザー既定のパン動作が無効になり、MouseMove が 1 本の指の動きだけに反応する

これで、キャンバス要素内で指を動かすと、マウス ポインターのように動作するようになります。すばらしいでしょう。しかし、疑問なのは「このコードで 1 本の指だけを追跡する理由」です。このように動作するのは、Internet Explorer 10 が最終手段として、マウスの動きをシミュレーションするためにいずれか 1 本の指をマップするという最も基本的なタッチ エクスペリエンスを提供するためです。私の知る限り、マウスを複数使う人は見かけません。そのため、このアプローチは「1 つのマウス == 最大 1 本の指」になります。では、マルチタッチ イベントを処理するにはどうすればよいでしょう。

手順 2: マウス イベントではなく MSPointer イベントを使用する

既存のコードの "mousedown/up/move" の登録を "“MSPointerDown/Up/Move" に置き換えるだけで、Internet Explorer 10 内でマルチタッチ エクスペリエンスが直接サポートされるようになります。

たとえば、前述のサンプルの場合、以下のコード行を

canvas.addEventListener("mousemove", paint, false);

以下のコード行に置き換えます。

canvas.addEventListener("MSPointerMove", paint, false);

図 4 に結果を示します。

図 4. mousemove ではなく MSPointerMove を使用するとマルチタッチが機能する

これで、画面でサポートされるタッチ ポイントの数だけ四角形が描画されるようになります。さらにすばらしいことに、同じコードでタッチ、マウス、およびペンに対応します。たとえば、マウスを使用していくつか線を描画しながら、同時に指で別の線を描画できます。

入力の種類に応じてコードの動作を変更する場合は、pointerType プロパティ値を使ってテストできます。たとえば、指を動かすと 10 x 10 ピクセルの赤い四角形、ペンを動かすと 5 x 5 ピクセルの緑の四角形、マウスを動かすと 2 x 2 ピクセルの青い四角形を描画するとします。この場合、前述のハンドラー (paint 関数) を以下のハンドラーに置き換えます。

function paint(event) { 
  if (event.pointerType) { 
    switch (event.pointerType) { 
      case event.MSPOINTER_TYPE_TOUCH: 
        // A touchscreen was used 
        // Drawing in red with a square of 10 
        context.fillStyle = "rgba(255, 0, 0, 0.5)"; 
        squaresize = 10; 
        break; 
      case event.MSPOINTER_TYPE_PEN: 
        // A pen was used 
        // Drawing in green with a square of 5 
        context.fillStyle = "rgba(0, 255, 0, 0.5)"; 
        squaresize = 5; 
        break; 
      case event.MSPOINTER_TYPE_MOUSE: 
        // A mouse was used 
        // Drawing in blue with a square of 2 
        context.fillStyle = "rgba(0, 0, 255, 0.5)"; 
        squaresize = 2; 
        break; 
    } 
  
        context.fillRect(event.clientX, event.clientY, squaresize,
          squaresize); 
  } 
}

図 5 で結果をテストできます。

図 5. pointerType をテストする。マウス/ペン/タッチの動作を変えられるが、図 4 以降は Internet Explorer 10 以上でなければコードが機能しない

この 3 種類の入力を正しくサポートするデバイス (Sony Duo 11、Microsoft Surface Pro、Samsung 製タブレットなど) があればこの動作を確認できます。すばらしいですよね。

しかし、このコードには問題があります。Internet Explorer 10 ではすべての種類の入力を正しく処理できるようになりましたが、MSPointer イベントをサポートしない Internet Explorer 9、Chrome、Firefox、Opera、Safari といったブラウザーではまったく機能しません。

手順 3: 機能検出を行ってフォールバック コードを用意する

既にお分かりだと思いますが、マルチブラウザー サポートを処理する最も適切なアプローチは機能検出です。そのため、以下のテストを行います。

window.navigator.msPointerEnabled

このコードは、現在のブラウザーが MSPointer をサポートするかどうかのみを判定します。タッチ操作をサポートするかどうかを判定するわけではありません。タッチ操作のサポートをテストするには、 msMaxTouchPoints をチェックします。

結論としては、Internet Explorer 10 では MSPointer がサポートされますが、他のブラウザーではマウス イベントに適切にフォールバックするコードが必要です。

var canvas = document.getElementById("drawSurface"); 
var context = canvas.getContext("2d"); 
context.fillStyle = "rgba(0, 0, 255, 0.5)"; 
if (window.navigator.msPointerEnabled) { 
  // Pointer events are supported. 
  canvas.addEventListener("MSPointerMove", paint, false); 
} 
else { 
  canvas.addEventListener("mousemove", paint, false); 
} 
  
function paint(event) { 
  // Default behavior for mouse on non-IE10 devices 
  var squaresize = 2; 
  context.fillStyle = "rgba(0, 0, 255, 0.5)"; 
  // Check for pointer type on IE10 
  if (event.pointerType) { 
    switch (event.pointerType) { 
      case event.MSPOINTER_TYPE_TOUCH: 
        // A touchscreen was used 
        // Drawing in red with a square of 10 
        context.fillStyle = "rgba(255, 0, 0, 0.5)"; 
        squaresize = 10; 
        break; 
      case event.MSPOINTER_TYPE_PEN: 
        // A pen was used 
        // Drawing in green with a square of 5 
        context.fillStyle = "rgba(0, 255, 0, 0.5)"; 
        squaresize = 5; 
        break; 
      case event.MSPOINTER_TYPE_MOUSE: 
        // A mouse was used 
        // Drawing in blue with a square of 2 
        context.fillStyle = "rgba(0, 0, 255, 0.5)"; 
        squaresize = 2; 
        break; 
    } 
  } 
  
  context.fillRect(event.clientX, event.clientY, squaresize, squaresize); 
}

同様に、結果をテストできます。図 6 を参照してください。

図 6.機能検出msPointerEnabled は Internet Explorer 10 では完全なエクスペリエンスを提供し、他のブラウザーでは既定のマウス イベントのエクスペリエンスを提供する

手順 4: すべてのタッチ実装をサポートする

さらに進んで、すべてのブラウザーおよびすべてのタッチ実装をサポートする場合、次の 2 つの選択肢があります。

  • 両方のイベント モデルに対処するコードを並列に記述する。「 Handling Multi-touch and Mouse Input in All Browsers」(すべてのブラウザーでマルチタッチおよびマウス入力を処理する、英語) の記事を参照。
  • 友人の David Catuhe が記述したすばらしい JavaScript ポリフィルである HandJS への参照を単純に追加する。「 Hand.JS: a polyfill for supporting pointer events on every browser」(Hand.JS: すべてのブラウザーでポインターのイベントをサポートするためのポリフィル、英語) の記事を参照。

冒頭で述べたように、Microsoft は最近、 MSPointer イベントの仕様を標準にするため W3C に提出 (英語) しました。W3C は新しいワーキング グループを立ち上げ、Microsoft の提案に基づく 最終草案 (英語) を公開しています。MS Open Tech チームは最近、興味深い Webkit 向けに Pointer Events の初期プロトタイプ をリリースしています。

Pointer Events の仕様はまだ標準にはなっていませんが、 David のポリフィル を利用して、Pointer Events をサポートするコードをすぐに実装し、Pointer Events がすべてのブラウザーに実装される標準になる日に備えてください。David のライブラリを使用する場合、Internet Explorer 10 ではイベントが MSPointer に、Webkit ベースのブラウザーではタッチ イベントに、どちらでもなければ最後の手段としてマウス イベントに送られます。これはかなり優れた動作です。彼の記事を参照して、しくみを調べて理解してください。このポリフィルは、マウス イベントへの優れたフォールバックで、以前のブラウザーをサポートするのにかなり便利です。

このライブラリの使用方法に関する考え方を知るには、ポインター イベントを使用して仮想タッチ ジョイスティックを作成する方法を説明している「 Creating a universal virtual touch joystick working for all touch models thanks to Hand.JS」(Hand.JS を使用してすべてのタッチ モデルで動作する統合型仮想タッチ ジョイスティックを作成する、英語) を参照してください。HandJS のおかげで、まったく同じコード ベースを使用して、Windows 8/RT デバイス、Windows Phone 8 デバイス、iPad/iPhone デバイス、および Android デバイスの Internet Explorer 10 で動作します。

簡単なジェスチャーを認識する

マルチタッチを処理する方法について確認したので、ここからは要素をタップしたりホールドするといった簡単なジェスチャーを認識する方法について確認します。さらに、要素の移動や拡大縮小のような高度なジェスチャーを認識する方法についても確認します。

Internet Explorer 10 には、ジェスチャーの認識に役立つ MSGesture オブジェクトがあります。このオブジェクトは、現時点では Internet Explorer 10 固有の機能で、W3C への提出された標準には含まれていません。 MSCSSMatrix 要素 (今回の WebKitCSSMatrix に相当) と組み合わせると、簡単な方法で非常に興味深いマルチタッチ エクスペリエンスを生み出せることがわかります。MSCSSMatrix は、実際には 4 行 4 列の同次行列を表し、ドキュメント オブジェクト モデル (DOM) スクリプトから CSS の 2-D 変換や 3-D 変換機能にアクセスできるようにします。しかし、これを使う前に基本を確認しておきましょう。

基本の考え方は、「まず MSPointerDown のイベント ハンドラーを登録」します。次に、MSPointerDown を処理するハンドラー内部で、「どのポインターを MSGesture オブジェクトに送信」して特定のジェスチャーを検出できるようにするかを「選択」します。続いて、 MSGestureTapMSGestureHoldMSGestureStartMSGestureChangeMSGestureEndMSInertiaStartの各イベントのいずれかをトリガーします。MSGesture オブジェクトは、送信されたすべてにポインターを入力パラメーターとして受け取り、ポインターにジェスチャー レコグナイザーを適用して、フォーマットしたデータを出力として提供します。必要なのは、(ポインターの ID、座標などに基づいて) ジェスチャーに含めるポインターを選択またはフィルター処理することだけです。これを行ったら、MSGesture オブジェクトがすべてを行います。

サンプル 1: ホールド ジェスチャーを処理する

ここでは、(背景に画像を含むシンプルな DIV) 要素をホールドする方法を見ていきます。要素がホールドされたら、コーナーを追加して要素が選択されていることをユーザーに示します。コーナーを動的に生成するには、画像の 4 隅の上に追加される 4 つの DIV を動的に生成します。最後に、CSS を使って変換や線状グラデーションをうまく利用して、図 7 のようにします。


図 7. ホールド ジェスチャーを処理する

手順は次のとおりです。

  1. 対象とする HTML 要素の MSPointerDown イベントと MSGestureHold イベントを登録する。
  2. この HTML 要素をターゲットにする MSGesture オブジェクトを作成する。
  3. MSPointerDown ハンドラー内で、監視するさまざまな PointerID を MSGesture オブジェクトに追加する (何を実現するかに応じてすべてまたはサブセットを追加する)。
  4. MSGestureHold イベント ハンドラー内で、ユーザーがホールド ジェスチャー (MSGESTURE_FLAG_BEGIN フラグ) を開始したかどうかを詳しくチェックする。ホールドを開始していればコーナーを追加し、そうでなければ、コーナーを削除する。

この手順の結果が以下のコードになります。

<!DOCTYPE html> 
<html> 
<head> 
  <title>Touch article sample 5: simple gesture handler</title> 
  <link rel="stylesheet" type="text/css" href="toucharticle.css" /> 
  <script src="Corners.js"></script> 
</head> 
<body> 
  <div id="myGreatPicture" class="container" /> 
  <script> 
    var myGreatPic = document.getElementById("myGreatPicture"); 
    // Creating a new MSGesture that will monitor the myGreatPic DOM Element 
    var myGreatPicAssociatedGesture = new MSGesture(); 
    myGreatPicAssociatedGesture.target = myGreatPic; 
  
    // You need to first register to MSPointerDown to be able to 
    // have access to more complex Gesture events 
    myGreatPic.addEventListener("MSPointerDown", pointerdown, false); 
    myGreatPic.addEventListener("MSGestureHold", holded, false); 
  
    // Once pointer down raised, we're sending all pointers to the 
    // MSGesture object 
    function pointerdown(event) { 
      myGreatPicAssociatedGesture.addPointer(event.pointerId); 
    } 
  
    // This event will be triggered by the MSGesture object 
    // based on the pointers provided during the MSPointerDown event 
    function holded(event) { 
      // The gesture begins, we're adding the corners 
      if (event.detail === event.MSGESTURE_FLAG_BEGIN) { 
        Corners.append(myGreatPic); 
      } 
      else { 
        // The user has released his finger, the gesture ends 
        // We're removing the corners 
        Corners.remove(myGreatPic); 
      } 
    } 
  
    // To avoid having the equivalent of the contextual   
    // "right click" menu being displayed on the MSPointerUp event,  
    // we're preventing the default behavior 
    myGreatPic.addEventListener("contextmenu", function (e) { 
      e.preventDefault();    // Disables system menu 
    }, false); 
  </script> 
</body> 
</html>

結果を 図 8 に示します。

図 8. 1 本の指でホールド ジェスチャーを始めるとにコーナーが追加される

要素をタップしたり、マウスでクリックしただけでは、何も起こりません。1 本の指で画像をタッチし続けるか、マウスで画像を長押しするとコーナーが表示されます。指を離すと、コーナーが消えます。

複数の指で画像をタッチし続けても何も起きません。ホールド ジェスチャーがトリガーされるのは、1 本の指で要素をホールドしている場合だけです。

注: 白い枠線、コーナー、および背景画像は、toucharticle.css で定義された CSS で設定します。Corners.js では (append 関数を使用して) 単純に 4 つの DIV を作成し、適切な CSS クラスを使用して要素の 4 隅に配置します。

しかし、この結果にはまだ納得がいかない部分があります。画像をホールドしてから少し指を動かすと、MSGESTURE_FLAG_CANCEL フラグが設定され、これをハンドラーがキャッチして、コーナーが消えます。ユーザーが画像から指を離すか、画像のボックス外に指を移動したときだけコーナーが消えるようにします。そのためには、MSPointerUp または MSPointerOut の発生時のみコーナーを削除します。その結果、コードは次のようになります。

var myGreatPic = document.getElementById("myGreatPicture"); 
// Creating a new MSGesture that will monitor the myGreatPic DOM Element 
var myGreatPicAssociatedGesture = new MSGesture(); 
myGreatPicAssociatedGesture.target = myGreatPic; 
  
// You need to first register to MSPointerDown to be able to 
// have access to more complex Gesture events 
myGreatPic.addEventListener("MSPointerDown", pointerdown, false); 
myGreatPic.addEventListener("MSGestureHold", holded, false); 
myGreatPic.addEventListener("MSPointerUp", removecorners, false); 
myGreatPic.addEventListener("MSPointerOut", removecorners, false); 
  
// Once touched, we're sending all pointers to the MSGesture object 
function pointerdown(event) { 
    myGreatPicAssociatedGesture.addPointer(event.pointerId); 
} 
  
// This event will be triggered by the MSGesture object 
// based on the pointers provided during the MSPointerDown event 
function holded(event) { 
    // The gesture begins, we're adding the corners 
    if (event.detail === event.MSGESTURE_FLAG_BEGIN) { 
        Corners.append(myGreatPic); 
    } 
} 
  
// We're removing the corners on pointer Up or Out 
function removecorners(event) { 
    Corners.remove(myGreatPic); 
} 
  
// To avoid having the equivalent of the contextual   
// "right click" menu being displayed on the MSPointerUp event,  
// we're preventing the default behavior 
myGreatPic.addEventListener("contextmenu", function (e) { 
    e.preventDefault();    // Disables system menu 
}, false);

これで、求めている動作を実現できます (図 9 参照)。

図 9. MSPointerUp または MSPointerOut を使用してコーナーの動作を調整する

サンプル 2: 拡大縮小、移動、および回転を処理する

最後に、要素の拡大縮小、移動、または回転を行うために、数行のコードを記述します。まず、 MSGestureChange イベントを登録します。 MSGestureEvent オブジェクト のドキュメントに記載されているように、このイベントには現在のところ HTML 要素に適用される、さまざまな属性 ( rotationscaletranslationXtranslationY など) があります。

さらに、MSGesture オブジェクトは既定で慣性アルゴリズムを提供します。つまり、指で HTML 要素を押さえて、画面上で動かすと、アニメーションが処理されます。

最後に、MSGesture から送信されたこのような変化を反映するには、変化に応じて要素を移動する必要があります。これを実行する最も簡単な方法は、指のジェスチャーに対応する回転、拡大縮小、および移動の詳細に対応付ける CSS 変換をいくつか適用することです。そのために、 MSCSSMatrix 要素を使用します。

要するに、前述のサンプルに示すジェスチャーをすべて処理する場合は、以下のようにイベントを登録します。

myGreatPic.addEventListener("MSGestureChange", manipulateElement, false);

次に、以下のハンドラーを使用します。

function manipulateElement(e) { 
  // Uncomment the following code if you want to disable the built-in inertia  
  // provided by dynamic gesture recognition 
  // if (e.detail == e.MSGESTURE_FLAG_INERTIA) 
  // return; 
  
  // Get the latest CSS transform on the element 
  var m = new MSCSSMatrix(e.target.currentStyle.transform);  
  e.target.style.transform = m 
  .translate(e.offsetX, e.offsetY) // Move the transform origin under the
                                   // center of the gesture 
  .rotate(e.rotation * 180 / Math.PI) // Apply Rotation 
  .scale(e.scale) // Apply Scale 
  .translate(e.translationX, e.translationY) // Apply Translation 
  .translate(-e.offsetX, -e.offsetY); // Move the transform origin back 
}

最終サンプルを 図 10 に示します。

図 10. 要素の拡大縮小、回転、および移動

1 本または複数の指を使って黒色の領域内の画像を動かしてみてください。1 本または複数の指を使って要素を拡大縮小してみたり、回転してみてください。複雑な部分はすべて Internet Explorer 10 がネイティブに処理するため、コードはかなりシンプルなのに優れた結果を得ることができます。

ビデオおよびすべてのサンプルへの直接リンク

Internet Explorer 10 を利用できるタッチ画面が手元になく、サンプルの動作が分からない方は、次のビデオをご覧ください。ビデオでは、この記事付属のすべてのサンプルを Samsung BUILD2011 タブレットを使って示しています。

ビデオのダウンロード:MP4WebM、および VideoJS による HTML5 Video Player

また、以下のリンクからすべてのサンプルを確認できます。

関連リソース

IE10 でタッチ操作を使用して、次のすばらしいゲームをプレーしてみてください。

理論的には、今回紹介した詳細情報や関連リソースへのリンクを参照すれば、Web サイトや Windows ストア アプリケーションに MSPointer Events モデルを実装する準備が整います。Internet Explorer 10 のユーザー エクスペリエンスを向上するチャンスです。

この記事は、Internet Explorer チームによる HTML5 技術シリーズの一部です。3 か月間無料の BrowserStack クロスブラウザー テスト ( https://modern.IE) を使って、この記事の概念をお試しください。

執筆者紹介

David Rousset は、マイクロソフトの開発者エバンジェリストであり、HTML5 と Web 開発を専門にしています。MSDN の 彼のブログ (英語) を見たり、Twitter ( @davrous、英語) でフォローできます。

David の連絡先は次のとおりです。