iPadで加速度センサー / jQueryゼロから

iPad/iPhoneでiOS4.2以降はブラウザでも加速度センサーの値がとれるのでちょっとテストした時のをまとめます。
javascriptではdevicemotionイベントで取れます。

1
2
3
4
5
6
7
8
$(window).bind('devicemotion', function(e){
    // 加速度
    var a = e.originalEvent.acceleration;
    // 重力加速度
    var g = e.originalEvent.accelerationIncludingGravity;
    // 回転加速度
    var r = e.originalEvent.rotationRate;
}

重力加速度で画面を傾けるとコリント的な動きさせる場合は、下記の感じ。

1
2
3
4
5
6
$(window).bind('devicemotion', function(e){
    // left, top が対象の左上の x, y 座標
    var g = e.originalEvent.accelerationIncludingGravity;
    left += g.x;
    top -= g.y;
}

これだけだとよくあるので、画面を傾けると回転しちゃう場合も考慮に入れてみます。
※画面ロックしなかった時にぐるっと回っちゃうので…
画面の回転はwindow.orientationから0, 90, 180, -90で取れます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$(window).bind('devicemotion', function(e){
    var g = e.originalEvent.accelerationIncludingGravity;
    var dx, dy = 0;
    if (window.orientation == 0) {
        dx = g.x;
        dy = -g.y;
    } else if (window.orientation == 90) {
        dx = -g.y;
        dy = -g.x;
    } else if (window.orientation == 180) {
        dx = -g.x;
        dy = g.y;
    } else {
        dx = g.y;
        dy = g.x;
    }
    left += dx;
    top += dy;
}

あとは画面からはみ出ないようにとかする場合は orientationchange イベントで調整できます。
例えば canvas を画面いっぱいにした場合は、canvasサイズも変更しつつ画面の右下の最大値を調整します。

1
2
3
4
5
6
7
$(window).bind('orientationchange', function(e){
// size は描画するオブジェクトの大きさ
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    maxX = canvas.width - size;
    maxY = canvas.height - size;
});

まあ、回転に対応するケースはなさそうだけど…

サンプル ※iPadでみてね

iPadでスワイプ / jQueryゼロから

ちょっと特殊だけど、iPadでスワイプ処理を自分で書くことがあったので。
たぶんGalaxyでもあんまり変わらないはず。

タッチイベントは touchstart, touchend, touchmove で拾えます。
touchmove の際に event.touches に座標が入ってます。
配列なのは5つまでデータが入っているから。
今回は、ただのスワイプなので touches[0] だけ使います。

とりあえず座標を拾ってみます。

1
2
3
// touchmove で座標を拾う
X = event.touches[0].pageX;
Y = event.touches[0].pageY;

サンプル ※iPadで見てください

touches には pageX, pageY, screenX, screenY, clientX, clientY があり、ページやスクリーンの相対座標として取得できます。
画面を固定する場合は特に変わりはないですが、スクロールする場合は使い分けが必要です。
※pageX, pageYはスクロールする場合は指に追従してページも移動するので

とりあえず、touchstart と touchend の時の座標の差でスワイプを判定してみます。
X方向に100px動いたらスワイプします。※値は適当です

1
2
3
4
5
6
// touchendで判定
if (startX - endX > 100) {
// prev
} else if (endX - startX > 100) {
// next
}

サンプル

これでもスワイプは出来るのですが、いくつか問題があるのでもう少し調整してみます。
・縦(斜め)にスワイプしても横移動が100px以上ならスワイプするのをやめる
→ touchstart と touchend の確度を小さくする(2点を結ぶ直線の傾きが0.5以下としてみる)
・速度が遅くてもスワイプするのをやめる
→ 0.7秒以内のみスワイプとする
・iPadだと画面がズレる(指に追従する)のをやめる
→ よく使われている方法を参考に preventDefault でブラウザの挙動を無視する

サンプル