Projekt

Obecné

Profil

Stáhnout (6.79 KB) Statistiky
| Větev: | Tag: | Revize:
1
import { Box } from 'native-base';
2
import React, { useRef } from 'react';
3
import { StyleSheet, Dimensions } from 'react-native';
4
import { PanGestureHandler, PinchGestureHandler } from 'react-native-gesture-handler';
5
import Animated, {
6
    useAnimatedGestureHandler,
7
    useAnimatedStyle,
8
    useSharedValue,
9
} from 'react-native-reanimated';
10
import { PlanImage, Room } from '../../types/plan';
11
import Svg, { Path, SvgXml, Text } from 'react-native-svg';
12

    
13
const CastlePlanView = (props: { mapImage: PlanImage, roomList: Room[], selectedRoom?: Room, fullScreenMode?: boolean, height?: number }) => {
14

    
15
    const DEFAULT_SCALE = 1
16
    const MIN_SCALE = 0.95
17

    
18
    const MAP_VIEW_SIZE = {
19
        height: 500,
20
        width: "100%"
21
    }
22

    
23
    const { mapImage, roomList, selectedRoom, fullScreenMode, height } = props;
24

    
25
    const panRef = useRef<React.ReactElement>();
26
    const pinchRef = useRef<React.ReactElement>();
27
    const svgRef = useRef<React.ReactElement>();
28

    
29
    const translateX = useSharedValue(0);
30
    const translateY = useSharedValue(0);
31
    const scale = useSharedValue(DEFAULT_SCALE);
32

    
33
    console.log(mapImage.svg.substring(0, 500))
34

    
35
    const onPanEvent = useAnimatedGestureHandler({
36
        // handle one finger -> drag / move
37
        onStart: (_, ctx: any) => {
38
            ctx.startX = translateX.value;
39
            ctx.startY = translateY.value;
40
        },
41
        onActive: (event, ctx: any) => {
42
            translateX.value = ctx.startX + event.translationX;
43
            translateY.value = ctx.startY + event.translationY;
44
        },
45
    });
46

    
47
    const onGestureEvent = useAnimatedGestureHandler({
48
        onStart: (_, ctx: any) => {
49
            ctx.startScale = scale.value;
50
        },
51
        onActive: (event: any, ctx: any) => {
52
            // handle two fingers -> zoom + -
53
            if (event.numberOfPointers === 2) {
54
                scale.value = ctx.startScale * event.scale;
55
            }
56
        },
57
        onEnd: (event) => {
58
            // handle two fingers -> zoom + -
59
            if (event.numberOfPointers === 2) {
60
                if (scale.value < MIN_SCALE) {
61
                    scale.value = MIN_SCALE;
62
                }
63
                // You may add additional logic for maximum scale if needed
64
            }
65
        },
66
    });
67

    
68
    const animatedStyle = useAnimatedStyle(() => {
69
        return {
70
            transform: [
71
                { translateX: translateX.value },
72
                { translateY: translateY.value },
73
                { scale: scale.value },
74
            ],
75
        };
76
    });
77

    
78
    console.log(fullScreenMode)
79

    
80
    console.log(Dimensions.get('window').height)
81
    console.log(Dimensions.get('window').width)
82

    
83
    return (
84
        // container
85
        <Box
86
            width={!fullScreenMode ? MAP_VIEW_SIZE.width : Dimensions.get('window').width - 5
87
            }
88
            height={height ? height : (!fullScreenMode ? MAP_VIEW_SIZE.height : Dimensions.get('window').height - 62.5)}
89
            // @ts-ignore
90
            style={
91
                fullScreenMode ? {
92
                    marginTop: 2.5,
93
                    marginLeft: 2.5,
94
                    marginRight: 2.5,
95
                }
96
                    :
97
                    { overflow: "hidden" }
98
            }
99
            borderColor={"light.300"}
100
            borderRadius={10}
101
            borderWidth={1}
102
        >
103

    
104
            <PinchGestureHandler
105
                ref={pinchRef}
106
                // @ts-ignore
107
                onGestureEvent={onGestureEvent}
108
                simultaneousHandlers={[svgRef, panRef]}>
109
                <Animated.View style={{ flex: 1 }}>
110
                    <PanGestureHandler
111
                        ref={panRef}
112
                        simultaneousHandlers={[svgRef, pinchRef]}
113
                        onGestureEvent={onPanEvent}
114
                    >
115
                        <Animated.View style={[{
116
                            flex: 1,
117
                        }, animatedStyle]}>
118
                            <Svg
119
                                ref={(ref: any) => (svgRef.current = ref)}
120
                            >
121
                                {mapImage && mapImage.viewBox &&
122
                                    // background image                    
123
                                    <SvgXml
124
                                        xml={mapImage.svg}
125
                                        width={"100%"}
126
                                        height={"100%"}
127

    
128
                                    />
129
                                }
130

    
131
                                {mapImage && roomList && roomList.length > 0 &&
132
                                    roomList.map((room) => {
133
                                        if (!room.in_plan) {
134
                                            return
135
                                        }
136
                                        return (
137
                                            <React.Fragment key={room.id}>
138
                                                <Path
139

    
140
                                                    d={room.svg_path}  // The path data defining the shape of the room
141
                                                    fill={selectedRoom && room.id == selectedRoom.id ? "#E6F7FF" : "none"}        // Fill the room shape with no color
142
                                                    stroke="#66B2FF"       // Outline color
143
                                                    strokeWidth={0.3}     // Outline width
144
                                                />
145
                                                {/* Text label in the middle of the room */}
146
                                                <Text
147
                                                    x={room.number_x}     // Adjust the x-coordinate based on your room data
148
                                                    y={room.number_y}     // Adjust the y-coordinate based on your room data
149
                                                    fill="red"      // Text color
150
                                                    fontSize={8}       // Font size
151
                                                    textAnchor="middle"  // Center the text horizontally
152
                                                    fontStyle='italic'
153
                                                    vectorEffect='non-scaling-stroke' // Helps prevent stroke from scaling
154
                                                >
155
                                                    {room.id}
156
                                                </Text>
157
                                            </React.Fragment>
158

    
159
                                        )
160
                                    })
161
                                }
162

    
163
                            </Svg>
164
                        </Animated.View>
165
                    </PanGestureHandler>
166
                </Animated.View>
167
            </PinchGestureHandler>
168
        </Box >
169
    );
170
};
171

    
172
export default CastlePlanView;
173

    
    (1-1/1)