liumingyi_1 5 жил өмнө
parent
commit
24743d06a0

+ 4 - 1
src/PhotoView.tsx

@@ -315,7 +315,7 @@ export default class PhotoView extends React.Component<
     const { current } = this.photoRef;
     if ((touched || maskTouched) && current) {
       const { onReachUp, onPhotoTap, onMaskTap } = this.props;
-      const { width, naturalWidth } = current.state;
+      const { width, height, naturalWidth } = current.state;
       const {
         x,
         y,
@@ -342,6 +342,9 @@ export default class PhotoView extends React.Component<
             y,
             lastX,
             lastY,
+            width,
+            height,
+            scale,
             touchedTime,
           }) : {
             x,

+ 48 - 12
src/utils/slideToPosition.ts

@@ -2,6 +2,8 @@ import {
   maxTouchTime,
   slideAcceleration,
 } from '../variables';
+import { CloseEdgeEnum } from '../types';
+import { getClosedHorizontal, getClosedVertical } from './getCloseEdge';
 
 /**
  * 适应到合适的图片偏移量
@@ -11,41 +13,75 @@ const slideToPosition = ({
   y,
   lastX,
   lastY,
+  width,
+  height,
+  scale,
   touchedTime,
 }: {
   x: number;
   y: number;
   lastX: number;
   lastY: number;
+  width: number;
+  height: number;
+  scale: number;
   touchedTime: number;
 }): {
   x: number;
   y: number;
-
 } => {
   const moveTime = Date.now() - touchedTime;
-  // 时间过长
-  if (moveTime >= maxTouchTime) {
-    return {
-      x,
-      y,
-    };
-  }
+
   // 初始速度
   const speedX = (x - lastX) / moveTime;
   const speedY = (y - lastY) / moveTime;
 
   // 停下所消耗时间
-  const slideTimeX = speedX / slideAcceleration;
-  const slideTimeY = speedY / slideAcceleration;
+  const slideTimeX = Math.abs(speedX / slideAcceleration);
+  const slideTimeY = Math.abs(speedY / slideAcceleration);
 
   // 计划滑动位置
   const planX = Math.floor(x + speedX * slideTimeX);
   const planY = Math.floor(y + speedY * slideTimeY);
 
+  let currentX = planX;
+  let currentY = planY;
+
+  const { innerWidth, innerHeight } = window;
+  // 图片超出的长度
+  const outOffsetX = (width * scale - innerWidth) / 2;
+  const outOffsetY = (height * scale - innerHeight) / 2;
+
+  const horizontalType = getClosedHorizontal(planX, scale, width);
+  const verticalType = getClosedVertical(planY, scale, height);
+
+  // x
+  if (horizontalType === CloseEdgeEnum.Small) {
+    currentX = 0;
+  } else if (horizontalType === CloseEdgeEnum.Before) {
+    currentX = outOffsetX;
+  } else if (horizontalType === CloseEdgeEnum.After) {
+    currentX = -outOffsetX;
+  }
+  // y
+  if (verticalType === CloseEdgeEnum.Small) {
+    currentY = 0;
+  } else if (verticalType === CloseEdgeEnum.Before) {
+    currentY = outOffsetY;
+  } else if (verticalType === CloseEdgeEnum.After) {
+    currentY = -outOffsetY;
+  }
+
+  // 时间过长
+  if (moveTime >= maxTouchTime && (currentX !== 0 || currentY !== 0)) {
+    return {
+      x,
+      y,
+    };
+  }
   return {
-    x: planX,
-    y: planY,
+    x: currentX,
+    y: currentY,
   };
 };
 

+ 1 - 1
src/variables.ts

@@ -36,7 +36,7 @@ export const maxScale: number = 6;
 /**
  * 滑动加速度
  */
-export const slideAcceleration: number = 0.8;
+export const slideAcceleration: number = 0.01;
 
 /**
  * 缩放弹性缓冲