From 0b037f46e9e798d377589444a9b82b7f76e152d6 Mon Sep 17 00:00:00 2001 From: Yunine Date: Fri, 17 Jul 2026 20:35:28 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8F=B3=E9=94=AE=E6=8C=89?= =?UTF-8?q?=E4=B8=8B=E6=97=B6=E4=B8=8D=E5=86=8D=E8=A7=A6=E5=8F=91=E7=94=BB?= =?UTF-8?q?=E5=B8=83=E5=B9=B3=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ImageCanvasStageInteractionModel.ts | 39 ++++++++++++------- .../useImageCanvasStageInteractions.ts | 38 +++++++++++++++--- 2 files changed, 57 insertions(+), 20 deletions(-) diff --git a/src/components/image-editor/ImageCanvasStageInteractionModel.ts b/src/components/image-editor/ImageCanvasStageInteractionModel.ts index 08ceb1a0d..19445fc06 100644 --- a/src/components/image-editor/ImageCanvasStageInteractionModel.ts +++ b/src/components/image-editor/ImageCanvasStageInteractionModel.ts @@ -30,10 +30,13 @@ type PointerSource = { }; }; -type CanvasRectLike = { - left?: number; - top?: number; -} | null | undefined; +type CanvasRectLike = + | { + left?: number; + top?: number; + } + | null + | undefined; const CANVAS_GENERATION_DIALOG_MODES = new Set([ 'generate', @@ -64,12 +67,22 @@ function hasCanvasGenerationDialogMode( export function getPointerButton(event: PointerSource) { const nativeButtons = Number(event.nativeEvent?.buttons); - if (Number.isFinite(nativeButtons) && (nativeButtons & 4) === 4) { - return 1; + if (Number.isFinite(nativeButtons)) { + if ((nativeButtons & 2) === 2) { + return 2; + } + if ((nativeButtons & 4) === 4) { + return 1; + } } const syntheticButtons = Number(event.buttons); - if (Number.isFinite(syntheticButtons) && (syntheticButtons & 4) === 4) { - return 1; + if (Number.isFinite(syntheticButtons)) { + if ((syntheticButtons & 2) === 2) { + return 2; + } + if ((syntheticButtons & 4) === 4) { + return 1; + } } const syntheticButton = Number(event.button); if (Number.isFinite(syntheticButton)) { @@ -200,9 +213,8 @@ export function createLayerDragStart({ isMultiSelectGesture, }); const selectedCanvasLayerIds = getSelectedLayerIds(nextSelectedLayerIds); - const selectedGenerationDialogIds = getSelectedGenerationDialogIds( - nextSelectedLayerIds, - ); + const selectedGenerationDialogIds = + getSelectedGenerationDialogIds(nextSelectedLayerIds); const dragLayerIds = selectedCanvasLayerIds.includes(layer.id) ? selectedCanvasLayerIds : [layer.id]; @@ -300,9 +312,8 @@ export function createGenerationFrameSelectionStart({ selectedIds: selectedLayerIds, isMultiSelectGesture, }); - const selectedGenerationDialogIds = getSelectedGenerationDialogIds( - nextSelectedLayerIds, - ); + const selectedGenerationDialogIds = + getSelectedGenerationDialogIds(nextSelectedLayerIds); const selectedCanvasLayerIds = getSelectedLayerIds(nextSelectedLayerIds); const dragDialogIds = selectedGenerationDialogIds.includes(dialog.id) ? selectedGenerationDialogIds diff --git a/src/components/image-editor/useImageCanvasStageInteractions.ts b/src/components/image-editor/useImageCanvasStageInteractions.ts index 5f19ae5d3..44145b9fd 100644 --- a/src/components/image-editor/useImageCanvasStageInteractions.ts +++ b/src/components/image-editor/useImageCanvasStageInteractions.ts @@ -92,9 +92,7 @@ type UseImageCanvasStageInteractionsOptions = { pickUiDesignSpecFromLayer: (layer: CanvasLayer) => void; pickPublicationReferenceFromLayer: (layer: CanvasLayer) => void; openLayerGenerationDialog?: (layer: CanvasLayer) => boolean; - activateCanvasGenerationDialog: ( - dialog: CanvasGenerationDialogState, - ) => void; + activateCanvasGenerationDialog: (dialog: CanvasGenerationDialogState) => void; updateCanvasGenerationDialogById: ( dialogId: string, updater: ( @@ -216,6 +214,15 @@ export function useImageCanvasStageInteractions({ } }, [finishViewportInteraction, flushMinimapViewportDrag]); + const rejectRightButtonInteraction = useCallback( + (event: ReactPointerEvent) => { + event.preventDefault(); + event.stopPropagation(); + clearActiveInteraction(); + }, + [clearActiveInteraction], + ); + const setShiftPressed = useCallback((pressed: boolean) => { isShiftPressedRef.current = pressed; }, []); @@ -239,12 +246,17 @@ export function useImageCanvasStageInteractions({ const handleCanvasPointerDown = useCallback( (event: ReactPointerEvent) => { const button = getPointerButton(event); - if (button === 1 ||(button !== 2 && effectiveTool === 'hand')) { + if (button === 2) { + rejectRightButtonInteraction(event); + return; + } + if (button === 1 || (button === 0 && effectiveTool === 'hand')) { startPan(event); return; } if (button !== 0) { + event.preventDefault(); return; } const target = event.target as HTMLElement; @@ -275,12 +287,17 @@ export function useImageCanvasStageInteractions({ const handleLayerPointerDown = useCallback( (event: ReactPointerEvent, layer: CanvasLayer) => { const button = getPointerButton(event); - if (button === 1 || effectiveTool === 'hand') { + if (button === 2) { + rejectRightButtonInteraction(event); + return; + } + if (button === 1 || (button === 0 && effectiveTool === 'hand')) { event.stopPropagation(); startPan(event); return; } if (button !== 0) { + event.preventDefault(); event.stopPropagation(); return; } @@ -481,12 +498,18 @@ export function useImageCanvasStageInteractions({ return; } const button = getPointerButton(event); - if (button === 1 || effectiveTool === 'hand') { + if (button === 2) { + rejectRightButtonInteraction(event); + return; + } + if (button === 1 || (button === 0 && effectiveTool === 'hand')) { event.stopPropagation(); startPan(event); return; } if (button !== 0) { + event.preventDefault(); + event.stopPropagation(); return; } @@ -554,6 +577,9 @@ export function useImageCanvasStageInteractions({ const handlePointerMove = useCallback( (event: ReactPointerEvent) => { + if ((event.buttons & 2) !== 0 && (event.buttons & (1 | 4)) === 0) { + return; + } if (canvasMarquee && canvasMarquee.pointerId === event.pointerId) { event.preventDefault(); const rect = canvasViewportRef.current?.getBoundingClientRect();