From b4d8b04d9e7234f574d484bc51eccb03b9d88951 Mon Sep 17 00:00:00 2001 From: David Luzar <5153846+dwelle@users.noreply.github.com> Date: Tue, 1 Oct 2024 21:27:17 +0200 Subject: [PATCH] refactor: `point()` -> `pointFrom()` to fix compiler issue (#8578) --- .../excalidraw/actions/actionFinalize.tsx | 4 +- .../excalidraw/actions/actionFlip.test.tsx | 18 +- .../excalidraw/actions/actionProperties.tsx | 4 +- packages/excalidraw/charts.ts | 10 +- packages/excalidraw/components/App.tsx | 141 +++++++++------- .../components/Stats/MultiDimension.tsx | 6 +- .../components/Stats/MultiPosition.tsx | 18 +- .../excalidraw/components/Stats/Position.tsx | 10 +- .../components/Stats/stats.test.tsx | 26 +-- packages/excalidraw/components/Stats/utils.ts | 10 +- .../components/hyperlink/Hyperlink.tsx | 8 +- .../components/hyperlink/helpers.ts | 13 +- packages/excalidraw/data/restore.ts | 6 +- packages/excalidraw/data/transform.test.ts | 6 +- packages/excalidraw/data/transform.ts | 6 +- packages/excalidraw/element/binding.ts | 81 +++++---- packages/excalidraw/element/bounds.test.ts | 8 +- packages/excalidraw/element/bounds.ts | 62 +++---- packages/excalidraw/element/collision.ts | 53 +++--- packages/excalidraw/element/flowchart.ts | 4 +- packages/excalidraw/element/heading.ts | 18 +- .../excalidraw/element/linearElementEditor.ts | 96 ++++++----- .../excalidraw/element/newElement.test.ts | 4 +- packages/excalidraw/element/resizeElements.ts | 96 ++++++----- packages/excalidraw/element/resizeTest.ts | 24 +-- packages/excalidraw/element/routing.test.tsx | 10 +- packages/excalidraw/element/routing.ts | 10 +- .../excalidraw/element/textWysiwyg.test.tsx | 4 +- .../excalidraw/element/transformHandles.ts | 6 +- packages/excalidraw/frame.ts | 14 +- packages/excalidraw/renderer/renderSnaps.ts | 38 +++-- packages/excalidraw/scene/Shape.ts | 4 +- packages/excalidraw/shapes.tsx | 52 +++--- packages/excalidraw/snapping.ts | 154 ++++++++++-------- packages/excalidraw/tests/binding.test.tsx | 13 +- packages/excalidraw/tests/helpers/api.ts | 10 +- packages/excalidraw/tests/helpers/ui.ts | 15 +- packages/excalidraw/tests/history.test.tsx | 18 +- .../tests/linearElementEditor.test.tsx | 85 +++++----- packages/excalidraw/tests/resize.test.tsx | 65 ++++---- packages/excalidraw/visualdebug.ts | 26 +-- packages/math/arc.test.ts | 42 ++--- packages/math/curve.ts | 22 +-- packages/math/point.test.ts | 10 +- packages/math/point.ts | 19 ++- packages/utils/collision.test.ts | 66 ++++---- packages/utils/collision.ts | 4 +- packages/utils/geometry/geometry.test.ts | 42 ++--- packages/utils/geometry/shape.ts | 80 ++++----- packages/utils/withinBounds.ts | 20 +-- 50 files changed, 843 insertions(+), 718 deletions(-) diff --git a/packages/excalidraw/actions/actionFinalize.tsx b/packages/excalidraw/actions/actionFinalize.tsx index 6184b4294a..9074f61113 100644 --- a/packages/excalidraw/actions/actionFinalize.tsx +++ b/packages/excalidraw/actions/actionFinalize.tsx @@ -15,7 +15,7 @@ import { isBindingElement, isLinearElement } from "../element/typeChecks"; import type { AppState } from "../types"; import { resetCursor } from "../cursor"; import { StoreAction } from "../store"; -import { pathIsALoop, point } from "../../math"; +import { pathIsALoop, pointFrom } from "../../math"; export const actionFinalize = register({ name: "finalize", @@ -114,7 +114,7 @@ export const actionFinalize = register({ mutateElement(multiPointElement, { points: linePoints.map((p, index) => index === linePoints.length - 1 - ? point(firstPoint[0], firstPoint[1]) + ? pointFrom(firstPoint[0], firstPoint[1]) : p, ), }); diff --git a/packages/excalidraw/actions/actionFlip.test.tsx b/packages/excalidraw/actions/actionFlip.test.tsx index ef71dbe940..4f8be5b49e 100644 --- a/packages/excalidraw/actions/actionFlip.test.tsx +++ b/packages/excalidraw/actions/actionFlip.test.tsx @@ -9,7 +9,7 @@ import { } from "../tests/test-utils"; import { API } from "../tests/helpers/api"; import type { LocalPoint } from "../../math"; -import { point, radians } from "../../math"; +import { pointFrom, radians } from "../../math"; import { actionFlipHorizontal, actionFlipVertical } from "./actionFlip"; import { Keyboard, Pointer, UI } from "../tests/helpers/ui"; import { vi } from "vitest"; @@ -144,9 +144,9 @@ const createLinearElementWithCurveInsideMinMaxPoints = ( link: null, locked: false, points: [ - point(0, 0), - point(-922.4761962890625, 300.3277587890625), - point(828.0126953125, 410.51605224609375), + pointFrom(0, 0), + pointFrom(-922.4761962890625, 300.3277587890625), + pointFrom(828.0126953125, 410.51605224609375), ], }); }; @@ -936,11 +936,11 @@ describe("flipping re-centers selection", () => { startArrowhead: null, endArrowhead: "arrow", points: [ - point(0, 0), - point(0, -35), - point(-90.9, -35), - point(-90.9, 204.9), - point(65.1, 204.9), + pointFrom(0, 0), + pointFrom(0, -35), + pointFrom(-90.9, -35), + pointFrom(-90.9, 204.9), + pointFrom(65.1, 204.9), ], elbowed: true, }), diff --git a/packages/excalidraw/actions/actionProperties.tsx b/packages/excalidraw/actions/actionProperties.tsx index 8a13c1a8ae..3b3b1fa38b 100644 --- a/packages/excalidraw/actions/actionProperties.tsx +++ b/packages/excalidraw/actions/actionProperties.tsx @@ -111,7 +111,7 @@ import { import { mutateElbowArrow } from "../element/routing"; import { LinearElementEditor } from "../element/linearElementEditor"; import type { LocalPoint } from "../../math"; -import { point, vector } from "../../math"; +import { pointFrom, vector } from "../../math"; const FONT_SIZE_RELATIVE_INCREASE_STEP = 0.1; @@ -1644,7 +1644,7 @@ export const actionChangeArrowType = register({ elementsMap, [finalStartPoint, finalEndPoint].map( (p): LocalPoint => - point(p[0] - newElement.x, p[1] - newElement.y), + pointFrom(p[0] - newElement.x, p[1] - newElement.y), ), vector(0, 0), { diff --git a/packages/excalidraw/charts.ts b/packages/excalidraw/charts.ts index 583120bcee..24edd39c5e 100644 --- a/packages/excalidraw/charts.ts +++ b/packages/excalidraw/charts.ts @@ -1,4 +1,4 @@ -import { point, radians } from "../math"; +import { pointFrom, radians } from "../math"; import { COLOR_PALETTE, DEFAULT_CHART_COLOR_INDEX, @@ -259,7 +259,7 @@ const chartLines = ( x, y, width: chartWidth, - points: [point(0, 0), point(chartWidth, 0)], + points: [pointFrom(0, 0), pointFrom(chartWidth, 0)], }); const yLine = newLinearElement({ @@ -270,7 +270,7 @@ const chartLines = ( x, y, height: chartHeight, - points: [point(0, 0), point(0, -chartHeight)], + points: [pointFrom(0, 0), pointFrom(0, -chartHeight)], }); const maxLine = newLinearElement({ @@ -283,7 +283,7 @@ const chartLines = ( strokeStyle: "dotted", width: chartWidth, opacity: GRID_OPACITY, - points: [point(0, 0), point(chartWidth, 0)], + points: [pointFrom(0, 0), pointFrom(chartWidth, 0)], }); return [xLine, yLine, maxLine]; @@ -440,7 +440,7 @@ const chartTypeLine = ( height: cy, strokeStyle: "dotted", opacity: GRID_OPACITY, - points: [point(0, 0), point(0, cy)], + points: [pointFrom(0, 0), pointFrom(0, cy)], }); }); diff --git a/packages/excalidraw/components/App.tsx b/packages/excalidraw/components/App.tsx index 14c6d4344a..bd4cfe2169 100644 --- a/packages/excalidraw/components/App.tsx +++ b/packages/excalidraw/components/App.tsx @@ -449,7 +449,7 @@ import type { } from "../../math"; import { pathIsALoop, - point, + pointFrom, pointCenter, pointDistance, pointSubtract, @@ -600,7 +600,7 @@ class App extends React.Component { lastPointerUpEvent: React.PointerEvent | PointerEvent | null = null; lastPointerMoveEvent: PointerEvent | null = null; - lastViewportPosition = point(0, 0); + lastViewportPosition = pointFrom(0, 0); animationFrameHandler = new AnimationFrameHandler(); @@ -1008,7 +1008,7 @@ class App extends React.Component { <> {embeddableElements.map((el) => { const [x, y] = sceneCoordsToViewportCoords( - point(el.x, el.y), + pointFrom(el.x, el.y), this.state, ); @@ -1294,11 +1294,11 @@ class App extends React.Component { if (frameNameDiv) { const box = frameNameDiv.getBoundingClientRect(); const boxSceneTopLeft = viewportCoordsToSceneCoords( - point(box.x, box.y), + pointFrom(box.x, box.y), this.state, ); const boxSceneBottomRight = viewportCoordsToSceneCoords( - point(box.right, box.bottom), + pointFrom(box.right, box.bottom), this.state, ); @@ -1354,7 +1354,10 @@ class App extends React.Component { return null; } - const [x1, y1] = sceneCoordsToViewportCoords(point(f.x, f.y), this.state); + const [x1, y1] = sceneCoordsToViewportCoords( + pointFrom(f.x, f.y), + this.state, + ); const FRAME_NAME_EDIT_PADDING = 6; @@ -3171,7 +3174,7 @@ class App extends React.Component { : this.state.height / 2 + this.state.offsetTop; const [x, y] = viewportCoordsToSceneCoords( - point(clientX, clientY), + pointFrom(clientX, clientY), this.state, ); @@ -3197,7 +3200,7 @@ class App extends React.Component { syncMovedIndices(nextElements, arrayToMap(newElements)); - const topLayerFrame = this.getTopLayerFrameAtSceneCoords(point(x, y)); + const topLayerFrame = this.getTopLayerFrameAtSceneCoords(pointFrom(x, y)); if (topLayerFrame) { const eligibleElements = filterElementsEligibleAsFrameChildren( @@ -3407,7 +3410,7 @@ class App extends React.Component { const originalText = normalizeText(line).trim(); if (originalText.length) { const topLayerFrame = this.getTopLayerFrameAtSceneCoords( - point(x, currentY), + pointFrom(x, currentY), ); let metrics = measureText(originalText, fontString, lineHeight); @@ -3848,7 +3851,7 @@ class App extends React.Component { private updateCurrentCursorPosition = withBatchedUpdates( (event: MouseEvent) => { - this.lastViewportPosition = point(event.clientX, event.clientY); + this.lastViewportPosition = pointFrom(event.clientX, event.clientY); }, ); @@ -4679,7 +4682,7 @@ class App extends React.Component { canvas: this.canvas, getViewportCoords: (x, y) => { const [viewportX, viewportY] = sceneCoordsToViewportCoords( - point(x, y), + pointFrom(x, y), this.state, ); return [ @@ -5039,7 +5042,7 @@ class App extends React.Component { const newHeight = Math.max(container.height, minHeight); const newWidth = Math.max(container.width, minWidth); mutateElement(container, { height: newHeight, width: newWidth }); - sceneCoords = point( + sceneCoords = pointFrom( container.x + newWidth / 2, container.y + newHeight / 2, ); @@ -5151,7 +5154,7 @@ class App extends React.Component { resetCursor(this.interactiveCanvas); let sceneCoords = viewportCoordsToSceneCoords( - point(event.clientX, event.clientY), + pointFrom(event.clientX, event.clientY), this.state, ); @@ -5259,11 +5262,14 @@ class App extends React.Component { isTouchScreen: boolean, ) => { const draggedDistance = pointDistance( - point( + pointFrom( this.lastPointerDownEvent!.clientX, this.lastPointerDownEvent!.clientY, ), - point(this.lastPointerUpEvent!.clientX, this.lastPointerUpEvent!.clientY), + pointFrom( + this.lastPointerUpEvent!.clientX, + this.lastPointerUpEvent!.clientY, + ), ); if ( !this.hitLinkElement || @@ -5274,7 +5280,7 @@ class App extends React.Component { return; } const lastPointerDownCoords = viewportCoordsToSceneCoords( - point( + pointFrom( this.lastPointerDownEvent!.clientX, this.lastPointerDownEvent!.clientY, ), @@ -5289,7 +5295,10 @@ class App extends React.Component { this.device.editor.isMobile, ); const lastPointerUpCoords = viewportCoordsToSceneCoords( - point(this.lastPointerUpEvent!.clientX, this.lastPointerUpEvent!.clientY), + pointFrom( + this.lastPointerUpEvent!.clientX, + this.lastPointerUpEvent!.clientY, + ), this.state, ); const lastPointerUpHittingLinkIcon = isPointHittingLink( @@ -5347,7 +5356,7 @@ class App extends React.Component { if (gesture.pointers.has(event.pointerId)) { gesture.pointers.set( event.pointerId, - point(event.clientX, event.clientY), + pointFrom(event.clientX, event.clientY), ); } @@ -5429,7 +5438,7 @@ class App extends React.Component { } const scenePointer = viewportCoordsToSceneCoords( - point(event.clientX, event.clientY), + pointFrom(event.clientX, event.clientY), this.state, ); @@ -5543,7 +5552,7 @@ class App extends React.Component { // threshold, add a point if ( pointDistance( - point(scenePointer[0] - rx, scenePointer[1] - ry), + pointFrom(scenePointer[0] - rx, scenePointer[1] - ry), lastPoint, ) >= LINE_CONFIRM_THRESHOLD ) { @@ -5552,7 +5561,10 @@ class App extends React.Component { { points: [ ...points, - point(scenePointer[0] - rx, scenePointer[1] - ry), + pointFrom( + scenePointer[0] - rx, + scenePointer[1] - ry, + ), ], }, false, @@ -5566,7 +5578,7 @@ class App extends React.Component { points.length > 2 && lastCommittedPoint && pointDistance( - point(scenePointer[0] - rx, scenePointer[1] - ry), + pointFrom(scenePointer[0] - rx, scenePointer[1] - ry), lastCommittedPoint, ) < LINE_CONFIRM_THRESHOLD ) { @@ -5616,7 +5628,7 @@ class App extends React.Component { this.scene.getNonDeletedElementsMap(), [ ...points.slice(0, -1), - point( + pointFrom( lastCommittedX + dxFromLastCommitted, lastCommittedY + dyFromLastCommitted, ), @@ -5635,7 +5647,7 @@ class App extends React.Component { { points: [ ...points.slice(0, -1), - point( + pointFrom( lastCommittedX + dxFromLastCommitted, lastCommittedY + dyFromLastCommitted, ), @@ -5872,10 +5884,10 @@ class App extends React.Component { (1 - distanceRatio) * p[0] + distanceRatio * scenePointer[0]; const nextY = (1 - distanceRatio) * p[1] + distanceRatio * scenePointer[1]; - p = point(nextX, nextY); + p = pointFrom(nextX, nextY); } - pointerDownState.lastCoords = point(scenePointer[0], scenePointer[1]); + pointerDownState.lastCoords = pointFrom(scenePointer[0], scenePointer[1]); if (didChange) { for (const element of this.scene.getNonDeletedElements()) { @@ -6227,7 +6239,7 @@ class App extends React.Component { }); const sceneCoords = viewportCoordsToSceneCoords( - point(event.clientX, event.clientY), + pointFrom(event.clientX, event.clientY), this.state, ); @@ -6315,7 +6327,7 @@ class App extends React.Component { this.lastPointerUpEvent = event; const scenePointer = viewportCoordsToSceneCoords( - point(event.clientX, event.clientY), + pointFrom(event.clientX, event.clientY), this.state, ); const clicklength = @@ -6522,7 +6534,10 @@ class App extends React.Component { private updateGestureOnPointerDown( event: React.PointerEvent, ): void { - gesture.pointers.set(event.pointerId, point(event.clientX, event.clientY)); + gesture.pointers.set( + event.pointerId, + pointFrom(event.clientX, event.clientY), + ); if (gesture.pointers.size === 2) { const [pointer1, pointer2] = Array.from(gesture.pointers.values()); @@ -6536,7 +6551,7 @@ class App extends React.Component { event: React.PointerEvent, ): PointerDownState { const origin = viewportCoordsToSceneCoords( - point(event.clientX, event.clientY), + pointFrom(event.clientX, event.clientY), this.state, ); const selectedElements = this.scene.getSelectedElements(this.state); @@ -6613,7 +6628,7 @@ class App extends React.Component { return false; } isDraggingScrollBar = true; - pointerDownState.lastCoords = point(event.clientX, event.clientY); + pointerDownState.lastCoords = pointFrom(event.clientX, event.clientY); const onPointerMove = withBatchedUpdatesThrottled((event: PointerEvent) => { const target = event.target; if (!(target instanceof HTMLElement)) { @@ -6977,7 +6992,7 @@ class App extends React.Component { if (hasBoundTextElement(element)) { container = element as ExcalidrawTextContainer; - sceneCoords = point( + sceneCoords = pointFrom( element.x + element.width / 2, element.y + element.height / 2, ); @@ -7010,7 +7025,7 @@ class App extends React.Component { ); const topLayerFrame = this.getTopLayerFrameAtSceneCoords( - point(gridX, gridY), + pointFrom(gridX, gridY), ); const simulatePressure = event.pressure === 0.5; @@ -7030,7 +7045,7 @@ class App extends React.Component { simulatePressure, locked: false, frameId: topLayerFrame ? topLayerFrame.id : null, - points: [point(0, 0)], + points: [pointFrom(0, 0)], pressures: simulatePressure ? [] : [event.pressure], }); @@ -7175,7 +7190,7 @@ class App extends React.Component { ); const topLayerFrame = addToFrameUnderCursor - ? this.getTopLayerFrameAtSceneCoords(point(gridX, gridY)) + ? this.getTopLayerFrameAtSceneCoords(pointFrom(gridX, gridY)) : null; const element = newImageElement({ @@ -7239,7 +7254,7 @@ class App extends React.Component { multiElement.points.length > 1 && lastCommittedPoint && pointDistance( - point( + pointFrom( pointerDownState.origin[0] - rx, pointerDownState.origin[1] - ry, ), @@ -7273,7 +7288,7 @@ class App extends React.Component { ); const topLayerFrame = this.getTopLayerFrameAtSceneCoords( - point(gridX, gridY), + pointFrom(gridX, gridY), ); /* If arrow is pre-arrowheads, it will have undefined for both start and end arrowheads. @@ -7343,7 +7358,7 @@ class App extends React.Component { }; }); mutateElement(element, { - points: [...element.points, point(0, 0)], + points: [...element.points, pointFrom(0, 0)], }); const boundElement = getHoveredElementForBinding( pointerDownState.origin, @@ -7392,7 +7407,7 @@ class App extends React.Component { ); const topLayerFrame = this.getTopLayerFrameAtSceneCoords( - point(gridX, gridY), + pointFrom(gridX, gridY), ); const baseElementAttributes = { @@ -7568,7 +7583,7 @@ class App extends React.Component { } const pointerCoords = viewportCoordsToSceneCoords( - point(event.clientX, event.clientY), + pointFrom(event.clientX, event.clientY), this.state, ); @@ -7942,7 +7957,7 @@ class App extends React.Component { mutateElement( newElement, { - points: [...points, point(dx, dy)], + points: [...points, pointFrom(dx, dy)], pressures, }, false, @@ -7971,7 +7986,7 @@ class App extends React.Component { mutateElement( newElement, { - points: [...points, point(dx, dy)], + points: [...points, pointFrom(dx, dy)], }, false, ); @@ -7979,7 +7994,7 @@ class App extends React.Component { mutateElbowArrow( newElement, elementsMap, - [...points.slice(0, -1), point(dx, dy)], + [...points.slice(0, -1), pointFrom(dx, dy)], vector(0, 0), undefined, { @@ -7991,7 +8006,7 @@ class App extends React.Component { mutateElement( newElement, { - points: [...points.slice(0, -1), point(dx, dy)], + points: [...points.slice(0, -1), pointFrom(dx, dy)], }, false, ); @@ -8128,7 +8143,10 @@ class App extends React.Component { this.translateCanvas({ scrollX: this.state.scrollX - dx / this.state.zoom.value, }); - pointerDownState.lastCoords = point(x, pointerDownState.lastCoords[1]); + pointerDownState.lastCoords = pointFrom( + x, + pointerDownState.lastCoords[1], + ); return true; } @@ -8138,7 +8156,10 @@ class App extends React.Component { this.translateCanvas({ scrollY: this.state.scrollY - dy / this.state.zoom.value, }); - pointerDownState.lastCoords = point(pointerDownState.lastCoords[0], y); + pointerDownState.lastCoords = pointFrom( + pointerDownState.lastCoords[0], + y, + ); return true; } return false; @@ -8280,7 +8301,7 @@ class App extends React.Component { if (newElement?.type === "freedraw") { const pointerCoords = viewportCoordsToSceneCoords( - point(childEvent.clientX, childEvent.clientY), + pointFrom(childEvent.clientX, childEvent.clientY), this.state, ); @@ -8299,9 +8320,9 @@ class App extends React.Component { : [...newElement.pressures, childEvent.pressure]; mutateElement(newElement, { - points: [...points, point(dx, dy)], + points: [...points, pointFrom(dx, dy)], pressures, - lastCommittedPoint: point(dx, dy), + lastCommittedPoint: pointFrom(dx, dy), }); this.actionManager.executeAction(actionFinalize); @@ -8340,7 +8361,7 @@ class App extends React.Component { this.store.shouldCaptureIncrement(); } const pointerCoords = viewportCoordsToSceneCoords( - point(childEvent.clientX, childEvent.clientY), + pointFrom(childEvent.clientX, childEvent.clientY), this.state, ); @@ -8348,7 +8369,7 @@ class App extends React.Component { mutateElement(newElement, { points: [ ...newElement.points, - point( + pointFrom( pointerCoords[0] - newElement.x, pointerCoords[1] - newElement.y, ), @@ -8465,7 +8486,7 @@ class App extends React.Component { if (pointerDownState.drag.hasOccurred) { const sceneCoords = viewportCoordsToSceneCoords( - point(childEvent.clientX, childEvent.clientY), + pointFrom(childEvent.clientX, childEvent.clientY), this.state, ); @@ -8665,13 +8686,13 @@ class App extends React.Component { this.eraserTrail.endPath(); const draggedDistance = pointDistance( - point(pointerStart.clientX, pointerStart.clientY), - point(pointerEnd.clientX, pointerEnd.clientY), + pointFrom(pointerStart.clientX, pointerStart.clientY), + pointFrom(pointerEnd.clientX, pointerEnd.clientY), ); if (draggedDistance === 0) { const scenePointer = viewportCoordsToSceneCoords( - point(pointerEnd.clientX, pointerEnd.clientY), + pointFrom(pointerEnd.clientX, pointerEnd.clientY), this.state, ); const hitElements = this.getElementsAtPosition(scenePointer); @@ -9208,7 +9229,7 @@ class App extends React.Component { const clientY = this.state.height / 2 + this.state.offsetTop; const [x, y] = viewportCoordsToSceneCoords( - point(clientX, clientY), + pointFrom(clientX, clientY), this.state, ); @@ -9500,7 +9521,7 @@ class App extends React.Component { // must be retrieved first, in the same frame const { file, fileHandle } = await getFileFromEvent(event); const [sceneX, sceneY] = viewportCoordsToSceneCoords( - point(event.clientX, event.clientY), + pointFrom(event.clientX, event.clientY), this.state, ); @@ -9693,7 +9714,7 @@ class App extends React.Component { } const position = viewportCoordsToSceneCoords( - point(event.clientX, event.clientY), + pointFrom(event.clientX, event.clientY), this.state, ); const element = this.getElementAtPosition(position, { @@ -10168,7 +10189,7 @@ class App extends React.Component { container?: ExcalidrawTextContainer | null, ) { if (container) { - let elementCenter = point( + let elementCenter = pointFrom( container.x + container.width / 2, container.y + container.height / 2, ); @@ -10203,7 +10224,7 @@ class App extends React.Component { return; } const [sceneX, sceneY] = viewportCoordsToSceneCoords( - point(x, y), + pointFrom(x, y), this.state, ); diff --git a/packages/excalidraw/components/Stats/MultiDimension.tsx b/packages/excalidraw/components/Stats/MultiDimension.tsx index f362005855..0d1a65e915 100644 --- a/packages/excalidraw/components/Stats/MultiDimension.tsx +++ b/packages/excalidraw/components/Stats/MultiDimension.tsx @@ -20,7 +20,7 @@ import { getAtomicUnits, getStepSizedValue, isPropertyEditable } from "./utils"; import { getElementsInAtomicUnit, resizeElement } from "./utils"; import type { AtomicUnit } from "./utils"; import { MIN_WIDTH_OR_HEIGHT } from "../../constants"; -import { point, type GlobalPoint } from "../../../math"; +import { pointFrom, type GlobalPoint } from "../../../math"; interface MultiDimensionProps { property: "width" | "height"; @@ -182,7 +182,7 @@ const handleDimensionChange: DragInputCallbackType< nextHeight, initialHeight, aspectRatio, - point(x1, y1), + pointFrom(x1, y1), property, latestElements, originalElements, @@ -287,7 +287,7 @@ const handleDimensionChange: DragInputCallbackType< nextHeight, initialHeight, aspectRatio, - point(x1, y1), + pointFrom(x1, y1), property, latestElements, originalElements, diff --git a/packages/excalidraw/components/Stats/MultiPosition.tsx b/packages/excalidraw/components/Stats/MultiPosition.tsx index d0f001663e..3285faf6ab 100644 --- a/packages/excalidraw/components/Stats/MultiPosition.tsx +++ b/packages/excalidraw/components/Stats/MultiPosition.tsx @@ -13,7 +13,7 @@ import { useMemo } from "react"; import { getElementsInAtomicUnit, moveElement } from "./utils"; import type { AtomicUnit } from "./utils"; import type { AppState } from "../../types"; -import { point, pointRotateRads } from "../../../math"; +import { pointFrom, pointRotateRads } from "../../../math"; interface MultiPositionProps { property: "x" | "y"; @@ -44,8 +44,8 @@ const moveElements = ( origElement.y + origElement.height / 2, ]; const [topLeftX, topLeftY] = pointRotateRads( - point(origElement.x, origElement.y), - point(cx, cy), + pointFrom(origElement.x, origElement.y), + pointFrom(cx, cy), origElement.angle, ); @@ -97,8 +97,8 @@ const moveGroupTo = ( ]; const [topLeftX, topLeftY] = pointRotateRads( - point(latestElement.x, latestElement.y), - point(cx, cy), + pointFrom(latestElement.x, latestElement.y), + pointFrom(cx, cy), latestElement.angle, ); @@ -171,8 +171,8 @@ const handlePositionChange: DragInputCallbackType< origElement.y + origElement.height / 2, ]; const [topLeftX, topLeftY] = pointRotateRads( - point(origElement.x, origElement.y), - point(cx, cy), + pointFrom(origElement.x, origElement.y), + pointFrom(cx, cy), origElement.angle, ); @@ -241,8 +241,8 @@ const MultiPosition = ({ const [cx, cy] = [el.x + el.width / 2, el.y + el.height / 2]; const [topLeftX, topLeftY] = pointRotateRads( - point(el.x, el.y), - point(cx, cy), + pointFrom(el.x, el.y), + pointFrom(cx, cy), el.angle, ); diff --git a/packages/excalidraw/components/Stats/Position.tsx b/packages/excalidraw/components/Stats/Position.tsx index 8e7671685a..47cc3fe250 100644 --- a/packages/excalidraw/components/Stats/Position.tsx +++ b/packages/excalidraw/components/Stats/Position.tsx @@ -4,7 +4,7 @@ import type { DragInputCallbackType } from "./DragInput"; import { getStepSizedValue, moveElement } from "./utils"; import type Scene from "../../scene/Scene"; import type { AppState } from "../../types"; -import { point, pointRotateRads } from "../../../math"; +import { pointFrom, pointRotateRads } from "../../../math"; interface PositionProps { property: "x" | "y"; @@ -33,8 +33,8 @@ const handlePositionChange: DragInputCallbackType<"x" | "y"> = ({ origElement.y + origElement.height / 2, ]; const [topLeftX, topLeftY] = pointRotateRads( - point(origElement.x, origElement.y), - point(cx, cy), + pointFrom(origElement.x, origElement.y), + pointFrom(cx, cy), origElement.angle, ); @@ -93,8 +93,8 @@ const Position = ({ appState, }: PositionProps) => { const [topLeftX, topLeftY] = pointRotateRads( - point(element.x, element.y), - point(element.x + element.width / 2, element.y + element.height / 2), + pointFrom(element.x, element.y), + pointFrom(element.x + element.width / 2, element.y + element.height / 2), element.angle, ); const value = diff --git a/packages/excalidraw/components/Stats/stats.test.tsx b/packages/excalidraw/components/Stats/stats.test.tsx index f281931c87..fc981ce6c6 100644 --- a/packages/excalidraw/components/Stats/stats.test.tsx +++ b/packages/excalidraw/components/Stats/stats.test.tsx @@ -25,7 +25,7 @@ import { API } from "../../tests/helpers/api"; import { actionGroup } from "../../actions"; import { isInGroup } from "../../groups"; import type { Degrees } from "../../../math"; -import { degreesToRadians, point, pointRotateRads } from "../../../math"; +import { degreesToRadians, pointFrom, pointRotateRads } from "../../../math"; const { h } = window; const mouse = new Pointer("mouse"); @@ -264,8 +264,8 @@ describe("stats for a generic element", () => { rectangle.y + rectangle.height / 2, ]; const [topLeftX, topLeftY] = pointRotateRads( - point(rectangle.x, rectangle.y), - point(cx, cy), + pointFrom(rectangle.x, rectangle.y), + pointFrom(cx, cy), rectangle.angle, ); @@ -283,8 +283,8 @@ describe("stats for a generic element", () => { testInputProperty(rectangle, "angle", "A", 0, 45); let [newTopLeftX, newTopLeftY] = pointRotateRads( - point(rectangle.x, rectangle.y), - point(cx, cy), + pointFrom(rectangle.x, rectangle.y), + pointFrom(cx, cy), rectangle.angle, ); @@ -294,8 +294,8 @@ describe("stats for a generic element", () => { testInputProperty(rectangle, "angle", "A", 45, 66); [newTopLeftX, newTopLeftY] = pointRotateRads( - point(rectangle.x, rectangle.y), - point(cx, cy), + pointFrom(rectangle.x, rectangle.y), + pointFrom(cx, cy), rectangle.angle, ); expect(newTopLeftX.toString()).not.toEqual(xInput.value); @@ -311,8 +311,8 @@ describe("stats for a generic element", () => { rectangle.y + rectangle.height / 2, ]; const [topLeftX, topLeftY] = pointRotateRads( - point(rectangle.x, rectangle.y), - point(cx, cy), + pointFrom(rectangle.x, rectangle.y), + pointFrom(cx, cy), rectangle.angle, ); testInputProperty(rectangle, "width", "W", rectangle.width, 400); @@ -321,8 +321,8 @@ describe("stats for a generic element", () => { rectangle.y + rectangle.height / 2, ]; let [currentTopLeftX, currentTopLeftY] = pointRotateRads( - point(rectangle.x, rectangle.y), - point(cx, cy), + pointFrom(rectangle.x, rectangle.y), + pointFrom(cx, cy), rectangle.angle, ); expect(currentTopLeftX).toBeCloseTo(topLeftX, 4); @@ -334,8 +334,8 @@ describe("stats for a generic element", () => { rectangle.y + rectangle.height / 2, ]; [currentTopLeftX, currentTopLeftY] = pointRotateRads( - point(rectangle.x, rectangle.y), - point(cx, cy), + pointFrom(rectangle.x, rectangle.y), + pointFrom(cx, cy), rectangle.angle, ); diff --git a/packages/excalidraw/components/Stats/utils.ts b/packages/excalidraw/components/Stats/utils.ts index f6cf167080..a6a443b9b6 100644 --- a/packages/excalidraw/components/Stats/utils.ts +++ b/packages/excalidraw/components/Stats/utils.ts @@ -1,5 +1,5 @@ import type { Radians } from "../../../math"; -import { point, pointRotateRads } from "../../../math"; +import { pointFrom, pointRotateRads } from "../../../math"; import { bindOrUnbindLinearElements, updateBoundElements, @@ -231,8 +231,8 @@ export const moveElement = ( originalElement.y + originalElement.height / 2, ]; const [topLeftX, topLeftY] = pointRotateRads( - point(originalElement.x, originalElement.y), - point(cx, cy), + pointFrom(originalElement.x, originalElement.y), + pointFrom(cx, cy), originalElement.angle, ); @@ -240,8 +240,8 @@ export const moveElement = ( const changeInY = newTopLeftY - topLeftY; const [x, y] = pointRotateRads( - point(newTopLeftX, newTopLeftY), - point(cx + changeInX, cy + changeInY), + pointFrom(newTopLeftX, newTopLeftY), + pointFrom(cx + changeInX, cy + changeInY), -originalElement.angle as Radians, ); diff --git a/packages/excalidraw/components/hyperlink/Hyperlink.tsx b/packages/excalidraw/components/hyperlink/Hyperlink.tsx index 4e8703116e..1594d1bbe4 100644 --- a/packages/excalidraw/components/hyperlink/Hyperlink.tsx +++ b/packages/excalidraw/components/hyperlink/Hyperlink.tsx @@ -37,7 +37,7 @@ import { useAppProps, useExcalidrawAppState } from "../App"; import { isEmbeddableElement } from "../../element/typeChecks"; import { getLinkHandleFromCoords } from "./helpers"; import type { ViewportPoint } from "../../../math"; -import { point } from "../../../math"; +import { pointFrom } from "../../../math"; const CONTAINER_WIDTH = 320; const SPACE_BOTTOM = 85; @@ -182,7 +182,7 @@ export const Hyperlink = ({ element, elementsMap, appState, - point(event.clientX, event.clientY), + pointFrom(event.clientX, event.clientY), ) as boolean; if (shouldHide) { timeoutId = window.setTimeout(() => { @@ -326,7 +326,7 @@ const getCoordsForPopover = ( ) => { const [x1, y1] = getElementAbsoluteCoords(element, elementsMap); const [viewportX, viewportY] = sceneCoordsToViewportCoords( - point(x1 + element.width / 2, y1), + pointFrom(x1 + element.width / 2, y1), appState, ); const x = viewportX - appState.offsetLeft - CONTAINER_WIDTH / 2; @@ -388,7 +388,7 @@ const renderTooltip = ( ); const linkViewportCoords = sceneCoordsToViewportCoords( - point(linkX, linkY), + pointFrom(linkX, linkY), appState, ); diff --git a/packages/excalidraw/components/hyperlink/helpers.ts b/packages/excalidraw/components/hyperlink/helpers.ts index e0d8d681bf..21cb744fa0 100644 --- a/packages/excalidraw/components/hyperlink/helpers.ts +++ b/packages/excalidraw/components/hyperlink/helpers.ts @@ -1,5 +1,5 @@ import type { GlobalPoint, Radians } from "../../../math"; -import { point, pointRotateRads } from "../../../math"; +import { pointFrom, pointRotateRads } from "../../../math"; import { MIME_TYPES } from "../../constants"; import { getElementAbsoluteCoords } from "../../element/bounds"; import { hitElementBoundingBox } from "../../element/collision"; @@ -35,8 +35,8 @@ export const getLinkHandleFromCoords = ( const y = y1 - dashedLineMargin - linkMarginY + centeringOffset; const [rotatedX, rotatedY] = pointRotateRads( - point(x + linkWidth / 2, y + linkHeight / 2), - point(centerX, centerY), + pointFrom(x + linkWidth / 2, y + linkHeight / 2), + pointFrom(centerX, centerY), angle, ); return [ @@ -85,5 +85,10 @@ export const isPointHittingLink = ( ) { return true; } - return isPointHittingLinkIcon(element, elementsMap, appState, point(x, y)); + return isPointHittingLinkIcon( + element, + elementsMap, + appState, + pointFrom(x, y), + ); }; diff --git a/packages/excalidraw/data/restore.ts b/packages/excalidraw/data/restore.ts index 7faed75755..1cf7ce0cdc 100644 --- a/packages/excalidraw/data/restore.ts +++ b/packages/excalidraw/data/restore.ts @@ -56,7 +56,7 @@ import { getNormalizedZoom, } from "../scene"; import type { LocalPoint } from "../../math"; -import { pointExtent, isFiniteNumber, point, radians } from "../../math"; +import { pointExtent, isFiniteNumber, pointFrom, radians } from "../../math"; type RestoredAppState = Omit< AppState, @@ -267,7 +267,7 @@ const restoreElement = ( let y = element.y; let points = // migrate old arrow model to new one !Array.isArray(element.points) || element.points.length < 2 - ? [point(0, 0), point(element.width, element.height)] + ? [pointFrom(0, 0), pointFrom(element.width, element.height)] : element.points; if (points[0][0] !== 0 || points[0][1] !== 0) { @@ -295,7 +295,7 @@ const restoreElement = ( let y: number | undefined = element.y; let points: readonly LocalPoint[] | undefined = // migrate old arrow model to new one !Array.isArray(element.points) || element.points.length < 2 - ? [point(0, 0), point(element.width, element.height)] + ? [pointFrom(0, 0), pointFrom(element.width, element.height)] : element.points; if (points[0][0] !== 0 || points[0][1] !== 0) { diff --git a/packages/excalidraw/data/transform.test.ts b/packages/excalidraw/data/transform.test.ts index d752f6766a..3fecf957b4 100644 --- a/packages/excalidraw/data/transform.test.ts +++ b/packages/excalidraw/data/transform.test.ts @@ -2,7 +2,7 @@ import { vi } from "vitest"; import type { ExcalidrawElementSkeleton } from "./transform"; import { convertToExcalidrawElements } from "./transform"; import type { ExcalidrawArrowElement } from "../element/types"; -import { point } from "../../math"; +import { pointFrom } from "../../math"; const opts = { regenerateIds: false }; @@ -917,7 +917,7 @@ describe("Test Transform", () => { x: 111.262, y: 57, strokeWidth: 2, - points: [point(0, 0), point(272.985, 0)], + points: [pointFrom(0, 0), pointFrom(272.985, 0)], label: { text: "How are you?", fontSize: 20, @@ -940,7 +940,7 @@ describe("Test Transform", () => { x: 77.017, y: 79, strokeWidth: 2, - points: [point(0, 0)], + points: [pointFrom(0, 0)], label: { text: "Friendship", fontSize: 20, diff --git a/packages/excalidraw/data/transform.ts b/packages/excalidraw/data/transform.ts index 7a59d4bdb7..678f02b6e5 100644 --- a/packages/excalidraw/data/transform.ts +++ b/packages/excalidraw/data/transform.ts @@ -53,7 +53,7 @@ import { randomId } from "../random"; import { syncInvalidIndices } from "../fractionalIndex"; import { getLineHeight } from "../fonts"; import { isArrowElement } from "../element/typeChecks"; -import { pointExtent, point, type LocalPoint } from "../../math"; +import { pointExtent, pointFrom, type LocalPoint } from "../../math"; export type ValidLinearElement = { type: "arrow" | "line"; @@ -536,7 +536,7 @@ export const convertToExcalidrawElements = ( excalidrawElement = newLinearElement({ width, height, - points: [point(0, 0), point(width, height)], + points: [pointFrom(0, 0), pointFrom(width, height)], ...element, }); @@ -549,7 +549,7 @@ export const convertToExcalidrawElements = ( width, height, endArrowhead: "arrow", - points: [point(0, 0), point(width, height)], + points: [pointFrom(0, 0), pointFrom(width, height)], ...element, type: "arrow", }); diff --git a/packages/excalidraw/element/binding.ts b/packages/excalidraw/element/binding.ts index 6d8cadda96..0dd4c6954a 100644 --- a/packages/excalidraw/element/binding.ts +++ b/packages/excalidraw/element/binding.ts @@ -52,7 +52,7 @@ import { import type { LocalPoint } from "../../math"; import { segment, - point, + pointFrom, pointRotateRads, type GlobalPoint, vectorFromPoint, @@ -701,7 +701,7 @@ export const getHeadingForElbowArrowSnap = ( return vectorToHeading( vectorFromPoint( p, - point( + pointFrom( bindableElement.x + bindableElement.width / 2, bindableElement.y + bindableElement.height / 2, ), @@ -741,14 +741,14 @@ export const bindPointToSnapToElementOutline = ( const intersections: GlobalPoint[] = [ ...(intersectElementWithLine( bindableElement, - point(p[0], p[1] - 2 * bindableElement.height), - point(p[0], p[1] + 2 * bindableElement.height), + pointFrom(p[0], p[1] - 2 * bindableElement.height), + pointFrom(p[0], p[1] + 2 * bindableElement.height), FIXED_BINDING_DISTANCE, ) ?? []), ...(intersectElementWithLine( bindableElement, - point(p[0] - 2 * bindableElement.width, p[1]), - point(p[0] + 2 * bindableElement.width, p[1]), + pointFrom(p[0] - 2 * bindableElement.width, p[1]), + pointFrom(p[0] + 2 * bindableElement.width, p[1]), FIXED_BINDING_DISTANCE, ) ?? []), ].filter((p) => p != null); @@ -786,25 +786,25 @@ const headingToMidBindPoint = ( switch (true) { case compareHeading(heading, HEADING_UP): return pointRotateRads( - point((aabb[0] + aabb[2]) / 2 + 0.1, aabb[1]), + pointFrom((aabb[0] + aabb[2]) / 2 + 0.1, aabb[1]), center, bindableElement.angle, ); case compareHeading(heading, HEADING_RIGHT): return pointRotateRads( - point(aabb[2], (aabb[1] + aabb[3]) / 2 + 0.1), + pointFrom(aabb[2], (aabb[1] + aabb[3]) / 2 + 0.1), center, bindableElement.angle, ); case compareHeading(heading, HEADING_DOWN): return pointRotateRads( - point((aabb[0] + aabb[2]) / 2 - 0.1, aabb[3]), + pointFrom((aabb[0] + aabb[2]) / 2 - 0.1, aabb[3]), center, bindableElement.angle, ); default: return pointRotateRads( - point(aabb[0], (aabb[1] + aabb[3]) / 2 - 0.1), + pointFrom(aabb[0], (aabb[1] + aabb[3]) / 2 - 0.1), center, bindableElement.angle, ); @@ -815,7 +815,7 @@ export const avoidRectangularCorner = ( element: ExcalidrawBindableElement, p: GlobalPoint, ): GlobalPoint => { - const center = point( + const center = pointFrom( element.x + element.width / 2, element.y + element.height / 2, ); @@ -825,13 +825,13 @@ export const avoidRectangularCorner = ( // Top left if (nonRotatedPoint[1] - element.y > -FIXED_BINDING_DISTANCE) { return pointRotateRads( - point(element.x - FIXED_BINDING_DISTANCE, element.y), + pointFrom(element.x - FIXED_BINDING_DISTANCE, element.y), center, element.angle, ); } return pointRotateRads( - point(element.x, element.y - FIXED_BINDING_DISTANCE), + pointFrom(element.x, element.y - FIXED_BINDING_DISTANCE), center, element.angle, ); @@ -842,13 +842,16 @@ export const avoidRectangularCorner = ( // Bottom left if (nonRotatedPoint[0] - element.x > -FIXED_BINDING_DISTANCE) { return pointRotateRads( - point(element.x, element.y + element.height + FIXED_BINDING_DISTANCE), + pointFrom( + element.x, + element.y + element.height + FIXED_BINDING_DISTANCE, + ), center, element.angle, ); } return pointRotateRads( - point(element.x - FIXED_BINDING_DISTANCE, element.y + element.height), + pointFrom(element.x - FIXED_BINDING_DISTANCE, element.y + element.height), center, element.angle, ); @@ -862,7 +865,7 @@ export const avoidRectangularCorner = ( element.width + FIXED_BINDING_DISTANCE ) { return pointRotateRads( - point( + pointFrom( element.x + element.width, element.y + element.height + FIXED_BINDING_DISTANCE, ), @@ -871,7 +874,7 @@ export const avoidRectangularCorner = ( ); } return pointRotateRads( - point( + pointFrom( element.x + element.width + FIXED_BINDING_DISTANCE, element.y + element.height, ), @@ -888,13 +891,16 @@ export const avoidRectangularCorner = ( element.width + FIXED_BINDING_DISTANCE ) { return pointRotateRads( - point(element.x + element.width, element.y - FIXED_BINDING_DISTANCE), + pointFrom( + element.x + element.width, + element.y - FIXED_BINDING_DISTANCE, + ), center, element.angle, ); } return pointRotateRads( - point(element.x + element.width + FIXED_BINDING_DISTANCE, element.y), + pointFrom(element.x + element.width + FIXED_BINDING_DISTANCE, element.y), center, element.angle, ); @@ -909,7 +915,10 @@ export const snapToMid = ( tolerance: number = 0.05, ): GlobalPoint => { const { x, y, width, height, angle } = element; - const center = point(x + width / 2 - 0.1, y + height / 2 - 0.1); + const center = pointFrom( + x + width / 2 - 0.1, + y + height / 2 - 0.1, + ); const nonRotated = pointRotateRads(p, center, radians(-angle)); // snap-to-center point is adaptive to element size, but we don't want to go @@ -924,7 +933,7 @@ export const snapToMid = ( ) { // LEFT return pointRotateRads( - point(x - FIXED_BINDING_DISTANCE, center[1]), + pointFrom(x - FIXED_BINDING_DISTANCE, center[1]), center, angle, ); @@ -935,7 +944,7 @@ export const snapToMid = ( ) { // TOP return pointRotateRads( - point(center[0], y - FIXED_BINDING_DISTANCE), + pointFrom(center[0], y - FIXED_BINDING_DISTANCE), center, angle, ); @@ -946,7 +955,7 @@ export const snapToMid = ( ) { // RIGHT return pointRotateRads( - point(x + width + FIXED_BINDING_DISTANCE, center[1]), + pointFrom(x + width + FIXED_BINDING_DISTANCE, center[1]), center, angle, ); @@ -957,7 +966,7 @@ export const snapToMid = ( ) { // DOWN return pointRotateRads( - point(center[0], y + height + FIXED_BINDING_DISTANCE), + pointFrom(center[0], y + height + FIXED_BINDING_DISTANCE), center, angle, ); @@ -994,11 +1003,11 @@ const updateBoundPoint = ( startOrEnd === "startBinding" ? "start" : "end", elementsMap, ).fixedPoint; - const globalMidPoint = point( + const globalMidPoint = pointFrom( bindableElement.x + bindableElement.width / 2, bindableElement.y + bindableElement.height / 2, ); - const global = point( + const global = pointFrom( bindableElement.x + fixedPoint[0] * bindableElement.width, bindableElement.y + fixedPoint[1] * bindableElement.height, ); @@ -1086,7 +1095,7 @@ export const calculateFixedPointForElbowArrowBinding = ( otherGlobalPoint, hoveredElement, ); - const globalMidPoint = point( + const globalMidPoint = pointFrom( bounds[0] + (bounds[2] - bounds[0]) / 2, bounds[1] + (bounds[3] - bounds[1]) / 2, ); @@ -1303,9 +1312,9 @@ export const bindingBorderTest = ( const threshold = maxBindingGap(element, element.width, element.height); const shape = getElementShape(element, elementsMap); return ( - isPointOnShape(point(x, y), shape, threshold) || + isPointOnShape(pointFrom(x, y), shape, threshold) || (fullShape === true && - pointInsideBounds(point(x, y), aabbForElement(element))) + pointInsideBounds(pointFrom(x, y), aabbForElement(element))) ); }; @@ -1333,7 +1342,7 @@ const determineFocusDistance = ( // Another point on the line, in absolute coordinates (closer to element) b: GlobalPoint, ): number => { - const center = point( + const center = pointFrom( element.x + element.width / 2, element.y + element.height / 2, ); @@ -1357,7 +1366,7 @@ const determineFocusPoint = ( focus: number, adjacentPoint: GlobalPoint, ): GlobalPoint => { - const center = point( + const center = pointFrom( element.x + element.width / 2, element.y + element.height / 2, ); @@ -1373,7 +1382,7 @@ const determineFocusPoint = ( ), Math.sign(focus) * Math.min( - pointDistance(point(element.x, element.y), center) * + pointDistance(pointFrom(element.x, element.y), center) * Math.abs(focus), element.width / 2, element.height / 2, @@ -1698,11 +1707,11 @@ export const getGlobalFixedPointForBindableElement = ( const [fixedX, fixedY] = normalizeFixedPoint(fixedPointRatio); return pointRotateRads( - point( + pointFrom( element.x + element.width * fixedX, element.y + element.height * fixedY, ), - point( + pointFrom( element.x + element.width / 2, element.y + element.height / 2, ), @@ -1730,7 +1739,7 @@ const getGlobalFixedPoints = ( arrow.startBinding.fixedPoint, startElement as ExcalidrawBindableElement, ) - : point( + : pointFrom( arrow.x + arrow.points[0][0], arrow.y + arrow.points[0][1], ); @@ -1740,7 +1749,7 @@ const getGlobalFixedPoints = ( arrow.endBinding.fixedPoint, endElement as ExcalidrawBindableElement, ) - : point( + : pointFrom( arrow.x + arrow.points[arrow.points.length - 1][0], arrow.y + arrow.points[arrow.points.length - 1][1], ); diff --git a/packages/excalidraw/element/bounds.test.ts b/packages/excalidraw/element/bounds.test.ts index f5ca0e901b..ffa89bb3e8 100644 --- a/packages/excalidraw/element/bounds.test.ts +++ b/packages/excalidraw/element/bounds.test.ts @@ -1,5 +1,5 @@ import type { LocalPoint } from "../../math"; -import { point } from "../../math"; +import { pointFrom } from "../../math"; import { ROUNDNESS } from "../constants"; import { arrayToMap } from "../utils"; import { getElementAbsoluteCoords, getElementBounds } from "./bounds"; @@ -125,9 +125,9 @@ describe("getElementBounds", () => { a: 0.6447741904932416, }), points: [ - point(0, 0), - point(67.33984375, 92.48828125), - point(-102.7890625, 52.15625), + pointFrom(0, 0), + pointFrom(67.33984375, 92.48828125), + pointFrom(-102.7890625, 52.15625), ], } as ExcalidrawLinearElement; diff --git a/packages/excalidraw/element/bounds.ts b/packages/excalidraw/element/bounds.ts index 0a3f667922..2e6d117e41 100644 --- a/packages/excalidraw/element/bounds.ts +++ b/packages/excalidraw/element/bounds.ts @@ -24,7 +24,7 @@ import { ShapeCache } from "../scene/ShapeCache"; import { arrayToMap, invariant } from "../utils"; import type { GlobalPoint, LocalPoint, Segment } from "../../math"; import { - point, + pointFrom, pointDistance, pointFromArray, pointRotateRads, @@ -95,8 +95,8 @@ class ElementBounds { const [minX, minY, maxX, maxY] = getBoundsFromFreeDrawPoints( element.points.map(([x, y]) => pointRotateRads( - point(x, y), - point(cx - element.x, cy - element.y), + pointFrom(x, y), + pointFrom(cx - element.x, cy - element.y), element.angle, ), ), @@ -112,23 +112,23 @@ class ElementBounds { bounds = getLinearElementRotatedBounds(element, cx, cy, elementsMap); } else if (element.type === "diamond") { const [x11, y11] = pointRotateRads( - point(cx, y1), - point(cx, cy), + pointFrom(cx, y1), + pointFrom(cx, cy), element.angle, ); const [x12, y12] = pointRotateRads( - point(cx, y2), - point(cx, cy), + pointFrom(cx, y2), + pointFrom(cx, cy), element.angle, ); const [x22, y22] = pointRotateRads( - point(x1, cy), - point(cx, cy), + pointFrom(x1, cy), + pointFrom(cx, cy), element.angle, ); const [x21, y21] = pointRotateRads( - point(x2, cy), - point(cx, cy), + pointFrom(x2, cy), + pointFrom(cx, cy), element.angle, ); const minX = Math.min(x11, x12, x22, x21); @@ -146,23 +146,23 @@ class ElementBounds { bounds = [cx - ww, cy - hh, cx + ww, cy + hh]; } else { const [x11, y11] = pointRotateRads( - point(x1, y1), - point(cx, cy), + pointFrom(x1, y1), + pointFrom(cx, cy), element.angle, ); const [x12, y12] = pointRotateRads( - point(x1, y2), - point(cx, cy), + pointFrom(x1, y2), + pointFrom(cx, cy), element.angle, ); const [x22, y22] = pointRotateRads( - point(x2, y2), - point(cx, cy), + pointFrom(x2, y2), + pointFrom(cx, cy), element.angle, ); const [x21, y21] = pointRotateRads( - point(x2, y1), - point(cx, cy), + pointFrom(x2, y1), + pointFrom(cx, cy), element.angle, ); const minX = Math.min(x11, x12, x22, x21); @@ -331,7 +331,7 @@ export const getMinMaxXYFromCurvePathOps = ( ops: Op[], transformXY?: (p: GlobalPoint) => GlobalPoint, ): Bounds => { - let currentP: GlobalPoint = point(0, 0); + let currentP: GlobalPoint = pointFrom(0, 0); const { minX, minY, maxX, maxY } = ops.reduce( (limits, { op, data }) => { @@ -345,9 +345,9 @@ export const getMinMaxXYFromCurvePathOps = ( // move operation does not draw anything; so, it always // returns false } else if (op === "bcurveTo") { - const _p1 = point(data[0], data[1]); - const _p2 = point(data[2], data[3]); - const _p3 = point(data[4], data[5]); + const _p1 = pointFrom(data[0], data[1]); + const _p2 = pointFrom(data[2], data[3]); + const _p3 = pointFrom(data[4], data[5]); const p1 = transformXY ? transformXY(_p1) : _p1; const p2 = transformXY ? transformXY(_p2) : _p2; @@ -442,8 +442,8 @@ const getLinearElementRotatedBounds = ( if (element.points.length < 2) { const [pointX, pointY] = element.points[0]; const [x, y] = pointRotateRads( - point(element.x + pointX, element.y + pointY), - point(cx, cy), + pointFrom(element.x + pointX, element.y + pointY), + pointFrom(cx, cy), element.angle, ); @@ -471,8 +471,8 @@ const getLinearElementRotatedBounds = ( const ops = getCurvePathOps(shape); const transformXY = ([x, y]: GlobalPoint) => pointRotateRads( - point(element.x + x, element.y + y), - point(cx, cy), + pointFrom(element.x + x, element.y + y), + pointFrom(cx, cy), element.angle, ); const res = getMinMaxXYFromCurvePathOps(ops, transformXY); @@ -620,8 +620,8 @@ export const getClosestElementBounds = ( elements.forEach((element) => { const [x1, y1, x2, y2] = getElementBounds(element, elementsMap); const distance = pointDistance( - point((x1 + x2) / 2, (y1 + y2) / 2), - point(from.x, from.y), + pointFrom((x1 + x2) / 2, (y1 + y2) / 2), + pointFrom(from.x, from.y), ); if (distance < minDistance) { @@ -652,7 +652,7 @@ export const getVisibleSceneBounds = ({ }; export const getCenterForBounds = (bounds: Bounds): GlobalPoint => - point( + pointFrom( bounds[0] + (bounds[2] - bounds[0]) / 2, bounds[1] + (bounds[3] - bounds[1]) / 2, ); @@ -696,7 +696,7 @@ export const createDiamondArc = ( end: GlobalPoint, r: number, ) => { - const c = point( + const c = pointFrom( (start[0] + end[0]) / 2, (start[1] + end[1]) / 2, ); diff --git a/packages/excalidraw/element/collision.ts b/packages/excalidraw/element/collision.ts index 4fe446d37e..b39593f798 100644 --- a/packages/excalidraw/element/collision.ts +++ b/packages/excalidraw/element/collision.ts @@ -31,7 +31,7 @@ import type { Arc, GlobalPoint, Polygon } from "../../math"; import { pathIsALoop, isPointWithinBounds, - point, + pointFrom, rectangle, pointRotateRads, radians, @@ -119,7 +119,11 @@ export const hitElementBoundingBox = ( y1 -= tolerance; x2 += tolerance; y2 += tolerance; - return isPointWithinBounds(point(x1, y1), scenePointer, point(x2, y2)); + return isPointWithinBounds( + pointFrom(x1, y1), + scenePointer, + pointFrom(x2, y2), + ); }; export const hitElementBoundingBoxOnly = ( @@ -175,13 +179,13 @@ export const intersectRectanguloidWithLine = ( offset: number, ): GlobalPoint[] => { const r = rectangle( - point(element.x - offset, element.y - offset), - point( + pointFrom(element.x - offset, element.y - offset), + pointFrom( element.x + element.width + offset, element.y + element.height + offset, ), ); - const center = point( + const center = pointFrom( element.x + element.width / 2, element.y + element.height / 2, ); @@ -203,20 +207,20 @@ export const intersectRectanguloidWithLine = ( ); const sideIntersections: GlobalPoint[] = [ segment( - point(r[0][0] + roundness, r[0][1]), - point(r[1][0] - roundness, r[0][1]), + pointFrom(r[0][0] + roundness, r[0][1]), + pointFrom(r[1][0] - roundness, r[0][1]), ), segment( - point(r[1][0], r[0][1] + roundness), - point(r[1][0], r[1][1] - roundness), + pointFrom(r[1][0], r[0][1] + roundness), + pointFrom(r[1][0], r[1][1] - roundness), ), segment( - point(r[1][0] - roundness, r[1][1]), - point(r[0][0] + roundness, r[1][1]), + pointFrom(r[1][0] - roundness, r[1][1]), + pointFrom(r[0][0] + roundness, r[1][1]), ), segment( - point(r[0][0], r[1][1] - roundness), - point(r[0][0], r[0][1] + roundness), + pointFrom(r[0][0], r[1][1] - roundness), + pointFrom(r[0][0], r[0][1] + roundness), ), ] .map((s) => @@ -228,25 +232,25 @@ export const intersectRectanguloidWithLine = ( roundness > 0 ? [ arc( - point(r[0][0] + roundness, r[0][1] + roundness), + pointFrom(r[0][0] + roundness, r[0][1] + roundness), roundness, radians(Math.PI), radians((3 / 4) * Math.PI), ), arc( - point(r[1][0] - roundness, r[0][1] + roundness), + pointFrom(r[1][0] - roundness, r[0][1] + roundness), roundness, radians((3 / 4) * Math.PI), radians(0), ), arc( - point(r[1][0] - roundness, r[1][1] - roundness), + pointFrom(r[1][0] - roundness, r[1][1] - roundness), roundness, radians(0), radians((1 / 2) * Math.PI), ), arc( - point(r[0][0] + roundness, r[1][1] - roundness), + pointFrom(r[0][0] + roundness, r[1][1] - roundness), roundness, radians((1 / 2) * Math.PI), radians(Math.PI), @@ -277,7 +281,10 @@ export const intersectDiamondWithLine = ( ): GlobalPoint[] => { const [topX, topY, rightX, rightY, bottomX, bottomY, leftX, leftY] = getDiamondPoints(element, offset); - const center = point((topX + bottomX) / 2, (topY + bottomY) / 2); + const center = pointFrom( + (topX + bottomX) / 2, + (topY + bottomY) / 2, + ); const verticalRadius = getCornerRadius(Math.abs(topX - leftX), element); const horizontalRadius = getCornerRadius(Math.abs(rightY - topY), element); @@ -286,10 +293,10 @@ export const intersectDiamondWithLine = ( const rotatedA = pointRotateRads(a, center, radians(-element.angle)); const rotatedB = pointRotateRads(b, center, radians(-element.angle)); const [top, right, bottom, left]: GlobalPoint[] = [ - point(element.x + topX, element.y + topY), - point(element.x + rightX, element.y + rightY), - point(element.x + bottomX, element.y + bottomY), - point(element.x + leftX, element.y + leftY), + pointFrom(element.x + topX, element.y + topY), + pointFrom(element.x + rightX, element.y + rightY), + pointFrom(element.x + bottomX, element.y + bottomY), + pointFrom(element.x + leftX, element.y + leftY), ]; const topRight = createDiamondSide( @@ -353,7 +360,7 @@ export const intersectEllipseWithLine = ( b: GlobalPoint, offset: number = 0, ): GlobalPoint[] => { - const center = point( + const center = pointFrom( element.x + element.width / 2, element.y + element.height / 2, ); diff --git a/packages/excalidraw/element/flowchart.ts b/packages/excalidraw/element/flowchart.ts index cc174bfa93..8c14bc01a7 100644 --- a/packages/excalidraw/element/flowchart.ts +++ b/packages/excalidraw/element/flowchart.ts @@ -29,7 +29,7 @@ import { isFlowchartNodeElement, } from "./typeChecks"; import { invariant } from "../utils"; -import { point, type LocalPoint } from "../../math"; +import { pointFrom, type LocalPoint } from "../../math"; import { aabbForElement } from "../shapes"; type LinkDirection = "up" | "right" | "down" | "left"; @@ -421,7 +421,7 @@ const createBindingArrow = ( strokeColor: appState.currentItemStrokeColor, strokeStyle: appState.currentItemStrokeStyle, strokeWidth: appState.currentItemStrokeWidth, - points: [point(0, 0), point(endX, endY)], + points: [pointFrom(0, 0), pointFrom(endX, endY)], elbowed: true, }); diff --git a/packages/excalidraw/element/heading.ts b/packages/excalidraw/element/heading.ts index 59dce8585a..a1c896ce27 100644 --- a/packages/excalidraw/element/heading.ts +++ b/packages/excalidraw/element/heading.ts @@ -7,7 +7,7 @@ import type { ViewportPoint, } from "../../math"; import { - point, + pointFrom, pointRotateRads, pointScaleFromOrigin, radiansToDegrees, @@ -85,7 +85,7 @@ export const headingForPointFromElement = < const top = pointRotateRads( pointScaleFromOrigin( - point(element.x + element.width / 2, element.y), + pointFrom(element.x + element.width / 2, element.y), midPoint, SEARCH_CONE_MULTIPLIER, ), @@ -94,7 +94,7 @@ export const headingForPointFromElement = < ); const right = pointRotateRads( pointScaleFromOrigin( - point(element.x + element.width, element.y + element.height / 2), + pointFrom(element.x + element.width, element.y + element.height / 2), midPoint, SEARCH_CONE_MULTIPLIER, ), @@ -103,7 +103,7 @@ export const headingForPointFromElement = < ); const bottom = pointRotateRads( pointScaleFromOrigin( - point(element.x + element.width / 2, element.y + element.height), + pointFrom(element.x + element.width / 2, element.y + element.height), midPoint, SEARCH_CONE_MULTIPLIER, ), @@ -112,7 +112,7 @@ export const headingForPointFromElement = < ); const left = pointRotateRads( pointScaleFromOrigin( - point(element.x, element.y + element.height / 2), + pointFrom(element.x, element.y + element.height / 2), midPoint, SEARCH_CONE_MULTIPLIER, ), @@ -136,22 +136,22 @@ export const headingForPointFromElement = < } const topLeft = pointScaleFromOrigin( - point(aabb[0], aabb[1]), + pointFrom(aabb[0], aabb[1]), midPoint, SEARCH_CONE_MULTIPLIER, ) as Point; const topRight = pointScaleFromOrigin( - point(aabb[2], aabb[1]), + pointFrom(aabb[2], aabb[1]), midPoint, SEARCH_CONE_MULTIPLIER, ) as Point; const bottomLeft = pointScaleFromOrigin( - point(aabb[0], aabb[3]), + pointFrom(aabb[0], aabb[3]), midPoint, SEARCH_CONE_MULTIPLIER, ) as Point; const bottomRight = pointScaleFromOrigin( - point(aabb[2], aabb[3]), + pointFrom(aabb[2], aabb[3]), midPoint, SEARCH_CONE_MULTIPLIER, ) as Point; diff --git a/packages/excalidraw/element/linearElementEditor.ts b/packages/excalidraw/element/linearElementEditor.ts index b9e871382c..9050d1d7a3 100644 --- a/packages/excalidraw/element/linearElementEditor.ts +++ b/packages/excalidraw/element/linearElementEditor.ts @@ -44,7 +44,7 @@ import type Scene from "../scene/Scene"; import type { Radians } from "../../math"; import { pointCenter, - point, + pointFrom, pointRotateRads, pointsEqual, vector, @@ -106,14 +106,14 @@ export class LinearElementEditor { this.elementId = element.id as string & { _brand: "excalidrawLinearElementId"; }; - if (!pointsEqual(element.points[0], point(0, 0))) { + if (!pointsEqual(element.points[0], pointFrom(0, 0))) { console.error("Linear element is not normalized", Error().stack); } this.selectedPointsIndices = null; this.lastUncommittedPoint = null; this.isDragging = false; - this.pointerOffset = point(0, 0); + this.pointerOffset = pointFrom(0, 0); this.startBindingElement = "keep"; this.endBindingElement = "keep"; this.pointerDownState = { @@ -293,7 +293,7 @@ export class LinearElementEditor { [ { index: selectedIndex, - point: point( + point: pointFrom( width + referencePoint[0], height + referencePoint[1], ), @@ -327,7 +327,7 @@ export class LinearElementEditor { ), event[KEYS.CTRL_OR_CMD] ? null : app.getEffectiveGridSize(), ) - : point( + : pointFrom( element.points[pointIndex][0] + deltaX, element.points[pointIndex][1] + deltaY, ); @@ -478,7 +478,7 @@ export class LinearElementEditor { ? [pointerDownState.lastClickedPoint] : selectedPointsIndices, isDragging: false, - pointerOffset: point(0, 0), + pointerOffset: pointFrom(0, 0), }; } @@ -586,7 +586,7 @@ export class LinearElementEditor { linearElementEditor.segmentMidPointHoveredCoords; if (existingSegmentMidpointHitCoords) { const distance = pointDistance( - point( + pointFrom( existingSegmentMidpointHitCoords[0], existingSegmentMidpointHitCoords[1], ), @@ -602,7 +602,7 @@ export class LinearElementEditor { while (index < midPoints.length) { if (midPoints[index] !== null) { const distance = pointDistance( - point(midPoints[index]![0], midPoints[index]![1]), + pointFrom(midPoints[index]![0], midPoints[index]![1]), scenePointer, ); if (distance <= threshold) { @@ -622,8 +622,8 @@ export class LinearElementEditor { zoom: AppState["zoom"], ) { let distance = pointDistance( - point(startPoint[0], startPoint[1]), - point(endPoint[0], endPoint[1]), + pointFrom(startPoint[0], startPoint[1]), + pointFrom(endPoint[0], endPoint[1]), ); if (element.points.length > 2 && element.roundness) { distance = getBezierCurveLength(element, endPoint); @@ -823,11 +823,11 @@ export class LinearElementEditor { const targetPoint = clickedPointIndex > -1 && pointRotateRads( - point( + pointFrom( element.x + element.points[clickedPointIndex][0], element.y + element.points[clickedPointIndex][1], ), - point(cx, cy), + pointFrom(cx, cy), element.angle, ); @@ -857,7 +857,7 @@ export class LinearElementEditor { selectedPointsIndices: nextSelectedPointsIndices, pointerOffset: targetPoint ? pointSubtract(scenePointer, targetPoint) - : point(0, 0), + : pointFrom(0, 0), }; return ret; @@ -922,7 +922,7 @@ export class LinearElementEditor { event[KEYS.CTRL_OR_CMD] ? null : app.getEffectiveGridSize(), ); - newPoint = point( + newPoint = pointFrom( width + lastCommittedPoint[0], height + lastCommittedPoint[1], ); @@ -976,8 +976,8 @@ export class LinearElementEditor { const { x, y } = element; return pointRotateRads( - point(x + p[0], y + p[1]), - point(cx, cy), + pointFrom(x + p[0], y + p[1]), + pointFrom(cx, cy), element.angle, ); } @@ -993,8 +993,8 @@ export class LinearElementEditor { return element.points.map((p) => { const { x, y } = element; return pointRotateRads( - point(x + p[0], y + p[1]), - point(cx, cy), + pointFrom(x + p[0], y + p[1]), + pointFrom(cx, cy), element.angle, ); }); @@ -1017,8 +1017,12 @@ export class LinearElementEditor { const { x, y } = element; return p - ? pointRotateRads(point(x + p[0], y + p[1]), point(cx, cy), element.angle) - : pointRotateRads(point(x, y), point(cx, cy), element.angle); + ? pointRotateRads( + pointFrom(x + p[0], y + p[1]), + pointFrom(cx, cy), + element.angle, + ) + : pointRotateRads(pointFrom(x, y), pointFrom(cx, cy), element.angle); } static pointFromAbsoluteCoords( @@ -1028,7 +1032,7 @@ export class LinearElementEditor { ): LocalPoint { if (isElbowArrow(element)) { // No rotation for elbow arrows - return point( + return pointFrom( absoluteCoords[0] - element.x, absoluteCoords[1] - element.y, ); @@ -1038,11 +1042,11 @@ export class LinearElementEditor { const cx = (x1 + x2) / 2; const cy = (y1 + y2) / 2; const [x, y] = pointRotateRads( - point(absoluteCoords[0], absoluteCoords[1]), - point(cx, cy), + pointFrom(absoluteCoords[0], absoluteCoords[1]), + pointFrom(cx, cy), -element.angle as Radians, ); - return point(x - element.x, y - element.y); + return pointFrom(x - element.x, y - element.y); } static getPointIndexUnderCursor( @@ -1087,12 +1091,12 @@ export class LinearElementEditor { const cx = (x1 + x2) / 2; const cy = (y1 + y2) / 2; const [rotatedX, rotatedY] = pointRotateRads( - point(pointerOnGrid[0], pointerOnGrid[1]), - point(cx, cy), + pointFrom(pointerOnGrid[0], pointerOnGrid[1]), + pointFrom(cx, cy), -element.angle as Radians, ); - return point(rotatedX - element.x, rotatedY - element.y); + return pointFrom(rotatedX - element.x, rotatedY - element.y); } /** @@ -1112,7 +1116,7 @@ export class LinearElementEditor { return { points: points.map((p) => { - return point(p[0] - offsetX, p[1] - offsetY); + return pointFrom(p[0] - offsetX, p[1] - offsetY); }), x: element.x + offsetX, y: element.y + offsetY, @@ -1166,8 +1170,8 @@ export class LinearElementEditor { } acc.push( nextPoint - ? point((p[0] + nextPoint[0]) / 2, (p[1] + nextPoint[1]) / 2) - : point(p[0], p[1]), + ? pointFrom((p[0] + nextPoint[0]) / 2, (p[1] + nextPoint[1]) / 2) + : pointFrom(p[0], p[1]), ); nextSelectedIndices.push(indexCursor + 1); @@ -1188,7 +1192,7 @@ export class LinearElementEditor { [ { index: element.points.length - 1, - point: point(lastPoint[0] + 30, lastPoint[1] + 30), + point: pointFrom(lastPoint[0] + 30, lastPoint[1] + 30), }, ], elementsMap, @@ -1229,7 +1233,9 @@ export class LinearElementEditor { const nextPoints = element.points.reduce((acc: LocalPoint[], p, idx) => { if (!pointIndices.includes(idx)) { acc.push( - !acc.length ? point(0, 0) : point(p[0] - offsetX, p[1] - offsetY), + !acc.length + ? pointFrom(0, 0) + : pointFrom(p[0] - offsetX, p[1] - offsetY), ); } return acc; @@ -1306,9 +1312,9 @@ export class LinearElementEditor { const deltaY = selectedPointData.point[1] - points[selectedPointData.index][1]; - return point(p[0] + deltaX - offsetX, p[1] + deltaY - offsetY); + return pointFrom(p[0] + deltaX - offsetX, p[1] + deltaY - offsetY); } - return offsetX || offsetY ? point(p[0] - offsetX, p[1] - offsetY) : p; + return offsetX || offsetY ? pointFrom(p[0] - offsetX, p[1] - offsetY) : p; }); LinearElementEditor._updatePoints( @@ -1483,8 +1489,8 @@ export class LinearElementEditor { const dX = prevCenterX - nextCenterX; const dY = prevCenterY - nextCenterY; const rotated = pointRotateRads( - point(offsetX, offsetY), - point(dX, dY), + pointFrom(offsetX, offsetY), + pointFrom(dX, dY), element.angle, ); mutateElement(element, { @@ -1530,8 +1536,8 @@ export class LinearElementEditor { ); return pointRotateRads( - point(width, height), - point(0, 0), + pointFrom(width, height), + pointFrom(0, 0), -element.angle as Radians, ); } @@ -1601,36 +1607,36 @@ export class LinearElementEditor { ); const boundTextX2 = boundTextX1 + boundTextElement.width; const boundTextY2 = boundTextY1 + boundTextElement.height; - const centerPoint = point(cx, cy); + const centerPoint = pointFrom(cx, cy); const topLeftRotatedPoint = pointRotateRads( - point(x1, y1), + pointFrom(x1, y1), centerPoint, element.angle, ); const topRightRotatedPoint = pointRotateRads( - point(x2, y1), + pointFrom(x2, y1), centerPoint, element.angle, ); const counterRotateBoundTextTopLeft = pointRotateRads( - point(boundTextX1, boundTextY1), + pointFrom(boundTextX1, boundTextY1), centerPoint, -element.angle as Radians, ); const counterRotateBoundTextTopRight = pointRotateRads( - point(boundTextX2, boundTextY1), + pointFrom(boundTextX2, boundTextY1), centerPoint, -element.angle as Radians, ); const counterRotateBoundTextBottomLeft = pointRotateRads( - point(boundTextX1, boundTextY2), + pointFrom(boundTextX1, boundTextY2), centerPoint, -element.angle as Radians, ); const counterRotateBoundTextBottomRight = pointRotateRads( - point(boundTextX2, boundTextY2), + pointFrom(boundTextX2, boundTextY2), centerPoint, -element.angle as Radians, ); diff --git a/packages/excalidraw/element/newElement.test.ts b/packages/excalidraw/element/newElement.test.ts index 770d0d9870..6a74e58f05 100644 --- a/packages/excalidraw/element/newElement.test.ts +++ b/packages/excalidraw/element/newElement.test.ts @@ -5,7 +5,7 @@ import { FONT_FAMILY, ROUNDNESS } from "../constants"; import { isPrimitive } from "../utils"; import type { ExcalidrawLinearElement } from "./types"; import type { LocalPoint } from "../../math"; -import { point } from "../../math"; +import { pointFrom } from "../../math"; const assertCloneObjects = (source: any, clone: any) => { for (const key in clone) { @@ -38,7 +38,7 @@ describe("duplicating single elements", () => { element.__proto__ = { hello: "world" }; mutateElement(element, { - points: [point(1, 2), point(3, 4)], + points: [pointFrom(1, 2), pointFrom(3, 4)], }); const copy = duplicateElement(null, new Map(), element); diff --git a/packages/excalidraw/element/resizeElements.ts b/packages/excalidraw/element/resizeElements.ts index 0191fddab6..8209b64c85 100644 --- a/packages/excalidraw/element/resizeElements.ts +++ b/packages/excalidraw/element/resizeElements.ts @@ -56,7 +56,7 @@ import type { GlobalPoint } from "../../math"; import { pointCenter, normalizeRadians, - point, + pointFrom, pointFromPair, pointRotateRads, type Radians, @@ -239,8 +239,8 @@ const resizeSingleTextElement = ( ); // rotation pointer with reverse angle const [rotatedX, rotatedY] = pointRotateRads( - point(pointerX, pointerY), - point(cx, cy), + pointFrom(pointerX, pointerY), + pointFrom(cx, cy), -element.angle as Radians, ); let scaleX = 0; @@ -275,23 +275,23 @@ const resizeSingleTextElement = ( const startBottomRight = [x2, y2]; const startCenter = [cx, cy]; - let newTopLeft = point(x1, y1); + let newTopLeft = pointFrom(x1, y1); if (["n", "w", "nw"].includes(transformHandleType)) { - newTopLeft = point( + newTopLeft = pointFrom( startBottomRight[0] - Math.abs(nextWidth), startBottomRight[1] - Math.abs(nextHeight), ); } if (transformHandleType === "ne") { const bottomLeft = [startTopLeft[0], startBottomRight[1]]; - newTopLeft = point( + newTopLeft = pointFrom( bottomLeft[0], bottomLeft[1] - Math.abs(nextHeight), ); } if (transformHandleType === "sw") { const topRight = [startBottomRight[0], startTopLeft[1]]; - newTopLeft = point( + newTopLeft = pointFrom( topRight[0] - Math.abs(nextWidth), topRight[1], ); @@ -310,12 +310,20 @@ const resizeSingleTextElement = ( } const angle = element.angle; - const rotatedTopLeft = pointRotateRads(newTopLeft, point(cx, cy), angle); - const newCenter = point( + const rotatedTopLeft = pointRotateRads( + newTopLeft, + pointFrom(cx, cy), + angle, + ); + const newCenter = pointFrom( newTopLeft[0] + Math.abs(nextWidth) / 2, newTopLeft[1] + Math.abs(nextHeight) / 2, ); - const rotatedNewCenter = pointRotateRads(newCenter, point(cx, cy), angle); + const rotatedNewCenter = pointRotateRads( + newCenter, + pointFrom(cx, cy), + angle, + ); newTopLeft = pointRotateRads( rotatedTopLeft, rotatedNewCenter, @@ -340,12 +348,12 @@ const resizeSingleTextElement = ( stateAtResizeStart.height, true, ); - const startTopLeft = point(x1, y1); - const startBottomRight = point(x2, y2); + const startTopLeft = pointFrom(x1, y1); + const startBottomRight = pointFrom(x2, y2); const startCenter = pointCenter(startTopLeft, startBottomRight); const rotatedPointer = pointRotateRads( - point(pointerX, pointerY), + pointFrom(pointerX, pointerY), startCenter, -stateAtResizeStart.angle as Radians, ); @@ -418,7 +426,7 @@ const resizeSingleTextElement = ( startCenter, angle, ); - const newCenter = point( + const newCenter = pointFrom( newTopLeft[0] + Math.abs(newBoundsWidth) / 2, newTopLeft[1] + Math.abs(newBoundsHeight) / 2, ); @@ -460,13 +468,13 @@ export const resizeSingleElement = ( stateAtResizeStart.height, true, ); - const startTopLeft = point(x1, y1); - const startBottomRight = point(x2, y2); + const startTopLeft = pointFrom(x1, y1); + const startBottomRight = pointFrom(x2, y2); const startCenter = pointCenter(startTopLeft, startBottomRight); // Calculate new dimensions based on cursor position const rotatedPointer = pointRotateRads( - point(pointerX, pointerY), + pointFrom(pointerX, pointerY), startCenter, -stateAtResizeStart.angle as Radians, ); @@ -647,7 +655,7 @@ export const resizeSingleElement = ( startCenter, angle, ); - const newCenter = point( + const newCenter = pointFrom( newTopLeft[0] + Math.abs(newBoundsWidth) / 2, newTopLeft[1] + Math.abs(newBoundsHeight) / 2, ); @@ -818,20 +826,20 @@ export const resizeMultipleElements = ( const direction = transformHandleType; const anchorsMap: Record = { - ne: point(minX, maxY), - se: point(minX, minY), - sw: point(maxX, minY), - nw: point(maxX, maxY), - e: point(minX, minY + height / 2), - w: point(maxX, minY + height / 2), - n: point(minX + width / 2, maxY), - s: point(minX + width / 2, minY), + ne: pointFrom(minX, maxY), + se: pointFrom(minX, minY), + sw: pointFrom(maxX, minY), + nw: pointFrom(maxX, maxY), + e: pointFrom(minX, minY + height / 2), + w: pointFrom(maxX, minY + height / 2), + n: pointFrom(minX + width / 2, maxY), + s: pointFrom(minX + width / 2, minY), }; // anchor point must be on the opposite side of the dragged selection handle // or be the center of the selection if shouldResizeFromCenter const [anchorX, anchorY] = shouldResizeFromCenter - ? point(midX, midY) + ? pointFrom(midX, midY) : anchorsMap[direction]; const resizeFromCenterScale = shouldResizeFromCenter ? 2 : 1; @@ -1045,8 +1053,8 @@ const rotateMultipleElements = ( const origAngle = originalElements.get(element.id)?.angle ?? element.angle; const [rotatedCX, rotatedCY] = pointRotateRads( - point(cx, cy), - point(centerX, centerY), + pointFrom(cx, cy), + pointFrom(centerX, centerY), (centerAngle + origAngle - element.angle) as Radians, ); @@ -1101,40 +1109,44 @@ export const getResizeOffsetXY = ( const angle = ( selectedElements.length === 1 ? selectedElements[0].angle : 0 ) as Radians; - [x, y] = pointRotateRads(point(x, y), point(cx, cy), -angle as Radians); + [x, y] = pointRotateRads( + pointFrom(x, y), + pointFrom(cx, cy), + -angle as Radians, + ); switch (transformHandleType) { case "n": return pointRotateRads( - point(x - (x1 + x2) / 2, y - y1), - point(0, 0), + pointFrom(x - (x1 + x2) / 2, y - y1), + pointFrom(0, 0), angle, ); case "s": return pointRotateRads( - point(x - (x1 + x2) / 2, y - y2), - point(0, 0), + pointFrom(x - (x1 + x2) / 2, y - y2), + pointFrom(0, 0), angle, ); case "w": return pointRotateRads( - point(x - x1, y - (y1 + y2) / 2), - point(0, 0), + pointFrom(x - x1, y - (y1 + y2) / 2), + pointFrom(0, 0), angle, ); case "e": return pointRotateRads( - point(x - x2, y - (y1 + y2) / 2), - point(0, 0), + pointFrom(x - x2, y - (y1 + y2) / 2), + pointFrom(0, 0), angle, ); case "nw": - return pointRotateRads(point(x - x1, y - y1), point(0, 0), angle); + return pointRotateRads(pointFrom(x - x1, y - y1), pointFrom(0, 0), angle); case "ne": - return pointRotateRads(point(x - x2, y - y1), point(0, 0), angle); + return pointRotateRads(pointFrom(x - x2, y - y1), pointFrom(0, 0), angle); case "sw": - return pointRotateRads(point(x - x1, y - y2), point(0, 0), angle); + return pointRotateRads(pointFrom(x - x1, y - y2), pointFrom(0, 0), angle); case "se": - return pointRotateRads(point(x - x2, y - y2), point(0, 0), angle); + return pointRotateRads(pointFrom(x - x2, y - y2), pointFrom(0, 0), angle); default: return [0, 0]; } diff --git a/packages/excalidraw/element/resizeTest.ts b/packages/excalidraw/element/resizeTest.ts index 99214b5a78..fdf93a26cb 100644 --- a/packages/excalidraw/element/resizeTest.ts +++ b/packages/excalidraw/element/resizeTest.ts @@ -23,7 +23,7 @@ import { SIDE_RESIZING_THRESHOLD } from "../constants"; import { isLinearElement } from "./typeChecks"; import type { GlobalPoint, Segment, LocalPoint } from "../../math"; import { - point, + pointFrom, segmentIncludesPoint, pointRotateRads, type Radians, @@ -92,9 +92,9 @@ export const resizeTest = ( if (!(isLinearElement(element) && element.points.length <= 2)) { const SPACING = SIDE_RESIZING_THRESHOLD / zoom.value; const sides = getSelectionBorders( - point(x1 - SPACING, y1 - SPACING), - point(x2 + SPACING, y2 + SPACING), - point(cx, cy), + pointFrom(x1 - SPACING, y1 - SPACING), + pointFrom(x2 + SPACING, y2 + SPACING), + pointFrom(cx, cy), element.angle, ); @@ -102,7 +102,7 @@ export const resizeTest = ( // test to see if x, y are on the line segment if ( segmentIncludesPoint( - point(x, y), + pointFrom(x, y), side as Segment, SPACING, ) @@ -178,9 +178,9 @@ export const getTransformHandleTypeFromCoords = ( const SPACING = SIDE_RESIZING_THRESHOLD / zoom.value; const sides = getSelectionBorders( - point(x1 - SPACING, y1 - SPACING), - point(x2 + SPACING, y2 + SPACING), - point(cx, cy), + pointFrom(x1 - SPACING, y1 - SPACING), + pointFrom(x2 + SPACING, y2 + SPACING), + pointFrom(cx, cy), 0 as Radians, ); @@ -265,10 +265,10 @@ const getSelectionBorders = ( center: Point, angle: Radians, ) => { - const topLeft = pointRotateRads(point(x1, y1), center, angle); - const topRight = pointRotateRads(point(x2, y1), center, angle); - const bottomLeft = pointRotateRads(point(x1, y2), center, angle); - const bottomRight = pointRotateRads(point(x2, y2), center, angle); + const topLeft = pointRotateRads(pointFrom(x1, y1), center, angle); + const topRight = pointRotateRads(pointFrom(x2, y1), center, angle); + const bottomLeft = pointRotateRads(pointFrom(x1, y2), center, angle); + const bottomRight = pointRotateRads(pointFrom(x2, y2), center, angle); return { n: [topLeft, topRight], diff --git a/packages/excalidraw/element/routing.test.tsx b/packages/excalidraw/element/routing.test.tsx index e451fae5d2..fb6b23f286 100644 --- a/packages/excalidraw/element/routing.test.tsx +++ b/packages/excalidraw/element/routing.test.tsx @@ -17,7 +17,7 @@ import type { ExcalidrawElbowArrowElement, } from "./types"; import { ARROW_TYPE } from "../constants"; -import { point } from "../../math"; +import { pointFrom } from "../../math"; const { h } = window; @@ -32,8 +32,8 @@ describe("elbow arrow routing", () => { }) as ExcalidrawElbowArrowElement; scene.insertElement(arrow); mutateElbowArrow(arrow, scene.getNonDeletedElementsMap(), [ - point(-45 - arrow.x, -100.1 - arrow.y), - point(45 - arrow.x, 99.9 - arrow.y), + pointFrom(-45 - arrow.x, -100.1 - arrow.y), + pointFrom(45 - arrow.x, 99.9 - arrow.y), ]); expect(arrow.points).toEqual([ [0, 0], @@ -69,7 +69,7 @@ describe("elbow arrow routing", () => { y: -100.1, width: 90, height: 200, - points: [point(0, 0), point(90, 200)], + points: [pointFrom(0, 0), pointFrom(90, 200)], }) as ExcalidrawElbowArrowElement; scene.insertElement(rectangle1); scene.insertElement(rectangle2); @@ -81,7 +81,7 @@ describe("elbow arrow routing", () => { expect(arrow.startBinding).not.toBe(null); expect(arrow.endBinding).not.toBe(null); - mutateElbowArrow(arrow, elementsMap, [point(0, 0), point(90, 200)]); + mutateElbowArrow(arrow, elementsMap, [pointFrom(0, 0), pointFrom(90, 200)]); expect(arrow.points).toEqual([ [0, 0], diff --git a/packages/excalidraw/element/routing.ts b/packages/excalidraw/element/routing.ts index 0ebace19c4..4614720654 100644 --- a/packages/excalidraw/element/routing.ts +++ b/packages/excalidraw/element/routing.ts @@ -1,7 +1,7 @@ import type { Radians } from "../../math"; import { pointExtent, - point, + pointFrom, pointScaleFromOrigin, pointTranslate, vector, @@ -743,13 +743,13 @@ const getDonglePosition = ( ): GlobalPoint => { switch (heading) { case HEADING_UP: - return point(p[0], bounds[1]); + return pointFrom(p[0], bounds[1]); case HEADING_RIGHT: - return point(bounds[2], p[1]); + return pointFrom(bounds[2], p[1]); case HEADING_DOWN: - return point(p[0], bounds[3]); + return pointFrom(p[0], bounds[3]); } - return point(bounds[0], p[1]); + return pointFrom(bounds[0], p[1]); }; const estimateSegmentCount = ( diff --git a/packages/excalidraw/element/textWysiwyg.test.tsx b/packages/excalidraw/element/textWysiwyg.test.tsx index 98063f05b1..ea57ca190c 100644 --- a/packages/excalidraw/element/textWysiwyg.test.tsx +++ b/packages/excalidraw/element/textWysiwyg.test.tsx @@ -19,7 +19,7 @@ import type { import { API } from "../tests/helpers/api"; import { getOriginalContainerHeightFromCache } from "./containerCache"; import { getTextEditor, updateTextEditor } from "../tests/queries/dom"; -import { point } from "../../math"; +import { pointFrom } from "../../math"; // Unmount ReactDOM from root ReactDOM.unmountComponentAtNode(document.getElementById("root")!); @@ -42,7 +42,7 @@ describe("textWysiwyg", () => { type: "line", width: 100, height: 0, - points: [point(0, 0), point(100, 0)], + points: [pointFrom(0, 0), pointFrom(100, 0)], }); const textSize = 20; const text = API.createElement({ diff --git a/packages/excalidraw/element/transformHandles.ts b/packages/excalidraw/element/transformHandles.ts index 68234814c3..7029f8de5a 100644 --- a/packages/excalidraw/element/transformHandles.ts +++ b/packages/excalidraw/element/transformHandles.ts @@ -19,7 +19,7 @@ import { isIOS, } from "../constants"; import type { Radians } from "../../math"; -import { point, pointRotateRads } from "../../math"; +import { pointFrom, pointRotateRads } from "../../math"; export type TransformHandleDirection = | "n" @@ -95,8 +95,8 @@ const generateTransformHandle = ( angle: Radians, ): TransformHandle => { const [xx, yy] = pointRotateRads( - point(x + width / 2, y + height / 2), - point(cx, cy), + pointFrom(x + width / 2, y + height / 2), + pointFrom(cx, cy), angle, ); return [xx - width / 2, yy - height / 2, width, height]; diff --git a/packages/excalidraw/frame.ts b/packages/excalidraw/frame.ts index bbbc265aad..73f8b36595 100644 --- a/packages/excalidraw/frame.ts +++ b/packages/excalidraw/frame.ts @@ -37,9 +37,9 @@ import type { GlobalPoint, Segment } from "../math"; import { isPointWithinBounds, segment, - point, pointRotateRads, segmentsIntersectAt, + pointFrom, } from "../math"; // --------------------------- Frame State ------------------------------------ @@ -88,7 +88,7 @@ const getElementLineSegments = ( elementsMap, ); - const center: GlobalPoint = point(cx, cy); + const center: GlobalPoint = pointFrom(cx, cy); if (isLinearElement(element) || isFreeDrawElement(element)) { const segments: Segment[] = []; @@ -99,7 +99,7 @@ const getElementLineSegments = ( segments.push( segment( pointRotateRads( - point( + pointFrom( element.points[i][0] + element.x, element.points[i][1] + element.y, ), @@ -107,7 +107,7 @@ const getElementLineSegments = ( element.angle, ), pointRotateRads( - point( + pointFrom( element.points[i + 1][0] + element.x, element.points[i + 1][1] + element.y, ), @@ -256,7 +256,11 @@ export const isCursorInFrame = ( ) => { const [fx1, fy1, fx2, fy2] = getElementAbsoluteCoords(frame, elementsMap); - return isPointWithinBounds(point(fx1, fy1), cursorCoords, point(fx2, fy2)); + return isPointWithinBounds( + pointFrom(fx1, fy1), + cursorCoords, + pointFrom(fx2, fy2), + ); }; export const groupsAreAtLeastIntersectingTheFrame = ( diff --git a/packages/excalidraw/renderer/renderSnaps.ts b/packages/excalidraw/renderer/renderSnaps.ts index fc6b8bb80d..afe78c21d7 100644 --- a/packages/excalidraw/renderer/renderSnaps.ts +++ b/packages/excalidraw/renderer/renderSnaps.ts @@ -1,5 +1,5 @@ import type { ViewportPoint } from "../../math"; -import { point, type GlobalPoint, type LocalPoint } from "../../math"; +import { pointFrom, type GlobalPoint, type LocalPoint } from "../../math"; import { THEME } from "../constants"; import type { PointSnapLine, PointerSnapLine } from "../snapping"; import type { InteractiveCanvasAppState } from "../types"; @@ -141,27 +141,31 @@ const drawGapLine = ( // (1) if (!appState.zenModeEnabled) { drawLine( - point(from[0], from[1] - FULL), - point(from[0], from[1] + FULL), + pointFrom(from[0], from[1] - FULL), + pointFrom(from[0], from[1] + FULL), context, ); } // (3) drawLine( - point(halfPoint[0] - QUARTER, halfPoint[1] - HALF), - point(halfPoint[0] - QUARTER, halfPoint[1] + HALF), + pointFrom(halfPoint[0] - QUARTER, halfPoint[1] - HALF), + pointFrom(halfPoint[0] - QUARTER, halfPoint[1] + HALF), context, ); drawLine( - point(halfPoint[0] + QUARTER, halfPoint[1] - HALF), - point(halfPoint[0] + QUARTER, halfPoint[1] + HALF), + pointFrom(halfPoint[0] + QUARTER, halfPoint[1] - HALF), + pointFrom(halfPoint[0] + QUARTER, halfPoint[1] + HALF), context, ); if (!appState.zenModeEnabled) { // (4) - drawLine(point(to[0], to[1] - FULL), point(to[0], to[1] + FULL), context); + drawLine( + pointFrom(to[0], to[1] - FULL), + pointFrom(to[0], to[1] + FULL), + context, + ); // (2) drawLine(from, to, context); @@ -171,27 +175,31 @@ const drawGapLine = ( // (1) if (!appState.zenModeEnabled) { drawLine( - point(from[0] - FULL, from[1]), - point(from[0] + FULL, from[1]), + pointFrom(from[0] - FULL, from[1]), + pointFrom(from[0] + FULL, from[1]), context, ); } // (3) drawLine( - point(halfPoint[0] - HALF, halfPoint[1] - QUARTER), - point(halfPoint[0] + HALF, halfPoint[1] - QUARTER), + pointFrom(halfPoint[0] - HALF, halfPoint[1] - QUARTER), + pointFrom(halfPoint[0] + HALF, halfPoint[1] - QUARTER), context, ); drawLine( - point(halfPoint[0] - HALF, halfPoint[1] + QUARTER), - point(halfPoint[0] + HALF, halfPoint[1] + QUARTER), + pointFrom(halfPoint[0] - HALF, halfPoint[1] + QUARTER), + pointFrom(halfPoint[0] + HALF, halfPoint[1] + QUARTER), context, ); if (!appState.zenModeEnabled) { // (4) - drawLine(point(to[0] - FULL, to[1]), point(to[0] + FULL, to[1]), context); + drawLine( + pointFrom(to[0] - FULL, to[1]), + pointFrom(to[0] + FULL, to[1]), + context, + ); // (2) drawLine(from, to, context); diff --git a/packages/excalidraw/scene/Shape.ts b/packages/excalidraw/scene/Shape.ts index ada172ebdf..d0a9ac32f9 100644 --- a/packages/excalidraw/scene/Shape.ts +++ b/packages/excalidraw/scene/Shape.ts @@ -25,7 +25,7 @@ import { canChangeRoundness } from "./comparisons"; import type { EmbedsValidationStatus } from "../types"; import { pathIsALoop, - point, + pointFrom, pointDistance, type GlobalPoint, type LocalPoint, @@ -409,7 +409,7 @@ export const _generateElementShape = ( // initial position to it const points = element.points.length ? element.points - : [point(0, 0)]; + : [pointFrom(0, 0)]; if (isElbowArrow(element)) { shape = [ diff --git a/packages/excalidraw/shapes.tsx b/packages/excalidraw/shapes.tsx index 4403bd4111..a556652dd1 100644 --- a/packages/excalidraw/shapes.tsx +++ b/packages/excalidraw/shapes.tsx @@ -1,7 +1,7 @@ import type { GenericPoint, ViewportPoint } from "../math"; import { isPoint, - point, + pointFrom, pointDistance, pointFromPair, pointRotateRads, @@ -167,15 +167,15 @@ export const getElementShape = ( ? getClosedCurveShape( element, roughShape, - point(element.x, element.y), + pointFrom(element.x, element.y), element.angle, - point(cx, cy), + pointFrom(cx, cy), ) : getCurveShape( roughShape, - point(element.x, element.y), + pointFrom(element.x, element.y), element.angle, - point(cx, cy), + pointFrom(cx, cy), ); } @@ -186,7 +186,7 @@ export const getElementShape = ( const [, , , , cx, cy] = getElementAbsoluteCoords(element, elementsMap); return getFreedrawShape( element, - point(cx, cy), + pointFrom(cx, cy), shouldTestInside(element), ); } @@ -231,7 +231,7 @@ export const getControlPointsForBezierCurve =

( } const ops = getCurvePathOps(shape[0]); - let currentP = point

(0, 0); + let currentP = pointFrom

(0, 0); let index = 0; let minDistance = Infinity; let controlPoints: P[] | null = null; @@ -247,9 +247,9 @@ export const getControlPointsForBezierCurve =

( } if (op === "bcurveTo") { const p0 = currentP; - const p1 = point

(data[0], data[1]); - const p2 = point

(data[2], data[3]); - const p3 = point

(data[4], data[5]); + const p1 = pointFrom

(data[0], data[1]); + const p2 = pointFrom

(data[2], data[3]); + const p3 = pointFrom

(data[4], data[5]); const distance = pointDistance(p3, endPoint); if (distance < minDistance) { minDistance = distance; @@ -277,7 +277,7 @@ export const getBezierXY =

( p0[idx] * Math.pow(t, 3); const tx = equation(t, 0); const ty = equation(t, 1); - return point(tx, ty); + return pointFrom(tx, ty); }; const getPointsInBezierCurve =

( @@ -299,12 +299,12 @@ const getPointsInBezierCurve =

( controlPoints[3], t, ); - pointsOnCurve.push(point(p[0], p[1])); + pointsOnCurve.push(pointFrom(p[0], p[1])); t -= 0.05; } if (pointsOnCurve.length) { if (pointsEqual(pointsOnCurve.at(-1)!, endPoint)) { - pointsOnCurve.push(point(endPoint[0], endPoint[1])); + pointsOnCurve.push(pointFrom(endPoint[0], endPoint[1])); } } return pointsOnCurve; @@ -391,24 +391,24 @@ export const aabbForElement = ( midY: element.y + element.height / 2, }; - const center = point(bbox.midX, bbox.midY); + const center = pointFrom(bbox.midX, bbox.midY); const [topLeftX, topLeftY] = pointRotateRads( - point(bbox.minX, bbox.minY), + pointFrom(bbox.minX, bbox.minY), center, element.angle, ); const [topRightX, topRightY] = pointRotateRads( - point(bbox.maxX, bbox.minY), + pointFrom(bbox.maxX, bbox.minY), center, element.angle, ); const [bottomRightX, bottomRightY] = pointRotateRads( - point(bbox.maxX, bbox.maxY), + pointFrom(bbox.maxX, bbox.maxY), center, element.angle, ); const [bottomLeftX, bottomLeftY] = pointRotateRads( - point(bbox.minX, bbox.maxY), + pointFrom(bbox.minX, bbox.maxY), center, element.angle, ); @@ -442,14 +442,14 @@ export const pointInsideBounds = < p[0] > bounds[0] && p[0] < bounds[2] && p[1] > bounds[1] && p[1] < bounds[3]; export const aabbsOverlapping = (a: Bounds, b: Bounds) => - pointInsideBounds(point(a[0], a[1]), b) || - pointInsideBounds(point(a[2], a[1]), b) || - pointInsideBounds(point(a[2], a[3]), b) || - pointInsideBounds(point(a[0], a[3]), b) || - pointInsideBounds(point(b[0], b[1]), a) || - pointInsideBounds(point(b[2], b[1]), a) || - pointInsideBounds(point(b[2], b[3]), a) || - pointInsideBounds(point(b[0], b[3]), a); + pointInsideBounds(pointFrom(a[0], a[1]), b) || + pointInsideBounds(pointFrom(a[2], a[1]), b) || + pointInsideBounds(pointFrom(a[2], a[3]), b) || + pointInsideBounds(pointFrom(a[0], a[3]), b) || + pointInsideBounds(pointFrom(b[0], b[1]), a) || + pointInsideBounds(pointFrom(b[2], b[1]), a) || + pointInsideBounds(pointFrom(b[2], b[3]), a) || + pointInsideBounds(pointFrom(b[0], b[3]), a); export const getCornerRadius = (x: number, element: ExcalidrawElement) => { if ( diff --git a/packages/excalidraw/snapping.ts b/packages/excalidraw/snapping.ts index 60b42eee07..ab0beb1b73 100644 --- a/packages/excalidraw/snapping.ts +++ b/packages/excalidraw/snapping.ts @@ -1,6 +1,6 @@ import type { InclusiveRange } from "../math"; import { - point, + pointFrom, pointRotateRads, rangeInclusive, rangeIntersection, @@ -228,52 +228,52 @@ export const getElementsCorners = ( !boundingBoxCorners ) { const leftMid = pointRotateRads( - point(x1, y1 + halfHeight), - point(cx, cy), + pointFrom(x1, y1 + halfHeight), + pointFrom(cx, cy), element.angle, ); const topMid = pointRotateRads( - point(x1 + halfWidth, y1), - point(cx, cy), + pointFrom(x1 + halfWidth, y1), + pointFrom(cx, cy), element.angle, ); const rightMid = pointRotateRads( - point(x2, y1 + halfHeight), - point(cx, cy), + pointFrom(x2, y1 + halfHeight), + pointFrom(cx, cy), element.angle, ); const bottomMid = pointRotateRads( - point(x1 + halfWidth, y2), - point(cx, cy), + pointFrom(x1 + halfWidth, y2), + pointFrom(cx, cy), element.angle, ); - const center = point(cx, cy); + const center = pointFrom(cx, cy); result = omitCenter ? [leftMid, topMid, rightMid, bottomMid] : [leftMid, topMid, rightMid, bottomMid, center]; } else { const topLeft = pointRotateRads( - point(x1, y1), - point(cx, cy), + pointFrom(x1, y1), + pointFrom(cx, cy), element.angle, ); const topRight = pointRotateRads( - point(x2, y1), - point(cx, cy), + pointFrom(x2, y1), + pointFrom(cx, cy), element.angle, ); const bottomLeft = pointRotateRads( - point(x1, y2), - point(cx, cy), + pointFrom(x1, y2), + pointFrom(cx, cy), element.angle, ); const bottomRight = pointRotateRads( - point(x2, y2), - point(cx, cy), + pointFrom(x2, y2), + pointFrom(cx, cy), element.angle, ); - const center = point(cx, cy); + const center = pointFrom(cx, cy); result = omitCenter ? [topLeft, topRight, bottomLeft, bottomRight] @@ -287,18 +287,18 @@ export const getElementsCorners = ( const width = maxX - minX; const height = maxY - minY; - const topLeft = point(minX, minY); - const topRight = point(maxX, minY); - const bottomLeft = point(minX, maxY); - const bottomRight = point(maxX, maxY); - const center = point(minX + width / 2, minY + height / 2); + const topLeft = pointFrom(minX, minY); + const topRight = pointFrom(maxX, minY); + const bottomLeft = pointFrom(minX, maxY); + const bottomRight = pointFrom(maxX, maxY); + const center = pointFrom(minX + width / 2, minY + height / 2); result = omitCenter ? [topLeft, topRight, bottomLeft, bottomRight] : [topLeft, topRight, bottomLeft, bottomRight, center]; } - return result.map((p) => point(round(p[0]), round(p[1]))); + return result.map((p) => pointFrom(round(p[0]), round(p[1]))); }; const getReferenceElements = ( @@ -375,8 +375,11 @@ export const getVisibleGaps = ( horizontalGaps.push({ startBounds, endBounds, - startSide: [point(startMaxX, startMinY), point(startMaxX, startMaxY)], - endSide: [point(endMinX, endMinY), point(endMinX, endMaxY)], + startSide: [ + pointFrom(startMaxX, startMinY), + pointFrom(startMaxX, startMaxY), + ], + endSide: [pointFrom(endMinX, endMinY), pointFrom(endMinX, endMaxY)], length: endMinX - startMaxX, overlap: rangeIntersection( rangeInclusive(startMinY, startMaxY), @@ -415,8 +418,11 @@ export const getVisibleGaps = ( verticalGaps.push({ startBounds, endBounds, - startSide: [point(startMinX, startMaxY), point(startMaxX, startMaxY)], - endSide: [point(endMinX, endMinY), point(endMaxX, endMinY)], + startSide: [ + pointFrom(startMinX, startMaxY), + pointFrom(startMaxX, startMaxY), + ], + endSide: [pointFrom(endMinX, endMinY), pointFrom(endMaxX, endMinY)], length: endMinY - startMaxY, overlap: rangeIntersection( rangeInclusive(startMinX, startMaxX), @@ -832,7 +838,7 @@ const createPointSnapLines = ( } snapsX[key].push( ...snap.points.map((p) => - point(round(p[0]), round(p[1])), + pointFrom(round(p[0]), round(p[1])), ), ); } @@ -849,7 +855,7 @@ const createPointSnapLines = ( } snapsY[key].push( ...snap.points.map((p) => - point(round(p[0]), round(p[1])), + pointFrom(round(p[0]), round(p[1])), ), ); } @@ -863,7 +869,7 @@ const createPointSnapLines = ( points: dedupePoints( points .map((p) => { - return point(Number(key), p[1]); + return pointFrom(Number(key), p[1]); }) .sort((a, b) => a[1] - b[1]), ), @@ -876,7 +882,7 @@ const createPointSnapLines = ( points: dedupePoints( points .map((p) => { - return point(p[0], Number(key)); + return pointFrom(p[0], Number(key)); }) .sort((a, b) => a[0] - b[0]), ), @@ -940,16 +946,16 @@ const createGapSnapLines = ( type: "gap", direction: "horizontal", points: [ - point(gapSnap.gap.startSide[0][0], gapLineY), - point(minX, gapLineY), + pointFrom(gapSnap.gap.startSide[0][0], gapLineY), + pointFrom(minX, gapLineY), ], }, { type: "gap", direction: "horizontal", points: [ - point(maxX, gapLineY), - point(gapSnap.gap.endSide[0][0], gapLineY), + pointFrom(maxX, gapLineY), + pointFrom(gapSnap.gap.endSide[0][0], gapLineY), ], }, ); @@ -966,16 +972,16 @@ const createGapSnapLines = ( type: "gap", direction: "vertical", points: [ - point(gapLineX, gapSnap.gap.startSide[0][1]), - point(gapLineX, minY), + pointFrom(gapLineX, gapSnap.gap.startSide[0][1]), + pointFrom(gapLineX, minY), ], }, { type: "gap", direction: "vertical", points: [ - point(gapLineX, maxY), - point(gapLineX, gapSnap.gap.endSide[0][1]), + pointFrom(gapLineX, maxY), + pointFrom(gapLineX, gapSnap.gap.endSide[0][1]), ], }, ); @@ -991,12 +997,15 @@ const createGapSnapLines = ( { type: "gap", direction: "horizontal", - points: [point(startMaxX, gapLineY), point(endMinX, gapLineY)], + points: [ + pointFrom(startMaxX, gapLineY), + pointFrom(endMinX, gapLineY), + ], }, { type: "gap", direction: "horizontal", - points: [point(endMaxX, gapLineY), point(minX, gapLineY)], + points: [pointFrom(endMaxX, gapLineY), pointFrom(minX, gapLineY)], }, ); } @@ -1011,12 +1020,18 @@ const createGapSnapLines = ( { type: "gap", direction: "horizontal", - points: [point(maxX, gapLineY), point(startMinX, gapLineY)], + points: [ + pointFrom(maxX, gapLineY), + pointFrom(startMinX, gapLineY), + ], }, { type: "gap", direction: "horizontal", - points: [point(startMaxX, gapLineY), point(endMinX, gapLineY)], + points: [ + pointFrom(startMaxX, gapLineY), + pointFrom(endMinX, gapLineY), + ], }, ); } @@ -1031,12 +1046,18 @@ const createGapSnapLines = ( { type: "gap", direction: "vertical", - points: [point(gapLineX, maxY), point(gapLineX, startMinY)], + points: [ + pointFrom(gapLineX, maxY), + pointFrom(gapLineX, startMinY), + ], }, { type: "gap", direction: "vertical", - points: [point(gapLineX, startMaxY), point(gapLineX, endMinY)], + points: [ + pointFrom(gapLineX, startMaxY), + pointFrom(gapLineX, endMinY), + ], }, ); } @@ -1051,12 +1072,15 @@ const createGapSnapLines = ( { type: "gap", direction: "vertical", - points: [point(gapLineX, startMaxY), point(gapLineX, endMinY)], + points: [ + pointFrom(gapLineX, startMaxY), + pointFrom(gapLineX, endMinY), + ], }, { type: "gap", direction: "vertical", - points: [point(gapLineX, endMaxY), point(gapLineX, minY)], + points: [pointFrom(gapLineX, endMaxY), pointFrom(gapLineX, minY)], }, ); } @@ -1070,7 +1094,7 @@ const createGapSnapLines = ( return { ...gapSnapLine, points: gapSnapLine.points.map((p) => - point(round(p[0]), round(p[1])), + pointFrom(round(p[0]), round(p[1])), ) as PointPair, }; }), @@ -1120,35 +1144,35 @@ export const snapResizingElements = ( if (transformHandle) { switch (transformHandle) { case "e": { - selectionSnapPoints.push(point(maxX, minY), point(maxX, maxY)); + selectionSnapPoints.push(pointFrom(maxX, minY), pointFrom(maxX, maxY)); break; } case "w": { - selectionSnapPoints.push(point(minX, minY), point(minX, maxY)); + selectionSnapPoints.push(pointFrom(minX, minY), pointFrom(minX, maxY)); break; } case "n": { - selectionSnapPoints.push(point(minX, minY), point(maxX, minY)); + selectionSnapPoints.push(pointFrom(minX, minY), pointFrom(maxX, minY)); break; } case "s": { - selectionSnapPoints.push(point(minX, maxY), point(maxX, maxY)); + selectionSnapPoints.push(pointFrom(minX, maxY), pointFrom(maxX, maxY)); break; } case "ne": { - selectionSnapPoints.push(point(maxX, minY)); + selectionSnapPoints.push(pointFrom(maxX, minY)); break; } case "nw": { - selectionSnapPoints.push(point(minX, minY)); + selectionSnapPoints.push(pointFrom(minX, minY)); break; } case "se": { - selectionSnapPoints.push(point(maxX, maxY)); + selectionSnapPoints.push(pointFrom(maxX, maxY)); break; } case "sw": { - selectionSnapPoints.push(point(minX, maxY)); + selectionSnapPoints.push(pointFrom(minX, maxY)); break; } } @@ -1191,10 +1215,10 @@ export const snapResizingElements = ( ); const corners: GlobalPoint[] = [ - point(x1, y1), - point(x1, y2), - point(x2, y1), - point(x2, y2), + pointFrom(x1, y1), + pointFrom(x1, y2), + pointFrom(x2, y1), + pointFrom(x2, y2), ]; getPointSnaps( @@ -1231,7 +1255,7 @@ export const snapNewElement = ( } const selectionSnapPoints: GlobalPoint[] = [ - point(origin.x + dragOffset.x, origin.y + dragOffset.y), + pointFrom(origin.x + dragOffset.x, origin.y + dragOffset.y), ]; const snapDistance = getSnapDistance(app.state.zoom.value); @@ -1331,7 +1355,7 @@ export const getSnapLinesAtPointer = ( verticalSnapLines.push({ type: "pointer", - points: [corner, point(corner[0], pointer.y)], + points: [corner, pointFrom(corner[0], pointer.y)], direction: "vertical", }); @@ -1347,7 +1371,7 @@ export const getSnapLinesAtPointer = ( horizontalSnapLines.push({ type: "pointer", - points: [corner, point(pointer.x, corner[1])], + points: [corner, pointFrom(pointer.x, corner[1])], direction: "horizontal", }); diff --git a/packages/excalidraw/tests/binding.test.tsx b/packages/excalidraw/tests/binding.test.tsx index 4f6d6b56bb..680cbfa857 100644 --- a/packages/excalidraw/tests/binding.test.tsx +++ b/packages/excalidraw/tests/binding.test.tsx @@ -7,7 +7,7 @@ import { API } from "./helpers/api"; import { KEYS } from "../keys"; import { actionWrapTextInContainer } from "../actions/actionBoundText"; import { arrayToMap } from "../utils"; -import { point } from "../../math"; +import { pointFrom } from "../../math"; const { h } = window; @@ -32,7 +32,12 @@ describe("element binding", () => { y: 0, width: 100, height: 1, - points: [point(0, 0), point(0, 0), point(100, 0), point(100, 0)], + points: [ + pointFrom(0, 0), + pointFrom(0, 0), + pointFrom(100, 0), + pointFrom(100, 0), + ], }); API.setElements([rect, arrow]); expect(arrow.startBinding).toBe(null); @@ -310,7 +315,7 @@ describe("element binding", () => { const arrow1 = API.createElement({ type: "arrow", id: "arrow1", - points: [point(0, 0), point(0, -87.45777932247563)], + points: [pointFrom(0, 0), pointFrom(0, -87.45777932247563)], startBinding: { elementId: "rectangle1", focus: 0.2, @@ -328,7 +333,7 @@ describe("element binding", () => { const arrow2 = API.createElement({ type: "arrow", id: "arrow2", - points: [point(0, 0), point(0, -87.45777932247563)], + points: [pointFrom(0, 0), pointFrom(0, -87.45777932247563)], startBinding: { elementId: "text1", focus: 0.2, diff --git a/packages/excalidraw/tests/helpers/api.ts b/packages/excalidraw/tests/helpers/api.ts index b7dc6e10d6..66c9408608 100644 --- a/packages/excalidraw/tests/helpers/api.ts +++ b/packages/excalidraw/tests/helpers/api.ts @@ -38,7 +38,7 @@ import type App from "../../components/App"; import { createTestHook } from "../../components/App"; import type { Action } from "../../actions/types"; import { mutateElement } from "../../element/mutateElement"; -import { point, type LocalPoint, type Radians } from "../../../math"; +import { pointFrom, type LocalPoint, type Radians } from "../../../math"; const readFile = util.promisify(fs.readFile); // so that window.h is available when App.tsx is not imported as well. @@ -307,8 +307,8 @@ export class API { height, type, points: rest.points ?? [ - point(0, 0), - point(100, 100), + pointFrom(0, 0), + pointFrom(100, 100), ], elbowed: rest.elbowed ?? false, }); @@ -320,8 +320,8 @@ export class API { height, type, points: rest.points ?? [ - point(0, 0), - point(100, 100), + pointFrom(0, 0), + pointFrom(100, 100), ], }); break; diff --git a/packages/excalidraw/tests/helpers/ui.ts b/packages/excalidraw/tests/helpers/ui.ts index 3c0cd769ca..721982212c 100644 --- a/packages/excalidraw/tests/helpers/ui.ts +++ b/packages/excalidraw/tests/helpers/ui.ts @@ -34,7 +34,7 @@ import { getTextEditor } from "../queries/dom"; import { arrayToMap } from "../../utils"; import { createTestHook } from "../../components/App"; import type { GlobalPoint, LocalPoint, Radians } from "../../../math"; -import { point, pointRotateRads } from "../../../math"; +import { pointFrom, pointRotateRads } from "../../../math"; // so that window.h is available when App.tsx is not imported as well. createTestHook(); @@ -142,7 +142,7 @@ const getElementPointForSelection = ( element: ExcalidrawElement, ): GlobalPoint => { const { x, y, width, height, angle } = element; - const target = point( + const target = pointFrom( x + (isLinearElement(element) || isFreeDrawElement(element) ? 0 : width / 2), y, @@ -151,9 +151,12 @@ const getElementPointForSelection = ( if (isLinearElement(element)) { const bounds = getElementPointsCoords(element, element.points); - center = point((bounds[0] + bounds[2]) / 2, (bounds[1] + bounds[3]) / 2); + center = pointFrom( + (bounds[0] + bounds[2]) / 2, + (bounds[1] + bounds[3]) / 2, + ); } else { - center = point(x + width / 2, y + height / 2); + center = pointFrom(x + width / 2, y + height / 2); } if (isTextElement(element)) { @@ -469,8 +472,8 @@ export class UI { const width = initialWidth ?? initialHeight ?? size; const height = initialHeight ?? size; const points: LocalPoint[] = initialPoints ?? [ - point(0, 0), - point(width, height), + pointFrom(0, 0), + pointFrom(width, height), ]; UI.clickTool(type); diff --git a/packages/excalidraw/tests/history.test.tsx b/packages/excalidraw/tests/history.test.tsx index 3c807cf915..6a5db9753f 100644 --- a/packages/excalidraw/tests/history.test.tsx +++ b/packages/excalidraw/tests/history.test.tsx @@ -46,7 +46,7 @@ import { HistoryEntry } from "../history"; import { AppStateChange, ElementsChange } from "../change"; import { Snapshot, StoreAction } from "../store"; import type { LocalPoint, Radians } from "../../math"; -import { point } from "../../math"; +import { pointFrom } from "../../math"; const { h } = window; @@ -2041,9 +2041,9 @@ describe("history", () => { width: 178.9000000000001, height: 236.10000000000002, points: [ - point(0, 0), - point(178.9000000000001, 0), - point(178.9000000000001, 236.10000000000002), + pointFrom(0, 0), + pointFrom(178.9000000000001, 0), + pointFrom(178.9000000000001, 236.10000000000002), ], startBinding: { elementId: "KPrBI4g_v9qUB1XxYLgSz", @@ -2159,11 +2159,11 @@ describe("history", () => { elements: [ newElementWith(h.elements[0] as ExcalidrawLinearElement, { points: [ - point(0, 0), - point(5, 5), - point(10, 10), - point(15, 15), - point(20, 20), + pointFrom(0, 0), + pointFrom(5, 5), + pointFrom(10, 10), + pointFrom(15, 15), + pointFrom(20, 20), ] as LocalPoint[], }), ], diff --git a/packages/excalidraw/tests/linearElementEditor.test.tsx b/packages/excalidraw/tests/linearElementEditor.test.tsx index 06ca24a9cb..5df260d1d5 100644 --- a/packages/excalidraw/tests/linearElementEditor.test.tsx +++ b/packages/excalidraw/tests/linearElementEditor.test.tsx @@ -28,7 +28,7 @@ import { ROUNDNESS, VERTICAL_ALIGN } from "../constants"; import { vi } from "vitest"; import { arrayToMap } from "../utils"; import type { GlobalPoint } from "../../math"; -import { pointCenter, point } from "../../math"; +import { pointCenter, pointFrom } from "../../math"; const renderInteractiveScene = vi.spyOn( InteractiveCanvas, @@ -57,8 +57,8 @@ describe("Test Linear Elements", () => { interactiveCanvas = container.querySelector("canvas.interactive")!; }); - const p1 = point(20, 20); - const p2 = point(60, 20); + const p1 = pointFrom(20, 20); + const p2 = pointFrom(60, 20); const midpoint = pointCenter(p1, p2); const delta = 50; const mouse = new Pointer("mouse"); @@ -75,7 +75,7 @@ describe("Test Linear Elements", () => { height: 0, type, roughness, - points: [point(0, 0), point(p2[0] - p1[0], p2[1] - p1[1])], + points: [pointFrom(0, 0), pointFrom(p2[0] - p1[0], p2[1] - p1[1])], roundness, }); API.setElements([line]); @@ -99,9 +99,9 @@ describe("Test Linear Elements", () => { type, roughness, points: [ - point(0, 0), - point(p3[0], p3[1]), - point(p2[0] - p1[0], p2[1] - p1[1]), + pointFrom(0, 0), + pointFrom(p3[0], p3[1]), + pointFrom(p2[0] - p1[0], p2[1] - p1[1]), ], roundness, }); @@ -161,7 +161,7 @@ describe("Test Linear Elements", () => { expect(line.points.length).toEqual(2); mouse.clickAt(midpoint[0], midpoint[1]); - drag(midpoint, point(midpoint[0] + 1, midpoint[1] + 1)); + drag(midpoint, pointFrom(midpoint[0] + 1, midpoint[1] + 1)); expect(line.points.length).toEqual(2); @@ -169,7 +169,7 @@ describe("Test Linear Elements", () => { expect(line.y).toBe(originalY); expect(line.points.length).toEqual(2); - drag(midpoint, point(midpoint[0] + delta, midpoint[1] + delta)); + drag(midpoint, pointFrom(midpoint[0] + delta, midpoint[1] + delta)); expect(line.x).toBe(originalX); expect(line.y).toBe(originalY); expect(line.points.length).toEqual(3); @@ -184,7 +184,7 @@ describe("Test Linear Elements", () => { expect((h.elements[0] as ExcalidrawLinearElement).points.length).toEqual(2); // drag line from midpoint - drag(midpoint, point(midpoint[0] + delta, midpoint[1] + delta)); + drag(midpoint, pointFrom(midpoint[0] + delta, midpoint[1] + delta)); expect(renderInteractiveScene.mock.calls.length).toMatchInlineSnapshot(`9`); expect(renderStaticScene.mock.calls.length).toMatchInlineSnapshot(`7`); expect(line.points.length).toEqual(3); @@ -248,7 +248,7 @@ describe("Test Linear Elements", () => { mouse.clickAt(midpoint[0], midpoint[1]); expect(line.points.length).toEqual(2); - drag(midpoint, point(midpoint[0] + 1, midpoint[1] + 1)); + drag(midpoint, pointFrom(midpoint[0] + 1, midpoint[1] + 1)); expect(line.x).toBe(originalX); expect(line.y).toBe(originalY); expect(line.points.length).toEqual(3); @@ -261,7 +261,7 @@ describe("Test Linear Elements", () => { enterLineEditingMode(line); // drag line from midpoint - drag(midpoint, point(midpoint[0] + delta, midpoint[1] + delta)); + drag(midpoint, pointFrom(midpoint[0] + delta, midpoint[1] + delta)); expect(renderInteractiveScene.mock.calls.length).toMatchInlineSnapshot( `12`, ); @@ -356,7 +356,7 @@ describe("Test Linear Elements", () => { const startPoint = pointCenter(points[0], midPoints[0]!); const deltaX = 50; const deltaY = 20; - const endPoint = point( + const endPoint = pointFrom( startPoint[0] + deltaX, startPoint[1] + deltaY, ); @@ -399,8 +399,8 @@ describe("Test Linear Elements", () => { // This is the expected midpoint for line with round edge // hence hardcoding it so if later some bug is introduced // this will fail and we can fix it - const firstSegmentMidpoint = point(55, 45); - const lastSegmentMidpoint = point(75, 40); + const firstSegmentMidpoint = pointFrom(55, 45); + const lastSegmentMidpoint = pointFrom(75, 40); let line: ExcalidrawLinearElement; @@ -416,7 +416,7 @@ describe("Test Linear Elements", () => { // drag line via first segment midpoint drag( firstSegmentMidpoint, - point( + pointFrom( firstSegmentMidpoint[0] + delta, firstSegmentMidpoint[1] + delta, ), @@ -426,7 +426,10 @@ describe("Test Linear Elements", () => { // drag line from last segment midpoint drag( lastSegmentMidpoint, - point(lastSegmentMidpoint[0] + delta, lastSegmentMidpoint[1] + delta), + pointFrom( + lastSegmentMidpoint[0] + delta, + lastSegmentMidpoint[1] + delta, + ), ); expect(renderInteractiveScene.mock.calls.length).toMatchInlineSnapshot( @@ -475,10 +478,10 @@ describe("Test Linear Elements", () => { h.state, ); - const hitCoords = point(points[0][0], points[0][1]); + const hitCoords = pointFrom(points[0][0], points[0][1]); // Drag from first point - drag(hitCoords, point(hitCoords[0] - delta, hitCoords[1] - delta)); + drag(hitCoords, pointFrom(hitCoords[0] - delta, hitCoords[1] - delta)); expect(renderInteractiveScene.mock.calls.length).toMatchInlineSnapshot( `12`, @@ -516,10 +519,10 @@ describe("Test Linear Elements", () => { h.state, ); - const hitCoords = point(points[0][0], points[0][1]); + const hitCoords = pointFrom(points[0][0], points[0][1]); // Drag from first point - drag(hitCoords, point(hitCoords[0] + delta, hitCoords[1] + delta)); + drag(hitCoords, pointFrom(hitCoords[0] + delta, hitCoords[1] + delta)); expect(renderInteractiveScene.mock.calls.length).toMatchInlineSnapshot( `12`, @@ -556,7 +559,7 @@ describe("Test Linear Elements", () => { // dragging line from last segment midpoint drag( lastSegmentMidpoint, - point(lastSegmentMidpoint[0] + 50, lastSegmentMidpoint[1] + 50), + pointFrom(lastSegmentMidpoint[0] + 50, lastSegmentMidpoint[1] + 50), ); expect(line.points.length).toEqual(4); @@ -589,11 +592,11 @@ describe("Test Linear Elements", () => { // This is the expected midpoint for line with round edge // hence hardcoding it so if later some bug is introduced // this will fail and we can fix it - const firstSegmentMidpoint = point( + const firstSegmentMidpoint = pointFrom( 55.9697848965255, 47.442326230998205, ); - const lastSegmentMidpoint = point( + const lastSegmentMidpoint = pointFrom( 76.08587175006699, 43.294165939653226, ); @@ -612,7 +615,7 @@ describe("Test Linear Elements", () => { // drag line from first segment midpoint drag( firstSegmentMidpoint, - point( + pointFrom( firstSegmentMidpoint[0] + delta, firstSegmentMidpoint[1] + delta, ), @@ -622,7 +625,10 @@ describe("Test Linear Elements", () => { // drag line from last segment midpoint drag( lastSegmentMidpoint, - point(lastSegmentMidpoint[0] + delta, lastSegmentMidpoint[1] + delta), + pointFrom( + lastSegmentMidpoint[0] + delta, + lastSegmentMidpoint[1] + delta, + ), ); expect(renderInteractiveScene.mock.calls.length).toMatchInlineSnapshot( `16`, @@ -669,10 +675,10 @@ describe("Test Linear Elements", () => { h.state, ); - const hitCoords = point(points[0][0], points[0][1]); + const hitCoords = pointFrom(points[0][0], points[0][1]); // Drag from first point - drag(hitCoords, point(hitCoords[0] - delta, hitCoords[1] - delta)); + drag(hitCoords, pointFrom(hitCoords[0] - delta, hitCoords[1] - delta)); const newPoints = LinearElementEditor.getPointsGlobalCoordinates( line, @@ -717,10 +723,10 @@ describe("Test Linear Elements", () => { h.state, ); - const hitCoords = point(points[0][0], points[0][1]); + const hitCoords = pointFrom(points[0][0], points[0][1]); // Drag from first point - drag(hitCoords, point(hitCoords[0] + delta, hitCoords[1] + delta)); + drag(hitCoords, pointFrom(hitCoords[0] + delta, hitCoords[1] + delta)); expect(renderInteractiveScene.mock.calls.length).toMatchInlineSnapshot( `12`, @@ -751,7 +757,10 @@ describe("Test Linear Elements", () => { drag( lastSegmentMidpoint, - point(lastSegmentMidpoint[0] + delta, lastSegmentMidpoint[1] + delta), + pointFrom( + lastSegmentMidpoint[0] + delta, + lastSegmentMidpoint[1] + delta, + ), ); expect(line.points.length).toEqual(4); @@ -811,8 +820,8 @@ describe("Test Linear Elements", () => { API.setSelectedElements([line]); enterLineEditingMode(line, true); drag( - point(line.points[0][0] + line.x, line.points[0][1] + line.y), - point( + pointFrom(line.points[0][0] + line.x, line.points[0][1] + line.y), + pointFrom( dragEndPositionOffset[0] + line.x, dragEndPositionOffset[1] + line.y, ), @@ -927,14 +936,14 @@ describe("Test Linear Elements", () => { // This is the expected midpoint for line with round edge // hence hardcoding it so if later some bug is introduced // this will fail and we can fix it - const firstSegmentMidpoint = point( + const firstSegmentMidpoint = pointFrom( 55.9697848965255, 47.442326230998205, ); // drag line from first segment midpoint drag( firstSegmentMidpoint, - point( + pointFrom( firstSegmentMidpoint[0] + delta, firstSegmentMidpoint[1] + delta, ), @@ -1151,7 +1160,7 @@ describe("Test Linear Elements", () => { ); // Drag from last point - drag(points[1], point(points[1][0] + 300, points[1][1])); + drag(points[1], pointFrom(points[1][0] + 300, points[1][1])); expect({ width: container.width, height: container.height }) .toMatchInlineSnapshot(` @@ -1350,11 +1359,11 @@ describe("Test Linear Elements", () => { [ { index: 0, - point: point(line.points[0][0] + 10, line.points[0][1] + 10), + point: pointFrom(line.points[0][0] + 10, line.points[0][1] + 10), }, { index: line.points.length - 1, - point: point( + point: pointFrom( line.points[line.points.length - 1][0] - 10, line.points[line.points.length - 1][1] - 10, ), diff --git a/packages/excalidraw/tests/resize.test.tsx b/packages/excalidraw/tests/resize.test.tsx index e5141219ba..12d213d854 100644 --- a/packages/excalidraw/tests/resize.test.tsx +++ b/packages/excalidraw/tests/resize.test.tsx @@ -17,7 +17,7 @@ import { isLinearElement } from "../element/typeChecks"; import { LinearElementEditor } from "../element/linearElementEditor"; import { arrayToMap } from "../utils"; import type { LocalPoint } from "../../math"; -import { point } from "../../math"; +import { pointFrom } from "../../math"; ReactDOM.unmountComponentAtNode(document.getElementById("root")!); @@ -220,12 +220,17 @@ describe("generic element", () => { describe.each(["line", "freedraw"] as const)("%s element", (type) => { const points: Record = { - line: [point(0, 0), point(60, -20), point(20, 40), point(-40, 0)], + line: [ + pointFrom(0, 0), + pointFrom(60, -20), + pointFrom(20, 40), + pointFrom(-40, 0), + ], freedraw: [ - point(0, 0), - point(-2.474600807561444, 41.021700699972), - point(3.6627956000014024, 47.84174560617245), - point(40.495224145598115, 47.15909710753482), + pointFrom(0, 0), + pointFrom(-2.474600807561444, 41.021700699972), + pointFrom(3.6627956000014024, 47.84174560617245), + pointFrom(40.495224145598115, 47.15909710753482), ], }; @@ -293,11 +298,11 @@ describe("arrow element", () => { it("resizes with a label", async () => { const arrow = UI.createElement("arrow", { points: [ - point(0, 0), - point(40, 140), - point(80, 60), // label's anchor - point(180, 20), - point(200, 120), + pointFrom(0, 0), + pointFrom(40, 140), + pointFrom(80, 60), // label's anchor + pointFrom(180, 20), + pointFrom(200, 120), ], }); const label = await UI.editText(arrow, "Hello"); @@ -747,24 +752,24 @@ describe("multiple selection", () => { x: 60, y: 40, points: [ - point(0, 0), - point(-40, 40), - point(-60, 0), - point(0, -40), - point(40, 20), - point(0, 40), + pointFrom(0, 0), + pointFrom(-40, 40), + pointFrom(-60, 0), + pointFrom(0, -40), + pointFrom(40, 20), + pointFrom(0, 40), ], }); const freedraw = UI.createElement("freedraw", { x: 63.56072661326618, y: 100, points: [ - point(0, 0), - point(-43.56072661326618, 18.15048126846341), - point(-43.56072661326618, 29.041198460587566), - point(-38.115368017204105, 42.652452795512204), - point(-19.964886748740696, 66.24829266003775), - point(19.056612930986716, 77.1390098521619), + pointFrom(0, 0), + pointFrom(-43.56072661326618, 18.15048126846341), + pointFrom(-43.56072661326618, 29.041198460587566), + pointFrom(-38.115368017204105, 42.652452795512204), + pointFrom(-19.964886748740696, 66.24829266003775), + pointFrom(19.056612930986716, 77.1390098521619), ], }); @@ -1101,13 +1106,13 @@ describe("multiple selection", () => { x: 60, y: 0, points: [ - point(0, 0), - point(-40, 40), - point(-20, 60), - point(20, 20), - point(40, 40), - point(-20, 100), - point(-60, 60), + pointFrom(0, 0), + pointFrom(-40, 40), + pointFrom(-20, 60), + pointFrom(20, 20), + pointFrom(40, 40), + pointFrom(-20, 100), + pointFrom(-60, 60), ], }); diff --git a/packages/excalidraw/visualdebug.ts b/packages/excalidraw/visualdebug.ts index 61b66d2256..21b027d740 100644 --- a/packages/excalidraw/visualdebug.ts +++ b/packages/excalidraw/visualdebug.ts @@ -1,5 +1,5 @@ import type { Segment } from "../math"; -import { isSegment, segment, point, type GlobalPoint } from "../math"; +import { isSegment, segment, pointFrom, type GlobalPoint } from "../math"; import { isBounds } from "./element/typeChecks"; import type { Bounds } from "./element/types"; @@ -52,8 +52,8 @@ export const debugDrawPoint = ( debugDrawLine( segment( - point(p[0] + xOffset - 10, p[1] + yOffset - 10), - point(p[0] + xOffset + 10, p[1] + yOffset + 10), + pointFrom(p[0] + xOffset - 10, p[1] + yOffset - 10), + pointFrom(p[0] + xOffset + 10, p[1] + yOffset + 10), ), { color: opts?.color ?? "cyan", @@ -62,8 +62,8 @@ export const debugDrawPoint = ( ); debugDrawLine( segment( - point(p[0] + xOffset - 10, p[1] + yOffset + 10), - point(p[0] + xOffset + 10, p[1] + yOffset - 10), + pointFrom(p[0] + xOffset - 10, p[1] + yOffset + 10), + pointFrom(p[0] + xOffset + 10, p[1] + yOffset - 10), ), { color: opts?.color ?? "cyan", @@ -83,20 +83,20 @@ export const debugDrawBounds = ( debugDrawLine( [ segment( - point(bbox[0], bbox[1]), - point(bbox[2], bbox[1]), + pointFrom(bbox[0], bbox[1]), + pointFrom(bbox[2], bbox[1]), ), segment( - point(bbox[2], bbox[1]), - point(bbox[2], bbox[3]), + pointFrom(bbox[2], bbox[1]), + pointFrom(bbox[2], bbox[3]), ), segment( - point(bbox[2], bbox[3]), - point(bbox[0], bbox[3]), + pointFrom(bbox[2], bbox[3]), + pointFrom(bbox[0], bbox[3]), ), segment( - point(bbox[0], bbox[3]), - point(bbox[0], bbox[1]), + pointFrom(bbox[0], bbox[3]), + pointFrom(bbox[0], bbox[1]), ), ], { diff --git a/packages/math/arc.test.ts b/packages/math/arc.test.ts index 972118e001..ed4176f8f3 100644 --- a/packages/math/arc.test.ts +++ b/packages/math/arc.test.ts @@ -6,31 +6,31 @@ import { arcSegmentInterceptPoints, } from "./arc"; import { line } from "./line"; -import { point } from "./point"; +import { pointFrom } from "./point"; import { segment } from "./segment"; describe("point on arc", () => { it("should detect point on simple arc", () => { expect( arcIncludesPoint( - arc(point(0, 0), 1, radians(-Math.PI / 4), radians(Math.PI / 4)), - point(0.92291667, 0.385), + arc(pointFrom(0, 0), 1, radians(-Math.PI / 4), radians(Math.PI / 4)), + pointFrom(0.92291667, 0.385), ), ).toBe(true); }); it("should not detect point outside of a simple arc", () => { expect( arcIncludesPoint( - arc(point(0, 0), 1, radians(-Math.PI / 4), radians(Math.PI / 4)), - point(-0.92291667, 0.385), + arc(pointFrom(0, 0), 1, radians(-Math.PI / 4), radians(Math.PI / 4)), + pointFrom(-0.92291667, 0.385), ), ).toBe(false); }); it("should not detect point with good angle but incorrect radius", () => { expect( arcIncludesPoint( - arc(point(0, 0), 1, radians(-Math.PI / 4), radians(Math.PI / 4)), - point(-0.5, 0.5), + arc(pointFrom(0, 0), 1, radians(-Math.PI / 4), radians(Math.PI / 4)), + pointFrom(-0.5, 0.5), ), ).toBe(false); }); @@ -40,42 +40,42 @@ describe("intersection", () => { it("should report correct interception point for segment", () => { expect( arcSegmentInterceptPoints( - arc(point(0, 0), 1, radians(-Math.PI / 4), radians(Math.PI / 4)), - segment(point(2, 1), point(0, 0)), + arc(pointFrom(0, 0), 1, radians(-Math.PI / 4), radians(Math.PI / 4)), + segment(pointFrom(2, 1), pointFrom(0, 0)), ), - ).toEqual([point(0.894427190999916, 0.447213595499958)]); + ).toEqual([pointFrom(0.894427190999916, 0.447213595499958)]); }); it("should report both interception points when present for segment", () => { expect( arcSegmentInterceptPoints( - arc(point(0, 0), 1, radians(-Math.PI / 4), radians(Math.PI / 4)), - segment(point(0.9, -2), point(0.9, 2)), + arc(pointFrom(0, 0), 1, radians(-Math.PI / 4), radians(Math.PI / 4)), + segment(pointFrom(0.9, -2), pointFrom(0.9, 2)), ), ).toEqual([ - point(0.9, -0.4358898943540668), - point(0.9, 0.4358898943540668), + pointFrom(0.9, -0.4358898943540668), + pointFrom(0.9, 0.4358898943540668), ]); }); it("should report correct interception point for line", () => { expect( arcLineInterceptPoints( - arc(point(0, 0), 1, radians(-Math.PI / 4), radians(Math.PI / 4)), - line(point(2, 1), point(0, 0)), + arc(pointFrom(0, 0), 1, radians(-Math.PI / 4), radians(Math.PI / 4)), + line(pointFrom(2, 1), pointFrom(0, 0)), ), - ).toEqual([point(0.894427190999916, 0.447213595499958)]); + ).toEqual([pointFrom(0.894427190999916, 0.447213595499958)]); }); it("should report both interception points when present for line", () => { expect( arcLineInterceptPoints( - arc(point(0, 0), 1, radians(-Math.PI / 4), radians(Math.PI / 4)), - line(point(0.9, -2), point(0.9, 2)), + arc(pointFrom(0, 0), 1, radians(-Math.PI / 4), radians(Math.PI / 4)), + line(pointFrom(0.9, -2), pointFrom(0.9, 2)), ), ).toEqual([ - point(0.9, 0.4358898943540668), - point(0.9, -0.4358898943540668), + pointFrom(0.9, 0.4358898943540668), + pointFrom(0.9, -0.4358898943540668), ]); }); }); diff --git a/packages/math/curve.ts b/packages/math/curve.ts index fb916c740c..bc0c6582d7 100644 --- a/packages/math/curve.ts +++ b/packages/math/curve.ts @@ -1,4 +1,4 @@ -import { point, pointRotateRads } from "./point"; +import { pointFrom, pointRotateRads } from "./point"; import type { Curve, GenericPoint, Radians } from "./types"; /** @@ -43,10 +43,10 @@ export function curveToBezier( const out: Point[] = []; if (len === 3) { out.push( - point(pointsIn[0][0], pointsIn[0][1]), // Points need to be cloned - point(pointsIn[1][0], pointsIn[1][1]), // Points need to be cloned - point(pointsIn[2][0], pointsIn[2][1]), // Points need to be cloned - point(pointsIn[2][0], pointsIn[2][1]), // Points need to be cloned + pointFrom(pointsIn[0][0], pointsIn[0][1]), // Points need to be cloned + pointFrom(pointsIn[1][0], pointsIn[1][1]), // Points need to be cloned + pointFrom(pointsIn[2][0], pointsIn[2][1]), // Points need to be cloned + pointFrom(pointsIn[2][0], pointsIn[2][1]), // Points need to be cloned ); } else { const points: Point[] = []; @@ -59,19 +59,19 @@ export function curveToBezier( } const b: Point[] = []; const s = 1 - curveTightness; - out.push(point(points[0][0], points[0][1])); + out.push(pointFrom(points[0][0], points[0][1])); for (let i = 1; i + 2 < points.length; i++) { const cachedVertArray = points[i]; - b[0] = point(cachedVertArray[0], cachedVertArray[1]); - b[1] = point( + b[0] = pointFrom(cachedVertArray[0], cachedVertArray[1]); + b[1] = pointFrom( cachedVertArray[0] + (s * points[i + 1][0] - s * points[i - 1][0]) / 6, cachedVertArray[1] + (s * points[i + 1][1] - s * points[i - 1][1]) / 6, ); - b[2] = point( + b[2] = pointFrom( points[i + 1][0] + (s * points[i][0] - s * points[i + 2][0]) / 6, points[i + 1][1] + (s * points[i][1] - s * points[i + 2][1]) / 6, ); - b[3] = point(points[i + 1][0], points[i + 1][1]); + b[3] = pointFrom(points[i + 1][0], points[i + 1][1]); out.push(b[1], b[2], b[3]); } } @@ -102,7 +102,7 @@ export const cubicBezierPoint = ( 3 * (1 - t) * Math.pow(t, 2) * p2[1] + Math.pow(t, 3) * p3[1]; - return point(x, y); + return pointFrom(x, y); }; /** diff --git a/packages/math/point.test.ts b/packages/math/point.test.ts index 77ea06c932..89cc4f8f38 100644 --- a/packages/math/point.test.ts +++ b/packages/math/point.test.ts @@ -1,4 +1,4 @@ -import { point, pointRotateRads } from "./point"; +import { pointFrom, pointRotateRads } from "./point"; import type { Radians } from "./types"; describe("rotate", () => { @@ -9,14 +9,14 @@ describe("rotate", () => { const y2 = 30; const angle = (Math.PI / 2) as Radians; const [rotatedX, rotatedY] = pointRotateRads( - point(x1, y1), - point(x2, y2), + pointFrom(x1, y1), + pointFrom(x2, y2), angle, ); expect([rotatedX, rotatedY]).toEqual([30, 20]); const res2 = pointRotateRads( - point(rotatedX, rotatedY), - point(x2, y2), + pointFrom(rotatedX, rotatedY), + pointFrom(x2, y2), -angle as Radians, ); expect(res2).toEqual([x1, x2]); diff --git a/packages/math/point.ts b/packages/math/point.ts index bdfdfbeaac..e24bd29c3e 100644 --- a/packages/math/point.ts +++ b/packages/math/point.ts @@ -10,7 +10,10 @@ import { vectorFromPoint, vectorScale } from "./vector"; * @param y The Y coordinate * @returns The branded and created point */ -export function point(x: number, y: number): Point { +export function pointFrom( + x: number, + y: number, +): Point { return [x, y] as Point; } @@ -24,7 +27,7 @@ export function pointFromArray( numberArray: number[], ): Point | undefined { return numberArray.length === 2 - ? point(numberArray[0], numberArray[1]) + ? pointFrom(numberArray[0], numberArray[1]) : undefined; } @@ -48,9 +51,9 @@ export function pointFromPair( */ export function pointFromVector

( v: Vector, - offset: P = point(0, 0), + offset: P = pointFrom(0, 0), ): P { - return point

(offset[0] + v[0], offset[1] + v[1]); + return pointFrom

(offset[0] + v[0], offset[1] + v[1]); } /** @@ -102,7 +105,7 @@ export function pointRotateRads( const cos = Math.cos(angle); const sin = Math.sin(angle); - return point( + return pointFrom( (x - cx) * cos - (y - cy) * sin + cx, (x - cx) * sin + (y - cy) * cos + cy, ); @@ -141,7 +144,7 @@ export function pointTranslate< From extends GenericPoint, To extends GenericPoint, >(p: From, v: Vector = [0, 0] as Vector): To { - return point(p[0] + v[0], p[1] + v[1]); + return pointFrom(p[0] + v[0], p[1] + v[1]); } /** @@ -171,7 +174,7 @@ export function pointAdd( a: Point, b: Point, ): Point { - return point(a[0] + b[0], a[1] + b[1]); + return pointFrom(a[0] + b[0], a[1] + b[1]); } /** @@ -186,7 +189,7 @@ export function pointSubtract( a: Point, b: Point, ): Point { - return point(a[0] - b[0], a[1] - b[1]); + return pointFrom(a[0] - b[0], a[1] - b[1]); } /** diff --git a/packages/utils/collision.test.ts b/packages/utils/collision.test.ts index 9f3ad61343..d6ad3a8ea8 100644 --- a/packages/utils/collision.test.ts +++ b/packages/utils/collision.test.ts @@ -4,7 +4,7 @@ import { degreesToRadians, segment, segmentRotate, - point, + pointFrom, pointRotateDegs, } from "../math"; import { pointOnCurve, pointOnPolyline } from "./collision"; @@ -12,21 +12,21 @@ import type { Polyline } from "./geometry/shape"; describe("point and curve", () => { const c: Curve = curve( - point(1.4, 1.65), - point(1.9, 7.9), - point(5.9, 1.65), - point(6.44, 4.84), + pointFrom(1.4, 1.65), + pointFrom(1.9, 7.9), + pointFrom(5.9, 1.65), + pointFrom(6.44, 4.84), ); it("point on curve", () => { expect(pointOnCurve(c[0], c, 10e-5)).toBe(true); expect(pointOnCurve(c[3], c, 10e-5)).toBe(true); - expect(pointOnCurve(point(2, 4), c, 0.1)).toBe(true); - expect(pointOnCurve(point(4, 4.4), c, 0.1)).toBe(true); - expect(pointOnCurve(point(5.6, 3.85), c, 0.1)).toBe(true); + expect(pointOnCurve(pointFrom(2, 4), c, 0.1)).toBe(true); + expect(pointOnCurve(pointFrom(4, 4.4), c, 0.1)).toBe(true); + expect(pointOnCurve(pointFrom(5.6, 3.85), c, 0.1)).toBe(true); - expect(pointOnCurve(point(5.6, 4), c, 0.1)).toBe(false); + expect(pointOnCurve(pointFrom(5.6, 4), c, 0.1)).toBe(false); expect(pointOnCurve(c[1], c, 0.1)).toBe(false); expect(pointOnCurve(c[2], c, 0.1)).toBe(false); }); @@ -34,52 +34,52 @@ describe("point and curve", () => { describe("point and polylines", () => { const polyline: Polyline = [ - segment(point(1, 0), point(1, 2)), - segment(point(1, 2), point(2, 2)), - segment(point(2, 2), point(2, 1)), - segment(point(2, 1), point(3, 1)), + segment(pointFrom(1, 0), pointFrom(1, 2)), + segment(pointFrom(1, 2), pointFrom(2, 2)), + segment(pointFrom(2, 2), pointFrom(2, 1)), + segment(pointFrom(2, 1), pointFrom(3, 1)), ]; it("point on the line", () => { - expect(pointOnPolyline(point(1, 0), polyline)).toBe(true); - expect(pointOnPolyline(point(1, 2), polyline)).toBe(true); - expect(pointOnPolyline(point(2, 2), polyline)).toBe(true); - expect(pointOnPolyline(point(2, 1), polyline)).toBe(true); - expect(pointOnPolyline(point(3, 1), polyline)).toBe(true); + expect(pointOnPolyline(pointFrom(1, 0), polyline)).toBe(true); + expect(pointOnPolyline(pointFrom(1, 2), polyline)).toBe(true); + expect(pointOnPolyline(pointFrom(2, 2), polyline)).toBe(true); + expect(pointOnPolyline(pointFrom(2, 1), polyline)).toBe(true); + expect(pointOnPolyline(pointFrom(3, 1), polyline)).toBe(true); - expect(pointOnPolyline(point(1, 1), polyline)).toBe(true); - expect(pointOnPolyline(point(2, 1.5), polyline)).toBe(true); - expect(pointOnPolyline(point(2.5, 1), polyline)).toBe(true); + expect(pointOnPolyline(pointFrom(1, 1), polyline)).toBe(true); + expect(pointOnPolyline(pointFrom(2, 1.5), polyline)).toBe(true); + expect(pointOnPolyline(pointFrom(2.5, 1), polyline)).toBe(true); - expect(pointOnPolyline(point(0, 1), polyline)).toBe(false); - expect(pointOnPolyline(point(2.1, 1.5), polyline)).toBe(false); + expect(pointOnPolyline(pointFrom(0, 1), polyline)).toBe(false); + expect(pointOnPolyline(pointFrom(2.1, 1.5), polyline)).toBe(false); }); it("point on the line with rotation", () => { const truePoints = [ - point(1, 0), - point(1, 2), - point(2, 2), - point(2, 1), - point(3, 1), + pointFrom(1, 0), + pointFrom(1, 2), + pointFrom(2, 2), + pointFrom(2, 1), + pointFrom(3, 1), ]; truePoints.forEach((p) => { const rotation = (Math.random() * 360) as Degrees; - const rotatedPoint = pointRotateDegs(p, point(0, 0), rotation); + const rotatedPoint = pointRotateDegs(p, pointFrom(0, 0), rotation); const rotatedPolyline = polyline.map((line) => - segmentRotate(line, degreesToRadians(rotation), point(0, 0)), + segmentRotate(line, degreesToRadians(rotation), pointFrom(0, 0)), ); expect(pointOnPolyline(rotatedPoint, rotatedPolyline)).toBe(true); }); - const falsePoints = [point(0, 1), point(2.1, 1.5)]; + const falsePoints = [pointFrom(0, 1), pointFrom(2.1, 1.5)]; falsePoints.forEach((p) => { const rotation = (Math.random() * 360) as Degrees; - const rotatedPoint = pointRotateDegs(p, point(0, 0), rotation); + const rotatedPoint = pointRotateDegs(p, pointFrom(0, 0), rotation); const rotatedPolyline = polyline.map((line) => - segmentRotate(line, degreesToRadians(rotation), point(0, 0)), + segmentRotate(line, degreesToRadians(rotation), pointFrom(0, 0)), ); expect(pointOnPolyline(rotatedPoint, rotatedPolyline)).toBe(false); }); diff --git a/packages/utils/collision.ts b/packages/utils/collision.ts index 84d617454b..f7199b2d06 100644 --- a/packages/utils/collision.ts +++ b/packages/utils/collision.ts @@ -3,7 +3,7 @@ import { type GeometricShape } from "./geometry/shape"; import type { Curve, GenericPoint } from "../math"; import { segment, - point, + pointFrom, polygonIncludesPoint, segmentIncludesPoint, pointOnPolygon, @@ -95,7 +95,7 @@ const polyLineFromCurve = ( for (let i = 0; i < segments; i++) { t += increment; if (t <= 1) { - const nextPoint: Point = point(equation(t, 0), equation(t, 1)); + const nextPoint: Point = pointFrom(equation(t, 0), equation(t, 1)); lineSegments.push(segment(startingPoint, nextPoint)); startingPoint = nextPoint; } diff --git a/packages/utils/geometry/geometry.test.ts b/packages/utils/geometry/geometry.test.ts index f770d4d45a..a8bee0169b 100644 --- a/packages/utils/geometry/geometry.test.ts +++ b/packages/utils/geometry/geometry.test.ts @@ -1,6 +1,6 @@ import type { GlobalPoint, Segment, Polygon } from "../../math"; import { - point, + pointFrom, segment, polygon, segmentIncludesPoint, @@ -9,40 +9,40 @@ import { } from "../../math"; describe("point and line", () => { - const s: Segment = segment(point(1, 0), point(1, 2)); + const s: Segment = segment(pointFrom(1, 0), pointFrom(1, 2)); it("point on the line", () => { - expect(segmentIncludesPoint(point(0, 1), s)).toBe(false); - expect(segmentIncludesPoint(point(1, 1), s, 0)).toBe(true); - expect(segmentIncludesPoint(point(2, 1), s)).toBe(false); + expect(segmentIncludesPoint(pointFrom(0, 1), s)).toBe(false); + expect(segmentIncludesPoint(pointFrom(1, 1), s, 0)).toBe(true); + expect(segmentIncludesPoint(pointFrom(2, 1), s)).toBe(false); }); }); describe("point and polygon", () => { const poly: Polygon = polygon( - point(10, 10), - point(50, 10), - point(50, 50), - point(10, 50), + pointFrom(10, 10), + pointFrom(50, 10), + pointFrom(50, 50), + pointFrom(10, 50), ); it("point on polygon", () => { - expect(pointOnPolygon(point(30, 10), poly)).toBe(true); - expect(pointOnPolygon(point(50, 30), poly)).toBe(true); - expect(pointOnPolygon(point(30, 50), poly)).toBe(true); - expect(pointOnPolygon(point(10, 30), poly)).toBe(true); - expect(pointOnPolygon(point(30, 30), poly)).toBe(false); - expect(pointOnPolygon(point(30, 70), poly)).toBe(false); + expect(pointOnPolygon(pointFrom(30, 10), poly)).toBe(true); + expect(pointOnPolygon(pointFrom(50, 30), poly)).toBe(true); + expect(pointOnPolygon(pointFrom(30, 50), poly)).toBe(true); + expect(pointOnPolygon(pointFrom(10, 30), poly)).toBe(true); + expect(pointOnPolygon(pointFrom(30, 30), poly)).toBe(false); + expect(pointOnPolygon(pointFrom(30, 70), poly)).toBe(false); }); it("point in polygon", () => { const poly: Polygon = polygon( - point(0, 0), - point(2, 0), - point(2, 2), - point(0, 2), + pointFrom(0, 0), + pointFrom(2, 0), + pointFrom(2, 2), + pointFrom(0, 2), ); - expect(polygonIncludesPoint(point(1, 1), poly)).toBe(true); - expect(polygonIncludesPoint(point(3, 3), poly)).toBe(false); + expect(polygonIncludesPoint(pointFrom(1, 1), poly)).toBe(true); + expect(polygonIncludesPoint(pointFrom(3, 3), poly)).toBe(false); }); }); diff --git a/packages/utils/geometry/shape.ts b/packages/utils/geometry/shape.ts index d7e4d2c189..ac6aa7d395 100644 --- a/packages/utils/geometry/shape.ts +++ b/packages/utils/geometry/shape.ts @@ -25,7 +25,7 @@ import { curve, ellipse, segment, - point, + pointFrom, pointFromArray, pointFromVector, pointRotateRads, @@ -115,23 +115,23 @@ export const getPolygonShape = ( const cx = x + width / 2; const cy = y + height / 2; - const center: Point = point(cx, cy); + const center: Point = pointFrom(cx, cy); let data: Polygon; if (element.type === "diamond") { data = polygon( - pointRotateRads(point(cx, y), center, angle), - pointRotateRads(point(x + width, cy), center, angle), - pointRotateRads(point(cx, y + height), center, angle), - pointRotateRads(point(x, cy), center, angle), + pointRotateRads(pointFrom(cx, y), center, angle), + pointRotateRads(pointFrom(x + width, cy), center, angle), + pointRotateRads(pointFrom(cx, y + height), center, angle), + pointRotateRads(pointFrom(x, cy), center, angle), ); } else { data = polygon( - pointRotateRads(point(x, y), center, angle), - pointRotateRads(point(x + width, y), center, angle), - pointRotateRads(point(x + width, y + height), center, angle), - pointRotateRads(point(x, y + height), center, angle), + pointRotateRads(pointFrom(x, y), center, angle), + pointRotateRads(pointFrom(x + width, y), center, angle), + pointRotateRads(pointFrom(x + width, y + height), center, angle), + pointRotateRads(pointFrom(x, y + height), center, angle), ); } @@ -159,11 +159,11 @@ export const getSelectionBoxShape = ( y2 += padding; //const angleInDegrees = angleToDegrees(element.angle); - const center = point(cx, cy); - const topLeft = pointRotateRads(point(x1, y1), center, element.angle); - const topRight = pointRotateRads(point(x2, y1), center, element.angle); - const bottomLeft = pointRotateRads(point(x1, y2), center, element.angle); - const bottomRight = pointRotateRads(point(x2, y2), center, element.angle); + const center = pointFrom(cx, cy); + const topLeft = pointRotateRads(pointFrom(x1, y1), center, element.angle); + const topRight = pointRotateRads(pointFrom(x2, y1), center, element.angle); + const bottomLeft = pointRotateRads(pointFrom(x1, y2), center, element.angle); + const bottomRight = pointRotateRads(pointFrom(x2, y2), center, element.angle); return { type: "polygon", @@ -179,7 +179,11 @@ export const getEllipseShape = ( return { type: "ellipse", - data: ellipse(point(x + width / 2, y + height / 2), width / 2, height / 2), + data: ellipse( + pointFrom(x + width / 2, y + height / 2), + width / 2, + height / 2, + ), }; }; @@ -195,20 +199,20 @@ export const getCurvePathOps = (shape: Drawable): Op[] => { // linear export const getCurveShape = ( roughShape: Drawable, - startingPoint: Point = point(0, 0), + startingPoint: Point = pointFrom(0, 0), angleInRadian: Radians, center: Point, ): GeometricShape => { const transform = (p: Point): Point => pointRotateRads( - point(p[0] + startingPoint[0], p[1] + startingPoint[1]), + pointFrom(p[0] + startingPoint[0], p[1] + startingPoint[1]), center, angleInRadian, ); const ops = getCurvePathOps(roughShape); const polycurve: Polycurve = []; - let p0 = point(0, 0); + let p0 = pointFrom(0, 0); for (const op of ops) { if (op.op === "move") { @@ -217,9 +221,9 @@ export const getCurveShape = ( p0 = transform(p); } if (op.op === "bcurveTo") { - const p1 = transform(point(op.data[0], op.data[1])); - const p2 = transform(point(op.data[2], op.data[3])); - const p3 = transform(point(op.data[4], op.data[5])); + const p1 = transform(pointFrom(op.data[0], op.data[1])); + const p2 = transform(pointFrom(op.data[2], op.data[3])); + const p3 = transform(pointFrom(op.data[4], op.data[5])); polycurve.push(curve(p0, p1, p2, p3)); p0 = p3; } @@ -280,13 +284,13 @@ export const getFreedrawShape = ( export const getClosedCurveShape = ( element: ExcalidrawLinearElement, roughShape: Drawable, - startingPoint: Point = point(0, 0), + startingPoint: Point = pointFrom(0, 0), angleInRadian: Radians, center: Point, ): GeometricShape => { const transform = (p: Point) => pointRotateRads( - point(p[0] + startingPoint[0], p[1] + startingPoint[1]), + pointFrom(p[0] + startingPoint[0], p[1] + startingPoint[1]), center, angleInRadian, ); @@ -308,17 +312,17 @@ export const getClosedCurveShape = ( if (operation.op === "move") { odd = !odd; if (odd) { - points.push(point(operation.data[0], operation.data[1])); + points.push(pointFrom(operation.data[0], operation.data[1])); } } else if (operation.op === "bcurveTo") { if (odd) { - points.push(point(operation.data[0], operation.data[1])); - points.push(point(operation.data[2], operation.data[3])); - points.push(point(operation.data[4], operation.data[5])); + points.push(pointFrom(operation.data[0], operation.data[1])); + points.push(pointFrom(operation.data[2], operation.data[3])); + points.push(pointFrom(operation.data[4], operation.data[5])); } } else if (operation.op === "lineTo") { if (odd) { - points.push(point(operation.data[0], operation.data[1])); + points.push(pointFrom(operation.data[0], operation.data[1])); } } } @@ -356,27 +360,27 @@ export const segmentIntersectRectangleElement = < element.x + element.width + gap, element.y + element.height + gap, ]; - const center = point( + const center = pointFrom( (bounds[0] + bounds[2]) / 2, (bounds[1] + bounds[3]) / 2, ); return [ segment( - pointRotateRads(point(bounds[0], bounds[1]), center, element.angle), - pointRotateRads(point(bounds[2], bounds[1]), center, element.angle), + pointRotateRads(pointFrom(bounds[0], bounds[1]), center, element.angle), + pointRotateRads(pointFrom(bounds[2], bounds[1]), center, element.angle), ), segment( - pointRotateRads(point(bounds[2], bounds[1]), center, element.angle), - pointRotateRads(point(bounds[2], bounds[3]), center, element.angle), + pointRotateRads(pointFrom(bounds[2], bounds[1]), center, element.angle), + pointRotateRads(pointFrom(bounds[2], bounds[3]), center, element.angle), ), segment( - pointRotateRads(point(bounds[2], bounds[3]), center, element.angle), - pointRotateRads(point(bounds[0], bounds[3]), center, element.angle), + pointRotateRads(pointFrom(bounds[2], bounds[3]), center, element.angle), + pointRotateRads(pointFrom(bounds[0], bounds[3]), center, element.angle), ), segment( - pointRotateRads(point(bounds[0], bounds[3]), center, element.angle), - pointRotateRads(point(bounds[0], bounds[1]), center, element.angle), + pointRotateRads(pointFrom(bounds[0], bounds[3]), center, element.angle), + pointRotateRads(pointFrom(bounds[0], bounds[1]), center, element.angle), ), ] .map((l) => segmentsIntersectAt(s, l)) diff --git a/packages/utils/withinBounds.ts b/packages/utils/withinBounds.ts index a5315d8fbf..3aee9b7d95 100644 --- a/packages/utils/withinBounds.ts +++ b/packages/utils/withinBounds.ts @@ -17,7 +17,7 @@ import { arrayToMap } from "../excalidraw/utils"; import type { LocalPoint } from "../math"; import { rangeIncludesValue, - point, + pointFrom, pointRotateRads, rangeInclusive, } from "../math"; @@ -36,17 +36,17 @@ const getNonLinearElementRelativePoints = ( ] => { if (element.type === "diamond") { return [ - point(element.width / 2, 0), - point(element.width, element.height / 2), - point(element.width / 2, element.height), - point(0, element.height / 2), + pointFrom(element.width / 2, 0), + pointFrom(element.width, element.height / 2), + pointFrom(element.width / 2, element.height), + pointFrom(0, element.height / 2), ]; } return [ - point(0, 0), - point(0 + element.width, 0), - point(0 + element.width, element.height), - point(0, element.height), + pointFrom(0, 0), + pointFrom(0 + element.width, 0), + pointFrom(0 + element.width, element.height), + pointFrom(0, element.height), ]; }; @@ -91,7 +91,7 @@ const getRotatedBBox = (element: NonDeletedExcalidrawElement): Bounds => { const points = getElementRelativePoints(element); const { cx, cy } = getMinMaxPoints(points); - const centerPoint = point(cx, cy); + const centerPoint = pointFrom(cx, cy); const rotatedPoints = points.map((p) => pointRotateRads(p, centerPoint, element.angle),