Code Monkey home page Code Monkey logo

react-native-image-zoom's People

Contributors

demedos avatar likashefqet avatar ubugnu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

react-native-image-zoom's Issues

Loading indicator "flashes" up when an image has already been loaded

Describe the bug
The loading indicator renders always, causing it to flash and disappear quickly when an image has already been downloaded because const [isLoading, setIsLoading] = useState(true); is set to true on mount and immediately set to false in onLoadEnd.

To Reproduce
Steps to reproduce the behavior:

  1. Render the ImageZoom component
  2. Unmount it and then re-render it
  3. The loading spinner will quickly flash, even though the image is resolved immediately.

Expected behavior
I'd expect the loader to not show at all as the image has been already loaded once.

Smartphone (please complete the following information):

  • iOS iPhone 13

Additional context

Something like this seems to work. Whilst just an idea, maybe there are other better ways to determine whether the loading state should be initially set to true instead of just on mount?

  const [isLoading, setIsLoading] = useState<boolean | undefined>(undefined);
  ...
  const onImageLoadStart = () => {
    // Defer setting the loading state to true slightly to give
    // onLoadEnd time to set the state to false if it already loaded.
    setTimeout(() => {
      setIsLoading((prev) => {
        // If not yet set to a value, we know for sure
        // the image has not loaded, so set loading
        // state to true.
        if (prev === undefined) {
          return true
        }
        return prev
      });
    }, 0)
  };
  ...
  <AnimatedImage onLoadStart={onImageLoadStart} />

Get the current scale/zoom level?

Is there a good way to be able to read the current scale whenever I need to? I don't see it on the ref, and I do see that there's a scale = useSharedValue() in the instance but can't find a way to get at it. I have a few places where I would like to be able to read out the current scale (and probably the x and y offsets), so I can save them for later.

I have a PR in for adding the scale to the onPinchEnd callback as a potential fix for one of my specific issues, but putting this note in in case there's a good way to accomplish this now that I'm missing.

Support for expo-image or other components

Is your feature request related to a problem? Please describe.
expo-image is beginning to take over <Image/> component from react native.

Describe the solution you'd like
Instead of making a new exported component maybe we could implement a createZoomComponent, which would make any kind of component zoomable, with your current implementation.

Then you could go:

import { createZoomComponent } from 'react-native-image-zoom'
import { Image }Β from 'expo-image'

const ZoomableImage = createZoomComponent(Image)

const MyComponent = () => {
    return <ZoomableImage 
         // ...expo-image props here
    />
}

Describe alternatives you've considered
Another way would be to implement a <ZoomableView>{children}</ZoomableView> kind of component that could just make any child component zoomable.

onSnapBackEnd / onResetEnd

Is your feature request related to a problem? Please describe.
I am conditionally displaying elements over the image component: they disappear as soon as there is zoom-interaction and reappear after. But currently they already appear once the finger-interaction ends and it would look much better if they would only reappear once the image is fully reset to its initial position.

Describe the solution you'd like
The same callback as all the other on...End functions but called once the image is fully reset to its initial position.

This little add-on would be amazing and much appreciated if its not too much effort as it would greatly improve the UX

Request to support ImageBackground and doubleTap feature

I need to display multiple images overlayed onto a base image. I would like to be able to zoom in and out on the group of images as a whole.

Maybe pass in the base image via uri or source like usual. Then, perhaps pass in an array of Animate.Image components as children.

So ImageZoom.tsx might look like this:

const AnimatedImageBackground = Animated.createAnimatedComponent(ImageBackground)
return (
    <GestureDetector gesture={gestures}>
      <Animated.View onLayout={onImageLayout}>
        <AnimatedImageBackground 
          style={[styles.image, style, animatedStyle]}
          source={{ uri }}
          resizeMode="contain"
          {...props}
        >
          {children}
        </AnimatedImageBackground> 
      </Animated.View>
    </GestureDetector>
);

And then the usage might look like this:

const overlayImages = images.map((image, index) => {
   return <Animated.Image resizeMode='contain' source={image} style={{ position: 'absolute'}} />
})

return (    
  <GestureHandlerRootView>
        <ImageZoom
          style={S.baseImageStyle}
          source={baseImage}
          isDoubleTapEnabled={true}>
             {overlayImages}
        </ImageZoom>
  </GestureHandlerRootView>
)

Feature Request: Implement 'Snap Back' prop for Zoom Functionality

Is your feature request related to a problem? Please describe.
When using the zoom feature, it automatically zooms back out after zooming in, which can be frustrating when wanting to focus on a specific area for a longer duration.

Describe the solution you'd like
Introduce a "snap back" property that retains the zoom level even after zooming in, ensuring that the view remains at the zoomed-in level until intentionally zoomed out by the user. The default setting for this property should be 'true'.

Describe alternatives you've considered
One alternative solution might be implementing a toggle button that allows users to manually lock the zoom level once they've zoomed in, preventing the automatic zoom-out behavior. However, the proposed "snap back" property would offer a more seamless and user-friendly experience.

Additional context
This feature is especially beneficial for tasks that involve detailed examination or precise adjustments in a particular area. It improves user control and enhances the user experience when focusing on specific elements without constant readjustment due to automatic zoom-out behavior.

Is it possible to disable "Reset zoom and snap back to initial position on gesture end"

The title pretty much sums my question/feature request. How can I remove resetting the zoom/pan state when any of the gesture end? I want to be able to continue zooming until maxZoom is reached. I tried removing the code in onFinish, but with no success.

Also, I am interested in using this zoom functionality with other <View>s besides <Image>, would you be open to a PR with such functionality?


Edit: I am able to preserve last zoomed value, but not position by introducing a new:

const lastScale = useSharedValue(1);

//...
const pinchHandler = useAnimatedGestureHandler({
  //...
  onActive: event => {
  //...
  scale.value = clamp(event.scale * lastScale.value, minScale, maxScale);
  //...
  },
  
  onFinish: () => {
  //...
  lastScale.value = scale.value;
  //...
  }
})

in modal is not working

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context
Add any other context about the problem here.

ExceptionsManager.js:184 TypeError: (0 , _reactNativeReanimated.useSharedValue) is not a function

Describe the bug
When trying to use this plugin I get the following error:
ExceptionsManager.js:184 TypeError: (0 , _reactNativeReanimated.useSharedValue) is not a function

I assume this plugin requires a specific minimum version of react maybe? would be good to specify in the readme

To Reproduce
Install the plugin, run the example

Expected behavior
It shoould work

Smartphone (please complete the following information):

  • Device: iPhone 13 Pro
  • React Native 0.66.5

Nothing is rendering on android

Describe the bug
Upgrading from v1* to v2* makes all the content vanish, when used as a tag renderer for React native render html

To Reproduce
When used as a custom image tag renderer, the component is working with version 1.2.1 but displays nothing in version 2.0.
It is integrated into React native render html as follows:

....
        img: (args) => {
            const attrs = args.tnode?.init?.domNode?.attribs;
            return ( //todo try with InternalRenderer or TDefaultRenderer
                <RenderHTMLImage
                    uri={attrs.src}
                    // onPress={(uri) => {
                    //     options.dispatch(setLightbox(attrs.src))
                    // }}
                    imagesMaxWidth={args.sharedProps?.computeEmbeddedMaxWidth(Math.min(deviceWidth - 30, Number.parseInt(attrs.width)), "img")}
                />
            )
        },

....
    const RenderHTMLImage = ({ uri, onPress, imagesMaxWidth }) => {
        const [ imageSize, setImageSize ] = useState({})

        useEffect(() => {
            Image.getSize(uri, (width, height) => {
                setImageSize({
                    width,
                    height,
                    aspectRatio: Number((width / height).toFixed(2)),
                })
            })
        }, [])

        return (
            <View
                style={{
                    width: imageSize.width > imagesMaxWidth
                        ? imagesMaxWidth
                        : imageSize.width,
                }}
            >
                <ImageZoom uri={uri}
                           //containerStyle={}
                           imageContainerStyle={{
                        width: imageSize.width > imagesMaxWidth
                            ? imagesMaxWidth
                            : imageSize.width,
                        aspectRatio: imageSize.aspectRatio,
                        resizeMode: 'contain',
                    }}/>
            </View>
        )
    }
....

    return <RenderHTML
            computeEmbeddedMaxWidth={(contentWidth, tagName) => {
                return contentWidth - rightOffset;
            }}
            ignoredStyles={['display', 'width', 'height', 'padding']}
            enableExperimentalMarginCollapsing
            renderers={renderers}
            ...
   
            renderersProps={{
                img: {
                    enableExperimentalPercentWidth: false,
                },
               ...
            }}
        />;

Downgrading helps, but then with react native 72 the app crashes when scrolling.

Expected behavior
The image is shown and rendering.

Desktop (please complete the following information):

  • OS: Windows (building for android)
  • Browser: chrome
  • Version: 116.0.5845.141

Smartphone (please complete the following information):

  • Device: xiaomi redmi note 10s
  • OS: android 13 (miui14.0.2)
  • Browser: chrome
  • Version: 116.0.5845.141

Additional context

{
  npm: '8.11.0',
  node: '16.16.0',
  v8: '9.4.146.24-node.21',
  uv: '1.43.0',
  zlib: '1.2.11',
  brotli: '1.0.9',
  ares: '1.18.1',
  modules: '93',
  nghttp2: '1.47.0',
  napi: '8',
  llhttp: '6.0.7',
  openssl: '1.1.1q+quic',
  cldr: '40.0',
  icu: '70.1',
  tz: '2021a3',
  unicode: '14.0',
  ngtcp2: '0.1.0-DEV',
  nghttp3: '0.1.0-DEV'
}

and


"@likashefqet/react-native-image-zoom": "^2.1.0",
"react-native": "0.72.4",
"react-native-render-html": "^6.3.4",

Not working on android :<

Describe the bug
Module works great on iOS but I can't get it working on Android :(

To Reproduce
Steps to reproduce the behavior:
Create a component like that:
<ImageZoom resizeMode="contain" minScale={1} maxScale={3} uri={source.uri}/>

and try to pinch on android, nothing happens.

Expected behavior
Properly zooms on android

Screenshots
Can't show it as it's directly connected to pinch

Desktop (please complete the following information):
N/A

Smartphone (please complete the following information):

  • Device: OnePlus Nord
  • OS: Oxygen OS 11.1.11.11.AC01BA
  • Browser - react native app
  • Version [e.g. 22]

Additional context
My package JSON
"dependencies": {
"@expo/config-plugins": "^6.0.1",
"@expo/webpack-config": "^18.0.1",
"@gorhom/bottom-sheet": "^4.4.5",
"@invertase/react-native-apple-authentication": "^2.2.2",
"@likashefqet/react-native-image-zoom": "^1.3.0",
"@react-native-community/netinfo": "9.3.7",
"@react-native-firebase/app": "^17.5.0",
"@react-native-firebase/auth": "^17.5.0",
"@react-native-firebase/database": "^17.5.0",
"@react-native-firebase/firestore": "^17.5.0",
"@react-native-firebase/storage": "^17.5.0",
"@react-navigation/bottom-tabs": "^6.5.5",
"@react-navigation/native": "^6.1.4",
"@react-navigation/stack": "^6.3.16",
"@rneui/base": "^4.0.0-rc.7",
"@rneui/themed": "^4.0.0-rc.7",
"@types/react": "~18.0.27",
"@types/react-native": "~0.70.6",
"@types/react-native-snap-carousel": "^3.8.5",
"base-64": "^1.0.0",
"buffer": "^6.0.3",
"expo": "~48.0.15",
"expo-application": "~5.1.1",
"expo-auth-session": "~4.0.3",
"expo-build-properties": "~0.6.0",
"expo-clipboard": "~4.1.2",
"expo-dev-client": "~2.2.1",
"expo-image-manipulator": "~11.1.1",
"expo-image-picker": "~14.1.1",
"expo-linear-gradient": "~12.1.2",
"expo-random": "~13.1.1",
"expo-secure-store": "~12.1.1",
"expo-splash-screen": "~0.18.2",
"expo-status-bar": "~1.4.4",
"expo-system-ui": "~2.2.1",
"expo-updates": "~0.16.4",
"expo-web-browser": "~12.1.1",
"lodash": "^4.17.21",
"lottie-react-native": "5.1.4",
"md5": "^2.3.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-native": "0.71.7",
"react-native-chart-kit": "^6.12.0",
"react-native-dotenv": "^3.4.7",
"react-native-dropdown-picker": "^5.4.4",
"react-native-gesture-handler": "~2.9.0",
"react-native-google-mobile-ads": "^9.1.1",
"react-native-image-marker": "^0.6.3",
"react-native-keyboard-aware-scroll-view": "^0.9.5",
"react-native-purchases": "^5.13.1",
"react-native-reanimated": "~2.14.4",
"react-native-render-html": "^6.3.4",
"react-native-root-toast": "^3.4.1",
"react-native-safe-area-context": "4.5.0",
"react-native-screens": "~3.20.0",
"react-native-share": "^8.2.1",
"react-native-snap-carousel": "^4.0.0-beta.6",
"react-native-sse": "^1.1.0",
"react-native-svg": "13.4.0",
"react-native-url-polyfill": "^1.3.0",
"react-native-web": "~0.18.11",
"typescript": "^4.9.4",
"zustand": "^4.3.6"
},
"devDependencies": {
"@babel/core": "^7.20.0"
}
`

Android - Failed to pinch to zoom when ImageZoom is in a Scrollview

Hello,

I've create a Carousel component who use ImageZoom lib.
All my images are in an horizontal ScrollView.
I've add GestureHandlerRootView before ImageZoom component. Now i can pinch but only vertical. In another direction, it try to swipe.

CleanShot 2022-12-11 at 19 07 55

I don't have this issue on iOS.

Do you have some ideas to resolve this issue ?

return (
        <View style={[styles.container, style]} {...rest}>
            <ScrollView
                pagingEnabled
                horizontal
                decelerationRate="fast"
                scrollEventThrottle={0}
                showsHorizontalScrollIndicator={false}
                onScroll={({ nativeEvent }) => {
                    const layoutWidth = nativeEvent.layoutMeasurement.width;
                    const offset = nativeEvent.contentOffset.x;
                    const currentIndex = Math.ceil(offset / layoutWidth);
                    setIndex(currentIndex);
                }}
            >
                {
                    /* Checking if the slides array is not empty. If it is not empty, it will return the
                    slides array. If it is empty, it will return null. */
                    slides.length > 0
                        ? slides.map((item, key) => {
                            return (
                                <GestureHandlerRootView key={key}>
                                    <ImageZoom
                                        key={key}
                                        /* Checking if the image is horizontal or vertical. If it is
                                        horizontal, it will cover the screen. If it is vertical, it will
                                        contain the image. */
                                        resizeMode={
                                            imagesInfos[
                                                imagesInfos?.findIndex(
                                                    (image) => image.uri === item
                                                )
                                            ]?.orientation == 'horizontal'
                                                ? 'cover'
                                                : 'contain'
                                        }
                                        source={
                                            typeof item === 'string'
                                                ? { uri: item }
                                                : item
                                        }
                                        style={[
                                            { width: screenWidth, flexGrow: 1 },
                                        ]}
                                    />
                                </GestureHandlerRootView>
                            );
                          })
                        : null
                }
                {
                    /* Cloning the children and adding the width of the screen to the style. */
                    React.Children.map(children, (child) => {
                        const s = child?.props?.style || {};
                        return (
                            <View style={{ width: screenWidth }}>
                                {React.cloneElement(child, {
                                    style: { ...s, width: screenWidth },
                                })}
                            </View>
                        );
                    })
                }
            </ScrollView>
            <Pager color={dotColor} index={index} length={itemsLength} />
        </View>
    );

ResizeMode for Image

Is your feature request related to a problem? Please describe.
Currently there is no option for the resizeMode of the underlaying image component. So in my case if i make a shared element transition from an image element to the ZoomImage the resizeMode changes and therefor the look of the image.

Describe the solution you'd like
Add the prop resizeMode to set the Image resizeMode.

Not Working on android

Describe the bug
I have already integrated the reanimated and gesture handler and both are working on android. But on android its showing the image but its not reacting to the gesture on the image for example pinch to zoom although everything is working fine on ios.

<ImageZoom uri={imagePath} />

Type declarations.ts

I'm using Typescript for my React Native project and after isntall the package I got this warning:

Cannot find module '@likashefqet/react-native-image-zoom' or its corresponding type declarations.ts

Moving the image around requires two fingers when used with react-native-snap-carousel

To move the image around the screen, is required to use two fingers simultaneously, as if the user would be panning, but not actually resizing the image. This problem happens in both android and iOS. Ideally, the user will use only one finger to move the image around.

A quick search in the RN documentation didnt brought anything about multiple touches inside a flatlist.

Android: Pinch gesture moves picture to the top-left corner

Describe the bug
When I do pinch gesture then a picture moves to the top left corner direction. The most annoying is pinching in the bottom right area. See the gif below...

My code:

<ImageZoom uri={uri} />

To Reproduce
Steps to reproduce the behavior:

  1. Pinch somewhere in the bottom right area
  2. See how it's moves to the top-left corner

Expected behavior
Pinching should act symmetrical in every area of the picture

Screenshots
ScreenRecorder_20220801-111219

Can it work with Lottie?

Hi thanks for the great work! Just to check can this component work with Lottie as loader?

renderLoader={() => }
doesn't seems to work?

renderLoader is not implemented as stated in the readme.

Describe the bug
renderLoader is not implemented as stated in the readme.

To Reproduce
Steps to reproduce the behavior:

<ImageZoom
  uri={image}
  renderLoader={() => <LoaderScreen loaderColor={Colors.primary} />

Expected behavior
renderLoader should be implemented.

Screenshots
If applicable, add screenshots to help explain your problem.
Screenshot 2023-08-10 at 09 45 22

Additional context
Related to this commit 8f76051

Setting state drops the pinch on android when using onInteraction function

Describe the bug
Hi,
Your library is great and smooth. I am having one problem, on android I want to do dispatch action on pinch start and dispatch action on pinch end, which is creating issue of dropping pinch.
Below are the code sample:

  const onInteractionStart = () => {
    if (isIOS()) {
      dispatch(isImageZoomedAction(true));
    }
    progress.stopAnimation(() =>
      Animated.timing(fadeAnim, {
        toValue: 0,
        duration: 100,
        useNativeDriver: true,
      }).start(),
    );
  };

  const onInteractionEnd = () => {
    if (isIOS()) {
      dispatch(isImageZoomedAction(false));
    }

    Animated.timing(fadeAnim, {
      toValue: 1,
      duration: 100,
      useNativeDriver: true,
    }).start(() => {
      startAnimation();
    });
  };
  
            <ImageZoomPan
            uri={content[current].image}
            activityIndicatorProps={{
              color: COLOR_SECONDARY,
            }}
            onInteractionStart={onInteractionStart}
            onInteractionEnd={onInteractionEnd}
            minScale={0.5}
            onLoadEnd={() => start()}
            resizeMode={isFullScreen ? 'cover' : 'center'}
          />

onPress handler event using Gesture.Exclusive

Hi! πŸ‘‹ @likashefqet
Firstly, thanks for your work on this project! πŸ™‚

Today I used patch-package to patch @likashefqet/[email protected] for the project I'm working on.

**getting an event for a simple onPress as requested on issue #36 **

<ImageZoom
  uri={imageUri}
  minScale={0.5}
  maxScale={3}
  onInteractionStart={() => console.log('Interaction started')}
  onInteractionEnd={() => console.log('Interaction ended')}
  onPinchStart={() => console.log('Pinch gesture started')}
  onPinchEnd={() => console.log('Pinch gesture ended')}
  onPanStart={() => console.log('Pan gesture started')}
  onPanEnd={() => console.log('Pan gesture ended')}
  onResetAnimationEnd={() => console.log('Reset animation ended')}
  onPress={(event) => {console.log("event", event)}}
  resizeMode="cover"
/>

how i solved it

i passed the doubleTapGesture and onetapGesture to an ExclusiveGesture
Here is the diff that solved my problem:

diff --git a/node_modules/@likashefqet/react-native-image-zoom/lib/typescript/ImageZoom.d.ts b/node_modules/@likashefqet/react-native-image-zoom/lib/typescript/ImageZoom.d.ts
index f33d200..3a764ed 100644
--- a/node_modules/@likashefqet/react-native-image-zoom/lib/typescript/ImageZoom.d.ts
+++ b/node_modules/@likashefqet/react-native-image-zoom/lib/typescript/ImageZoom.d.ts
@@ -15,6 +15,8 @@ declare const _default: React.ForwardRefExoticComponent<Omit<import("react-nativ
     onPinchEnd?: Function | undefined;
     onPanStart?: Function | undefined;
     onPanEnd?: Function | undefined;
+    onPress?: Function | undefined;
+    ExclusiveTapGestures?: never[] | undefined;
     source?: import("react-native").ImageSourcePropType | undefined;
 } & React.RefAttributes<unknown>>;
 export default _default;
diff --git a/node_modules/@likashefqet/react-native-image-zoom/src/ImageZoom.tsx b/node_modules/@likashefqet/react-native-image-zoom/src/ImageZoom.tsx
index 08ae41f..f3b626e 100644
--- a/node_modules/@likashefqet/react-native-image-zoom/src/ImageZoom.tsx
+++ b/node_modules/@likashefqet/react-native-image-zoom/src/ImageZoom.tsx
@@ -31,6 +31,7 @@ export default forwardRef(function ImageZoom(
     onPinchEnd,
     onPanStart,
     onPanEnd,
+    onPress,
     onLayout,
     style = {},
     ...props
@@ -56,6 +57,7 @@ export default forwardRef(function ImageZoom(
     onPinchEnd,
     onPanStart,
     onPanEnd,
+    onPress,
   });
 
   useImperativeHandle(
diff --git a/node_modules/@likashefqet/react-native-image-zoom/src/hooks/useGestures.ts b/node_modules/@likashefqet/react-native-image-zoom/src/hooks/useGestures.ts
index f41c61c..98f200e 100644
--- a/node_modules/@likashefqet/react-native-image-zoom/src/hooks/useGestures.ts
+++ b/node_modules/@likashefqet/react-native-image-zoom/src/hooks/useGestures.ts
@@ -36,7 +36,8 @@ export const useGestures = ({
   onPinchEnd,
   onPanStart,
   onPanEnd,
-}: ImageZoomUseGesturesProps) => {
+  onPress,
+}: ImageZoomUseGesturesProps ) => {
   const isInteracting = useRef(false);
   const isPanning = useRef(false);
   const isPinching = useRef(false);
@@ -131,6 +132,8 @@ export const useGestures = ({
     }
   };
 
+
+
   const onPinchStarted = () => {
     onInteractionStarted();
     isPinching.current = true;
@@ -149,12 +152,17 @@ export const useGestures = ({
     onPanStart?.();
   };
 
+  const onPressed = (e) => {
+    onPress?.(e);
+  }
+
   const onPanEnded = () => {
     isPanning.current = false;
     onPanEnd?.();
     onInteractionEnded();
   };
 
+
   const panGesture = Gesture.Pan()
     .enabled(isPanEnabled)
     .minPointers(minPanPointers)
@@ -172,6 +180,8 @@ export const useGestures = ({
       runOnJS(onPanEnded)();
     });
 
+   
+
   const pinchGesture = Gesture.Pinch()
     .enabled(isPinchEnabled)
     .onStart(
@@ -220,6 +230,17 @@ export const useGestures = ({
       }
     );
 
+
+    const onetapGesture = Gesture.Tap()
+    .numberOfTaps(1)
+    .maxDuration(250)
+    .onStart(
+      (event: GestureStateChangeEvent<TapGestureHandlerEventPayload>)=>{
+        runOnJS(onPressed)(event);
+      }
+    )
+
+    
   const animatedStyle = useAnimatedStyle(() => ({
     transform: [
       { translateX: translate.x.value },
@@ -231,8 +252,9 @@ export const useGestures = ({
   }));
 
   const simultaneousGestures = Gesture.Simultaneous(pinchGesture, panGesture);
+  const tapGesture = Gesture.Exclusive(doubleTapGesture, onetapGesture);
   const gestures = isDoubleTapEnabled
-    ? Gesture.Race(doubleTapGesture, simultaneousGestures)
+    ? Gesture.Race(tapGesture, simultaneousGestures)
     : simultaneousGestures;
 
   return { gestures, animatedStyle, reset };
diff --git a/node_modules/@likashefqet/react-native-image-zoom/src/types.ts b/node_modules/@likashefqet/react-native-image-zoom/src/types.ts
index 62dd3ce..e898024 100644
--- a/node_modules/@likashefqet/react-native-image-zoom/src/types.ts
+++ b/node_modules/@likashefqet/react-native-image-zoom/src/types.ts
@@ -68,6 +68,9 @@ export type ImageZoomProps = Omit<ImageProps, 'source'> & {
    * A callback triggered when the image panning ends.
    */
   onPanEnd?: Function;
+
+  onPress?: Function;
+
   /**
    * @see https://facebook.github.io/react-native/docs/image.html#source
    * @default undefined
@@ -136,4 +139,5 @@ export type ImageZoomUseGesturesProps = Pick<
     | 'onPinchEnd'
     | 'onPanStart'
     | 'onPanEnd'
+    | 'onPress'
   >;

This issue body was partially generated by patch-package.

[Feature Request] Disable Snap Back via a dedicated property.

Is your feature request related to a problem? Please describe.
Our app has inconsistent sized image (by design) and this package makes it super easy to handle all the zooming etc. However the "snap back to level 1" feature after about 1s is frustrating users who are zooming in to inspect imagery then being taken back zoomed out, Currently they have to keep their fingers on the screen to try and inspect them which can be a pain, so we'd like to make this a smoother experience for them.

Describe the solution you'd like
It would be great to have a standalone prop that could simply disable the snapping back feature e.g. snapBack={ true/false } as this would solve all our problems.

Describe alternatives you've considered
We've looked at the isDoubleTapEnabled prop which also disables the snap back functionality, however this enables double tap to zoom in/out, which in our scenario conflicts with our "approve" or "unapprove" feature as each time they double tap to approve it, it zooms them out.

Additional context
N/A

Simple onPress handler?

Is is possible to get an event for a simple onPress? Like, if the image is just tapped once?

Zoom works but the zoomed image renders under all the components below

I have a problem, once I zoom on the image , the image is correctly zoomed on top of the above components, but is rendered UNDER the below components... this is inside a chat
here is the code snippet

            <View>
              {message.Desc === '' ? (
                <View style={{ zIndex: 10 }}>
                  <ImageZoom
                    uri={`${REACT_APP_API_URL}${
                      message?.Path ? message?.Path : message?.path
                    }`}
                    minScale={0.5}
                    maxScale={5}
                    doubleTapScale={3}
                    isDoubleTapEnabled
                    style={styles.imageStyle}
                    resizeMode="cover"
                  />
                </View>
              ) : (
                <View style={{ zIndex: -10 }}>
                  <Text style={styles.message} selectable>
                    {message.Desc}
                  </Text>
                </View>
              )}
            </View>
            <View style={styles.triangle_shape_right} />
            <Text style={styles.time} selectable={true}>
              {message.NameEmp} - {message_time_convert(message.Date)}
            </Text>
          </View>```

as you can see I tried to add zIndex with no luck... am I missing something ?

thanks!

Is it working on expo?

I wonder if this library works on expo? I tried to put it on expo but without success. this library doesn't work there i can't move the photo at all

Cannot find module '@likashefqet/react-native-image-zoom' or its corresponding type declarations.ts(2307)

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context
Add any other context about the problem here.

on flick or on pan out callback

It'd be really nice to have an "on flick" gesture that is triggered when the user "flicks" the image (ie to dismiss it). This is similar to a lot of social media apps, ie Twitter.

A stop gap could also be exposing the pan values (start/end) in the onPanEnd callback.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.