From d74a497618fa623bbd94f80363dfdf2de5175585 Mon Sep 17 00:00:00 2001 From: Anton Kalinin Date: Wed, 1 Jan 2020 21:58:45 +0100 Subject: [PATCH] Add option to disable double tap to zoom on Android --- README.md | 23 ++++++++++++----------- src/ImageItem/ImageItem.android.tsx | 7 +++++-- src/ImageItem/ImageItem.d.ts | 1 + src/ImageViewing.tsx | 3 +++ src/hooks/useZoomPanResponder.ts | 8 +++++--- 5 files changed, 26 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 004272c..3a5efce 100644 --- a/README.md +++ b/README.md @@ -59,17 +59,18 @@ const [visible, setIsVisible] = useState(false); ## Props -| Prop name | Description | Type | Required | -| --------------------- | ----------------------------------------------------- | ----------------------- | -------- | -| `images` | Array of images to display | ImageSource[] | true | -| `imageIndex` | Current index of image to display | number | true | -| `visible` | Is modal shown or not | boolean | true | -| `onRequestClose` | Function called to close the modal | function | true | -| `animationType` | Animation modal presented with: default `fade` | `none`, `fade`, `slide` | false | -| `backgroundColor` | Background color of the modal in HEX (#000000EE) | string | false | -| `swipeToCloseEnabled` | Close modal with swipe up or down: default `true` | boolean | false | -| `HeaderComponent` | Header component, gets current `imageIndex` as a prop | component, function | false | -| `FooterComponent` | Footer component, gets current `imageIndex` as a prop | component, function | false | +| Prop name | Description | Type | Required | +| ------------------------ | ------------------------------------------------------------- | ----------------------- | -------- | +| `images` | Array of images to display | ImageSource[] | true | +| `imageIndex` | Current index of image to display | number | true | +| `visible` | Is modal shown or not | boolean | true | +| `onRequestClose` | Function called to close the modal | function | true | +| `animationType` | Animation modal presented with: default `fade` | `none`, `fade`, `slide` | false | +| `backgroundColor` | Background color of the modal in HEX (#000000EE) | string | false | +| `swipeToCloseEnabled` | Close modal with swipe up or down: default `true` | boolean | false | +| `doubleTapToZoomEnabled` | Zoom image by double tap on it (Android only): default `true` | boolean | false | +| `HeaderComponent` | Header component, gets current `imageIndex` as a prop | component, function | false | +| `FooterComponent` | Footer component, gets current `imageIndex` as a prop | component, function | false | - ImageSource is an object like { uri: '' } diff --git a/src/ImageItem/ImageItem.android.tsx b/src/ImageItem/ImageItem.android.tsx index 3ee0913..0620e81 100644 --- a/src/ImageItem/ImageItem.android.tsx +++ b/src/ImageItem/ImageItem.android.tsx @@ -34,13 +34,15 @@ type Props = { onRequestClose: () => void; onZoom: (isZoomed: boolean) => void; swipeToCloseEnabled?: boolean; + doubleTapToZoomEnabled?: boolean; }; const ImageItem = ({ imageSrc, onZoom, onRequestClose, - swipeToCloseEnabled = true + swipeToCloseEnabled = true, + doubleTapToZoomEnabled = true }: Props) => { const imageContainer = React.createRef(); const imageDimensions = useImageDimensions(imageSrc); @@ -62,7 +64,8 @@ const ImageItem = ({ const [panHandlers, scaleValue, translateValue] = useZoomPanResponder({ initialScale: scale || 1, initialTranslate: translate || { x: 0, y: 0 }, - onZoom: onZoomPerformed + onZoom: onZoomPerformed, + doubleTapToZoomEnabled }); const imagesStyles = getImageStyles( diff --git a/src/ImageItem/ImageItem.d.ts b/src/ImageItem/ImageItem.d.ts index 6cf7b0f..974d4a3 100644 --- a/src/ImageItem/ImageItem.d.ts +++ b/src/ImageItem/ImageItem.d.ts @@ -14,6 +14,7 @@ declare type Props = { onRequestClose: () => void; onZoom: (isZoomed: boolean) => void; swipeToCloseEnabled?: boolean; + doubleTapToZoomEnabled?: boolean; }; declare const _default: React.MemoExoticComponent<({ diff --git a/src/ImageViewing.tsx b/src/ImageViewing.tsx index d866b14..d976a1c 100644 --- a/src/ImageViewing.tsx +++ b/src/ImageViewing.tsx @@ -32,6 +32,7 @@ type Props = { animationType?: "none" | "fade" | "slide"; backgroundColor?: string; swipeToCloseEnabled?: boolean; + doubleTapToZoomEnabled?: boolean; HeaderComponent?: ComponentType<{ imageIndex: number }>; FooterComponent?: ComponentType<{ imageIndex: number }>; }; @@ -49,6 +50,7 @@ function ImageViewing({ animationType = DEFAULT_ANIMATION_TYPE, backgroundColor = DEFAULT_BG_COLOR, swipeToCloseEnabled, + doubleTapToZoomEnabled, HeaderComponent, FooterComponent }: Props) { @@ -112,6 +114,7 @@ function ImageViewing({ imageSrc={imageSrc} onRequestClose={onRequestCloseEnhanced} swipeToCloseEnabled={swipeToCloseEnabled} + doubleTapToZoomEnabled={doubleTapToZoomEnabled} /> )} onMomentumScrollEnd={onScroll} diff --git a/src/hooks/useZoomPanResponder.ts b/src/hooks/useZoomPanResponder.ts index 5e64266..80d1b88 100644 --- a/src/hooks/useZoomPanResponder.ts +++ b/src/hooks/useZoomPanResponder.ts @@ -36,12 +36,14 @@ type Props = { initialScale: number; initialTranslate: Position; onZoom: (isZoomed: boolean) => void; + doubleTapToZoomEnabled: boolean; }; const useZoomPanResponder = ({ initialScale, initialTranslate, - onZoom + onZoom, + doubleTapToZoomEnabled }: Props): Readonly<[ GestureResponderHandlers, Animated.Value, @@ -129,7 +131,7 @@ const useZoomPanResponder = ({ lastTapTS && tapTS - lastTapTS < DOUBLE_TAP_DELAY ); - if (isDoubleTapPerformed) { + if (doubleTapToZoomEnabled && isDoubleTapPerformed) { const isScaled = currentTranslate.x !== initialTranslate.x; // currentScale !== initialScale; const { pageX: touchX, pageY: touchY } = event.nativeEvent.touches[0]; const targetScale = SCALE_MAX; @@ -184,7 +186,7 @@ const useZoomPanResponder = ({ gestureState: PanResponderGestureState ) => { // Don't need to handle move because double tap in progress (was handled in onStart) - if (isDoubleTapPerformed) return; + if (doubleTapToZoomEnabled && isDoubleTapPerformed) return; if ( numberInitialTouches === 1 &&