diff --git a/.changeset/breezy-knives-tie.md b/.changeset/breezy-knives-tie.md new file mode 100644 index 000000000..e0ecf8e07 --- /dev/null +++ b/.changeset/breezy-knives-tie.md @@ -0,0 +1,5 @@ +--- +'@plait/draw': minor +--- + +support snap angle when rotate with hotkey diff --git a/packages/draw/src/plugins/with-draw-rotate.ts b/packages/draw/src/plugins/with-draw-rotate.ts index 0fdf42d07..b05120f81 100644 --- a/packages/draw/src/plugins/with-draw-rotate.ts +++ b/packages/draw/src/plugins/with-draw-rotate.ts @@ -19,10 +19,11 @@ import { SELECTION_BORDER_COLOR, setAngleForG, rotateElements, - PlaitElement, getAngleBetweenPoints, ROTATE_HANDLE_CLASS_NAME, - SELECTION_RECTANGLE_CLASS_NAME + SELECTION_RECTANGLE_CLASS_NAME, + normalizeAngle, + degreesToRadians } from '@plait/core'; import { addRotating, removeRotating, drawHandle, drawRotateHandle, isRotating, RotateRef } from '@plait/common'; import { PlaitDrawElement } from '../interfaces'; @@ -62,6 +63,7 @@ export const withDrawRotate = (board: PlaitBoard) => { board.pointerMove = (event: PointerEvent) => { if (rotateRef) { event.preventDefault(); + const isShift = !!event.shiftKey; addRotating(board, rotateRef); const endPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y)); const selectionRectangle = getRectangleByElements(board, rotateRef.elements, false); @@ -72,7 +74,26 @@ export const withDrawRotate = (board: PlaitBoard) => { throttleRAF(board, 'with-common-rotate', () => { if (rotateRef && rotateRef.startPoint) { - rotateRef.angle = getAngleBetweenPoints(rotateRef.startPoint, endPoint, selectionCenterPoint); + let angle = getAngleBetweenPoints(rotateRef.startPoint, endPoint, selectionCenterPoint); + if (isShift) { + angle += Math.PI / 12 / 2; + angle -= angle % (Math.PI / 12); + } + + const selectionAngle = getSelectionAngle(rotateRef.elements); + let remainder = (selectionAngle + angle) % (Math.PI / 2); + + if (Math.PI / 2 - remainder <= degreesToRadians(5)) { + const snapAngle = Math.PI / 2 - remainder; + angle += snapAngle; + } + + if (remainder <= degreesToRadians(5)) { + const snapAngle = -remainder; + angle += snapAngle; + } + + rotateRef.angle = normalizeAngle(angle); if (rotateRef.angle) { rotateElements(board, rotateRef.elements, rotateRef.angle); }