openspacelabs / react-native-zoomable-view

A view component for react-native with pinch to zoom, tap to move and double tap to zoom capability.
MIT License
191 stars 58 forks source link

unable to Use Method zoomTo and moveTo #55

Open mguyard opened 1 year ago

mguyard commented 1 year ago

Hello,

I'm pretty new in React Native dev. For my app dev with Expo, i've a carousel(horizontal ScrollView) with images (using FastImage) with ability to fullscreen. Everything work great, expect a case i have when user zoom on image and go on a border of the image. In this case, when he disable the fullscreen, image is not center.

A video is sometime better to explain :

https://user-images.githubusercontent.com/5262395/210151503-ae3b957e-31af-43a3-95b1-b292bbbe3129.mp4

So i've try to use moveTo(0,0) to come back to initial when fullscreen is disabled.

My ScrollView Code is :

<ScrollView
                pagingEnabled
                horizontal
                decelerationRate="fast"
                scrollEventThrottle={200}
                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 (
                                    // <Pinchable key={key}>
                                    <ReactNativeZoomableView
                                        key={key}
                                        zoomEnabled={isFullscreen}
                                        maxZoom={3}
                                        minZoom={1}
                                        initialZoom={1}
                                        ref={zoomableViewRef}
                                    >
                                        <FastImage
                                            key={generateKey(key)}
                                            /* Storing the image's uri, width, height, and orientation in
                                            an array. */
                                            onLoad={e => storeImageSizeOnLoad(item, e.nativeEvent.width, e.nativeEvent.height)}
                                            /* 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={getResizeMode(item)}
                                            source={{ uri: item.uri }}
                                            style={[
                                                { width: screenWidth, flexGrow: 1 },
                                            ]}
                                        />
                                    {/* </Pinchable> */}
                                    </ReactNativeZoomableView>
                            );
                          })
                        : 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>

Of course, i've create ref :

const zoomableViewRef = useRef(null);

and my part who try to moveTo is :

    /* Calling the switchFullScreen function from the parent component. */
    useEffect(() => {
        switchFullScreen(isFullscreen);
        if (!isFullscreen) {
            zoomableViewRef.current?.moveTo(0,0);
            zoomableViewRef.current?.zoomTo(1);
        }
    }, [isFullscreen]);

I suppose i've done something bad but if someone can help me, this will be very appreciated. Thank you

nimrodbens commented 1 year ago

same here. moveTo seems to not do anything. i'm using it just as described in the docs and with any value nothing happens.

zoomableViewRef.current?.moveTo(200, 200);

and the bool that should return in the promise returns as undefined.

any ideas?

luisfuertes commented 1 year ago

Same problem here, this code don't do nothing (zoomViewLayoutRef is child view onLayout layout):

        await zoomViewRef.current?.zoomTo(2);
        console.log('zoomToEnd');
        await zoomViewRef.current?.moveTo(Math.round(zoomViewLayoutRef.current?.width / 2), zoomViewLayoutRef.current?.height);
        console.log('moveToEnd');

And this code works but in 2 steps, first do zoom animated and after move without animation (bad UX):

await zoomViewRef.current?.zoomTo(2);
        console.log('zoomToEnd');
        setTimeout(
          async () =>
            await zoomViewRef.current?.moveTo(Math.round(zoomViewLayoutRef.current?.width / 2), zoomViewLayoutRef.current?.height),
          1000,
        );
        console.log('moveToEnd');

Any solution?

dustinlakin commented 1 year ago

I am having a similar problem with moveTo and zoomTo, they sometimes do something, but never seem to do the right thing like the initialOffsetX, initialOffsetY, and initialZoom do.

What a great library though, can't thank the team enough for the work on it.

davide-granello commented 4 months ago

I have the same problem. I want to reset the initial position and zoom of the image when a certain condition happens, but when i do:

zoomViewRef.current?.moveTo(0, 0)
zoomViewRef.current?.zoomTo(1)

The zoom is reset back to 1, but the position is not correct.

I also tried to swap instructions with no luck.