2012年2月1日水曜日

Titanium MobileでWheel Gestureを作ってみた


ジョグダイアルみたいな操作を実現しようとしたら、訳が分からなくなりました...ので、忘れないために書き残しておきます。

ポイントはtouchmoveイベントに入っているxy座標がビューでのローカル座標な所です。

transformで回転などを設定しているとよく分からない(ビューでのローカル座標なので)
感じになってしまうのですが、それをうまく利用して(?)以外と簡単なコードになりました。

正直、感覚的に作ったので理屈は?なところがあります。
なので、あまり鋭く突っ込まれると泣いてしまいます。

こんなことをやりたい
*Let's note のホイールパッドみたいな操作
*2本指で回転させるのは面倒なので、1本指で回転させたい

こんな感じ


app.js
// this sets the background color of the master UIView (when there are no windows/tab groups on it)
Titanium.UI.setBackgroundColor('#ffe');

var window = Ti.UI.createWindow();

var wheelImage = Ti.UI.createImageView({
 image:'wheel.png'
});
window.add(wheelImage);

var angleLabel = Ti.UI.createLabel({
 text:'0',
 width:'auto',
 height:'auto',
 color:'#aaa',
 font:{ fontSize:48 }
});
window.add(angleLabel);

var initialAngle = 0.0; // touchstart時点での角度(rad)
var currentAngle = 0.0; // 現在の回転角度(rad)

wheelImage.addEventListener('touchstart', function(e){
    // ビューの中心とタッチした位置のなす角度を求めます
 initialAngle = Math.atan2(e.x - this.width/2.0, -(e.y - this.height/2.0));
});

wheelImage.addEventListener('touchmove', function(e){
    // ビューの中心とタッチした位置のなす角度を求めます
 var movedAngle = Math.atan2(e.x - this.width/2.0, -(e.y - this.height/2.0));
    // e.x/e.y はローカル座標なので、なぜかこれで角度の増分が求められる
    // (ここを今ひとつ理解していないがうまくいくんです)
 var deltaAngle = movedAngle - initialAngle;
 currentAngle += deltaAngle;
    // 0 〜 2πでリミットします
 if (currentAngle > 2.0 * Math.PI){
  currentAngle -= 2.0 * Math.PI; 
 }
   if (currentAngle < 0.0){
    currentAngle += 2.0 * Math.PI;
   }
    // 現在角度に応じて回転させて表示させてあげます
   wheelImage.transform = Ti.UI.create2DMatrix().rotate(currentAngle / Math.PI * 180.0);
    // 現在角度を表示してあげます
   angleLabel.text = parseInt(currentAngle / Math.PI * 180.0);
});

window.open();



ソースはgithubに置いておきます。
https://github.com/atsusy/Wheel-Gesture-Sample