From 74f28b49abaae86975af5161007838f45d1ea7dc Mon Sep 17 00:00:00 2001 From: pubuzhixing8 Date: Sat, 14 Dec 2024 21:51:39 +0800 Subject: [PATCH] feat(zoom): support zoom by custom center --- .changeset/ninety-buckets-drum.md | 5 +++++ packages/angular-board/src/board/board.component.ts | 2 +- packages/core/src/plugins/with-hotkey.ts | 2 +- packages/core/src/transforms/board.ts | 7 +++---- packages/core/src/utils/math.ts | 12 ++++++++++++ packages/graph-viz/src/perfect-arrows/get-arrow.ts | 3 ++- packages/graph-viz/src/perfect-arrows/utils.ts | 12 ------------ 7 files changed, 24 insertions(+), 19 deletions(-) create mode 100644 .changeset/ninety-buckets-drum.md diff --git a/.changeset/ninety-buckets-drum.md b/.changeset/ninety-buckets-drum.md new file mode 100644 index 000000000..3d9dfc3a5 --- /dev/null +++ b/.changeset/ninety-buckets-drum.md @@ -0,0 +1,5 @@ +--- +'@plait/core': minor +--- + +updateZoom support center param diff --git a/packages/angular-board/src/board/board.component.ts b/packages/angular-board/src/board/board.component.ts index 5f8973565..a53ac857f 100644 --- a/packages/angular-board/src/board/board.component.ts +++ b/packages/angular-board/src/board/board.component.ts @@ -543,7 +543,7 @@ export class PlaitBoardComponent implements BoardComponentInterface, OnInit, OnC -sign * // reduced amplification for small deltas (small movements on a trackpad) Math.min(1, absDelta / 20); - BoardTransforms.updateZoom(this.board, newZoom, false); + BoardTransforms.updateZoom(this.board, newZoom, PlaitBoard.getMovingPointInBoard(this.board)); } }); } diff --git a/packages/core/src/plugins/with-hotkey.ts b/packages/core/src/plugins/with-hotkey.ts index 0abaf9a3a..83321f485 100644 --- a/packages/core/src/plugins/with-hotkey.ts +++ b/packages/core/src/plugins/with-hotkey.ts @@ -83,7 +83,7 @@ export const withHotkey = (board: PlaitBoard) => { if (PlaitBoard.getMovingPointInBoard(board) || PlaitBoard.isMovingPointInBoard(board)) { if (isHotkey(['mod+=', 'mod++'], { byKey: true })(event)) { event.preventDefault(); - BoardTransforms.updateZoom(board, board.viewport.zoom + 0.1, false); + BoardTransforms.updateZoom(board, board.viewport.zoom + 0.1); return; } if (isHotkey(['mod+shift+=', 'mod+shift++'], { byKey: true })(event)) { diff --git a/packages/core/src/transforms/board.ts b/packages/core/src/transforms/board.ts index 1cd6cd061..8de56c6ab 100644 --- a/packages/core/src/transforms/board.ts +++ b/packages/core/src/transforms/board.ts @@ -27,17 +27,16 @@ function updateViewport(board: PlaitBoard, origination: Point, zoom?: number) { clearViewportOrigination(board); } -function updateZoom(board: PlaitBoard, newZoom: number, isCenter = true) { +function updateZoom(board: PlaitBoard, newZoom: number, center?: Point) { newZoom = clampZoomLevel(newZoom); - const movingPoint = PlaitBoard.getMovingPointInBoard(board); const nativeElement = PlaitBoard.getBoardContainer(board); const nativeElementRect = nativeElement.getBoundingClientRect(); const boardContainerRect = PlaitBoard.getBoardContainer(board).getBoundingClientRect(); let focusPoint = [boardContainerRect.width / 2, boardContainerRect.height / 2]; - if (!isCenter && movingPoint && distanceBetweenPointAndRectangle(movingPoint[0], movingPoint[1], nativeElementRect) === 0) { - focusPoint = [movingPoint[0] - nativeElementRect.x, movingPoint[1] - nativeElementRect.y]; + if (center && distanceBetweenPointAndRectangle(center[0], center[1], nativeElementRect) === 0) { + focusPoint = [center[0] - nativeElementRect.x, center[1] - nativeElementRect.y]; } const zoom = board.viewport.zoom; diff --git a/packages/core/src/utils/math.ts b/packages/core/src/utils/math.ts index 8edb067af..d2e3a617c 100644 --- a/packages/core/src/utils/math.ts +++ b/packages/core/src/utils/math.ts @@ -428,3 +428,15 @@ export function getCrossingPointsBetweenEllipseAndSegment( .map(t => [startPoint[0] + (endPoint[0] - startPoint[0]) * t + cx, startPoint[1] + (endPoint[1] - startPoint[1]) * t + cy]) ); } + +/** + * Get a point between two points. + * @param x0 The x-axis coordinate of the first point. + * @param y0 The y-axis coordinate of the first point. + * @param x1 The x-axis coordinate of the second point. + * @param y1 The y-axis coordinate of the second point. + * @param d Normalized + */ +export function getPointBetween(x0: number, y0: number, x1: number, y1: number, d = 0.5) { + return [x0 + (x1 - x0) * d, y0 + (y1 - y0) * d]; +} \ No newline at end of file diff --git a/packages/graph-viz/src/perfect-arrows/get-arrow.ts b/packages/graph-viz/src/perfect-arrows/get-arrow.ts index 11e1aac97..3a918bb3e 100644 --- a/packages/graph-viz/src/perfect-arrows/get-arrow.ts +++ b/packages/graph-viz/src/perfect-arrows/get-arrow.ts @@ -1,7 +1,8 @@ // Credits to perfect-arrows // https://github.com/steveruizok/perfect-arrows/blob/master/src/lib/getArrow.ts -import { getAngle, getDistance, getAngliness, projectPoint, getPointBetween, getSector, rotatePoint, modulate } from './utils'; +import { getPointBetween } from '@plait/core'; +import { getAngle, getDistance, getAngliness, projectPoint, getSector, rotatePoint, modulate } from './utils'; export type ArrowOptions = { bow?: number; diff --git a/packages/graph-viz/src/perfect-arrows/utils.ts b/packages/graph-viz/src/perfect-arrows/utils.ts index 4c60d539a..606268ef6 100644 --- a/packages/graph-viz/src/perfect-arrows/utils.ts +++ b/packages/graph-viz/src/perfect-arrows/utils.ts @@ -88,18 +88,6 @@ export function projectPoint(x0: number, y0: number, a: number, d: number) { return [Math.cos(a) * d + x0, Math.sin(a) * d + y0]; } -/** - * Get a point between two points. - * @param x0 The x-axis coordinate of the first point. - * @param y0 The y-axis coordinate of the first point. - * @param x1 The x-axis coordinate of the second point. - * @param y1 The y-axis coordinate of the second point. - * @param d Normalized - */ -export function getPointBetween(x0: number, y0: number, x1: number, y1: number, d = 0.5) { - return [x0 + (x1 - x0) * d, y0 + (y1 - y0) * d]; -} - /** * Get the sector of an angle (e.g. quadrant, octant) * @param a The angle to check.