Projekt

Obecné

Profil

Stáhnout (7.19 KB) Statistiky
| Větev: | Tag: | Revize:
1
import React, { useState, useEffect, useRef } from "react";
2

    
3
import { Box, Flex, Text, Image, Popover, Pressable, VStack, View, Modal, Overlay, HStack } from "native-base"
4
import { PinchGestureHandler, PanGestureHandler, State, GestureHandlerRootView } from "react-native-gesture-handler";
5
import Animated, { useAnimatedGestureHandler, useAnimatedStyle, useSharedValue } from "react-native-reanimated";
6
import Svg, { SvgXml, Path } from "react-native-svg";
7
import { FullscreenIcon, ExitfullscreenIcon } from "../general/Icons";
8
import { Button, Dimensions } from "react-native";
9

    
10
export const ZoomableImage = (props: { size: number, imageUri: string, fullScreen?: boolean }) => {
11
    const DEFAULT_SCALE = 1
12
    const MIN_SCALE = 0.95
13

    
14
    const [fullScreenMode, setFullScreenMode] = useState<boolean>(false);
15
    const [viewSize, setViewSize] = useState({ height: 0, width: 0 });
16

    
17
    const imgRef = useRef<React.ReactElement>();
18
    const panRef = useRef<React.ReactElement>();
19
    const pinchRef = useRef<React.ReactElement>();
20

    
21

    
22
    useEffect(() => {
23
        if (props.fullScreen != undefined) {
24
            setFullScreenMode(props.fullScreen)
25
        }
26
    }, [props.fullScreen])
27

    
28
    useEffect(() => {
29
        setViewSize({
30
            width: fullScreenMode ?
31
                Dimensions.get('window').width - 20 : // full screen
32
                Dimensions.get('window').width - 20, // not full screen
33
            height: fullScreenMode ?
34
                Dimensions.get('window').height - 122.5 : // full scren
35
                Dimensions.get('window').height - 350, // not full screen
36
        })
37
    }, [fullScreenMode])
38
    const translateX = useSharedValue(0);
39
    const translateY = useSharedValue(0);
40
    const scale = useSharedValue(DEFAULT_SCALE);
41

    
42
    const onPanEvent = useAnimatedGestureHandler({
43
        // handle one finger -> drag / move
44
        onStart: (event, ctx: any) => {
45
            if (event.numberOfPointers === 1) {
46
                ctx.startX = translateX.value;
47
                ctx.startY = translateY.value;
48
            }
49
        },
50
        onActive: (event, ctx: any) => {
51
            if (event.numberOfPointers === 1) {
52
                translateX.value = ctx.startX + event.translationX;
53
                translateY.value = ctx.startY + event.translationY;
54

    
55
                console.log("xTranslate " + translateX.value + " yTranslate " + translateY.value)
56
            }
57
        },
58
    });
59

    
60
    const onGestureEvent = useAnimatedGestureHandler({
61
        onStart: (_, ctx: any) => {
62
            ctx.startScale = scale.value;
63
        },
64
        onActive: (event: any, ctx: any) => {
65
            // handle two fingers -> zoom + -
66
            if (event.numberOfPointers === 2) {
67
                scale.value = ctx.startScale * event.scale;
68
            }
69
        },
70
        onEnd: (event) => {
71
            // handle two fingers -> zoom + -
72
            if (event.numberOfPointers === 2) {
73
                if (scale.value < MIN_SCALE) {
74
                    scale.value = MIN_SCALE;
75
                }
76
                // You may add additional logic for maximum scale if needed
77

    
78
                console.log("scale")
79
                console.log(scale.value)
80
            }
81
        },
82
    });
83

    
84
    const animatedStyle = useAnimatedStyle(() => {
85
        return {
86
            transform: [
87
                { translateX: translateX.value },
88
                { translateY: translateY.value },
89
                { scale: scale.value },
90
            ],
91
        };
92
    });
93

    
94
    const zoomOut = () => {
95
        translateX.value = 0;
96
        translateY.value = 0;
97
        scale.value = DEFAULT_SCALE;
98
    }
99

    
100
    return (
101
        <View>
102
            <Pressable onPress={() => setFullScreenMode(true)}>
103
                <Image size={viewSize.width} source={{ uri: props.imageUri }} alt="image" resizeMode={"contain"} />
104
            </Pressable>
105

    
106
            <Modal isOpen={fullScreenMode} onClose={() => setFullScreenMode(false)} size="full">
107
                <View
108
                    flex={1}
109
                    justifyContent="center"
110
                    alignItems="center"
111
                    backgroundColor="white" // Make the background transparent
112
                >
113
                    <Flex direction="row" alignItems="center" justify="flex-end" style={{ height: 50, width: 100, bottom: fullScreenMode ? 10 : 0, right: fullScreenMode ? 20 : 15, position: "absolute", zIndex: 5 }}>
114
                        <Pressable padding={1.5} backgroundColor={"#654B07"} borderRadius={5} marginRight={1} onPress={() => { zoomOut()}}>
115
                            <ExitfullscreenIcon color="white" />
116
                        </Pressable>
117
                        <Pressable padding={1.5} backgroundColor={"#654B07"} borderRadius={5} marginRight={-2} onPress={() => setFullScreenMode(false)}>
118
                            <FullscreenIcon color="white" />
119
                        </Pressable>
120

    
121
                    </Flex>
122
                    <GestureHandlerRootView>
123
                        <PinchGestureHandler
124
                            ref={pinchRef}
125
                            // @ts-ignore
126
                            onGestureEvent={onGestureEvent}
127
                            simultaneousHandlers={[imgRef, panRef]}>
128
                            <Animated.View style={[{ flex: 1 }, animatedStyle]}>
129
                                <PanGestureHandler
130
                                    ref={panRef}
131
                                    simultaneousHandlers={[imgRef, pinchRef]}
132
                                    onGestureEvent={onPanEvent}
133
                                    onHandlerStateChange={(nativeEvent: any) => {
134
                                        if (nativeEvent.state === State.END) {
135
                                            console.log(nativeEvent)
136
                                        }
137
                                    }}
138
                                >
139
                                    <Animated.View style={[{
140
                                        flex: 1,
141
                                    }]}>
142
                                        <Image
143
                                            ref={imgRef}
144
                                            height={viewSize.height}
145
                                            width={viewSize.width}
146
                                            alt="image"
147
                                            source={{ uri: props.imageUri }}
148
                                            resizeMode={"contain"}
149
                                        />
150
                                    </Animated.View>
151
                                </PanGestureHandler>
152
                            </Animated.View>
153
                        </PinchGestureHandler >
154
                    </GestureHandlerRootView>
155
                </View>
156
            </Modal>
157
        </View>
158
        // <Flex direction="row" alignItems="center" justify="flex-end" style={{ height: 50, width: 100, top: fullScreenMode ? 10 : 0, right: fullScreenMode ? 20 : 15, position: "absolute", zIndex: 5 }}>
159
        //     {
160
        //         fullScreenMode &&
161
        //         <Pressable padding={1.5} backgroundColor={"#654B07"} borderRadius={5} marginRight={-2} onPress={() => setFullScreenMode(false)}>
162
        //             <FullscreenIcon color="white" />
163
        //         </Pressable>
164
        //     }
165

    
166
        // </Flex>
167
    )
168

    
169
}
(3-3/3)