WhiteNightsAdminPanel/src/pages/route-preview/Sight.tsx
2025-05-04 22:40:44 +03:00

115 lines
3.0 KiB
TypeScript

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 } from "./utils";
interface SightProps {
sight: SightData;
id: number;
}
export function Sight({
sight, id
}: Readonly<SightProps>) {
const { rotation, scale } = useTransform();
const [position, setPosition] = useState({ x: 0, y: 0 });
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;
const dy = (e.globalY - startMousePosition.y) / 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);
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={coordinates.x * UP_SCALE - SIGHT_SIZE/2 + position.x} // Offset by half width to center
y={coordinates.y * UP_SCALE - SIGHT_SIZE/2 + position.y} // 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>
);
}