Revize 28ab969f
Přidáno uživatelem Fantič před více než 1 rok
src/components/plan/CastlePlanView.tsx | ||
---|---|---|
1 | 1 |
import { Box } from 'native-base'; |
2 | 2 |
import React, { useRef } from 'react'; |
3 | 3 |
import { StyleSheet, Dimensions } from 'react-native'; |
4 |
import { PinchGestureHandler } from 'react-native-gesture-handler'; |
|
4 |
import { PanGestureHandler, PinchGestureHandler } from 'react-native-gesture-handler';
|
|
5 | 5 |
import Animated, { |
6 | 6 |
useAnimatedGestureHandler, |
7 | 7 |
useAnimatedStyle, |
8 | 8 |
useSharedValue, |
9 | 9 |
} from 'react-native-reanimated'; |
10 |
import { PlanImage } from '../../types/plan'; |
|
11 |
import { Room } from '../../types/searchFormTypes'; |
|
10 |
import { PlanImage, Room } from '../../types/plan'; |
|
12 | 11 |
import Svg, { SvgXml } from 'react-native-svg'; |
13 | 12 |
|
14 |
const CastlePlanView = (props: { mapImage: PlanImage, selectedRoom?: Room }) => { |
|
15 |
const { mapImage } = props; |
|
13 |
const CastlePlanView = (props: { mapImage: PlanImage, roomList: Room[], selectedRoom?: Room }) => { |
|
16 | 14 |
|
15 |
const DEFAULT_SCALE = 1 |
|
16 |
const MIN_SCALE = 0.95 |
|
17 |
|
|
18 |
const MAP_VIEW_SIZE = { |
|
19 |
height : 400, |
|
20 |
width : "100%" |
|
21 |
} |
|
22 |
|
|
23 |
const { mapImage, roomList, selectedRoom } = props; |
|
24 |
|
|
25 |
const panRef = useRef<React.ReactElement>(); |
|
26 |
const pinchRef = useRef<React.ReactElement>(); |
|
17 | 27 |
const svgRef = useRef<React.ReactElement>(); |
18 | 28 |
|
19 | 29 |
const translateX = useSharedValue(0); |
20 | 30 |
const translateY = useSharedValue(0); |
21 |
const scale = useSharedValue(1);
|
|
31 |
const scale = useSharedValue(DEFAULT_SCALE);
|
|
22 | 32 |
|
23 |
console.log(mapImage.svg.substring(0,500)) |
|
33 |
console.log(mapImage.svg.substring(0, 500))
|
|
24 | 34 |
|
25 |
const DEFAULT_SCALE = 0 |
|
26 |
const MIN_SCALE = 0.95 |
|
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 |
}); |
|
27 | 46 |
|
28 | 47 |
const onGestureEvent = useAnimatedGestureHandler({ |
29 | 48 |
onActive: (event: any) => { |
30 |
|
|
31 |
// handle one finger -> drag |
|
32 |
if (event.numberOfPointers === 1) { |
|
33 |
|
|
34 |
} |
|
35 | 49 |
// handle two fingers -> zoom + - |
36 |
else if (event.numberOfPointers === 2) { |
|
37 |
|
|
38 |
if(event.scale < MIN_SCALE){ |
|
39 |
console.log("tohle je moc") |
|
50 |
if (event.numberOfPointers === 2) { |
|
51 |
if (event.scale < MIN_SCALE) { |
|
40 | 52 |
scale.value = MIN_SCALE |
41 | 53 |
} |
42 |
else{ |
|
54 |
else {
|
|
43 | 55 |
scale.value = event.scale; |
44 | 56 |
} |
45 |
|
|
46 |
console.log(scale.value) |
|
47 | 57 |
} |
48 | 58 |
}, |
49 | 59 |
}); |
... | ... | |
60 | 70 |
|
61 | 71 |
return ( |
62 | 72 |
// container |
63 |
<Box width="100%" height={370} style={{ borderColor: "#F5F5F", borderWidth: 1, overflow: "hidden" }}> |
|
64 |
<PinchGestureHandler onGestureEvent={onGestureEvent} simultaneousHandlers={svgRef}> |
|
65 |
<Animated.View style={[{ |
|
66 |
flex: 1, |
|
67 |
}, animatedStyle]}> |
|
68 |
<Svg |
|
69 |
ref={(ref: any) => (svgRef.current = ref)} |
|
70 |
|
|
73 |
<Box width={MAP_VIEW_SIZE.width} height={MAP_VIEW_SIZE.height} style={{ borderColor: "#F5F5F", borderWidth: 1, overflow: "hidden" }}> |
|
74 |
<PinchGestureHandler |
|
75 |
ref={pinchRef} |
|
76 |
// @ts-ignore |
|
77 |
onGestureEvent={onGestureEvent} |
|
78 |
simultaneousHandlers={[svgRef, panRef]}> |
|
79 |
<Animated.View style={{ flex: 1 }}> |
|
80 |
<PanGestureHandler |
|
81 |
ref={panRef} |
|
82 |
simultaneousHandlers={[svgRef, pinchRef]} |
|
83 |
onGestureEvent={onPanEvent} |
|
71 | 84 |
> |
72 |
{mapImage && mapImage.viewBox && |
|
73 |
// background image |
|
74 |
<SvgXml |
|
75 |
xml={mapImage.svg} |
|
76 |
width={"100%"} |
|
77 |
height={"100%"} |
|
85 |
<Animated.View style={[{ |
|
86 |
flex: 1, |
|
87 |
}, animatedStyle]}> |
|
88 |
<Svg |
|
89 |
ref={(ref: any) => (svgRef.current = ref)} |
|
90 |
> |
|
91 |
{mapImage && mapImage.viewBox && |
|
92 |
// background image |
|
93 |
<SvgXml |
|
94 |
xml={mapImage.svg} |
|
95 |
width={"100%"} |
|
96 |
height={"100%"} |
|
78 | 97 |
|
79 |
/>} |
|
98 |
/>} |
|
99 |
{mapImage && roomList && roomList.length > 0 && |
|
100 |
<></>} |
|
80 | 101 |
|
81 |
</Svg> |
|
102 |
</Svg> |
|
103 |
</Animated.View> |
|
104 |
</PanGestureHandler> |
|
82 | 105 |
</Animated.View> |
83 | 106 |
</PinchGestureHandler> |
84 | 107 |
</Box> |
src/pages/PlanViewPage.tsx | ||
---|---|---|
5 | 5 |
import { log } from "../logging/logger" |
6 | 6 |
import { DrawerScreenProps } from "@react-navigation/drawer" |
7 | 7 |
import { RootDrawerParamList } from "./Navigation" |
8 |
import { Box, CloseIcon, Select, useToast, Button, Flex, Text, Center, VStack, ScrollView } from "native-base" |
|
8 |
import { Box, CloseIcon, Select, useToast, Button, Flex, Text, Center, VStack, ScrollView, View } from "native-base"
|
|
9 | 9 |
import { ErrorToast } from "../components/toast/ErrorToast" |
10 | 10 |
import { Floor, Place, Room } from "../types/plan" |
11 | 11 |
import { getFloorList, getPlanFloorImage, getPlanInventories, getPlanItems } from "../stores/actions/planThunks" |
... | ... | |
36 | 36 |
const [selectedRoom, setSelectedRoom] = useState<Room | undefined>(undefined) |
37 | 37 |
const [selectedPlace, setSelectedPlace] = useState<Place | undefined>(undefined) |
38 | 38 |
|
39 |
const [isInteractingWithCastlePlan, setIsInteractingWithCastlePlan] = useState(false); |
|
40 |
|
|
39 | 41 |
const { floorListLoading, floorList, totalItemsCount, lastError } = useSelector((state: RootState) => state.planViewState) |
40 | 42 |
|
41 | 43 |
const inventories = useSelector((state: RootState) => state.planViewState.itemInventories) |
... | ... | |
178 | 180 |
return ( |
179 | 181 |
<Center m={2} mr={0} mb={6} flex={1}> |
180 | 182 |
|
181 |
<ScrollView flex={1} w={"100%"} > |
|
183 |
<ScrollView flex={1} w={"100%"} nestedScrollEnabled={!isInteractingWithCastlePlan}>
|
|
182 | 184 |
<VStack space={1} mr={4}> |
183 | 185 |
|
184 | 186 |
{/* Selection */} |
... | ... | |
298 | 300 |
<LoadingBox text="Loading castle plan" /> |
299 | 301 |
: |
300 | 302 |
floorMapImage && |
301 |
<Box mt={2.5} ml={2.5}> |
|
302 |
<CastlePlanView mapImage={floorMapImage} selectedRoom={selectedRoom} /> |
|
303 |
<Box mt={2.5} ml={2.5} |
|
304 |
onTouchStart={() => setIsInteractingWithCastlePlan(true)} |
|
305 |
onTouchEnd={() => setIsInteractingWithCastlePlan(true)}> |
|
306 |
<CastlePlanView mapImage={floorMapImage} selectedRoom={selectedRoom} roomList={selectedFloor.roomList} /> |
|
303 | 307 |
</Box> |
304 | 308 |
) |
305 | 309 |
} |
src/stores/actions/planThunks.ts | ||
---|---|---|
133 | 133 |
|
134 | 134 |
const output : PlanImage = { |
135 | 135 |
svg: svg, |
136 |
viewBox :{ x:0, y:0, width:0, height:0 } |
|
136 | 137 |
} |
137 | 138 |
|
138 | 139 |
parseString(svg, (err : any, result: any) => { |
Také k dispozici: Unified diff
re #10871: PlanViewPage: Drag/move castlePlan