From 0dfce17f6ca01d91db1e6e665670f69e619b3989 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=99=88=E5=98=89=E6=B6=B5?= <chenjiahan@youzan.com>
Date: Mon, 13 Jan 2020 15:40:38 +0800
Subject: [PATCH] feat: add use-touch hook

---
 src/hooks/use-click-outside.ts                |  8 +--
 .../{use-handler.ts => use-global-event.ts}   |  2 +-
 src/hooks/use-touch.ts                        | 63 +++++++++++++++++++
 3 files changed, 67 insertions(+), 6 deletions(-)
 rename src/hooks/{use-handler.ts => use-global-event.ts} (95%)
 create mode 100644 src/hooks/use-touch.ts

diff --git a/src/hooks/use-click-outside.ts b/src/hooks/use-click-outside.ts
index 0e97c1b47..db64eb2a0 100644
--- a/src/hooks/use-click-outside.ts
+++ b/src/hooks/use-click-outside.ts
@@ -1,5 +1,5 @@
-import { Ref, onMounted } from 'vue';
-import { useHandler } from './use-handler';
+import { Ref } from 'vue';
+import { useGlobalEvent } from './use-global-event';
 
 export type UseClickOutsideOpitons = {
   event: string;
@@ -17,7 +17,5 @@ export function useClickOutside(options: UseClickOutsideOpitons) {
     }
   }
 
-  onMounted(() => {
-    useHandler(document, event, onClick, false, flag);
-  });
+  useGlobalEvent(document, event, onClick, false, flag);
 }
diff --git a/src/hooks/use-handler.ts b/src/hooks/use-global-event.ts
similarity index 95%
rename from src/hooks/use-handler.ts
rename to src/hooks/use-global-event.ts
index 0ea54b909..319c043bf 100644
--- a/src/hooks/use-handler.ts
+++ b/src/hooks/use-global-event.ts
@@ -8,7 +8,7 @@ import {
   onDeactivated
 } from 'vue';
 
-export function useHandler(
+export function useGlobalEvent(
   target: EventTarget,
   event: string,
   handler: EventListener,
diff --git a/src/hooks/use-touch.ts b/src/hooks/use-touch.ts
new file mode 100644
index 000000000..aaaa5fb5c
--- /dev/null
+++ b/src/hooks/use-touch.ts
@@ -0,0 +1,63 @@
+import { ref } from 'vue';
+
+const MIN_DISTANCE = 10;
+
+function getDirection(x: number, y: number) {
+  if (x > y && x > MIN_DISTANCE) {
+    return 'horizontal';
+  }
+
+  if (y > x && y > MIN_DISTANCE) {
+    return 'vertical';
+  }
+
+  return '';
+}
+
+export function useTouch() {
+  const startX = ref(0);
+  const startY = ref(0);
+  const deltaX = ref(0);
+  const deltaY = ref(0);
+  const offsetX = ref(0);
+  const offsetY = ref(0);
+  const direction = ref('');
+
+  function reset() {
+    direction.value = '';
+    deltaX.value = 0;
+    deltaY.value = 0;
+    offsetX.value = 0;
+    offsetY.value = 0;
+  }
+
+  function start(event: TouchEvent) {
+    reset();
+    startX.value = event.touches[0].clientX;
+    startY.value = event.touches[0].clientY;
+  }
+
+  function move(event: TouchEvent) {
+    const touch = event.touches[0];
+    deltaX.value = touch.clientX - this.startX;
+    deltaY.value = touch.clientY - this.startY;
+    offsetX.value = Math.abs(this.deltaX);
+    offsetY.value = Math.abs(this.deltaY);
+
+    if (!direction.value) {
+      direction.value = getDirection(offsetX.value, offsetY.value);
+    }
+  }
+
+  return {
+    move,
+    start,
+    startX,
+    startY,
+    deltaX,
+    deltaY,
+    offsetX,
+    offsetY,
+    direction
+  };
+}