Revize 36ede89c
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 |
import { StyleSheet, Dimensions, TouchableOpacity } from 'react-native'; |
|
3 |
import { StyleSheet, Dimensions, TouchableOpacity, GestureResponderEvent } from 'react-native';
|
|
4 | 4 |
import { PanGestureHandler, PinchGestureHandler, State, TapGestureHandler } from 'react-native-gesture-handler'; |
5 | 5 |
import Animated, { |
6 | 6 |
useAnimatedGestureHandler, |
... | ... | |
11 | 11 |
import Svg, { Path, SvgXml, Text } from 'react-native-svg'; |
12 | 12 |
|
13 | 13 |
// @ts-ignore |
14 |
import { pointInSvgPath } from 'point-in-svg-path'; |
|
15 |
import { getFloorList } from '../../stores/actions/planThunks'; |
|
14 |
import pointInSvgPolygon from "point-in-svg-polygon" |
|
16 | 15 |
|
17 |
|
|
18 |
const CastlePlanView = (props: { mapImage: PlanImage, roomList: Room[], selectedRoom?: Room, fullScreenMode?: boolean, height?: number }) => { |
|
16 |
const CastlePlanView = (props: { mapImage: PlanImage, roomList: Room[], selectedRoom?: Room, fullScreenMode?: boolean, height?: number, setSelectedRoom?: (room: Room) => void }) => { |
|
19 | 17 |
|
20 | 18 |
const DEFAULT_SCALE = 1 |
21 | 19 |
const MIN_SCALE = 0.95 |
... | ... | |
25 | 23 |
width: "100%" |
26 | 24 |
} |
27 | 25 |
|
28 |
const { mapImage, roomList, selectedRoom, fullScreenMode, height } = props; |
|
26 |
const { mapImage, roomList, selectedRoom, fullScreenMode, height, setSelectedRoom } = props;
|
|
29 | 27 |
|
30 | 28 |
const panRef = useRef<React.ReactElement>(); |
31 | 29 |
const pinchRef = useRef<React.ReactElement>(); |
32 | 30 |
|
33 | 31 |
const svgRef = useRef<React.ReactElement>(); |
34 |
const pathRefs = useRef<(Path | null)[]>([]); |
|
35 | 32 |
|
36 | 33 |
const translateX = useSharedValue(0); |
37 | 34 |
const translateY = useSharedValue(0); |
... | ... | |
41 | 38 |
|
42 | 39 |
const onPanEvent = useAnimatedGestureHandler({ |
43 | 40 |
// handle one finger -> drag / move |
44 |
onStart: (_, ctx: any) => { |
|
45 |
ctx.startX = translateX.value; |
|
46 |
ctx.startY = translateY.value; |
|
41 |
onStart: (event, ctx: any) => { |
|
42 |
if (event.numberOfPointers === 1) { |
|
43 |
ctx.startX = translateX.value; |
|
44 |
ctx.startY = translateY.value; |
|
45 |
} |
|
47 | 46 |
}, |
48 | 47 |
onActive: (event, ctx: any) => { |
49 |
translateX.value = ctx.startX + event.translationX; |
|
50 |
translateY.value = ctx.startY + event.translationY; |
|
48 |
if (event.numberOfPointers === 1) { |
|
49 |
translateX.value = ctx.startX + event.translationX; |
|
50 |
translateY.value = ctx.startY + event.translationY; |
|
51 |
} |
|
51 | 52 |
}, |
52 | 53 |
}); |
53 | 54 |
|
... | ... | |
82 | 83 |
}; |
83 | 84 |
}); |
84 | 85 |
|
85 |
const handleSvgPress = (event: any) => { |
|
86 |
const locationX = Number(event.nativeEvent.locationX); |
|
87 |
const locationY = Number(event.nativeEvent.locationY); |
|
86 |
|
|
87 |
function calculateStraightLineDistance(x1: number, y1: number, planX: number, planY: number, log?: boolean) { |
|
88 |
// Apply scale and translations to both points |
|
89 |
|
|
90 |
const xOffset = 250 |
|
91 |
const yOffset = 120 |
|
92 |
|
|
93 |
const x2 = planX + xOffset |
|
94 |
const y2 = planY + yOffset |
|
95 |
|
|
96 |
|
|
97 |
const x_distance = Math.abs(x1 - x2); |
|
98 |
const y_distance = Math.abs(y1 - y2); |
|
99 |
|
|
100 |
if (log) { |
|
101 |
console.log("Original X: ", x1, "Original Y: ", y1); |
|
102 |
console.log("Clicked X: ", planX, "Clicked Y: ", planY); |
|
103 |
console.log("Transformed X: ", x2, "Transformed Y: ", y2); |
|
104 |
console.log("Scale: ", scale.value, "TranslateX: ", translateX.value, "TranslateY: ", translateY.value); |
|
105 |
console.log("X Distance: ", x_distance, "Y Distance: ", y_distance); |
|
106 |
} |
|
107 |
return x_distance + y_distance; |
|
108 |
} |
|
109 |
|
|
110 |
|
|
111 |
const handleSvgPress = (event: GestureResponderEvent) => { |
|
112 |
|
|
113 |
// Get the raw event coordinates |
|
114 |
const rawLocationX = event.nativeEvent.locationX; |
|
115 |
const rawLocationY = event.nativeEvent.locationY; |
|
116 |
|
|
117 |
// Log raw coordinates |
|
118 |
console.log("Raw Location X: ", rawLocationX, "Raw Location Y: ", rawLocationY); |
|
119 |
|
|
120 |
// If needed, you can get the SVG element's dimensions to normalize the coordinates |
|
121 |
const svgWidth = Dimensions.get('window').width |
|
122 |
const svgHeight = height ? height : (!fullScreenMode ? MAP_VIEW_SIZE.height : Dimensions.get('window').height - 62.5) |
|
123 |
|
|
124 |
// Normalize the coordinates based on the SVG dimensions |
|
125 |
// @ts-ignore |
|
126 |
const locationX = (rawLocationX / svgWidth) * 100; |
|
127 |
const locationY = (rawLocationY / svgHeight) * 100; |
|
128 |
|
|
88 | 129 |
|
89 | 130 |
// Check if the touch event is within the bounds of a room |
90 | 131 |
let clickedRoom: Room | undefined = undefined |
91 | 132 |
|
133 |
// TODO set accordingaly |
|
134 |
const maxNumberDistance = 100 |
|
135 |
|
|
136 |
let minDistance = Number.MAX_VALUE |
|
137 |
|
|
138 |
for (let i = 0; i < roomList.length; i++) { |
|
139 |
const room: Room = roomList[i] |
|
140 |
if (room.in_plan) { |
|
92 | 141 |
|
93 |
for (let i = 0; i < pathRefs.current.length; i++) { |
|
94 |
const pathRef: Path | null = pathRefs.current[i] |
|
95 |
const id = pathRef?.props.id |
|
142 |
const currentDistance = calculateStraightLineDistance(room.number_x, room.number_y, locationX, locationY, true) |
|
96 | 143 |
|
97 |
if (id?.startsWith("roomList_")) { |
|
98 |
const listIndex = parseInt(id.split("roomList_")[1]) |
|
99 |
console.log(listIndex) |
|
100 |
if (pathRef && pathRef.isPointInFill({ x: locationX, y: locationY })) { |
|
101 |
clickedRoom = roomList[listIndex] |
|
144 |
if (currentDistance < minDistance) { |
|
145 |
minDistance = currentDistance |
|
146 |
clickedRoom = room |
|
102 | 147 |
} |
103 | 148 |
} |
104 |
|
|
105 | 149 |
}; |
106 | 150 |
|
107 |
if (clickedRoom) { |
|
108 |
// TODO |
|
109 |
console.log('Room clicked with id:', clickedRoom.id); |
|
151 |
console.log('Room clicked with id:', clickedRoom.id); |
|
152 |
console.log(minDistance) |
|
153 |
if (clickedRoom && minDistance < maxNumberDistance) { |
|
154 |
// TODO |
|
155 |
|
|
110 | 156 |
// Perform any actions you need with the clicked room |
157 |
|
|
158 |
// TODO fix -> point recognition |
|
159 |
setSelectedRoom && setSelectedRoom(clickedRoom) |
|
111 | 160 |
} else { |
112 |
// TODO |
|
113 | 161 |
console.log("no room found") |
114 | 162 |
} |
115 | 163 |
}; |
... | ... | |
176 | 224 |
} |
177 | 225 |
return ( |
178 | 226 |
<Path |
179 |
ref={(ref) => (pathRefs.current[index] = ref)} |
|
180 | 227 |
id={"roomList_" + index.toString()} |
181 | 228 |
key={'room_' + room.id} |
182 | 229 |
d={room.svg_path} // The path data defining the shape of the room |
Také k dispozici: Unified diff
re #10871: PlanViewPage: getSelectedRoom from coordinates: TODO fix coordinates