liumingyi_1 5 жил өмнө
parent
commit
81ed597ef6
3 өөрчлөгдсөн 80 нэмэгдсэн , 28 устгасан
  1. 64 26
      src/PhotoView.tsx
  2. 9 0
      src/types.ts
  3. 7 2
      src/variables.ts

+ 64 - 26
src/PhotoView.tsx

@@ -8,11 +8,19 @@ import getPositionOnMoveOrScale from './utils/getPositionOnMoveOrScale';
 import slideToPosition from './utils/slideToPosition';
 import { getClosedHorizontal, getClosedVertical } from './utils/getCloseEdge';
 import withContinuousTap, { TapFuncType } from './utils/withContinuousTap';
-import { maxScale, minReachOffset, minScale, scaleBuffer } from './variables';
+import {
+  maxScale,
+  minReachOffset,
+  minStartTouchOffset,
+  minScale,
+  scaleBuffer,
+} from './variables';
 import {
   ReachFunction,
   PhotoTapFunction,
-  ReachTypeEnum, CloseEdgeEnum,
+  ReachTypeEnum,
+  CloseEdgeEnum,
+  TouchStartEnum,
 } from './types';
 import './PhotoView.less';
 
@@ -77,6 +85,8 @@ const initialState = {
 
   // 当前边缘触发状态
   reachState: ReachTypeEnum.Normal,
+  // 初始响应状态
+  initialTouchState: TouchStartEnum.Normal,
 };
 
 export default class PhotoView extends React.Component<
@@ -132,42 +142,70 @@ export default class PhotoView extends React.Component<
   };
 
   onMove = (newClientX: number, newClientY: number, touchLength: number = 0) => {
-    const { touched, maskTouched } = this.state;
+    // minInitialTouchOffset
+    const {
+      x,
+      y,
+      clientX,
+      clientY,
+      lastX,
+      lastY,
+      scale,
+      lastTouchLength,
+      reachState,
+      touched,
+      maskTouched,
+      initialTouchState,
+    } = this.state;
     const { current } = this.photoRef;
+    let handleClientX = newClientX;
+    let handleClientY = newClientY;
     if ((touched || maskTouched) && current) {
+      // 最小缩放下,以初始移动距离来判断意图
+      if (scale === minScale && initialTouchState === TouchStartEnum.Normal) {
+        const isBeyondX = Math.abs(newClientX - clientX) > minStartTouchOffset;
+        const isBeyondY = Math.abs(newClientY - clientY) > minStartTouchOffset;
+
+        // 初始移动距离不足则不做操作
+        if (!(isBeyondX || isBeyondY)) {
+          return;
+        }
+
+        this.setState({
+          initialTouchState: isBeyondX ? TouchStartEnum.X : TouchStartEnum.Y,
+        });
+      }
+      if (initialTouchState === TouchStartEnum.X) {
+        handleClientX = newClientX - clientX > 0
+          ? newClientX + minStartTouchOffset
+          : newClientX - minStartTouchOffset;
+      } else {
+        handleClientY = newClientY - clientY > 0
+          ? newClientY - minStartTouchOffset
+          : newClientY + minStartTouchOffset;
+      }
+
       const { width, height, naturalWidth } = current.state;
-      const {
-        x,
-        y,
-        clientX,
-        clientY,
-        lastX,
-        lastY,
-        scale,
-        lastTouchLength,
-        reachState,
-      } = this.state;
       let currentX = x;
       let currentY = y;
       // 边缘触发状态
       let currentReachState = ReachTypeEnum.Normal;
       if (touchLength === 0) {
-        const planX = newClientX - clientX + lastX;
-        const planY = newClientY - clientY + lastY;
+        const planX = handleClientX - clientX + lastX;
+        currentY = handleClientY - clientY + lastY;
         // 边缘超出状态
         const horizontalCloseEdge = getClosedHorizontal(planX, scale, width);
-        const verticalCloseEdge = getClosedVertical(planY, scale, height);
-        // 非正常滑动则响应距离减少
-        currentX = (newClientX - clientX) / (horizontalCloseEdge !== CloseEdgeEnum.Normal ? 2 : 1)  + lastX;
-        currentY = (newClientY - clientY) / (verticalCloseEdge !== CloseEdgeEnum.Normal ? 2 : 1) + lastY;
+        const verticalCloseEdge = getClosedVertical(currentY, scale, height);
+        // X 方向响应距离减小
+        currentX = (handleClientX - clientX) / (horizontalCloseEdge !== CloseEdgeEnum.Normal ? 2 : 1)  + lastX;
         // 边缘触发检测
         currentReachState = this.handleReachCallback({
           x: planX,
-          y: planY,
+          y: currentY,
           horizontalCloseEdge,
           verticalCloseEdge,
-          clientX: newClientX,
-          clientY: newClientY,
+          clientX: handleClientX,
+          clientY: handleClientY,
           scale,
           reachState,
         });
@@ -194,8 +232,8 @@ export default class PhotoView extends React.Component<
           ...getPositionOnMoveOrScale({
             x: currentX,
             y: currentY,
-            clientX: newClientX,
-            clientY: newClientY,
+            clientX: handleClientX,
+            clientY: handleClientY,
             fromScale: scale,
             toScale,
           }),
@@ -233,7 +271,6 @@ export default class PhotoView extends React.Component<
   };
 
   handleWheel = (e) => {
-    e.preventDefault();
     const { current } = this.photoRef;
     if (current) {
       const { clientX, clientY, deltaY } = e;
@@ -330,6 +367,7 @@ export default class PhotoView extends React.Component<
           minScale,
         ),
         reachState: ReachTypeEnum.Normal, // 重置触发状态
+        initialTouchState: TouchStartEnum.Normal,
         ...hasMove
           ? slideToPosition({
             x,

+ 9 - 0
src/types.ts

@@ -74,3 +74,12 @@ export enum ReachTypeEnum {
   XReach, // x 轴
   YReach, // y 轴
 }
+
+/**
+ * 初始响应状态
+ */
+export enum TouchStartEnum {
+  Normal, // 未触发
+  X, // X 轴优先
+  Y, // Y 轴优先
+}

+ 7 - 2
src/variables.ts

@@ -11,12 +11,17 @@ export const maxMoveOffset: number = 40;
 /**
  * 图片的间隔
  */
-export const horizontalOffset: number = 40;
+export const horizontalOffset: number = 20;
 
 /**
  * 最小触发边缘事件距离
  */
-export const minReachOffset: number = 20;
+export const minReachOffset: number = 10;
+
+/**
+ * 最小初始响应距离
+ */
+export const minStartTouchOffset: number = 100;
 
 /**
  * 默认背景透明度