Multitouchの最近のブログ記事

タッチシーケンスは、タッチデバイスに触れてから離れるまでのタッチポイントの一連の動きのことです。タッチシーケンスを把握すると、自前のジェスチャも実装できるようになります。

タッチシーケンスは 1 つの touchBegin イベントと、必要に応じて 1 つ以上の touchMove イベント、それから 1 つの touchEnd イベントからなります。

タッチシーケンス: touchBegin (1) → touchMove (0 以上) → touchEnd (1)

touchBegin から touchEnd までの一連のイベントを順番に並べることで、タッチポイントの軌跡が再現等ができるようになります。

タッチポイントの識別

ところで、マルチタッチをサポートするデバイスの場合は、複数のタッチシーケンスが並行して発生する可能性があります。例えば、タッチパネル上で親指と人差し指を同時に動かしている間は、両方の指から touchMove イベントが発生し続けます。

そのような場合には、それぞれのイベントがどちらのタッチポイントに属するものかを区別しないと、正しいシーケンスを把握することができません。そのため、TouchEvent を処理する際は、TouchEvent.touchPointID 属性を使って、イベントの元となったタッチポイントを判断するという処理が必要になってきます。

下のコードは、最初の touchBegin イベントで touchPointID を記録しておくことで、他の touchPointID を持つイベントは無視する、というイベントハンドラのサンプルです。オブジェクトを指でドラッグしたいときなどは、指 1 本だけでの操作なので、このようなアプローチが有効かもしれません。

Flash Player 10.1 から Sprite クラスに 2 つの新しいメソッドが追加されました。タッチ操作によるドラッグ機能を、Sprite (またはそのサブクラス) に提供するためのメソッドです。マウス操作に対する Sprite.startDrag() メソッドと Sprite.stopDrag() メソッドに相当します。

public function startTouchDrag(touchPointID:int, 
                               lockCenter:Boolean = false, 
                               bounds:Rectangle = null):void
public function stopTouchDrag(touchPointID:int):void
 

Sprite.startDrag() や stopDrag() との違いは、最初の引数に touchPointID を必要とすることです。この値は TouchEvent の touchPointID 属性から取得できます。stopTouchDrag() でドラッグを中止するには、startTouchDrag() で指定した touchPointID と同じ値を指定します。

startTouchDrag() の残り 2 つの引数は startDrag() の引数と同じで、

  • lockCenter: false の場合 Sprite 内の最初に触れた箇所が、true の場合 Sprite の基準点がドラッグする位置になる
  • bounds: Rectangle を使って親オブジェクトの座標でドラッグできる領域を指定する

です。

startTouchDrag() でドラッグできる Sprite は同時に 1 つだけです。stopTouchDrag() が明示的に呼ばれるか、他の Sprite がドラッグ可能な状態になると、ドラッグ中の Sprite はドラッグできなくなります。

TouchEvent の属性は MouseEvent と良く似ていて、殆どの属性は MouseEvent と共通です。大きく 3 つに分けて、押されているキー、操作の行われた座標、タッチイベント固有の情報、のカテゴリーで捉えることができます。

まずは、押されているキー関連の TouchEvent の属性のリストです。

  • altKey : Boolean (Windows, Linux のみ)
    Alt キーが押されているかを示す
  • commandKey : Boolean (Mac のみ)
    Control キー か Command キー が押されているかを示す
  • controlKey : Boolean
    Ctrl キー (Windows, Linux) もしくは Control キー (Mac) が押されているかを示す
  • ctrlKey : Boolean
    Ctrl キー (Windows, Linux) もしくは Control キー か Command キーのいずれか (Mac) が押されているかを示す
  • shiftKey : Boolean
    Shift キーが押されているかを示す

MouseEvent との違いは、commandKey が Flash Player からも使えるようになっている点です。ただ、現時点ではまだ Mac で TouchEvent 自体がサポートされていないので、この件については動作確認ができるようになってから信用するのがよいかもしれません。

次に操作の行われた座標関連は、

Flash Player 10.1 から新しく TouchEvent が追加されました。これにより、指やスタイラスによるたタッチパネル操作をイベントとして扱えるようになっています。TouchEvent は MouseEvent と違い、複数の指 (タッチポイント) による操作を同時に追いかけることができます (マルチタッチのサポート)。前回まで説明した SWIPE、ZOOM 等のジェスチャーイベントは、複数の TouchEvent を 1 つにまとめて作られたものです。

TouchEvent を使うときは、Multitouch.inputmode に TOUCH_POINT を設定します。

Multitouch.inputMode=MultitouchInputMode.TOUCH_POINT;
 
var mySprite:Sprite = new Sprite();
mySprite.graphics.beginFill(0xFF6600);
mySprite.graphics.drawRect(0, 0, 80, 80);
addChild(mySprite);
 
mySprite.addEventListener(TouchEvent.TOUCH_TAP, taphandler);
 
function taphandler(e:TouchEvent): void {
  trace("touchTap");
}
 

残念ながら、TouchEvent は今のところ Mac 上ではサポートされません。

GestureEvent に phase という属性があります。ここには、ジェスチャーのフェーズ (例えば、新しいジェスチャーが開始された、さっきのジェスチャーの続きである、等) の情報が設定されます。

設定可能な値は GesturePhase クラスに定義されていて、下の 4 つがあります。

  • ALL : String [static]
  • BEGIN : String [static]
  • UPDATE : String [static]
  • END : String [static]

一番上の ALL は、色々な段階を持たない単純なジェスチャーによるイベントに使われます。

具体的には、GESTURE_TWO_FINGER_TAP と GESTURE_SWIPE の 2 つのイベントが、phase 属性は常に ALL になります。どちらのジェスチャーも、タップする、素早く移動する、と 1 つの動作だけで終わるジェスチャーなので、細かいフェーズを管理する必要が無い、という理解でよいかと思います。

addEventListener(TransformGestureEvent.GESTURE_SWIPE, onSwipe);
 
function onSwipe(e:TransformGestureEvent):void {
  trace(e.phase); // ALL が出力される
}
 

その他の 4 つのジェスチャーについては、BEGIN、UPDATE、END が状況に応じて設定されます。

新しいジェスチャーの開始時には BEGIN、既に始まったジェスチャーの続きの場合は UPDATE、そしてジェスチャーが終了した際のイベントには END が設定されます。この情報を利用することより、オブジェクトを拡大後に回転させるといったより複雑な操作にも対応できるようになります。

下のサンプルは、phase 属性の値を使い、GESTURE_PAN が始まったら対象のオブジェクトを視覚的に変化させ、終了したら元に戻す、というものです。

GestureEvent の属性

GestureEvent クラスにはジェスチャーイベントの基本的な属性が定義されています。これらの属性はおおまかに、押されているキー、操作の行われた座標、ジェスチャー固有の情報、の 3 つのカテゴリーに分けられます。

  • altKey : Boolean (Windows, Linux のみ)
    Alt キーが押されているかを示す
  • commandKey : Boolean (Mac & AIR のみ)
    Control キー か Command キー が押されているかを示す
  • controlKey : Boolean
    Ctrl キー (Windows, Linux) もしくは Control キー (Mac) が押されているかを示す
  • ctrlKey : Boolean
    Ctrl キー (Windows, Linux) もしくは Control キー か Command キーのいずれか (Mac) が押されているかを示す
  • shiftKey : Boolean
    Shift キーが押されているかを示す
  • localX : Number
    イベントの発生したオブジェクトを基準としたイベント発生位置の x 座標
  • localY : Number
    イベントの発生したオブジェクトを基準としたイベント発生位置の y 座標
  • stageX : Number [read-only]
    グローバルなステージの座標を基準としたイベント発生位置の x 座標
  • stageY : Number [read-only]
    グローバルなステージの座標を基準としたイベント発生位置の y 座標
  • phase : String
    ジェスチャーの進行状況を示す値

最後の phase 属性以外は MouseEvent にあるものと基本的に同様に考えてよさそうです。その他の主な MouseEvent との違いは buttonDown 属性が無いこと (当たり前ですが) や、controlKey 属性が Flash Player からも利用可能になっていること (MouseEvent では AIR からのみ) あたりです。

今回は、Flash Player 10.1 のサポートするジェスチャーの種類と使い方について、簡単に説明してみます。

ジェスチャーイベントの種類

Flash Player 10.1 が提供するジェスチャーイベントクラスは 3 種類存在します。基本になるのは GestureEvent クラスです。MouseEvent クラスとは近からず遠からずという感じのクラスです。

GestureEvent クラスのサブクラスとして、更に PressAndTapGestureEvent と TransformGestureEvent の 2 つのクラスがあります。

flash.events.GestureEvent
flash.events.PressAndTapGestureEvent
flash.events.TransformGestureEvent
 

これらのうち TransformGestureEvent だけは 4 種類のイベントがあるため (他は 1 つだけ)、利用できるジェスチャーイベントは全部で 6 種類になります。ただし、OS によって利用できるイベントが異なります (6 種類全てが利用できる OS は今のところ無い)。

以下は各イベントの簡単な説明です。

  1. GestureEvent.GESTURE_TWO_FINGER_TAP: (Windows7 のみ)
    操作: 2つの指を同時にタップ
    用途例: ダブルクリックの代わり
  2. PressAndTapGestureEvent.GESTURE_PRESS_AND_TAP: (Windows7 のみ)
    操作: 1つ目の指が触れた状態で2つめの指をタップ
    用途例: メニューを開いてからアイテムを選択
  3. TransformGestureEvent.GESTURE_SWIPE:(Mac OS X, iPhone OS のみ)
    操作: 複数の指が触れた状態で全ての指を平行に動かす
    注: Mac OS X では 4 本指のスワイプが利用できるが、Flash ランタイムは 3 本指まで
    用途例: アイテムの削除、画面の切り替え
  4. TransformGestureEvent.GESTURE_PAN:
    操作: 指を触れたまま移動させる(例えば左から右)
    用途例: スクロール、ドラッグ
  5. TransformGestureEvent.GESTURE_ROTATE:
    操作: オブジェクト上で2つの指を円を書くように動かす
    用途例: オブジェクトを回転
  6. TransformGestureEvent.GESTURE_ZOOM:
    操作: 2つの指が触れた状態で指をそれぞれ遠ざかる (または近づく) 方向に移動
    用途例: 表示を拡大 (縮小)

Flash Player 10.1 から新しく追加された Multitouch クラス関連のトピックです。

(Flash Lite 4 もマルチタッチをサポートします。今後搭載されるデバイスによっては、Flash Lite 4 を使ったマルチタッチアプリケーションを作ることが可能です。)

入力の指定

Flash でユーザ入力を処理する際はイベントを使うのが定番ですが、タッチやジェスチャーに関しても同様で、タッチイベントやジェスチャーイベントを使って、ユーザからの入力を処理します。

ところで、タッチイベントとジェスチャーイベントを同時に利用することはできません。どちらを使えるか (使うか) は Multitouch.inputMode 属性を使って確認/設定します。

(Multitouch クラスの属性は全て static です)

Multitouch.inputMode:String   利用する入力(イベント)の種類を設定
 

この属性に指定できる値は MultitouchInputMode クラスに定義されており、以下の 3 種類があります。

  • MultitouchInputMode.GESTURE:
    マルチタッチ操作をジェスチャーイベントとして受け取りたいときに指定します。ジェスチャーとして定義されていないタッチ操作はマウスイベントとして解釈されます。例えば、タップ操作をすると MouseEvent.CLICK イベントが発生します。
    Multitouch.inputMode のデフォルト値は GESTURE です。
  • MultitouchInputMode.TOUCH_POINT:
    マルチタッチ操作をタッチイベントとして受け取りたいときに指定します。単純なタッチ操作のみで十分な場合、またはカスタムでマルチタッチのジェスチャーを実装したいときにお勧めです。このモードでもマウスイベントは発生します。
  • MultitouchInputMode.NONE:
    全てのタッチ操作がマウスイベントとして解釈されます。ジェスチャーイベントもタッチイベントも発生しません。タッチが利用できない環境とできる環境で同じコードを実行したい場合に向いています。マルチタッチが不要であれば (マウスイベントでは個々のタッチポイントを識別できないため) 1 本指で行えるジェスチャーを実装することは可能ですが、それが目的であれば GESTURE モードの方が便利かもです。

ということで、同じ操作の結果でも発生するイベントは複数の種類が想定されます。例えば、ユーザが、指を左から右に移動して MovieClip 上に動かしたとして、デバイスはその操作を mouseOver, touchOver, gesturePan のいずれにも解釈する可能性があります。その際 inputMode が GESTURE の時は mouseOver, gesturePan の両方が生成されるかもしれませんし、TOUCH_POINT の場合は mouseOver, touchOver の両方が生成されるかもしれません。

どのイベントを利用するかでユーザーに提供できる操作性がが影響を受ける可能性があります。マルチタッチを扱う際は、提供されるジェスチャーイベントだけで十分なのか、もし足りなければマルチタッチが必要なのかシングルタッチで十分なのか、ターゲットのプラットフォームは何で互換性はどうするか、などを最初によく考えておく必要がありそうです。

Flash Player 10.1 (と AIR 2) の新機能であるマルチタッチとジェスチャーのサポートについて、まずは概要を少しばかり。

はじめに

既にご存知の方は飛ばしていただければと思いますが、Flash では新しい分野なので、最初に言葉の整理をしておくと、

  • タッチ: デバイスに触れた、移動した、離れた、などの個々の動作
  • マルチタッチ: 複数のタッチを同時に扱うこと
  • ジェスチャー: 複数の動作の組み合わせ (例: 指をデバイスに 「触れて」 から 「横に移動」 する)

という感じかと思います。

"タッチ" はマウスの代わりにデバイスに直接触れることにより行う入力行為です。「クリックしていない」 という状態が無いことを除けばほぼマウスと同じように扱うことができます。Flash Player 10.1 ではタッチによる操作を処理できるよう、新しく TouchEvent が追加されています。

マルチタッチに対応するには、複数の指で操作が同時に行われた時、個々の指の動きを識別できる必要があります。そのため、TouchEvent にはタッチポイントを識別するための ID が属性として定義されています。指がデバイスに触れてから離れるまでの間、その指からの TouchEvent には同じ ID が割り当てられます。

さて、ジェスチャーは、特定の動作に特定の意味を持たせるものです。例えば、2 本の指を反対の方向に広げる → 拡大表示、というのは良く知られたジェスチャーです。その他にも、円を描いたらメニューを表示するというジェスチャーの使い方もあるかも知れません。また、ショートカットキー代わりに画面に文字を書いたら対応するコマンドを実行するというジェスチャーもあるかもしれません。とりあえず識別可能な動作であればジェスチャーとして使用される可能性を持っています。

まとめると、タッチは、デバイスの機能として検出可能な操作、という理解でよいかと思いますが、ジェスチャーは、ユーザーがデバイスに対して行うことのできる動作の捕捉、と捉えることができそうです。デバイスにユーザーが合わせる (タッチ) とユーザーにデバイスが合わせる (ジェスチャー) というコペルニクス的な (ちょっと大げさ) 視点の転換が両者の間にはありそうです。

容易に想像できるように、利用できるジェスチャーはプラットフォームにより異なります。また、ジェスチャーの実装の仕方も、ジェスチャーの判別を行ってくれるプラットフォームがあれば、タッチイベントだけ通知してそれらからジェスチャーに組み上げる作業は開発者任せのプラットフォームもあります。Flash Player 10.1 では標準的なジェスチャーの発生を知らせるジェスチャーイベントがサポートされていますが、TouchEvent を使ってジェスチャー処理用のライブラリを開発するという方法も選択できるようになっています。

マルチタッチと環境について

GUI であればポインティングデバイスが使える、というのはもはや "当然のこと" として受け入れられているかと思います。一方、マルチタッチやジェスチャーはその歴史が浅いこともあり、きちんと使える環境はまだまだ限られています。Flash Player 10.1 がサポートする、だけではマルチタッチ/ジェスチャーの利用には十分では無いのです。

2014年1月

Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
レンタルサーバー

月別 アーカイブ

Powered by Movable Type 4.261