From e77411d9dab14fcfde5175c5683366d2fe385800 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 Aug 2025 17:36:27 +0800 Subject: [PATCH] Add touch screen dragging support to minimap (#4781) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: snomiao <7323030+snomiao@users.noreply.github.com> --- src/components/graph/MiniMap.vue | 14 +- src/composables/useMinimap.ts | 15 +- tests-ui/tests/composables/useMinimap.test.ts | 135 ++++++++++++++---- 3 files changed, 126 insertions(+), 38 deletions(-) diff --git a/src/components/graph/MiniMap.vue b/src/components/graph/MiniMap.vue index 2ce097646..3b1a3c953 100644 --- a/src/components/graph/MiniMap.vue +++ b/src/components/graph/MiniMap.vue @@ -4,10 +4,10 @@ ref="containerRef" class="litegraph-minimap absolute bottom-[20px] right-[90px] z-[1000]" :style="containerStyles" - @mousedown="handleMouseDown" - @mousemove="handleMouseMove" - @mouseup="handleMouseUp" - @mouseleave="handleMouseUp" + @pointerdown="handlePointerDown" + @pointermove="handlePointerMove" + @pointerup="handlePointerUp" + @pointerleave="handlePointerUp" @wheel="handleWheel" > { + // Pointer event handlers for touch screen support + const handlePointerDown = (e: PointerEvent) => { isDragging.value = true updateContainerRect() - handleMouseMove(e) + handlePointerMove(e) } - const handleMouseMove = (e: MouseEvent) => { + const handlePointerMove = (e: PointerEvent) => { if (!isDragging.value || !canvasRef.value || !canvas.value) return const x = e.clientX - containerRect.value.left @@ -455,7 +456,7 @@ export function useMinimap() { centerViewOn(worldX, worldY) } - const handleMouseUp = () => { + const handlePointerUp = () => { isDragging.value = false } @@ -695,9 +696,9 @@ export function useMinimap() { init, destroy, toggle, - handleMouseDown, - handleMouseMove, - handleMouseUp, + handlePointerDown, + handlePointerMove, + handlePointerUp, handleWheel, setMinimapRef } diff --git a/tests-ui/tests/composables/useMinimap.test.ts b/tests-ui/tests/composables/useMinimap.test.ts index fb468a66d..1c1b12cb7 100644 --- a/tests-ui/tests/composables/useMinimap.test.ts +++ b/tests-ui/tests/composables/useMinimap.test.ts @@ -490,72 +490,159 @@ describe('useMinimap', () => { }) }) - describe('mouse interactions', () => { - it('should handle mouse down and start dragging', async () => { + describe('pointer interactions', () => { + it('should handle pointer down and start dragging (mouse)', async () => { const minimap = await createAndInitializeMinimap() - const mouseEvent = new MouseEvent('mousedown', { + const pointerEvent = new PointerEvent('pointerdown', { clientX: 150, - clientY: 150 + clientY: 150, + pointerType: 'mouse' }) - minimap.handleMouseDown(mouseEvent) + minimap.handlePointerDown(pointerEvent) expect(mockContainerElement.getBoundingClientRect).toHaveBeenCalled() expect(mockCanvas.setDirty).toHaveBeenCalledWith(true, true) }) - it('should handle mouse move while dragging', async () => { + it('should handle pointer move while dragging (mouse)', async () => { const minimap = await createAndInitializeMinimap() - const mouseDownEvent = new MouseEvent('mousedown', { + const pointerDownEvent = new PointerEvent('pointerdown', { clientX: 150, - clientY: 150 + clientY: 150, + pointerType: 'mouse' }) - minimap.handleMouseDown(mouseDownEvent) + minimap.handlePointerDown(pointerDownEvent) - const mouseMoveEvent = new MouseEvent('mousemove', { + const pointerMoveEvent = new PointerEvent('pointermove', { clientX: 200, - clientY: 200 + clientY: 200, + pointerType: 'mouse' }) - minimap.handleMouseMove(mouseMoveEvent) + minimap.handlePointerMove(pointerMoveEvent) expect(mockCanvas.setDirty).toHaveBeenCalledWith(true, true) expect(mockCanvas.ds.offset).toBeDefined() }) - it('should not move when not dragging', async () => { + it('should handle pointer up to stop dragging (mouse)', async () => { const minimap = await createAndInitializeMinimap() + const pointerDownEvent = new PointerEvent('pointerdown', { + clientX: 150, + clientY: 150, + pointerType: 'mouse' + }) + minimap.handlePointerDown(pointerDownEvent) + + minimap.handlePointerUp() + mockCanvas.setDirty.mockClear() - const mouseMoveEvent = new MouseEvent('mousemove', { + const pointerMoveEvent = new PointerEvent('pointermove', { clientX: 200, - clientY: 200 + clientY: 200, + pointerType: 'mouse' }) - minimap.handleMouseMove(mouseMoveEvent) + minimap.handlePointerMove(pointerMoveEvent) expect(mockCanvas.setDirty).not.toHaveBeenCalled() }) - it('should handle mouse up to stop dragging', async () => { + it('should handle pointer down and start dragging (touch)', async () => { const minimap = await createAndInitializeMinimap() - const mouseDownEvent = new MouseEvent('mousedown', { + const pointerEvent = new PointerEvent('pointerdown', { clientX: 150, - clientY: 150 + clientY: 150, + pointerType: 'touch' }) - minimap.handleMouseDown(mouseDownEvent) - minimap.handleMouseUp() + minimap.handlePointerDown(pointerEvent) + + expect(mockContainerElement.getBoundingClientRect).toHaveBeenCalled() + expect(mockCanvas.setDirty).toHaveBeenCalledWith(true, true) + }) + + it('should handle pointer move while dragging (touch)', async () => { + const minimap = await createAndInitializeMinimap() + + const pointerDownEvent = new PointerEvent('pointerdown', { + clientX: 150, + clientY: 150, + pointerType: 'touch' + }) + minimap.handlePointerDown(pointerDownEvent) + + const pointerMoveEvent = new PointerEvent('pointermove', { + clientX: 200, + clientY: 200, + pointerType: 'touch' + }) + minimap.handlePointerMove(pointerMoveEvent) + + expect(mockCanvas.setDirty).toHaveBeenCalledWith(true, true) + expect(mockCanvas.ds.offset).toBeDefined() + }) + + it('should handle pointer move while dragging (pen)', async () => { + const minimap = await createAndInitializeMinimap() + + const pointerDownEvent = new PointerEvent('pointerdown', { + clientX: 150, + clientY: 150, + pointerType: 'pen' + }) + minimap.handlePointerDown(pointerDownEvent) + + const pointerMoveEvent = new PointerEvent('pointermove', { + clientX: 200, + clientY: 200, + pointerType: 'pen' + }) + minimap.handlePointerMove(pointerMoveEvent) + + expect(mockCanvas.setDirty).toHaveBeenCalledWith(true, true) + expect(mockCanvas.ds.offset).toBeDefined() + }) + + it('should not move when not dragging with pointer', async () => { + const minimap = await createAndInitializeMinimap() mockCanvas.setDirty.mockClear() - const mouseMoveEvent = new MouseEvent('mousemove', { + const pointerMoveEvent = new PointerEvent('pointermove', { clientX: 200, - clientY: 200 + clientY: 200, + pointerType: 'touch' }) - minimap.handleMouseMove(mouseMoveEvent) + minimap.handlePointerMove(pointerMoveEvent) + + expect(mockCanvas.setDirty).not.toHaveBeenCalled() + }) + + it('should handle pointer up to stop dragging (touch)', async () => { + const minimap = await createAndInitializeMinimap() + + const pointerDownEvent = new PointerEvent('pointerdown', { + clientX: 150, + clientY: 150, + pointerType: 'touch' + }) + minimap.handlePointerDown(pointerDownEvent) + + minimap.handlePointerUp() + + mockCanvas.setDirty.mockClear() + + const pointerMoveEvent = new PointerEvent('pointermove', { + clientX: 200, + clientY: 200, + pointerType: 'touch' + }) + minimap.handlePointerMove(pointerMoveEvent) expect(mockCanvas.setDirty).not.toHaveBeenCalled() })