DuDigital / 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
243 stars 113 forks source link

zoomTo doesn't work with multiple images #85

Closed phillipcmittmann closed 3 years ago

phillipcmittmann commented 3 years ago

I can't figure out why zoomTo() only works for the last image of the list. I also tried mapping inside a scrollview and two images side by side.

I need a FlatList because in the end I will be rendering around 80 images, so it will impact the performance.

FlatList snippet:

import React, { useRef } from 'react';

import {
    View,
    Image,
    FlatList,
    Dimensions,
    Button
} from 'react-native';

import ZoomableView from '@dudigital/react-native-zoomable-view/src/ReactNativeZoomableView';

const images = [
    // Simplest usage.
    'https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg',
    'https://images.unsplash.com/photo-1541963463532-d68292c34b19?ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8Ym9va3xlbnwwfHwwfHw%3D&ixlib=rb-1.2.1&w=1000&q=80',
    'https://images.unsplash.com/photo-1503023345310-bd7c1de61c7d?ixid=MnwxMjA3fDB8MHxzZWFyY2h8M3x8aHVtYW58ZW58MHx8MHx8&ixlib=rb-1.2.1&w=1000&q=80',
    'https://images.ctfassets.net/hrltx12pl8hq/3MbF54EhWUhsXunc5Keueb/60774fbbff86e6bf6776f1e17a8016b4/04-nature_721703848.jpg?fit=fill&w=480&h=270'
];

const App = () => {
    let arrayRefs = useRef([]);
    arrayRefs.current = Array(4).fill(useRef(null)); // also tried React.createRef()

    return (
        <View style={{ flex: 1, backgroundColor: 'white' }}>
            <FlatList
                data={images}
                extraData={arrayRefs.current}
                horizontal={true}
                pagingEnabled={true}
                decelerationRate={'fast'}
                bounces={false}
                scrollEventThrottle={16}
                renderItem={({ item, index }) => {
                    return (
                        <View style={{ overflow: 'hidden' }}>
                            <ZoomableView
                                maxZoom={1.5}
                                minZoom={0.5}
                                zoomStep={0.5}
                                initialZoom={1.0}
                                bindToBorders={true}
                                captureEvent={true}
                                ref={arrayRefs.current[index]}
                                onZoomEnd={(event, gestureState, zoomableViewEventObject) => {
                                    console.log(zoomableViewEventObject.zoomLevel)
                                    console.log(index)
                                }}
                            >
                                <Image
                                    source={{ uri: item }}
                                    style={{ width: Dimensions.get('window').width, height: 500 }}
                                />
                            </ZoomableView>

                            <View style={{ marginBottom: 100 }}>
                                <Button
                                    title={'Press Me'}
                                    onPress={() => {
                                        arrayRefs.current[index].current.zoomTo(1);
                                        console.log(index)
                                        console.log(arrayRefs.current[index].current.state)
                                    }}
                                />
                            </View>
                        </View>
                    )
                }}
            />
        </View>
    )
}

export default App;

EDIT: Two images snippet:

Obs: When keeping only the first one and changing its refs to any other index, it works

import React, { useRef } from 'react';

import {
    View,
    Image,
    Button,
} from 'react-native';

import ZoomableView from '@dudigital/react-native-zoomable-view/src/ReactNativeZoomableView';

const images = [
    // Simplest usage.
    'https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg',
    'https://images.unsplash.com/photo-1541963463532-d68292c34b19?ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8Ym9va3xlbnwwfHwwfHw%3D&ixlib=rb-1.2.1&w=1000&q=80',
    'https://images.unsplash.com/photo-1503023345310-bd7c1de61c7d?ixid=MnwxMjA3fDB8MHxzZWFyY2h8M3x8aHVtYW58ZW58MHx8MHx8&ixlib=rb-1.2.1&w=1000&q=80',
    'https://images.ctfassets.net/hrltx12pl8hq/3MbF54EhWUhsXunc5Keueb/60774fbbff86e6bf6776f1e17a8016b4/04-nature_721703848.jpg?fit=fill&w=480&h=270'
];

const App = () => {
    let arrayRefs = useRef([]);
    arrayRefs.current = Array(2).fill(useRef(null)); // also tried React.createRef()

    return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
            <View style={{ height: '20%', width: '80%' }}>
                <ZoomableView
                    maxZoom={1.5}
                    minZoom={0.5}
                    zoomStep={0.5}
                    initialZoom={1.0}
                    bindToBorders={true}
                    captureEvent={true}
                    ref={arrayRefs.current[0]}
                    style={{ borderColor: 'red', borderWidth: 1 }}
                >
                    <Image
                        source={{ uri: images[0] }}
                        resizeMode={'contain'}
                        style={{ flex: 1 }}
                    />
                </ZoomableView>
            </View>

            <Button
                title={'Press Me'}
                onPress={() => arrayRefs.current[0].current.zoomTo(1)}
            />

            <View style={{ height: '20%', width: '80%' }}>
                <ZoomableView
                    maxZoom={1.5}
                    minZoom={0.5}
                    zoomStep={0.5}
                    initialZoom={1.0}
                    bindToBorders={true}
                    captureEvent={true}
                    ref={arrayRefs.current[1]}
                    style={{ borderColor: 'red', borderWidth: 1 }}
                >
                    <Image
                        source={{ uri: images[1] }}
                        resizeMode={'contain'}
                        style={{ flex: 1 }}
                    />
                </ZoomableView>
            </View>

            <Button
                title={'Press Me'}
                onPress={() => arrayRefs.current[1].current.zoomTo(1)}
            />
        </View>
    )
}

export default App;
phillipcmittmann commented 3 years ago

Looks like I was doing it wrong, instead of:

arrayRefs.current = Array(2).fill(useRef(null));

It should be:

arrayRefs.current = Array(2).fill(0).map(i => useRef(null));

Isn't a bug, so will be closing the issue.