MinJieLiu há 7 anos atrás
pai
commit
0f5c8c0730
2 ficheiros alterados com 40 adições e 10 exclusões
  1. 21 9
      src/PhotoView.tsx
  2. 19 1
      src/utils.ts

+ 21 - 9
src/PhotoView.tsx

@@ -3,7 +3,12 @@ import { Motion, spring } from 'react-motion';
 import throttle from 'lodash.throttle';
 import Photo from './Photo';
 import { PhotoContainer, Backdrop } from './StyledElements';
-import { isMobile, getPositionOnScale, jumpToSuitableOffset } from './utils';
+import {
+  isMobile,
+  getTouchCenter,
+  getPositionOnScale,
+  jumpToSuitableOffset,
+} from './utils';
 import { defaultAnimationConfig } from './variables';
 import { animationType } from './types';
 
@@ -87,8 +92,7 @@ export default class PhotoView extends React.Component<
     }
   }
 
-  handleStart = e => {
-    const { pageX, pageY } = e;
+  handleStart = (pageX, pageY) => {
     this.setState(prevState => ({
       touched: true,
       pageX,
@@ -124,6 +128,7 @@ export default class PhotoView extends React.Component<
           fromScale: scale,
           toScale: scale < 4 ? scale * 2 : 1,
         }),
+        animation: defaultAnimationConfig,
       };
     });
   }
@@ -148,16 +153,22 @@ export default class PhotoView extends React.Component<
   }
 
   handleTouchStart = e => {
-    this.handleStart(e.touches[0]);
+    const { pageX, pageY } = e.touches.length >= 2
+      ? getTouchCenter(e)
+      : e.touches[0];
+    this.handleStart(pageX, pageY);
   }
 
   handleMouseDown = e => {
-    this.handleStart(e);
+    this.handleStart(e.pageX, e.pageY);
   }
 
-  handleTouchMove = evt => {
-    const e = evt.touches[0];
-    this.handleMove(e.pageX, e.pageY);
+  handleTouchMove = e => {
+    e.preventDefault();
+    const { pageX, pageY } = e.touches.length >= 2
+      ? getTouchCenter(e)
+      : e.touches[0];
+    this.handleMove(pageX, pageY);
   }
 
   handleMouseMove = e => {
@@ -176,7 +187,8 @@ export default class PhotoView extends React.Component<
       touchedTime,
       ...restPrevState
     }) => {
-      const hasMove = pageX !== restPrevState.pageX || pageY !== restPrevState.pageY;
+      const hasMove = pageX !== restPrevState.pageX
+        || pageY !== restPrevState.pageY;
       return {
         touched: false,
         ...jumpToSuitableOffset({

+ 19 - 1
src/utils.ts

@@ -1,3 +1,4 @@
+import React from 'react';
 import { animationType } from './types';
 import { maxTouchTime, defaultAnimationConfig } from './variables';
 
@@ -7,6 +8,23 @@ import { maxTouchTime, defaultAnimationConfig } from './variables';
 export const isMobile: boolean = window.navigator.userAgent.includes('Mobile');
 
 /**
+ * 从 Touch 事件中获取双指中心点
+ */
+export const getTouchCenter = (evt: React.TouchEvent): {
+  pageX: number;
+  pageY: number;
+} => {
+  const firstTouch = evt.touches[0];
+  const secondTouch = evt.touches[1];
+  const pageX = (firstTouch.pageX + secondTouch.pageX) / 2;
+  const pageY = (firstTouch.pageY + secondTouch.pageY) / 2;
+  return {
+    pageX,
+    pageY,
+  };
+};
+
+/**
  * 获取图片合适的大小
  * @param naturalWidth 图片真实宽度
  * @param naturalHeight 图片真实高度
@@ -122,7 +140,7 @@ export const slideToPosition = ({
   const speedX = (x - lastX) / moveTime;
   const speedY = (y - lastY) / moveTime;
   const maxSpeed = Math.max(speedX, speedY);
-  const slideTime = moveTime < maxTouchTime ? Math.abs(maxSpeed) * 10 + 400 : 0;
+  const slideTime = moveTime < maxTouchTime ? Math.abs(maxSpeed) * 20 + 400 : 0;
   return {
     endX: Math.floor(x + speedX * slideTime),
     endY: Math.floor(y + speedY * slideTime),