From cfc1b7687e1237161fea373a49fe3f421b7806e6 Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Tue, 15 Jul 2025 20:56:02 +0200 Subject: [PATCH] Allow click and drag to pan --- plugins/minimap/web/CanvasMinimapPage.tsx | 81 ++++++++++++++++++++++- 1 file changed, 79 insertions(+), 2 deletions(-) diff --git a/plugins/minimap/web/CanvasMinimapPage.tsx b/plugins/minimap/web/CanvasMinimapPage.tsx index 7ce0269d..c8c44bca 100644 --- a/plugins/minimap/web/CanvasMinimapPage.tsx +++ b/plugins/minimap/web/CanvasMinimapPage.tsx @@ -51,6 +51,9 @@ export default function CanvasMinimapPage() { }); const [resizeCounter, setResizeCounter] = useState(0); + // Mouse drag state for panning (for cursor display only) + const [isDragging, setIsDragging] = useState(false); + // Canvas refs const canvasRef = useRef(null); const containerRef = useRef(null); @@ -70,6 +73,10 @@ export default function CanvasMinimapPage() { // Animation frame for smooth rendering const animationFrameRef = useRef(); + // Refs for drag state to avoid re-attaching event listeners + const isDraggingRef = useRef(false); + const lastMousePosRef = useRef<{ x: number; y: number } | null>(null); + const control = useContext(ControlContext); // Load instance bounds on component mount @@ -155,6 +162,76 @@ export default function CanvasMinimapPage() { }; }, [viewState.zoomLevel]); + // Mouse event handlers for click and drag panning + useEffect(() => { + const canvasElement = canvasRef.current; + + if (!canvasElement) { + return; + } + + const handleMouseDown = (e: MouseEvent) => { + if (e.button === 0) { // Left mouse button + isDraggingRef.current = true; + lastMousePosRef.current = { x: e.clientX, y: e.clientY }; + setIsDragging(true); // Update state for cursor change + e.preventDefault(); + } + }; + + const handleMouseMove = (e: MouseEvent) => { + if (isDraggingRef.current && lastMousePosRef.current) { + const deltaX = e.clientX - lastMousePosRef.current.x; + const deltaY = e.clientY - lastMousePosRef.current.y; + + // Convert screen delta to world delta (invert because dragging right should move view left) + const worldDeltaX = -deltaX / viewState.zoomLevel; + const worldDeltaY = -deltaY / viewState.zoomLevel; + + setViewState(prev => ({ + ...prev, + centerX: prev.centerX + worldDeltaX, + centerY: prev.centerY + worldDeltaY + })); + + lastMousePosRef.current = { x: e.clientX, y: e.clientY }; + } + }; + + const handleMouseUp = (e: MouseEvent) => { + if (e.button === 0) { // Left mouse button + isDraggingRef.current = false; + lastMousePosRef.current = null; + setIsDragging(false); // Update state for cursor change + } + }; + + const handleMouseLeave = () => { + // Stop dragging if mouse leaves canvas + isDraggingRef.current = false; + lastMousePosRef.current = null; + setIsDragging(false); // Update state for cursor change + }; + + canvasElement.addEventListener('mousedown', handleMouseDown); + canvasElement.addEventListener('mousemove', handleMouseMove); + canvasElement.addEventListener('mouseup', handleMouseUp); + canvasElement.addEventListener('mouseleave', handleMouseLeave); + + // Also listen to document for mouse events to handle dragging outside canvas + document.addEventListener('mousemove', handleMouseMove); + document.addEventListener('mouseup', handleMouseUp); + + return () => { + canvasElement.removeEventListener('mousedown', handleMouseDown); + canvasElement.removeEventListener('mousemove', handleMouseMove); + canvasElement.removeEventListener('mouseup', handleMouseUp); + canvasElement.removeEventListener('mouseleave', handleMouseLeave); + document.removeEventListener('mousemove', handleMouseMove); + document.removeEventListener('mouseup', handleMouseUp); + }; + }, [viewState.zoomLevel, selectedInstance]); // Add selectedInstance to trigger setup when canvas becomes available + // Render loop useEffect(() => { const render = () => { @@ -674,7 +751,7 @@ export default function CanvasMinimapPage() { {selectedInstance ? (
- Use WASD to move, +/- or scroll wheel to zoom. Current zoom: {viewState.zoomLevel}x + Use WASD to move, click and drag to pan, +/- or scroll wheel to zoom. Current zoom: {viewState.zoomLevel}x