こんにちは。普段からiPhoneを愛用している橋本です。
最近、「せっかくiPhone持ってるんだし、iPhone向けのアプリ作ってみようかしら?」と思い立ったのですが、iPhoneのネイティブアプリを作るには、"Objective-C"と、"cocoa Touch"というiPhone/ipodTouch向けのフレームワークを理解する必要があり、また、自分で開発したアプリを実機に入れて動かしてみるには、そこそこの費用と各種手続きが必要だったり(iPhoneエミュレータ上で動かす分には問題ないのですが…)と、何かと大変です。
「何かもっと手軽にiPhone特有の機能を活かしたアプリを作る方法はないかなぁ。。」と考え、思い立ったのがWebアプリ。Webアプリなら、今までの知識+αでアプリを作成することが出来るのではないかと。そこで、今回から数回に渡ってiPhoneとjavascriptを使って色々と試してみようと思います。
今回はまずiPhone特有の機能であるタッチ機能に関するイベントを取得するjavascriptについて調べてみました。
現在、iPhoneで公式に使用出来る唯一のブラウザ"safari3"には、iPhoneのタッチ機能とジェスチャー機能の情報を、"touchXXX"、"gestureXXX"というイベントで取得する処理が実装されています。
それぞれ、各ノードに対して、ontouchXXX="funcXX();"といった形で要素を追加することも出来ますし、
document.addEventListener("touchXXX", touchXXXHandler, false);
function touchXXXHandler(event) {
//各処理
}
といった感じで、イベントリスナーに追加することも出来ます。
XXXの中身ですが、"touchXXX"イベントについては、start,move,end,canselの四つ、
"gestureXXX"イベントについては、start,change,endの三つがあり、それぞれ次のようなイベントを意味しています。
touchstart: 新しくスクリーンに指が触れた場合に発生するイベント
touchend: スクリーンから指を離した場合に発生するイベント
touchmove: スクリーンに触れている指をスライドさせた場合に発生するイベント
touchcancel: システムによってタッチイベントがキャンセルされた場合に発生するイベント
gesturestart: 新しくスクリーンに二本以上の指が触れた場合に発生するイベント
gesturechange: 二本以上の指がスクリーンに触れている状態で指をスライドさせた場合に発生するイベント
gestureend: ジェスチャーイベントが終了した場合(スクリーンに触れている指が一本以下になった場合)に発生するイベント
また、タッチイベントの情報についてはイベントオブジェクト毎に、touches、targetTouches,changedTouchesの三つのリストがあり、次のような情報が格納されています。
touches: スクリーンに触れている各指の情報
targetTouches: 同じノード内で開始された各指の情報
changedTouches: イベント発生の元となった指の情報
また、それぞれのリストからは以下の情報を取得することが出来ます。
clientX: クライアント領域(viewport)に対するX座標
clientY: クライアント領域(viewport)に対するY座標
screenX: 画面の表示領域に対する指のX座標
screenY: 画面の表示領域に対する指のX座標
pageX: ページ全体に対する指のX座標(スクロールを必要とする領域も含む、ということです)
pageY: ページ全体に対する指のX座標
target: タッチイベントが発生したノード
identifier: それぞれのタッチイベントに対する、ユニークな値
各リストは配列の形式となっており、インデックスを指定することにより各タッチイベントの情報を取得することが出来ます。
// 1本めの指のX座標を取得する
event.touches[0].pageX;
また、event.touches.lengthとすることで、現在画面にタッチされている指の本数を取得することもできます。
ジェスチャーイベントについては、"event.scale"で拡大縮小用の倍率を取得することが出来、また"event.rotation"でジェスチャーの回転した角度を取得することができます。
では、実際に各情報を取得して表示するプログラムを使って、タッチイベントに関する各情報を確認してみます。
コードは以下のとおりです。
<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", multiTouchHandler, false);
document.addEventListener("touchmove", multiTouchHandler, false);
document.addEventListener("touchend", multiTouchHandler, false);
// ジェスチャーイベントの初期化
document.addEventListener("gesturestart", multiTouchHandler, false);
document.addEventListener("gesturechange", multiTouchHandler, false);
document.addEventListener("gestureend", multiTouchHandler, false);
// フォントカラーの初期化
document.body.style.color = "#ffffff";
}
function multiTouchHandler(event) {
// ジェスチャーイベントを取得すると、イベントによってフォントの色が変化
switch (event.type) {
case "gesturestart" :
document.body.style.color = "#ff0000";
break;
case "gesturechange" :
document.body.style.color = "#ffff00";
break;
case "gestureend" :
document.body.style.color = "#ffffff";
break;
default :
// タッチイベントに関する各情報を取得してセットする
for (var i = 0; i < 5; i++) {
// 各情報をセット
document.getElementById("identifier_" + i).innerHTML = event.touches[i] ? "identifier: " + event.touches[i].identifier : "";
document.getElementById("target_" + i).innerHTML = event.touches[i] ? "target: " + event.touches[i].target : "";
document.getElementById("clientX_" + i).innerHTML = event.touches[i] ? "clientX: " + event.touches[i].clientX : "";
document.getElementById("clientY_" + i).innerHTML = event.touches[i] ? "clientY: " + event.touches[i].clientY : "";
document.getElementById("screenX_" + i).innerHTML = event.touches[i] ? "screenX: " + event.touches[i].screenX : "";
document.getElementById("screenY_" + i).innerHTML = event.touches[i] ? "screenY: " + event.touches[i].screenY : "";
document.getElementById("pageX_" + i).innerHTML = event.touches[i] ? "pageX: " + event.touches[i].pageX : "";
document.getElementById("pageY_" + i).innerHTML = event.touches[i] ? "pageY: " + event.touches[i].pageY : "";
}
}
// 縦スクロールを抑止するための記述
event.preventDefault();
}
</script>
<style type="text/css">
body {
background-color: #000000;
font-color: #ffffff;
}
li {
list-style: none;
}
.touch_list li {
display: inline;
margin-left: auto;
}
</style>
</head>
<body onLoad="init();">
<ul>
<?php for($i = 0; $i < 5; $i++) : ?>
<li>
<ul class="touch_list">
<li id="identifier_<?php echo $i ?>"></li>
<li id="target_<?php echo $i ?>"></li>
<li id="clientX_<?php echo $i ?>"></li>
<li id="clientY_<?php echo $i ?>"></li>
<li id="screenX_<?php echo $i ?>"></li>
<li id="screenY_<?php echo $i ?>"></li>
<li id="pageX_<?php echo $i ?>"></li>
<li id="pageY_<?php echo $i ?>"></li>
</ul>
</li>
<?php endfor; ?>
</ul>
</body>
</html>
iPhone/ipodTouch(各OS2.0以上)をお持ちの方は、ここで実際に動かしてみてください。
画面にタッチすると、タッチイベントに関する情報が画面に表示されます。
また、二本以上の指でタッチすると、各ジェスチャーイベント毎にフォントの色が変わります。
このように,簡単にタッチイベントとジェスチャーイベントに関する情報を取得することが出来ます。
次回はこの情報を利用して、もう少し動きのあるiPhoneらしいアプリを作ってみたいと思います。