JavaScript

gestureイベントでrotate(回転)・scale(拡大縮小)

CSSのtransformで特定要素を簡単にrotate(回転)したりscale(拡大/縮小)する事が出来るようになりましたが、
ユーザーの操作に応じて動的に値を変化させるには座標を取得・計算する必要があると思っていました。

ところがgestureイベント(gesturestart、gesturechange、gestureend)を使えば、gesture(2本指)で操作した際に、
scaleの倍率とrotateの角度が取得可能で、JSでガリガリ座標計算する事なく動的に変化させることが出来ます。

gestureイベントの種類

2013年6月現在、下記イベントが実装されています。
Androidは対応していませんのでiOSのみが対象の場合か、Android対応が必要な場合は自前実装する必要があります。

  • gesturestart(指が2本以上触れた時に発火)
  • gesturechange(2本以上触れた状態で移動した時に発火)
  • gestureend(指を離して1本以下になった時に発火)

touchイベントとgestureイベントの発火順序

gestureイベントは2本以上の指が画面に触れる事で発火しますが、指を1本画面に触れた段階でtouchイベントが発火しています。
手元のiPhone(iOS6+Safari)で確認した発火順序は下記の通り。

  1. touchstart(1本目の指が触れた時に発火)
  2. gesturestart(2本目の指が触れた時に発火)
  3. touchstart(2本目の指が触れた時に発火、gesturestartとほぼ同時)
  4. touchmove(指を動かした時に発火)
  5. gesturechange(指を動かした時に発火、touchmoveとほぼ同時)
  6. gestureend(2本目の指を離した時に発火)
  7. touchend(2本目の指を離した時に発火)
  8. touchend(1本目の指を離した時に発火)

ただし、1本目と2本目の指を意図的にタイミングを揃えて(同時に)画面に触れた場合は3(2回目のtouchstart)は発火しない事があります。
同様の理由で、2本の指を同じタイミングで画面から離した場合も8(2回目のtouchend)が発火しない事があります。
また、指の動かし方によって4(touchmove)と5(gesturechange)の発火順序が入れ替わる事がありますが、ほぼ同じタイミングで発火します。

gestureイベントの特徴

touchイベントとの大きな違いとして、scale、rotateを値として返してくれるため、
タッチ開始位置と終了位置の座標を計算して云々と言った実装をすることなくCSSのtransform(scale、rotate)と連携可能です。

  • event.scaleでscaleの倍率が取得可能
  • event.rotationで、rotateの角度を取得可能

gestureイベントの問題

touchイベントとは異なり、TouchList(event.touches、event.changedTouchesなど)が取得出来ないため、
座標(event.changedTouches.pageXなど)が取得出来ません。
そのため、指の移動(座標の変化)と連動して特定要素を動かす必要がある場合はtouchイベントと連携させる必要があります。

gestureイベントのデモ

gestureイベントで取得可能な値(event.scaleとevent.rotation)とtouchイベントで取得可能な座標を使って下記実装をしています。

  • event.rotationとtransform(rotate)で回転
  • event.scaleとtransform(scale)で拡大縮小
  • touchイベントで取得した座標とtransform(translate)でドラッグ

JSをガリガリ書けば従来から実装可能な処理ですが、特筆すべきは実質100行程度のコードで全て実装可能な事でしょうか。
下記デモはgestureイベントに対応したiOSからご覧ください。
※AndroidやPCでは動作しません

最後に

ここまでgestureイベントを中心に書いていきましたが、個人的には現時点では実用的ではないと感じています。

touchイベントはW3Cによって標準化が進められており、最新のiOS・Androidブラウザーはほぼ仕様通りの動作をするため、フロントエンドの実装を工夫すれば実用可能です。
ただ、gestureイベントの標準化は特許問題の絡みもあり一向に進んでいないため、Androidの対応時期は未定です。

一方、関連した動向としてMicrosoftがWindows 8(IE10)でMSPointerEventという独自の仕様を採用しました。
これは従来PCのマウス、Galaxy Noteに代表されるようなスタイラスペン、そしてタッチ操作を全てポインターという概念で考え、
今後登場するデバイスにも対応しようというコンセプトです。

このPointerEventの仕様はW3Cにも提案として提出されているため、今後の動向に注文しています。
レスポンシブWebデザインのようにマウスとタッチ操作両方に対応する必要がある場合でも、ポインターという概念で標準化されれば実装が楽になるのではないでしょうか。
今後機会があればMSPointerEventを検証したいと思います。

HTML5を導入した制作の依頼・ご質問など、お気軽にお問合せください

※(株)インフォマークのお問合せフォームへ移動します。