diff --git a/.changeset/friendly-pets-yell.md b/.changeset/friendly-pets-yell.md new file mode 100644 index 000000000..91b0dc217 --- /dev/null +++ b/.changeset/friendly-pets-yell.md @@ -0,0 +1,5 @@ +--- +'@plait/core': minor +--- + +support board movement control diff --git a/packages/core/src/interfaces/plugin.ts b/packages/core/src/interfaces/plugin.ts index 3e6953607..6790cd970 100644 --- a/packages/core/src/interfaces/plugin.ts +++ b/packages/core/src/interfaces/plugin.ts @@ -12,6 +12,11 @@ export interface WithSelectionPluginOptions extends WithPluginOptions { isPreventClearSelection: boolean; // is clear selection on click outside of board container } +export interface WithHandPluginOptions extends WithPluginOptions { + isHandMode: (board: PlaitBoard, event: PointerEvent) => boolean; +} + export enum PlaitPluginKey { - 'withSelection' = 'withSelection' + 'withSelection' = 'withSelection', + 'withHand' = 'withHand' } diff --git a/packages/core/src/plugins/with-hand.ts b/packages/core/src/plugins/with-hand.ts index 5a8e8284e..0f14c3193 100644 --- a/packages/core/src/plugins/with-hand.ts +++ b/packages/core/src/plugins/with-hand.ts @@ -1,44 +1,56 @@ -import { PlaitPointerType, PlaitBoard, PlaitBoardMove } from '../interfaces'; +import { PlaitPointerType, PlaitBoard, PlaitBoardMove, WithHandPluginOptions, PlaitPluginKey } from '../interfaces'; import { BoardTransforms } from '../transforms'; import { isMainPointer } from '../utils/dom/common'; import { updateViewportContainerScroll } from '../utils/viewport'; +import { PlaitOptionsBoard } from './with-options'; export function withHandPointer(board: T) { - const { pointerDown, pointerMove, globalPointerUp, keyDown, keyUp } = board; + const { pointerDown, pointerMove, globalPointerUp, keyDown, keyUp, pointerUp } = board; let isMoving: boolean = false; - const plaitBoardMove: PlaitBoardMove = { - x: 0, - y: 0 - }; + let movingPoint: PlaitBoardMove | null = null; board.pointerDown = (event: PointerEvent) => { - if (PlaitBoard.isPointer(board, PlaitPointerType.hand) && isMainPointer(event)) { - isMoving = true; - PlaitBoard.getBoardContainer(board).classList.add('viewport-moving'); - plaitBoardMove.x = event.x; - plaitBoardMove.y = event.y; + const options = ((board as unknown) as PlaitOptionsBoard).getPluginOptions(PlaitPluginKey.withHand); + if ((options?.isHandMode(board, event) || PlaitBoard.isPointer(board, PlaitPointerType.hand)) && isMainPointer(event)) { + movingPoint = { + x: event.x, + y: event.y + }; } pointerDown(event); }; board.pointerMove = (event: PointerEvent) => { - if (PlaitBoard.isPointer(board, PlaitPointerType.hand) && isMoving) { + const options = ((board as unknown) as PlaitOptionsBoard).getPluginOptions(PlaitPluginKey.withHand); + if (movingPoint && !isMoving) { + isMoving = true; + PlaitBoard.getBoardContainer(board).classList.add('viewport-moving'); + } + if ((options?.isHandMode(board, event) || PlaitBoard.isPointer(board, PlaitPointerType.hand)) && isMoving && movingPoint) { const viewportContainer = PlaitBoard.getViewportContainer(board); - const left = viewportContainer.scrollLeft - (event.x - plaitBoardMove.x); - const top = viewportContainer.scrollTop - (event.y - plaitBoardMove.y); + const left = viewportContainer.scrollLeft - (event.x - movingPoint.x); + const top = viewportContainer.scrollTop - (event.y - movingPoint.y); updateViewportContainerScroll(board, left, top, false); - plaitBoardMove.x = event.x; - plaitBoardMove.y = event.y; + movingPoint.x = event.x; + movingPoint.y = event.y; } pointerMove(event); }; + board.pointerUp = (event: PointerEvent) => { + if (isMoving) { + return; + } + pointerUp(event); + }; + board.globalPointerUp = (event: PointerEvent) => { + if (movingPoint) { + movingPoint = null; + } if (isMoving) { isMoving = false; PlaitBoard.getBoardContainer(board).classList.remove('viewport-moving'); - plaitBoardMove.x = 0; - plaitBoardMove.y = 0; } globalPointerUp(event); };