From 3b1ea530d4e6c508f0bab4e095d5eb374d0f0177 Mon Sep 17 00:00:00 2001 From: liulirui Date: Sat, 17 Jun 2023 23:29:48 +0800 Subject: [PATCH] feat: #18 add maxScale & doubleTapScale props for ImageViewer --- README.md | 18 ++++++++++-------- src/components/imageViewer.tsx | 18 +++++++++++------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 0c23747..b02772e 100644 --- a/README.md +++ b/README.md @@ -71,14 +71,16 @@ You need to wrap your image components used by ImageWrapper in this package. ## Props ### ImageViewer -| name | required | type | default | description | Example | -|------------------------|----------|------------------------------------------------------------------------------------------|------------|-------------------------------------------------------------------------|-------------------------------------------------------------------------| -| data | true | ```{key: string; source: ImageURISource}[]``` | undefined | The original source & key of image | ```[{key: 'image-1', source: {uri:'http://***.***/***.png'}}]``` | -| renderCustomComponent | false | ```(_: {item: {key: string; source: ImageURISource}; index: number;}) => ReactElement``` | undefined | The custom Element in ImageViewer | ```({index}) => current index is {index}``` | -| onLongPress | false | ```(_: {item: {key: string; source: ImageURISource}; index: number;}) => void``` | undefined | Once you pressed image viewer for a long time, the function will active | ```({index}) => console.log(`${index} pressed long`)``` | -| imageResizeMode | false | ```ImageResizeMode``` | undefined | The resizeMode props of image in viewer | ```"contain"``` | -| onChange | false | ```(currentIndex: number) => void``` | undefined | When the viewer finished swiping, the function will be called | ```(currentIndex) => console.log(`current index is ${currentIndex}`)``` | -| dragUpToCloseEnabled | false | ```boolean``` | undefined | Enable dragging up to close the viewer | ```true``` | +| name | required | type | default | description | Example | +|-----------------------|----------|------------------------------------------------------------------------------------------|-----------|-------------------------------------------------------------------------|-------------------------------------------------------------------------| +| data | true | ```{key: string; source: ImageURISource}[]``` | undefined | The original source & key of image | ```[{key: 'image-1', source: {uri:'http://***.***/***.png'}}]``` | +| renderCustomComponent | false | ```(_: {item: {key: string; source: ImageURISource}; index: number;}) => ReactElement``` | undefined | The custom Element in ImageViewer | ```({index}) => current index is {index}``` | +| onLongPress | false | ```(_: {item: {key: string; source: ImageURISource}; index: number;}) => void``` | undefined | Once you pressed image viewer for a long time, the function will active | ```({index}) => console.log(`${index} pressed long`)``` | +| imageResizeMode | false | ```ImageResizeMode``` | undefined | The resizeMode props of image in viewer | ```"contain"``` | +| onChange | false | ```(currentIndex: number) => void``` | undefined | When the viewer finished swiping, the function will be called | ```(currentIndex) => console.log(`current index is ${currentIndex}`)``` | +| dragUpToCloseEnabled | false | ```boolean``` | undefined | Enable dragging up to close the viewer | ```true``` | +| maxScale | false | ```number``` | 3 | Image maximum magnification | ```3``` | +| doubleTapScale | false | ```number``` | 2 | The magnification when double-clicking the image | ```2``` | ### ImageWrapper | name | required | type | default | description | Example | |-----------|----------|----------------------------------------|-----------|---------------------------------------------------------------------------------------------------|----------------------------------------------------------| diff --git a/src/components/imageViewer.tsx b/src/components/imageViewer.tsx index a38d5d4..66546b5 100644 --- a/src/components/imageViewer.tsx +++ b/src/components/imageViewer.tsx @@ -50,6 +50,8 @@ export type ImageViewerProps = { imageResizeMode?: ImageResizeMode; onChange?: (currentIndex: number) => void; dragUpToCloseEnabled?: boolean; + maxScale?: number; + doubleTapScale?: number; }; type LayoutData = { width: number; height: number; pageX: number; pageY: number }; export type ImageViewerRef = { @@ -87,6 +89,8 @@ const ImageViewer = forwardRef((props, ref) => imageResizeMode, onChange, dragUpToCloseEnabled, + maxScale = 3, + doubleTapScale = 2, } = props; const imageItemRef = useRef[]>([]); const imageMemoSizeRef = useRef>({}); @@ -564,17 +568,17 @@ const ImageViewer = forwardRef((props, ref) => if (imageScale.value !== 1) { resetScale(); } else { - imageScale.value = withTiming(3); - savedImageScale.value = 3; - const currentX = (screenDimensions.width / 2 - event.x) * 3; + imageScale.value = withTiming(doubleTapScale); + savedImageScale.value = doubleTapScale; + const currentX = (screenDimensions.width / 2 - event.x) * doubleTapScale; imageX.value = withTiming(currentX); savedImageX.value = currentX; - const currentY = (screenDimensions.height / 2 - event.y) * 3; + const currentY = (screenDimensions.height / 2 - event.y) * doubleTapScale; imageY.value = withTiming(currentY); savedImageY.value = currentY; } }), - [resetScale, imageScale], + [resetScale, imageScale, doubleTapScale], ); const imageTapGesture = useMemo( () => Gesture.Exclusive(imageDoubleTapGesture, imageSingleTapGesture), @@ -599,7 +603,7 @@ const ImageViewer = forwardRef((props, ref) => savedImageY.value * event.scale; }) .onEnd(() => { - const currentScale = Math.max(1, imageScale.value); + const currentScale = Math.min(Math.max(1, imageScale.value), maxScale); if (currentScale === 1) { resetScale(); } else { @@ -609,7 +613,7 @@ const ImageViewer = forwardRef((props, ref) => savedImageX.value = imageX.value; } }), - [imageScale, savedImageScale, imageX, imageY, savedImageY, savedImageX, resetScale], + [imageScale, savedImageScale, imageX, imageY, savedImageY, savedImageX, resetScale, maxScale], ); const imageLongPressGesture = useMemo( () =>