Browse Source

修复位置不准确的问题

MinJieLiu 7 years ago
parent
commit
cbc96093ca

+ 1 - 0
examples/simple.tsx

@@ -10,6 +10,7 @@ const Container = styled.div`
 const Header = styled.header`
   padding: 40px;
   font-size: 32px;
+  height: 1000px;
   border-bottom: 1px solid #ccc;
 `;
 

+ 3 - 3
package.json

@@ -1,7 +1,9 @@
 {
   "name": "react-photo-view",
-  "version": "0.1.2",
+  "version": "0.1.3",
   "description": "React photo preview",
+  "main": "./lib",
+  "module": "./es",
   "keywords": [
     "react",
     "react-component",
@@ -30,8 +32,6 @@
   "files": [
     "lib"
   ],
-  "main": "lib/index.js",
-  "module": "./es",
   "author": "LMY",
   "license": "MIT",
   "devDependencies": {

+ 30 - 30
src/PhotoSlider.tsx

@@ -41,9 +41,9 @@ type PhotoSliderState = {
   // 图片处于触摸的状态
   touched: boolean;
   // Reach 开始时 x 坐标
-  lastPageX: number | undefined;
+  lastClientX: number | undefined;
   // Reach 开始时 y 坐标
-  lastPageY: number | undefined;
+  lastClientY: number | undefined;
   // 背景透明度
   backdropOpacity: number;
   // 缩放度
@@ -77,8 +77,8 @@ export default class PhotoSlider extends React.Component<
       photoIndex: 0,
       touched: false,
 
-      lastPageX: undefined,
-      lastPageY: undefined,
+      lastClientX: undefined,
+      lastClientY: undefined,
       backdropOpacity: defaultOpacity,
       photoScale: 1,
     };
@@ -102,78 +102,78 @@ export default class PhotoSlider extends React.Component<
     this.setState(({ photoIndex }) => {
       return {
         translateX: -(innerWidth + horizontalOffset) * photoIndex,
-        lastPageX: undefined,
-        lastPageY: undefined,
+        lastClientX: undefined,
+        lastClientY: undefined,
       };
     });
   }
 
-  handleReachVerticalMove = (pageX, pageY) => {
-    this.setState(({ lastPageY, backdropOpacity }) => {
-      if (lastPageY === undefined) {
+  handleReachVerticalMove = (clientX, clientY) => {
+    this.setState(({ lastClientY, backdropOpacity }) => {
+      if (lastClientY === undefined) {
         return {
           touched: true,
-          lastPageY: pageY,
+          lastClientY: clientY,
           backdropOpacity,
           photoScale: 1,
         };
       }
-      const offsetPageY = Math.abs(pageY - lastPageY);
+      const offsetClientY = Math.abs(clientY - lastClientY);
       return {
         touched: true,
-        lastPageY,
+        lastClientY,
         backdropOpacity: Math.max(
-          Math.min(defaultOpacity, defaultOpacity - offsetPageY / 100 / 2),
+          Math.min(defaultOpacity, defaultOpacity - offsetClientY / 100 / 2),
           0,
         ),
-        photoScale: Math.max(Math.min(1, 1 - offsetPageY / 100 / 10), 0.6),
+        photoScale: Math.max(Math.min(1, 1 - offsetClientY / 100 / 10), 0.6),
       };
     });
   }
 
-  handleReachHorizontalMove = (pageX) => {
+  handleReachHorizontalMove = (clientX) => {
     const { innerWidth } = window;
-    this.setState(({ lastPageX, translateX, photoIndex }) => {
-      if (lastPageX === undefined) {
+    this.setState(({ lastClientX, translateX, photoIndex }) => {
+      if (lastClientX === undefined) {
         return {
           touched: true,
-          lastPageX: pageX,
+          lastClientX: clientX,
           translateX,
         };
       }
-      const offsetPageX = pageX - lastPageX;
+      const offsetClientX = clientX - lastClientX;
       return {
         touched: true,
-        lastPageX: lastPageX,
-        translateX: -(innerWidth + horizontalOffset) * photoIndex + offsetPageX,
+        lastClientX: lastClientX,
+        translateX: -(innerWidth + horizontalOffset) * photoIndex + offsetClientX,
       };
     });
   }
 
-  handleReachUp = (pageX, pageY) => {
+  handleReachUp = (clientX, clientY) => {
     const { innerWidth, innerHeight } = window;
     const { images, onIndexChange, onClose } = this.props;
-    const { lastPageX = pageX, lastPageY = pageY, photoIndex } = this.state;
+    const { lastClientX = clientX, lastClientY = clientY, photoIndex } = this.state;
 
-    const offsetPageX = pageX - lastPageX;
-    const offsetPageY = pageY - lastPageY;
+    const offsetClientX = clientX - lastClientX;
+    const offsetClientY = clientY - lastClientY;
     const singlePageWidth = innerWidth + horizontalOffset;
 
     // 当前偏移
     let currentTranslateX = -singlePageWidth * photoIndex;
     let currentPhotoIndex = photoIndex;
 
-    if (Math.abs(offsetPageY) > innerHeight * 0.14) {
+    if (Math.abs(offsetClientY) > innerHeight * 0.14) {
       onClose();
       // 下一张
-    } else if (offsetPageX < -maxMoveOffset && photoIndex < images.length - 1) {
+    } else if (offsetClientX < -maxMoveOffset && photoIndex < images.length - 1) {
       currentPhotoIndex = photoIndex + 1;
       currentTranslateX = -singlePageWidth * currentPhotoIndex;
       if (onIndexChange) {
         onIndexChange(currentPhotoIndex);
       }
       // 上一张
-    } else if (offsetPageX > maxMoveOffset && photoIndex > 0) {
+    } else if (offsetClientX > maxMoveOffset && photoIndex > 0) {
       currentPhotoIndex = photoIndex - 1;
       currentTranslateX = -singlePageWidth * currentPhotoIndex;
       if (onIndexChange) {
@@ -184,8 +184,8 @@ export default class PhotoSlider extends React.Component<
       touched: false,
       translateX: currentTranslateX,
       photoIndex: currentPhotoIndex,
-      lastPageX: undefined,
-      lastPageY: undefined,
+      lastClientX: undefined,
+      lastClientY: undefined,
       backdropOpacity: defaultOpacity,
       photoScale: 1,
     });

+ 56 - 56
src/PhotoView.tsx

@@ -17,7 +17,7 @@ import {
   scaleBuffer,
 } from './variables';
 
-type ReachFunction = (pageX: number, pageY: number) => void;
+type ReachFunction = (clientX: number, clientY: number) => void;
 
 interface IPhotoViewProps {
   // 图片地址
@@ -62,9 +62,9 @@ const initialState = {
   maskTouched: false,
 
   // 触摸开始时 x 原始坐标
-  pageX: 0,
+  clientX: 0,
   // 触摸开始时 y 原始坐标
-  pageY: 0,
+  clientY: 0,
 
   // 触摸开始时图片 x 偏移量
   lastX: 0,
@@ -117,11 +117,11 @@ export default class PhotoView extends React.Component<
     }
   }
 
-  handleStart = (pageX: number, pageY: number, touchLength: number = 0) => {
+  handleStart = (clientX: number, clientY: number, touchLength: number = 0) => {
     this.setState(prevState => ({
       touched: true,
-      pageX,
-      pageY,
+      clientX,
+      clientY,
       lastX: prevState.x,
       lastY: prevState.y,
       lastTouchLength: touchLength,
@@ -129,15 +129,15 @@ export default class PhotoView extends React.Component<
     }));
   }
 
-  handleMove = (newPageX: number, newPageY: number, touchLength: number = 0) => {
+  handleMove = (newClientX: number, newClientY: number, touchLength: number = 0) => {
     const { touched, maskTouched } = this.state;
     if (touched || maskTouched) {
       const { width, naturalWidth } = this.photoRef.state;
       const {
         x,
         y,
-        pageX,
-        pageY,
+        clientX,
+        clientY,
         lastX,
         lastY,
         scale,
@@ -149,15 +149,15 @@ export default class PhotoView extends React.Component<
       // 边缘状态
       let currentReachState = 0;
       if (touchLength === 0) {
-        currentX = newPageX - pageX + lastX;
-        currentY = newPageY - pageY + lastY;
+        currentX = newClientX - clientX + lastX;
+        currentY = newClientY - clientY + lastY;
         // 边缘触发检测
         currentReachState = this.handleReachCallback(
           currentX,
           currentY,
           scale,
-          newPageX,
-          newPageY,
+          newClientX,
+          newClientY,
           reachState,
         );
       }
@@ -183,8 +183,8 @@ export default class PhotoView extends React.Component<
           ...getPositionOnMoveOrScale({
             x: currentX,
             y: currentY,
-            pageX: newPageX,
-            pageY: newPageY,
+            clientX: newClientX,
+            clientY: newClientY,
             fromScale: scale,
             toScale,
           }),
@@ -195,17 +195,17 @@ export default class PhotoView extends React.Component<
 
   handleDoubleClick = (e) => {
     e.preventDefault();
-    const { pageX, pageY } = e;
+    const { clientX, clientY } = e;
     const { width, naturalWidth } = this.photoRef.state;
     this.setState(({ x, y, scale }) => {
       return {
-        pageX,
-        pageY,
+        clientX,
+        clientY,
         ...getPositionOnMoveOrScale({
           x,
           y,
-          pageX,
-          pageY,
+          clientX,
+          clientY,
           fromScale: scale,
           // 若图片足够大,则放大适应的倍数
           toScale: scale !== 1 ? 1 : Math.max(2, naturalWidth / width),
@@ -217,7 +217,7 @@ export default class PhotoView extends React.Component<
 
   handleWheel = (e) => {
     e.preventDefault();
-    const { pageX, pageY, deltaY } = e;
+    const { clientX, clientY, deltaY } = e;
     const { width, naturalWidth } = this.photoRef.state;
     this.setState(({ x, y, scale }) => {
       const endScale = scale - deltaY / 100 / 2;
@@ -230,13 +230,13 @@ export default class PhotoView extends React.Component<
         minScale,
       );
       return {
-        pageX,
-        pageY,
+        clientX,
+        clientY,
         ...getPositionOnMoveOrScale({
           x,
           y,
-          pageX,
-          pageY,
+          clientX,
+          clientY,
           fromScale: scale,
           toScale,
         }),
@@ -245,11 +245,11 @@ export default class PhotoView extends React.Component<
     });
   }
 
-  handleMaskStart = (pageX: number, pageY: number) => {
+  handleMaskStart = (clientX: number, clientY: number) => {
     this.setState(prevState => ({
       maskTouched: true,
-      pageX,
-      pageY,
+      clientX,
+      clientY,
       lastX: prevState.x,
       lastY: prevState.y,
       touchedTime: Date.now(),
@@ -257,46 +257,46 @@ export default class PhotoView extends React.Component<
   }
 
   handleMaskMouseDown = (e) => {
-    this.handleMaskStart(e.pageX, e.pageY);
+    this.handleMaskStart(e.clientX, e.clientY);
   }
 
   handleMaskTouchStart = (e) => {
-    const { pageX, pageY } = e.touches[0];
-    this.handleMaskStart(pageX, pageY);
+    const { clientX, clientY } = e.touches[0];
+    this.handleMaskStart(clientX, clientY);
   }
 
   handleTouchStart = e => {
     if (e.touches.length >= 2) {
-      const { pageX, pageY, touchLength } = getMultipleTouchPosition(e);
-      this.handleStart(pageX, pageY, touchLength);
+      const { clientX, clientY, touchLength } = getMultipleTouchPosition(e);
+      this.handleStart(clientX, clientY, touchLength);
     } else {
-      const { pageX, pageY } = e.touches[0];
-      this.handleStart(pageX, pageY);
+      const { clientX, clientY } = e.touches[0];
+      this.handleStart(clientX, clientY);
     }
   }
 
   handleMouseDown = e => {
     e.preventDefault();
-    this.handleStart(e.pageX, e.pageY);
+    this.handleStart(e.clientX, e.clientY);
   }
 
   handleTouchMove = e => {
     e.preventDefault();
     if (e.touches.length >= 2) {
-      const { pageX, pageY, touchLength } = getMultipleTouchPosition(e);
-      this.handleMove(pageX, pageY, touchLength);
+      const { clientX, clientY, touchLength } = getMultipleTouchPosition(e);
+      this.handleMove(clientX, clientY, touchLength);
     } else {
-      const { pageX, pageY } = e.touches[0];
-      this.handleMove(pageX, pageY);
+      const { clientX, clientY } = e.touches[0];
+      this.handleMove(clientX, clientY);
     }
   }
 
   handleMouseMove = e => {
     e.preventDefault();
-    this.handleMove(e.pageX, e.pageY);
+    this.handleMove(e.clientX, e.clientY);
   }
 
-  handleUp = (newPageX: number, newPageY: number) => {
+  handleUp = (newClientX: number, newClientY: number) => {
     const { touched, maskTouched } = this.state;
     if (touched || maskTouched) {
       const { onReachUp } = this.props;
@@ -308,13 +308,13 @@ export default class PhotoView extends React.Component<
         lastY,
         scale,
         touchedTime,
-        pageX,
-        pageY,
+        clientX,
+        clientY,
       }) => {
         if (onReachUp) {
-          onReachUp(newPageX, newPageY);
+          onReachUp(newClientX, newClientY);
         }
-        const hasMove = pageX !== newPageX || pageY !== newPageY;
+        const hasMove = clientX !== newClientX || clientY !== newClientY;
         // 缩放弹性效果
         const toScale = Math.max(
           Math.min(
@@ -349,13 +349,13 @@ export default class PhotoView extends React.Component<
   }
 
   handleTouchEnd = (e) => {
-    const { pageX, pageY } = e.changedTouches[0];
-    this.handleUp(pageX, pageY);
+    const { clientX, clientY } = e.changedTouches[0];
+    this.handleUp(clientX, clientY);
   }
 
   handleMouseUp = (e) => {
-    const { pageX, pageY } = e;
-    this.handleUp(pageX, pageY);
+    const { clientX, clientY } = e;
+    this.handleUp(clientX, clientY);
   }
 
   handleResize = () => {
@@ -370,8 +370,8 @@ export default class PhotoView extends React.Component<
     x: number,
     y: number,
     scale: number,
-    newPageX: number,
-    newPageY: number,
+    newClientX: number,
+    newClientY: number,
     reachState: number,
   ): number => {
     const { width, height } = this.photoRef.state;
@@ -392,7 +392,7 @@ export default class PhotoView extends React.Component<
       && reachState === 0
       || reachState === 1)
     ) {
-      onReachLeftMove(newPageX, newPageY);
+      onReachLeftMove(newClientX, newClientY);
       return 1;
     } else if (
       onReachRightMove
@@ -401,7 +401,7 @@ export default class PhotoView extends React.Component<
       && reachState === 0
       || reachState === 1)
     ) {
-      onReachRightMove(newPageX, newPageY);
+      onReachRightMove(newClientX, newClientY);
       return 1;
     } else if (
       onReachTopMove
@@ -410,7 +410,7 @@ export default class PhotoView extends React.Component<
       && reachState === 0
       || reachState === 2)
     ) {
-      onReachTopMove(newPageX, newPageY);
+      onReachTopMove(newClientX, newClientY);
       return 2;
     } else if (
       onReachBottomMove
@@ -419,7 +419,7 @@ export default class PhotoView extends React.Component<
       && reachState === 0
       || reachState === 2)
     ) {
-      onReachBottomMove(newPageX, newPageY);
+      onReachBottomMove(newClientX, newClientY);
       return 2;
     }
     return 0;

+ 7 - 7
src/utils/getMultipleTouchPosition.ts

@@ -6,17 +6,17 @@ import React from 'react';
 const getMultipleTouchPosition = (
   evt: React.TouchEvent,
 ): {
-  pageX: number;
-  pageY: number;
+  clientX: number;
+  clientY: number;
   touchLength: number;
 } => {
-  const { pageX, pageY } = evt.touches[0];
-  const { pageX: nextPageX, pageY: nextPageY } = evt.touches[1];
+  const { clientX, clientY } = evt.touches[0];
+  const { clientX: nextClientX, clientY: nextClientY } = evt.touches[1];
   return {
-    pageX: (pageX + nextPageX) / 2,
-    pageY: (pageY + nextPageY) / 2,
+    clientX: (clientX + nextClientX) / 2,
+    clientY: (clientY + nextClientY) / 2,
     touchLength: Math.sqrt(
-      Math.pow(nextPageX - pageX, 2) + Math.pow(nextPageY - pageY, 2),
+      Math.pow(nextClientX - clientX, 2) + Math.pow(nextClientY - clientY, 2),
     ),
   };
 };

+ 10 - 10
src/utils/getPositionOnMoveOrScale.ts

@@ -4,15 +4,15 @@
 const getPositionOnMoveOrScale = ({
   x,
   y,
-  pageX,
-  pageY,
+  clientX,
+  clientY,
   fromScale,
   toScale,
 }: {
   x: number;
   y: number;
-  pageX: number;
-  pageY: number;
+  clientX: number;
+  clientY: number;
   fromScale: number;
   toScale: number;
 }): {
@@ -21,17 +21,17 @@ const getPositionOnMoveOrScale = ({
   scale: number;
 } => {
   const { innerWidth, innerHeight } = window;
-  const centerPageX = innerWidth / 2;
-  const centerPageY = innerHeight / 2;
+  const centerClientX = innerWidth / 2;
+  const centerClientY = innerHeight / 2;
   // 坐标偏移
-  const lastPositionX = centerPageX + x;
-  const lastPositionY = centerPageY + y;
+  const lastPositionX = centerClientX + x;
+  const lastPositionY = centerClientY + y;
 
   // 放大偏移量
   const offsetScale = toScale / fromScale;
   // 偏移位置
-  const originX = pageX - (pageX - lastPositionX) * offsetScale - centerPageX;
-  const originY = pageY - (pageY - lastPositionY) * offsetScale - centerPageY;
+  const originX = clientX - (clientX - lastPositionX) * offsetScale - centerClientX;
+  const originY = clientY - (clientY - lastPositionY) * offsetScale - centerClientY;
   return {
     x: originX,
     y: originY,