90秒で理解するiPhone JavaScript(マルチタッチ編)
仕事でiPhone向けサイトを作ることになるかもしれず、色々と調査中です。
まずはiPhoneならではの機能ということで、マルチタッチについて調べてみました。
ここまでわかったことをメモ代わりに記載したいと思います。
今回はひとまず座標の取得までです。
ゆくゆくは、こちらのムービーのように凝ったギミックを作りこみたいと思っています。
マルチタッチの座標を取得するのは思ったより簡単で、抑えるポイントは4つだけです。
- Safari自体のスクロールや拡大・縮小は動作しないようにした方が無難
- タッチのイベントは、リスナーまたは「onTouchXXX」から取得
- タッチ数は「event.touches.length」で取得
- 座標は「event.touches[i].pageX (or pageY)」で取得
1. Safari自体のスクロールや拡大・縮小は動作しないようにした方が無難
マルチタッチを行う前の下準備として、Safari自体のスクロールや拡大・縮小を、動作しないようにしておいた方が無難です。
対象をドラッグしようとしているのか、画面をスクロールしようとしているのか、プログラム側で判断するのは難しいためです。
今回は次のように調整しました。
<meta name=”viewport” content=”width=480, user-scalable=no, maximum-scale=0.6667″ />
横スクロールと拡大・縮小を禁止しています。
縦スクロールは、「event.preventDefault();」で抑止できるようです。
(後述のサンプルプログラム内でご確認ください)
2. タッチのイベントは、リスナーまたはonTouchXXXから取得
タッチ関連のイベントには
- onTouchStart
- onTouchMove
- onTouchEnd
- onTouchCancel
の4つがあり、それぞれonClick()などと同じような形で、イベントを取得できます。
またリスナー方式の場合は、
document.addEventListener("touchstart", touchHandler, false);
document.addEventListener("touchmove", touchHandler, false);
document.addEventListener("touchend", touchHandler, false);
document.addEventListener("touchcancel", touchHandler, false);
のような形で利用します。
touchcancelはどのようなケースで使われるのかは不明です。
もしご存じの方がいましたら教えてください。
3. タッチ数は「event.touches.length」で取得
これは簡単です。
タッチ情報は「event.touches」に配列の形で格納されますので、その数を見ればOKです。
(event変数が何かについては、後述のサンプルプログラムでご確認ください)
4. 座標は「event.touches[i].pageX (or pageY)」で取得
タッチ座標は「event.touches[i].pageX」のような形で取得します。
シングルタッチの場合は「event.touches[0].pageX」。
ダブルタッチの場合は、上記に加え「event.touches[1].pageX」にも値がセットされます。
最大5個(touches[4])まで機能するようです。
サンプルプログラムは下記の通りです。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=480, user-scalable=no, maximum-scale=0.6667" />
<script type="text/javascript" charset="utf-8">
<!--
// 初期化
function init() {
document.addEventListener("touchstart", touchHandler, false);
document.addEventListener("touchmove", touchHandler, false);
document.addEventListener("touchend", touchHandler, false);
}
function touchHandler(event) {
// タッチ数を取得
document.getElementById("touchnum").innerHTML = event.touches.length;
// タッチ位置を取得
for (var i = 0; i < 5; i++) {
if (event.touches[i]) {
// 座標をセット
document.getElementById("loc" + i + "_x").innerHTML = event.touches[i].pageX;
document.getElementById("loc" + i + "_y").innerHTML = event.touches[i].pageY;
} else {
document.getElementById("loc" + i + "_x").innerHTML = '';
document.getElementById("loc" + i + "_y").innerHTML = '';
}
}
event.preventDefault();
}
// -->
</script>
</head>
<body onLoad="init();">
タッチ数: <span id="touchnum"></span><br />
タッチ0: X:<span id="loc0_x"></span>, Y:<span id="loc0_y"></span><br />
タッチ1: X:<span id="loc1_x"></span>, Y:<span id="loc1_y"></span><br />
タッチ2: X:<span id="loc2_x"></span>, Y:<span id="loc2_y"></span><br />
タッチ3: X:<span id="loc3_x"></span>, Y:<span id="loc3_y"></span><br />
タッチ4: X:<span id="loc4_x"></span>, Y:<span id="loc4_y"></span><br />
</body>
</html>
実際にiPhone/iPodTouchをお持ちの方はこちらかお試しください。
http://ke-tai.org/test/multitouch/multitouch.html
座標が取得できてしまえば、線を引くのも、画像を回転させるのも自由自在ですね。
とりあえず動作はしていますが、アップルの公式ドキュメントを読んで作ったわけではないので、もし間違っていたらご指摘をお願いします。
もし90秒で理解できなかったら(というか難しいですよね・・・)ご勘弁ください。