ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript でジェスチャ ライブラリを実装する方法

JavaScript でジェスチャ ライブラリを実装する方法

醉折花枝作酒筹
醉折花枝作酒筹転載
2021-05-07 09:25:322526ブラウズ

この記事では、JS で日付比較を実装する方法を紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。

JavaScript でジェスチャ ライブラリを実装する方法

開始イベント

まず、開始イベントをトリガーします。つまり、指が画面に触れたとき、トリガーされたイベント。この時点では 3 つの状況が考えられます。

  • 指を離してください
    • 終了イベントがトリガーされ、タップクリック動作を構成します
    • 終了イベントをリッスンすることで実現できます
  • 指で 10 ピクセル以上ドラッグします
      #これは
    • パン スタート ドラッグの動作です
    • 移動イベントで現在の接触点と前の接触点の間の距離を判断できます
  • 指が現在の位置に 0.5 秒以上留まる
      これは
    • press start の動作です
    • setTimeout を追加して
Press イベントを実装できます

したがって、最初のステップは、

setTimout ハンドラー ハンドラーを start 関数に追加することです。

let handler;let start = point => {
  handler = setTimeout(() => {
    console.log('presss ');
  }, 500);};

一般的に、

press は私たちにとって一般的な行動です。しかし実際には、これはプレス開始イベントとそれに続くプレス終了イベントです。このイベントをまとめて press と呼ぶこともでき、その場合、このジェスチャ ライブラリのユーザーは、この press イベントをリッスンするだけで済みます。まれに、press をリッスンする必要がある場合もあります。終了 イベント。

ここで注意する必要があるのは、他のイベントをトリガーすると、500 ミリ秒の setTimout がキャンセルされる可能性があるということです。したがって、他のイベントがこの変数を取得して、この処理ロジックをキャンセルするために使用できるように、このロジックに

handler を与え、グローバル スコープに置く必要があります。

パン イベント

次に、10 ピクセル移動する

pan イベントをリッスンします。ここでは、最初のユーザー タッチを記録する必要があります。ユーザーが指を動かすと、画面の x 座標と y 座標は、新しく移動した位置と最初の位置の間の距離を計算し続けます。この距離が 10px を超える場合、pan start イベントがトリガーされる可能性があります。

したがって、まず、

startXstartY の座標レコードを start 関数に追加する必要があります。ここで注意すべき点は、これら 2 つの値は、複数の場所で使用されるため、グローバル スコープでも宣言する必要があります。

次に、現在の接触点と移動関数の開始点の間の直径距離を計算します。ここでは、数学の直径計算式 z 2 x^2 y^2 = z^2x を使用する必要があります。 2 y 2 =z 2 ここで、x は現在の接点の x 座標 - 始点の x 座標間の x 軸距離、y は現在の出力点の y 座標から計算された y 軸距離 -開始点の y 座標。 2 つの距離の 2 乗の最終合計が、直径距離の 2 乗になります。

ラジカル操作はパフォーマンスに一定の影響を与えるため、コードでは通常、ラジカル操作の使用を避けるようにしています。最終的な判断は、直径の距離が固定の 10px より大きいかどうかであることがわかっています。つまり、z = 10、z の 2 乗は 100 であるため、直径距離が 100 より大きいかどうかを直接判断できます。

ここでもう 1 つ注意すべき点は、指が 10 ピクセルを超えて移動したときに、指が画面から離れずに戻った場合、開始点から 10 ピクセル離れていないことになります。しかし、これは実際にはパン イベントです。10 ピクセルを超える距離を移動し、この距離以降の動きはすべてパン イベントであるためです。

したがって、

isPan の状態が必要です。最初の動きが 10px を超えると、pan-start イベントがトリガーされ、isPan が設定されますtrue に設定すると、後続のすべての動きが pan イベントをトリガーします。

上記の

press イベントによると、指を押してから 0.5 秒以内に動きがあった場合、press イベントはキャンセルされます。したがって、ここでは pressstarthandler をクリアするために clearTimeout が必要です。

let handler;let startX, startY;let isPan = false;let start = point => {
  (startX = point.clientX), (startY = point.clientY);

  isPan = false;

  handler = setTimeout(() => {
    console.log('pressstart');
  }, 500);};let move = point => {
  let dx = point.clientX - startX,
    dy = point.clientY - startY;

  let d = dx ** 2 + dy ** 2;

  if (!isPan && d > 100) {
    isPan = true;
    console.log('pan-start');
    clearTimeout(handler);
  }

  if (isPan) {
    console.log(dx, dy);
    console.log('pan');
  }};

タップイベント

Tap 的这个逻辑我们可以在 end 事件里面去检查。首先我们默认有一个 isTap 等于 true 的状态,如果我们触发了 pan 事件的话,那就不会去触发 tap 的逻辑了,所以 tap 和 pan 是互斥的关系。但是为了不让它们变得很耦合,所以我们不使用原有的 isPan 作为判断状态,而是另外声明一个 isTap 的状态来记录。

这里我们 tap 和 pan 都有单独的状态,那么我们 press 也不例外,所以也给 press 加上一个 isPress 的状态,它的默认值是 false。如果我们 0.5 秒的定时器被触发了,isPress 也就会变成 true。

既然我们给每个事件都加入了状态,那么这里我们就给每一个事件触发的时候设置好这些状态的值。

  • press 时  
    • isTap = false
    • isPan = false
    • isPress = true
  • pan 时  
    • isTap = false
    • isPan = true
    • isPress = false
  • tap 时  
    • isTap = true
    • isPan = false
    • isPress = false

如果我们发现用户没有移动,也没有按住触屏超过 0.5 秒,当用户离开屏幕时就会调用 end 函数,这个时候我们就可以认定用户的操作就是 tap。这里我们要注意的是,我们 press 的 0.5 秒定时器是没有被关闭的,所以我们在 isTap 的逻辑中需要 clearTimeout(handler)

说到取消 press 定时器,其实我们 handler 的回调函数中,也需要做一个保护代码逻辑,在触发了 press-start 之后,我们需要保证每次点击屏幕只会触发一次,所以在 setTimout 的回调函数中的最后,我们需要加上 handler = null。这样只要 press-start 触发了,就不会再被触发。

let handler;let startX, startY;let isPan = false,
  isPress = false,
  isTap = false;let start = point => {
  (startX = point.clientX), (startY = point.clientY);

  isPan = false;
  isTap = true;
  isPress = false;

  handler = setTimeout(() => {
    isPan = false;
    isTap = false;
    isPress = true;
    console.log('press-start');
    handler = null;
  }, 500);};let move = point => {
  let dx = point.clientX - startX,
    dy = point.clientY - startY;

  let d = dx ** 2 + dy ** 2;

  if (!isPan && d > 100) {
    isPan = true;
    isTap = false;
    isPress = false;
    console.log('pan-start');
    clearTimeout(handler);
  }

  if (isPan) {
    console.log(dx, dy);
    console.log('pan');
  }};let end = point => {
  if (isTap) {
    console.log('tap');
    clearTimeout(handler);
  }};

End 事件

到了最后这里我们要处理的就是所有的结束时间,包括 press-endpan-end

这两个 end 事件都会在 end 函数中判断所得,如果在用户操作的过程中触发了 pan-start 或者 press-start 事件,到了 end 函数这里,对应的状态就会是 true。

所以我们对 end 函数做了以下改造:

let end = point => {
  if (isTap) {
    console.log('tap');
    clearTimeout(handler);
  }

  if (isPan) {
    console.log('pan-end');
  }

  if (isPress) {
    console.log('press-end');
  }};

最后我们需要在 cancel 事件触发的时候,清楚掉 press 事件的 setTimeout。既然我们的操作被打断了,那也不可能会触发我们的长按事件了。

// 加入 cancellet cancel = point => {
  clearTimeout(handler);
  console.log('cancel');};

我们除了 flick 的逻辑,我们已经完成所有手势库里面的事件了。并且也能正确的区分这几种手势操作了。

【推荐学习:javascript高级教程

以上がJavaScript でジェスチャ ライブラリを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。