マルチタッチの活用
2009-08-09 (日) 20:19:00 (909d)

lifebuoy.png iPhone/iPod touch搭載のMobileSafariがサポートするタッチ入力についての応用編

複数タッチ情報の取得  

複数タッチ  

  • 基本的には、1本の時と変わりません。
  • e.touches[i]にタッチしている本数分だけリアルタイムに値が入ってきますので、イベントハンドラー(touchstart)の中で、e.touches.lengthの数だけループでまわして座標を読み取っていきます。
  • 座標は、e.touches[i].pageXとe.touches[i].pageYに入っています。
  • divなりspanなりで、idが'loc0_x'~'loc4_x'、同様の'locN_y'がある場合、下記の記述をすればダイナミックにマルチタッチの座標が取れるでしょう。
    for (var i = 0; i < 5; i++) {
    	if (e.touches[i]) {
    		// 座標をセット
    		$("loc" + i + "_x").innerHTML = e.touches[i].pageX;
    		$("loc" + i + "_y").innerHTML = e.touches[i].pageY;
    	} else {
    		$("loc" + i + "_x").innerHTML = '';
    		$("loc" + i + "_y").innerHTML = '';
    	}
    }

ジェスチャー処理  

ジェスチャー  

  • 複雑といっても、基本を抑えていればカンタンです。
  • ジェスチャー操作を取得するには、ジェスチャー用イベントを追加しておく必要があります。
    document.addEventListener("gesturestart", gestureHandler, false);
    document.addEventListener("gesturechange", gestureHandler, false);
    document.addEventListener("gestureend", gestureHandler, false);
  • その後、タッチと同様にイベントハンドラー内でジェスチャー時の動作を記述します。
    e.scale:拡大縮小用の倍率が取得できます。
    e.rotation:回転角を取得できます。
  • 後は、上記2つの数値を元にジェスチャー時の動作を記述するだけです。
  • 先ほどのタッチと同様に、「gesturestart」時のe.scaleとe.rotationを保存しておき、gesturechangeが発生すれば差を判定し、e.rotationが変化していればその差分だけ図形なりを回転させればOKです。
  • 同様にピンチ操作もe.scaleの拡大率を判断した後、図形なりをその差分だけ変化させることになります。

やっかいな混乱の処理方法  

prevent処理  

  • タッチイベントで座標取得すると分かりますが、 MobileSafariのデフォルトスクロール動作が発生した場合にタッチ座標が移動していない状態が発生します。キャンバスというか下地が移動してしまっているためにtouchmoveしていないことになりますので、当然といえば当然です。※touchmove(例えばフリック)とは固定しているオブジェクトをこする動作といえば分かりやすいでしょうか。
  • そこで、MobileSafariのデフォルトスクロール動作を停止させる必要が出てきます。下記の記述を、touchmoveが発生した直後に記述すれば、デフォルトのスクロール動作が停止するため、touchmoveイベントでの座標変化が正常に取得できるようになります。gesturestartまたはgesturechangeでも同様に、必要に応じて行うといいでしょう。
    e.preventDefault();
  • iPhoneOS2.0以降のみ

タッチイベントの切り替え  

  • いろいろとタッチイベントを操作するようになると、複数レイヤーを操ってみたくなります。例えば画面にフロートで出るメニューダイアログのようなものですね。
  • かぶせてみるとわかりますが、メニューが出ている場合にも下位レイヤーのタッチイベントが発生してスクロールなりタッチイベント処理が発生してしまうような事態が起こります。
  • こういった場合には、レイヤーを意識した上で、それぞれのレイヤーに対してaddEventListener?とremoveEventListener?を行うことで制御する必要が出てきます。
  • 実際には、メニューを出した瞬間に下地のレイヤーに対してremoveEventListener?を行うと共に、メニューレイヤーに対してはaddEventListener?でタッチイベントが発生するようにします。メニューを閉じる際にはその逆の処理を順に行うことで、メニューを出している間は下位レイヤーはピクりともしなくなります。

さらに複雑な処理へ  

実現したいことの整理  

  • これまで説明してきたことで、iPhoneで実現できるタッチ操作およびジェスチャー操作の基本動作はすべて処理できるようになります。
  • しかし実際にはここまでが要素技術であり、実現したいUIにはまだ到達していないと思います。ただこれ以降については実現したいUIによってまったく処理記述が異なってくるのはご理解頂けると思います。
  • 例えばアニメーション的な表示を行う場合には、CSS3のCSSTransitionsCSSAnimationsを行う必要がありますし、HTML5のCanvasで処理を行うケースもあるでしょう。
  • 今まで説明してきた要素を組み合わせることによって自分の実現したいUIを組み立ててみることが出来れば、処理も見えてくることでしょう。

独自のヘッダーフッターの追加  

  • 独自スクロール処理を説明することで考え方を整理してみましょう。※後日追記




スポンサード リンク