iPhoneのSafariで左右フリックを検出するjQueryプラグイン作った
はじめに
iPhoneのSafari上で動くアプリを作っているのですが、左右方向のフリックを検出をしたくなったのでjQueryのプラグイン(landscapeFlickSensor)を作りました。せっかくなので公開します。ソースは一番下です。
JavaScriptやjQueryは最近かじり始めたばかりなので間違いやお作法に沿ってない部分があったらぜひ教えてください。
できること
iPhoneのSafari上で画面をフリックしたときに指定の関数を呼び出すことができます。
一応iPadでも動いてるっぽいことを確認しましたが、どうなんでしょう・・・androidとかは手元に無いのでさっぱり分からんです。
できないこと、制約
フリック、スワイプの区別
個人的に、タップと同時に画面をなぞることをフリック、画面を掃くような動作をスワイプと呼んでいます*1。
このプラグインはFlickSensorとか言っていますが、実は速度の検知は行なっていないのでどんなに遅く(早く)画面をなぞってもフリックとみなされます。
上下のフリック
個人的に必要がなかったのと、上下はスクロールに利用するため上下のフリック検出は実装していません*2。
使い方
プラグインの読み込み
jquery.jsとlandscapeFlickSensorを読み込んで下さい(landscapeFlickSensorのソースは最下部です)*3。
<script type="text/javascript" src="/resources/js/jquery.js" ></script> <script type="text/javascript" src="/resources/js/jquery.landscapeFlickSensor.js"></script>
プラグインの適用
検知部にプラグインを適用します。その際左右フリック時の動作やオプションを同時に渡します(全て省略可)。
<script type="text/javascript"> <!-- $(document).ready(function() { $('#flickPane').landscapeFlickSensor({ distanceThreshold : 30, /* フリックとみなす最低距離 */ degreeThreshold : 10.0, /* フリックとみなす最大角度(度) */ onRightFlick : function() { /* 右フリック持の動作 */ }, onLeftFlick : function() { /* 左フリック時の動作 */ } }); }); //--> </script>
フリックとみなす最低距離(distanceThreshold)
フリックの始点と終点の距離がこの指定値以上の場合にフリックとみなされます。省略した場合30が設定されます*5。
右フリック持の動作(onRightFlick)
右フリックをしたときに呼び出される関数を記述します。引数はありません。省略した場合は空の関数が実行されます。
左フリック持の動作(onLeftFlick)
左フリックをしたときに呼び出される関数を記述します。引数はありません。省略した場合は空の関数が実行されます。
使用例
左右にフリックすると画面上にメッセージを表示する例を上げます。
サンプルソース
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8" /> <!-- iPhoneでの画面サイズの固定 --> <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=no" /> <!-- jqueryとlandscapeFlickSensorの読み込み --> <script type="text/javascript" src="/resources/js/jquery.js" ></script> <script type="text/javascript" src="/resources/js/jquery.landscapeFlickSensor.js"></script> <script type="text/javascript"> <!-- $(document).ready(function() { $('#flickPane').css("min-height", $(document).height()); //反応範囲を全範囲にする /* フリックした時の動作 */ $('#flickPane').landscapeFlickSensor({ onRightFlick : function () { $('#message').text('右フリック'); }, onLeftFlick : function() { $('#message').text('左フリック'); } }); }); //--> </script> </head> <body> <div id="flickPane"> <p id="message">ここをフリックする</p> </div> </body> </html>
ソースコード
/** * jquery.landscapeFlickSensor.js * iPhoneで左右のフリックを検出するプラグイン。 * * 商用・非商用、改変、報告、ライセンス表示等何も制限しないので好きに使って下さい。 * もちろん何も責任は取りません。 * * @author tatesuke */ (function($){ $.fn.landscapeFlickSensor=function(config){ var opts = $.extend({}, $.fn.landscapeFlickSensor.defaults, config); return this.each(function(i){ var startX = -1; var startY = -1; $(this).bind('touchstart', function() { startX = event.changedTouches[0].pageX; startY = event.changedTouches[0].pageY; }); $(this).bind('touchend', function() { var endX = event.changedTouches[0].pageX; var endY = event.changedTouches[0].pageY; var dx = endX - startX; var dy = endY - startY; var distance = Math.sqrt((dx * dx) + (dy * dy)); var degree = Math.abs(toDegree(Math.atan2(dy, dx))); if (opts.distanceThreshold <= distance) { if (isRightFlick(degree)) { opts.onRightFlick(); } else if (isLeftFlick(degree)) { opts.onLeftFlick(); } } }); function toDegree(radian) { return 180.0 * radian / Math.PI; } function isRightFlick(degree) { return (0.0 <= degree) && (degree <= opts.degreeThreshold); } function isLeftFlick(degree) { return ((180.0 - opts.degreeThreshold) <= degree) && (degree <= 180); } }); }; $.fn.landscapeFlickSensor.defaults = { distanceThreshold : 30, /* フリックとみなす最低距離(多分px) */ degreeThreshold : 10.0, /* フリックとみなす最大角度(度) */ onRightFlick : function(){ /* 右フリック時の処理はこれを上書く */ }, onLeftFlick : function() { /* 左フリック時の処理これを上書く */ }, }; })(jQuery);