【jsステップアップ】[2]ドラッグ値/スワイプ値を取得する

29/03/2019

ドラッグ値(PC)・スワイプ値(SP)を取得する

現場で役立つjs実装サンプル。として初心者の方に向けての連載2回目です。
前回は完成目標のサンプルと全体の概要を説明しました。
今回から実際にコード(html/css/js)の説明に入ろうかと思います。

主な内容としてはマウスドラッグ値(PCの場合)/スワイプ値(スマホ・タブレットの場合)を
javascript(フロントエンド)で取得する方法のサンプル・説明です。

【拡大機能付きスライダー】javascript実装サンプルの連載一覧

  1. [1]初心者の方向けに作成手順や説明等していきます
  2. [2]ドラッグ値/スワイプ値を取得する
  3. [3]スライダーを作成する
  4. [4]モーダルを作成する
  5. [5]拡大(ズーム)機能を作成する
  6. [6]拡大(ズーム)機能を作成する②

【スライダーを作成】するにあたり

前回の完成サンプルを目標としては
まず最初はスライダーを作成をする事になるかと思います。

(1)スライダー機能

prev/nextボタンのクリック/タップでスライド
+PCの場合画像マウスドラッグでスライド
+SPの場合スワイプでスライド

上記のようなスライダーを作成するにあたり
マウスドラッグ&スワイプでのスライド
で利用するのでマウスドラッグ値/スワイプ値を取得する
必要が出てきます。

今回はその部分の説明しようと思います。

PCドラッグ/スマホスワイプの情報取得サンプル

さっそくですが下記がcodepenでのドラッグ/スマホスワイプの情報取得サンプルです。

See the Pen スマホ/タブレット等スワイプの情報取得サンプル by admin@nocebo.jp (@nocebojp) on CodePen.

ただ数値が表示される文字だけのサンプルですが、
基本的にこういった数値を取得/利用して色々な仕組みを作成していきます。

htmlに関しては多分特殊な事はしていないと思うので、省略します。

以降はjavascriptの各処理の細かい部分等を説明していきます。

Pointクラス

// /* ===========================================================
// # Point
// =========================================================== */
class Point {
    constructor(x = 0, y = 0) {
        this.x = x || 0;
        this.y = y || 0;
    }
    // ~~~~~~~~
    // 省略
    // ~~~~~~~~
    subtract(p) {
        this.x -= p.x;
        this.y -= p.y;
        return this;
    }
}

(x,y)の座標を管理するクラスです。
良くある作りなのですが、javascript単体だとそういった機能は無いので
独自にクラスを作成します。

constructor

コンストラクタです。
因みにコンストラクタは
newでインスタンスを作成した時に実行される処理です。
であってると思う、多分。

constructorで(x = 0, y = 0)となっているのは、デフォルトの引数です。

new Point()と引数無しでnewした場合は(0,0)のpointが作成されます。

subtract

今回のサンプルで使用するメソッドはsubtractだけなのですが、
subtractはポイントとポイントを減算した結果を返します。
ざっくり言うと2点間の差を計算します。

Pointクラスを利用してクリックやタップ等の
各種イベントを組み合わせて必要な数値を取得していきます。

EventTouchクラス

EventTouchクラスと命名してますが、
マウスの処理とかもまざってます。
名前とかは割と適当です。ご愛嬌。

細かい所でポイントかなと思われる所を説明します。

this.currentPoint = new Point(); // 現在位置を保持
this.startPoint = new Point(); // スタート位置を保持
this.diffPoint = new Point(); // スワイプ/ドラッグ値を保持

コメントのままですが、上記の3つのpointを利用してスワイプ値とドラッグの値を取得します。

// PC
document.addEventListener('mousedown', this.onStart.bind(this), false);
document.addEventListener('mousemove', this.onMove.bind(this), false);
document.addEventListener('mouseup', this.onUp.bind(this), false);
// SP
document.addEventListener('touchstart', this.onStart.bind(this), false);
document.addEventListener('touchmove', this.onMove.bind(this), false);
document.addEventListener('touchend', this.onUp.bind(this), false);

PC/SP共にそれぞれのイベントに関連付けしてます。

onStart(e)

this.originalEvent(e); // (1)
this.isDown = true; // (2)
this.diffPoint = new Point(); // (3)
this.startPoint = this.clientPosition(e); // (4)

上記が抜粋ですがstartの処理です。
ちなみに(e)のeっていいうのは各種イベントのeventです。

(1) originalEvent

originalEventはコメントにも書いてますが、
今回は不使用なので不要ではありますが、
jquery使用時にeventがjquery用のeventになってたして上手く動かったりするので
originalEvent取得を取得します。

(2) isDown

isDownはPCだとマウスをダウンしているのかの判定です。
SPだと画面にタッチしているかの判定です。

(3) diffPoint

diffPointはダウン時の位置と現在位置の差分を管理します。
ダウン時にはダウン位置=現在位置なので
差分は0なのでnew Point()をいれます。

(4) startPoint

startPointはダウン時の位置を管理します
次に説明しますが、clientPositionで現在の位置を入れます。

clientPosition(e)

if (e.touches) {
    return new Point(e.touches[0].clientX, e.touches[0].clientY);
} else {
    return new Point(e.clientX, e.clientY);
}

e.touches

e.touchesはタッチデバイス特有のプロパティなので
ifでPC/SPの判定をして
PCの場合はclientX,Y
SPの場合はtouches[0].clientX,Yを返します。

touches[0]っていうのはタッチデバイスは2本とか3本とか接してる場合があるので。
touches[0] = “最初に触れたの指”
っていう認識で良い、はず。多分。

onMove(e)

this.currentPoint = this.clientPosition(e);

if (!this.isDown) return;
this.diffPoint = new Point(this.currentPoint.x, this.currentPoint.y).subtract(this.startPoint);

move(e)は

PCの場合マウスを動かした時
SPの場合画面に触れて動かした時

に実行されます。

currentPoint

currentPointは現在位置なので

PC=現在のマウス位置
SP=現在の指の位置

が入ります。

diffPoint

PCだと

マウスダウン位置 – マウス現在位置 = 差分値

なので、ここで上部で登場したsubtractを利用します。

if (!this.isDown) return;

上記でマウスダウン時のみdiffPointを更新する。です。

onUp(e)

this.isDown = false;

startと逆でisDownをfalseにします。

取得した数値をwindowに反映させる

var update = () => {
    document.querySelector('.point__current span').innerText = `${~~EventTouch.instance.currentPoint.x}, ${~~EventTouch.instance.currentPoint.y}`;
    document.querySelector('.point__start span').innerText = `${~~EventTouch.instance.startPoint.x}, ${~~EventTouch.instance.startPoint.y}`;
    document.querySelector('.point__diff span').innerText = `${~~EventTouch.instance.diffPoint.x}, ${~~EventTouch.instance.diffPoint.y}`;
}

document.addEventListener('touchmove', update, false);
document.addEventListener('mousemove', update, false);

あとは上記部分のinnerText等で取得した数値を文字にして画面に表示しています。

es6の変数展開

${}っていうのはes6の変数展開です。

ビット反転演算子で整数化

js特有?かもですが、
~~(num)で整数化です。
なんで整数値になるかは忘れたけど楽なのと覚えやすいので、
個人的によく使います。

【拡大機能付きスライダー】javascript実装サンプル第2回 次回とかその他

今回は以上です。

ただ画面に文字表示だけなので少しばかり地味ですが、
次回からはこの数値を利用してスライダーを作成していきたいと思います。

またその他は今回のサンプル現状では利用していないものの
次回以降で利用したりするコード等も入ってる状態なのですが書きながら
追々整理して行こうと思います。

【拡大機能付きスライダー】javascript実装サンプルの連載一覧

  1. [1]初心者の方向けに作成手順や説明等していきます
  2. [2]ドラッグ値/スワイプ値を取得する
  3. [3]スライダーを作成する
  4. [4]モーダルを作成する
  5. [5]拡大(ズーム)機能を作成する
  6. [6]拡大(ズーム)機能を作成する②

本連載に関して

本連載では、初心者向けに各所の解説をしていますが、
一歩踏み込んだ実践的な内容にはなっていると思います。
※フロントエンド(HTML/CSS/JavaScript)の基礎知識は必須になります。