import { DragControls, Line } from "@react-three/drei"; import React, { useMemo, useState } from "react"; import { useActiveTool, useToolMode } from "../../../../store/builder/store"; import { useThree } from "@react-three/fiber"; import { LineCurve3, Plane, Vector3 } from "three"; import { getPathsByPointId, setPathPosition } from "./function/getPaths"; import { handleCanvasCursors } from "../../../../utils/mouseUtils/handleCanvasCursors"; type PointData = { pointId: string; position: [number, number, number]; isCurved?: boolean; handleA?: [number, number, number] | null; handleB?: [number, number, number] | null; }; interface PathDataInterface { pathId: string; isActive?: boolean; isCurved?: boolean; pathPoints: [PointData, PointData]; } type PathData = PathDataInterface[]; type PathHandlerProps = { selectedPath: PathDataInterface; points: [PointData, PointData]; paths: PathData; setPaths: React.Dispatch>; setHoveredLine: React.Dispatch< React.SetStateAction >; hoveredLine: PathDataInterface | null; hoveredPoint: PointData | null; }; export default function PathHandler({ selectedPath, setPaths, points, paths, setHoveredLine, hoveredLine, hoveredPoint, }: PathHandlerProps) { const { toolMode } = useToolMode(); const { scene, raycaster } = useThree(); const [dragOffset, setDragOffset] = useState(null); const [initialPositions, setInitialPositions] = useState<{ paths?: any; }>({}); const [isHovered, setIsHovered] = useState(false); const { activeTool } = useActiveTool(); const plane = useMemo(() => new Plane(new Vector3(0, 1, 0), 0), []); const path = useMemo(() => { const [start, end] = points.map((p) => new Vector3(...p.position)); return new LineCurve3(start, end); }, [points]); const removePath = (pathId: string) => { setPaths((prevPaths) => prevPaths.filter((p) => p.pathId !== pathId)); }; const handlePathClick = (pointId: string) => { if (toolMode === "3D-Delete") { removePath(pointId); } }; const handleDragStart = (points: [PointData, PointData]) => { if (activeTool !== "cursor") return; const intersectionPoint = new Vector3(); const hit = raycaster.ray.intersectPlane(plane, intersectionPoint); if (hit) { const start = new Vector3(...points[0].position); const end = new Vector3(...points[1].position); const midPoint = new Vector3().addVectors(start, end).multiplyScalar(0.5); const offset = new Vector3().subVectors(midPoint, hit); setDragOffset(offset); const pathSet = getPathsByPointId(points[0].pointId, paths); setInitialPositions({ paths: pathSet }); } }; // const handleDrag = (points: [PointData, PointData]) => { // if (isHovered && dragOffset) { // const intersectionPoint = new Vector3(); // const hit = raycaster.ray.intersectPlane(plane, intersectionPoint); // if (hit) { // handleCanvasCursors("grabbing"); // const positionWithOffset = new Vector3().addVectors(hit, dragOffset); // const start = new Vector3(...points[0].position); // const end = new Vector3(...points[1].position); // const midPoint = new Vector3() // .addVectors(start, end) // .multiplyScalar(0.5); // const delta = new Vector3().subVectors(positionWithOffset, midPoint); // const newStart = new Vector3().addVectors(start, delta); // const newEnd = new Vector3().addVectors(end, delta); // setPathPosition( // points[0].pointId, // [newStart.x, newStart.y, newStart.z], // setPaths // ); // setPathPosition( // points[1].pointId, // [newEnd.x, newEnd.y, newEnd.z], // setPaths // ); // } // } // }; const handleDrag = (points: [PointData, PointData]) => { if (isHovered && dragOffset) { const intersectionPoint = new Vector3(); const hit = raycaster.ray.intersectPlane(plane, intersectionPoint); if (hit) { handleCanvasCursors("grabbing"); const positionWithOffset = new Vector3().addVectors(hit, dragOffset); const start = new Vector3(...points[0].position); const end = new Vector3(...points[1].position); const midPoint = new Vector3() .addVectors(start, end) .multiplyScalar(0.5); const delta = new Vector3().subVectors(positionWithOffset, midPoint); const newStart: [number, number, number] = [ start.x + delta.x, start.y + delta.y, start.z + delta.z, ]; const newEnd: [number, number, number] = [ end.x + delta.x, end.y + delta.y, end.z + delta.z, ]; // ✅ Move both points separately (won’t overwrite other updates) setPathPosition(points[0].pointId, newStart, setPaths); setPathPosition(points[1].pointId, newEnd, setPaths); } } }; const handleDragEnd = (points: [PointData, PointData]) => {}; return ( <> handleDragStart(points)} onDrag={() => handleDrag(points)} onDragEnd={() => handleDragEnd(points)} > { e.stopPropagation(); handlePathClick(selectedPath.pathId); }} onPointerOver={(e) => { if (e.buttons === 0 && !e.ctrlKey) { setHoveredLine(selectedPath); setIsHovered(true); if (!hoveredPoint) { // handleCanvasCursors("grab"); } } }} onPointerOut={() => { if (isHovered && hoveredLine) { setHoveredLine(null); if (!hoveredPoint) { // handleCanvasCursors("default"); } } setIsHovered(false); }} /> ); }