Webページでマウスのシェイクイベント(ブルブルっと動かした)の検知 | TypeScript, RxJS
はじめに
ユーザーがマウスをブルブルっと動かした(シェイクした)時になんらかのタスクを実行したいと思ったことはありますか?ありませんよね。
こんなイメージです。マウスシェイク検知したらその旨をコンソールに出力します。
RxJSを使えばそこまで難しくはありません。
ちなみにRxJSとは非同期処理やストリーム処理のライブラリです。
実装コード
今回はマウスのシェイクイベントを、このように噛み砕きました。
"500ミリ秒以内に4回、マウスのX軸方向の動きが反転した"
それをRxJSで表現します。
// ↓最終的なマウスシェイクイベントのストリーム const mouseShakeEvents$ = fromEvent<MouseEvent>(document, 'mousemove').pipe( // 上流はmousemoveイベントのストリーム // ↓マウスのx軸が動いたイベントだけにフィルタ filter(e => e.movementX !== 0), // マウスのx軸の動きが反転した時だけ流すように distinctUntilChanged((e1, e2) => Math.sign(e1.movementX) === Math.sign(e2.movementX)), // 直近の4件のイベントのまとまりで流すように bufferCount(4, 1), // 直近4件のイベントの、最初と最後の間の時間が500ms以下の場合に流すように filter(events => events.length === 4 && events[3].timeStamp - events[0].timeStamp < 500) );
要点・補足:
- RxJSのfromEventで、document (DOM)上のmousemoveイベントを、
Observable<MouseEvent>
に変換します。- Observableは端的に言うとストリームのようなオブジェクトです。
- mousemoveイベントにはどの方向にどれだけ動いたかを示すmovementX, movementYプロパティがあります
- RxJSのdistinctUntilChangedオペレーターは、流れてきた値と前回の値の等価性を検証する関数を取り、true(等価とみなした)場合はフィルタします。
Math.sign(e1.movementX)
は、movementXの値がマイナスなら-1, プラスなら1を返します。
- RxJSのbufferCountは値を指定個数分バッファして配列で流すオペレータです。
bufferCount(3, 2)
とした時、1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7
という値の流れは[1, 2, 3] -> [3, 4, 5] -> [5, 6, 7]
のように変換されます。 (3つのまとまりで2つごとに流れる)
RxJSとっても便利です!