feat: Move route-preview
This commit is contained in:
		
							
								
								
									
										119
									
								
								src/pages/Route/route-preview/Sight.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								src/pages/Route/route-preview/Sight.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,119 @@ | ||||
| import { useEffect, useState } from "react"; | ||||
| import { useTransform } from "./TransformContext"; | ||||
| import { SightData } from "./types"; | ||||
| import { Assets, FederatedMouseEvent, Graphics, Texture } from "pixi.js"; | ||||
| import { COLORS } from "../../contexts/color-mode/theme"; | ||||
| import { SIGHT_SIZE, UP_SCALE } from "./Constants"; | ||||
| import { coordinatesToLocal, localToCoordinates } from "./utils"; | ||||
| import { useMapData } from "./MapDataContext"; | ||||
|  | ||||
| interface SightProps { | ||||
| 	sight: SightData; | ||||
| 	id: number; | ||||
| } | ||||
|  | ||||
| export function Sight({ | ||||
| 	sight, id | ||||
| }: Readonly<SightProps>) { | ||||
| 	const { rotation, scale } = useTransform(); | ||||
| 	const { setSightCoordinates } = useMapData(); | ||||
|  | ||||
| 	const [position, setPosition] = useState(coordinatesToLocal(sight.latitude, sight.longitude)); | ||||
| 	const [isDragging, setIsDragging] = useState(false); | ||||
|     const [startPosition, setStartPosition] = useState({ x: 0, y: 0 }); | ||||
|     const [startMousePosition, setStartMousePosition] = useState({ x: 0, y: 0 }); | ||||
|  | ||||
|     const handlePointerDown = (e: FederatedMouseEvent) => { | ||||
|         setIsDragging(true); | ||||
|         setStartPosition({ | ||||
|             x: position.x, | ||||
|             y: position.y | ||||
|         }); | ||||
| 		setStartMousePosition({ | ||||
| 			x: e.globalX, | ||||
| 			y: e.globalY | ||||
| 		}); | ||||
| 		 | ||||
|         e.stopPropagation(); | ||||
|     }; | ||||
|     const handlePointerMove = (e: FederatedMouseEvent) => { | ||||
|         if (!isDragging) return; | ||||
| 		const dx = (e.globalX - startMousePosition.x) / scale / UP_SCALE; | ||||
| 		const dy = (e.globalY - startMousePosition.y) / scale / UP_SCALE; | ||||
| 		const cos = Math.cos(rotation); | ||||
| 		const sin = Math.sin(rotation); | ||||
| 		const newPosition = { | ||||
| 			x: startPosition.x + dx * cos + dy * sin, | ||||
| 			y: startPosition.y - dx * sin + dy * cos | ||||
| 		}; | ||||
| 		setPosition(newPosition); | ||||
| 		const coordinates = localToCoordinates(newPosition.x, newPosition.y); | ||||
| 		setSightCoordinates(sight.id, coordinates.latitude, coordinates.longitude); | ||||
|         e.stopPropagation(); | ||||
|     }; | ||||
|  | ||||
|     const handlePointerUp = (e: FederatedMouseEvent) => { | ||||
|         setIsDragging(false); | ||||
|         e.stopPropagation(); | ||||
|     }; | ||||
|  | ||||
| 	const [texture, setTexture] = useState(Texture.EMPTY); | ||||
| 	useEffect(() => { | ||||
|         if (texture === Texture.EMPTY) { | ||||
|             Assets | ||||
|                 .load('/SightIcon.png') | ||||
|                 .then((result) => { | ||||
|                     setTexture(result) | ||||
|                 }); | ||||
|         } | ||||
|     }, [texture]); | ||||
|  | ||||
| 	function draw(g: Graphics) { | ||||
| 		g.clear(); | ||||
| 		g.circle(0, 0, 20); | ||||
| 		g.fill({color: COLORS.primary}); // Fill circle with primary color | ||||
| 	} | ||||
|  | ||||
| 	if(!sight) { | ||||
| 		console.error("sight is null"); | ||||
| 		return null; | ||||
| 	} | ||||
|  | ||||
| 	const coordinates = coordinatesToLocal(sight.latitude, sight.longitude); | ||||
|  | ||||
| 	return ( | ||||
| 		<pixiContainer rotation={-rotation} | ||||
| 			eventMode='static' | ||||
| 			interactive | ||||
| 			onPointerDown={handlePointerDown} | ||||
| 			onGlobalPointerMove={handlePointerMove} | ||||
| 			onPointerUp={handlePointerUp} | ||||
| 			onPointerUpOutside={handlePointerUp} | ||||
| 			x={position.x * UP_SCALE - SIGHT_SIZE/2} // Offset by half width to center | ||||
| 			y={position.y * UP_SCALE - SIGHT_SIZE/2} // Offset by half height to center | ||||
| 		> | ||||
| 			<pixiSprite | ||||
| 				texture={texture}  | ||||
| 				width={SIGHT_SIZE} | ||||
| 				height={SIGHT_SIZE} | ||||
| 			/> | ||||
| 			<pixiGraphics | ||||
| 				draw={draw} | ||||
| 				x={SIGHT_SIZE} | ||||
| 				y={0} | ||||
| 			/> | ||||
| 			<pixiText | ||||
| 				text={`${id+1}`} | ||||
| 				x={SIGHT_SIZE+1} | ||||
| 				y={0} | ||||
| 				anchor={0.5} | ||||
| 				 | ||||
| 				style={{ | ||||
| 					fontSize: 24, | ||||
| 					fontWeight: 'bold', | ||||
| 					fill: "#ffffff", | ||||
| 				}} | ||||
| 			/> | ||||
| 		</pixiContainer> | ||||
| 	); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user