tldraw 4.1.1 → 4.2.0-next.d76c345101d5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.d.ts +15 -11
- package/dist-cjs/index.js +3 -1
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/defaultEmbedDefinitions.js +2 -25
- package/dist-cjs/lib/defaultEmbedDefinitions.js.map +2 -2
- package/dist-cjs/lib/defaultExternalContentHandlers.js +8 -31
- package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
- package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +31 -101
- package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/bookmark/bookmarks.js +138 -0
- package/dist-cjs/lib/shapes/bookmark/bookmarks.js.map +7 -0
- package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +25 -3
- package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Cropping.js +20 -4
- package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Cropping.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.js +23 -11
- package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +18 -5
- package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js +21 -9
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingResizeHandle.js +24 -8
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingResizeHandle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingRotateHandle.js +21 -9
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingRotateHandle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +23 -8
- package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js +21 -9
- package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js +26 -11
- package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
- package/dist-cjs/lib/ui/components/DebugMenu/DefaultDebugMenuContent.js +2 -2
- package/dist-cjs/lib/ui/components/DebugMenu/DefaultDebugMenuContent.js.map +1 -1
- package/dist-cjs/lib/ui/components/menu-items.js +2 -2
- package/dist-cjs/lib/ui/components/menu-items.js.map +1 -1
- package/dist-cjs/lib/ui/context/actions.js +23 -29
- package/dist-cjs/lib/ui/context/actions.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useEditorEvents.js +1 -1
- package/dist-cjs/lib/ui/hooks/useEditorEvents.js.map +1 -1
- package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +4 -4
- package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +1 -1
- package/dist-cjs/lib/ui/version.js +3 -3
- package/dist-cjs/lib/ui/version.js.map +1 -1
- package/dist-esm/index.d.mts +15 -11
- package/dist-esm/index.mjs +3 -1
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/defaultEmbedDefinitions.mjs +2 -25
- package/dist-esm/lib/defaultEmbedDefinitions.mjs.map +2 -2
- package/dist-esm/lib/defaultExternalContentHandlers.mjs +8 -31
- package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
- package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +34 -101
- package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/bookmark/bookmarks.mjs +124 -0
- package/dist-esm/lib/shapes/bookmark/bookmarks.mjs.map +7 -0
- package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +26 -3
- package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Cropping.mjs +20 -4
- package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Cropping.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.mjs +23 -11
- package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +18 -5
- package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs +21 -9
- package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/PointingResizeHandle.mjs +24 -8
- package/dist-esm/lib/tools/SelectTool/childStates/PointingResizeHandle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/PointingRotateHandle.mjs +21 -9
- package/dist-esm/lib/tools/SelectTool/childStates/PointingRotateHandle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +23 -8
- package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs +21 -9
- package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs +26 -11
- package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
- package/dist-esm/lib/ui/components/DebugMenu/DefaultDebugMenuContent.mjs +2 -2
- package/dist-esm/lib/ui/components/DebugMenu/DefaultDebugMenuContent.mjs.map +1 -1
- package/dist-esm/lib/ui/components/menu-items.mjs +2 -2
- package/dist-esm/lib/ui/components/menu-items.mjs.map +1 -1
- package/dist-esm/lib/ui/context/actions.mjs +23 -29
- package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useEditorEvents.mjs +1 -1
- package/dist-esm/lib/ui/hooks/useEditorEvents.mjs.map +1 -1
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +4 -4
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +1 -1
- package/dist-esm/lib/ui/version.mjs +3 -3
- package/dist-esm/lib/ui/version.mjs.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +1 -0
- package/src/lib/defaultEmbedDefinitions.ts +2 -25
- package/src/lib/defaultExternalContentHandlers.ts +10 -35
- package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +39 -133
- package/src/lib/shapes/bookmark/bookmarks.ts +170 -0
- package/src/lib/shapes/embed/EmbedShapeUtil.tsx +28 -2
- package/src/lib/tools/SelectTool/childStates/Crop/children/Cropping.ts +23 -6
- package/src/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.ts +24 -12
- package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +21 -10
- package/src/lib/tools/SelectTool/childStates/PointingArrowLabel.ts +23 -11
- package/src/lib/tools/SelectTool/childStates/PointingResizeHandle.ts +26 -9
- package/src/lib/tools/SelectTool/childStates/PointingRotateHandle.ts +23 -10
- package/src/lib/tools/SelectTool/childStates/Resizing.ts +24 -9
- package/src/lib/tools/SelectTool/childStates/Rotating.ts +27 -11
- package/src/lib/tools/SelectTool/childStates/Translating.ts +28 -12
- package/src/lib/ui/components/DebugMenu/DefaultDebugMenuContent.tsx +2 -2
- package/src/lib/ui/components/menu-items.tsx +2 -2
- package/src/lib/ui/context/actions.tsx +27 -31
- package/src/lib/ui/hooks/useEditorEvents.ts +1 -1
- package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +4 -4
- package/src/lib/ui/version.ts +3 -3
- package/src/lib/utils/embeds/embeds.test.ts +16 -34
- package/src/test/SelectTool.test.ts +251 -0
- package/src/test/bookmark-shapes.test.ts +129 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/tools/SelectTool/childStates/Resizing.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\tBox,\n\tHALF_PI,\n\tMat,\n\tPI,\n\tPI2,\n\tSelectionCorner,\n\tSelectionEdge,\n\tStateNode,\n\tTLFrameShape,\n\tTLPointerEventInfo,\n\tTLShape,\n\tTLShapeId,\n\tTLShapePartial,\n\tTLTextShape,\n\tTLTickEventInfo,\n\tVec,\n\tVecLike,\n\tareAnglesCompatible,\n\tcompact,\n\tisAccelKey,\n\tkickoutOccludedShapes,\n} from '@tldraw/editor'\n\nexport type ResizingInfo = TLPointerEventInfo & {\n\ttarget: 'selection'\n\thandle: SelectionEdge | SelectionCorner\n\tisCreating?: boolean\n\tcreatingMarkId?: string\n\tonCreate?(shape: TLShape | null): void\n\tcreationCursorOffset?: VecLike\n\tonInteractionEnd?: string\n}\n\nexport class Resizing extends StateNode {\n\tstatic override id = 'resizing'\n\n\tinfo = {} as ResizingInfo\n\n\tmarkId = ''\n\n\t// A switch to detect when the user is holding ctrl\n\tprivate didHoldCommand = false\n\n\t// we transition into the resizing state from the geo pointing state, which starts with a shape of size w: 1, h: 1,\n\t// so if the user drags x: +50, y: +50 after mouseDown, the shape will be w: 51, h: 51, which is too many pixels, alas\n\t// so we allow passing a further offset into this state to negate such issues\n\tcreationCursorOffset = { x: 0, y: 0 } as VecLike\n\n\tprivate snapshot = {} as any as Snapshot\n\n\toverride onEnter(info: ResizingInfo) {\n\t\tconst { isCreating = false, creatingMarkId, creationCursorOffset = { x: 0, y: 0 } } = info\n\n\t\tthis.info = info\n\t\tthis.didHoldCommand = false\n\n\t\tthis.parent.setCurrentToolIdMask(info.onInteractionEnd)\n\t\tthis.creationCursorOffset = creationCursorOffset\n\n\t\ttry {\n\t\t\t// On rare and mysterious occasions, the user can enter the resizing state with no shapes selected\n\t\t\tthis.snapshot = this._createSnapshot()\n\t\t} catch (e) {\n\t\t\tconsole.error(e)\n\t\t\tthis.cancel()\n\t\t\treturn\n\t\t}\n\n\t\tthis.markId = ''\n\n\t\tif (isCreating) {\n\t\t\tif (creatingMarkId) {\n\t\t\t\tthis.markId = creatingMarkId\n\t\t\t} else {\n\t\t\t\t// handle legacy implicit `creating:{shapeId}` marks\n\t\t\t\tconst markId = this.editor.getMarkIdMatching(\n\t\t\t\t\t`creating:${this.editor.getOnlySelectedShapeId()}`\n\t\t\t\t)\n\t\t\t\tif (markId) {\n\t\t\t\t\tthis.markId = markId\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.markId = this.editor.markHistoryStoppingPoint('starting resizing')\n\t\t}\n\n\t\tif (isCreating) {\n\t\t\tthis.editor.setCursor({ type: 'cross', rotation: 0 })\n\t\t}\n\n\t\tthis.handleResizeStart()\n\t\tthis.updateShapes()\n\t}\n\n\toverride onTick({ elapsed }: TLTickEventInfo) {\n\t\tconst { editor } = this\n\t\teditor.edgeScrollManager.updateEdgeScrolling(elapsed)\n\t}\n\n\toverride onPointerMove() {\n\t\tthis.updateShapes()\n\t}\n\n\toverride onKeyDown() {\n\t\tthis.updateShapes()\n\t}\n\toverride onKeyUp() {\n\t\tthis.updateShapes()\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onComplete() {\n\t\tthis.complete()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\tprivate cancel() {\n\t\t// Call onResizeCancel callback before resetting\n\t\tconst { shapeSnapshots } = this.snapshot\n\n\t\tshapeSnapshots.forEach(({ shape }) => {\n\t\t\tconst current = this.editor.getShape(shape.id)\n\t\t\tif (current) {\n\t\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\t\tutil.onResizeCancel?.(shape, current)\n\t\t\t}\n\t\t})\n\n\t\tthis.editor.bailToMark(this.markId)\n\n\t\tif (this.info.onInteractionEnd) {\n\t\t\tthis.editor.setCurrentTool(this.info.onInteractionEnd, {})\n\t\t} else {\n\t\t\tthis.parent.transition('idle')\n\t\t}\n\t}\n\n\tprivate complete() {\n\t\tkickoutOccludedShapes(this.editor, this.snapshot.selectedShapeIds)\n\n\t\tthis.handleResizeEnd()\n\n\t\tif (this.info.isCreating && this.info.onCreate) {\n\t\t\tthis.info.onCreate?.(this.editor.getOnlySelectedShape())\n\t\t\treturn\n\t\t}\n\n\t\tif (this.editor.getInstanceState().isToolLocked && this.info.onInteractionEnd) {\n\t\t\tthis.editor.setCurrentTool(this.info.onInteractionEnd, {})\n\t\t\treturn\n\t\t}\n\n\t\tthis.parent.transition('idle')\n\t}\n\n\tprivate handleResizeStart() {\n\t\tconst { shapeSnapshots } = this.snapshot\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tshapeSnapshots.forEach(({ shape }) => {\n\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\tconst change = util.onResizeStart?.(shape)\n\t\t\tif (change) {\n\t\t\t\tchanges.push(change)\n\t\t\t}\n\t\t})\n\n\t\tif (changes.length > 0) {\n\t\t\tthis.editor.updateShapes(changes)\n\t\t}\n\t}\n\n\tprivate handleResizeEnd() {\n\t\tconst { shapeSnapshots } = this.snapshot\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tshapeSnapshots.forEach(({ shape }) => {\n\t\t\tconst current = this.editor.getShape(shape.id)!\n\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\tconst change = util.onResizeEnd?.(shape, current)\n\t\t\tif (change) {\n\t\t\t\tchanges.push(change)\n\t\t\t}\n\t\t})\n\n\t\tif (changes.length > 0) {\n\t\t\tthis.editor.updateShapes(changes)\n\t\t}\n\t}\n\n\tprivate updateShapes() {\n\t\tconst { altKey, shiftKey } = this.editor.inputs\n\t\tconst {\n\t\t\tframes,\n\t\t\tshapeSnapshots,\n\t\t\tselectionBounds,\n\t\t\tcursorHandleOffset,\n\t\t\tselectedShapeIds,\n\t\t\tselectionRotation,\n\t\t\tcanShapesDeform,\n\t\t} = this.snapshot\n\n\t\tlet isAspectRatioLocked = shiftKey || !canShapesDeform\n\n\t\tif (shapeSnapshots.size === 1) {\n\t\t\tconst onlySnapshot = [...shapeSnapshots.values()][0]!\n\t\t\tif (this.editor.isShapeOfType<TLTextShape>(onlySnapshot.shape, 'text')) {\n\t\t\t\tisAspectRatioLocked = !(this.info.handle === 'left' || this.info.handle === 'right')\n\t\t\t}\n\t\t}\n\n\t\t// first negate the 'cursor handle offset'\n\t\t// we need to do this because we do grid snapping based on the page point of the handle\n\t\t// rather than the page point of the cursor, so it's easier to pretend that the cursor\n\t\t// is really where the handle actually is\n\t\t//\n\t\t// *** Massively zoomed-in diagram of the initial mouseDown ***\n\t\t//\n\t\t//\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502corner handle\n\t\t// \u250C\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2510\n\t\t// selection \u2502 \u2502\n\t\t// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 x\u25C4\u2500\u2500\u253C\u2500\u2500\u2500\u2500 drag handle point \u25B2\n\t\t// \u2502 \u2502 \u2502\n\t\t// \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u251C\u2500 cursorHandleOffset.y\n\t\t// \u2502\n\t\t// originPagePoint\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25BAx\u2500\u2510 \u25BC\n\t\t// \u2502 \u2514\u2500\u2510\n\t\t// \u2502 \u2514\u2500\u2510\n\t\t// \u2502 \u2502 mouse (sorry)\n\t\t// \u2514\u2500\u2500\u2510 \u250C\u2518\n\t\t// \u2502 \u2502\n\t\t// \u2514\u2500\u2518\n\t\t// \u25C4\u2500\u2500\u252C\u2500\u2500\u25BA\n\t\t// \u2502\n\t\t// cursorHandleOffset.x\n\n\t\tconst isHoldingAccel = isAccelKey(this.editor.inputs)\n\n\t\tconst currentPagePoint = this.editor.inputs.currentPagePoint\n\t\t\t.clone()\n\t\t\t.sub(cursorHandleOffset)\n\t\t\t.sub(this.creationCursorOffset)\n\n\t\tconst originPagePoint = this.editor.inputs.originPagePoint.clone().sub(cursorHandleOffset)\n\n\t\tif (this.editor.getInstanceState().isGridMode && !isHoldingAccel) {\n\t\t\tconst { gridSize } = this.editor.getDocumentSettings()\n\t\t\tcurrentPagePoint.snapToGrid(gridSize)\n\t\t}\n\n\t\tconst dragHandle = this.info.handle as SelectionCorner | SelectionEdge\n\t\tconst scaleOriginHandle = rotateSelectionHandle(dragHandle, Math.PI)\n\n\t\tthis.editor.snaps.clearIndicators()\n\n\t\tconst shouldSnap = this.editor.user.getIsSnapMode() ? !isHoldingAccel : isHoldingAccel\n\n\t\tif (shouldSnap && selectionRotation % HALF_PI === 0) {\n\t\t\tconst { nudge } = this.editor.snaps.shapeBounds.snapResizeShapes({\n\t\t\t\tdragDelta: Vec.Sub(currentPagePoint, originPagePoint),\n\t\t\t\tinitialSelectionPageBounds: this.snapshot.initialSelectionPageBounds,\n\t\t\t\thandle: rotateSelectionHandle(dragHandle, selectionRotation),\n\t\t\t\tisAspectRatioLocked,\n\t\t\t\tisResizingFromCenter: altKey,\n\t\t\t})\n\n\t\t\tcurrentPagePoint.add(nudge)\n\t\t}\n\n\t\t// get the page point of the selection handle opposite to the drag handle\n\t\t// or the center of the selection box if altKey is pressed\n\t\tconst scaleOriginPage = Vec.RotWith(\n\t\t\taltKey ? selectionBounds.center : selectionBounds.getHandlePoint(scaleOriginHandle),\n\t\t\tselectionBounds.point,\n\t\t\tselectionRotation\n\t\t)\n\n\t\t// calculate the scale by measuring the current distance between the drag handle and the scale origin\n\t\t// and dividing by the original distance between the drag handle and the scale origin\n\n\t\t// bug: for edges, the page point doesn't matter, the\n\n\t\tconst distanceFromScaleOriginNow = Vec.Sub(currentPagePoint, scaleOriginPage).rot(\n\t\t\t-selectionRotation\n\t\t)\n\n\t\tconst distanceFromScaleOriginAtStart = Vec.Sub(originPagePoint, scaleOriginPage).rot(\n\t\t\t-selectionRotation\n\t\t)\n\n\t\tconst scale = Vec.DivV(distanceFromScaleOriginNow, distanceFromScaleOriginAtStart)\n\n\t\tif (!Number.isFinite(scale.x)) scale.x = 1\n\t\tif (!Number.isFinite(scale.y)) scale.y = 1\n\n\t\tconst isXLocked = dragHandle === 'top' || dragHandle === 'bottom'\n\t\tconst isYLocked = dragHandle === 'left' || dragHandle === 'right'\n\n\t\t// lock an axis if required\n\t\tif (isAspectRatioLocked) {\n\t\t\tif (isYLocked) {\n\t\t\t\t// holding shift and dragging either the left or the right edge\n\t\t\t\tscale.y = Math.abs(scale.x)\n\t\t\t} else if (isXLocked) {\n\t\t\t\t// holding shift and dragging either the top or the bottom edge\n\t\t\t\tscale.x = Math.abs(scale.y)\n\t\t\t} else if (Math.abs(scale.x) > Math.abs(scale.y)) {\n\t\t\t\t// holding shift and the drag has moved further in the x dimension\n\t\t\t\tscale.y = Math.abs(scale.x) * (scale.y < 0 ? -1 : 1)\n\t\t\t} else {\n\t\t\t\t// holding shift and the drag has moved further in the y dimension\n\t\t\t\tscale.x = Math.abs(scale.y) * (scale.x < 0 ? -1 : 1)\n\t\t\t}\n\t\t} else {\n\t\t\t// not holding shift, but still need to lock axes if dragging an edge\n\t\t\tif (isXLocked) {\n\t\t\t\tscale.x = 1\n\t\t\t}\n\t\t\tif (isYLocked) {\n\t\t\t\tscale.y = 1\n\t\t\t}\n\t\t}\n\n\t\tif (!this.info.isCreating) {\n\t\t\tthis.updateCursor({\n\t\t\t\tdragHandle,\n\t\t\t\tisFlippedX: scale.x < 0,\n\t\t\t\tisFlippedY: scale.y < 0,\n\t\t\t\trotation: selectionRotation,\n\t\t\t})\n\t\t}\n\n\t\tfor (const id of shapeSnapshots.keys()) {\n\t\t\tconst snapshot = shapeSnapshots.get(id)!\n\n\t\t\tthis.editor.resizeShape(id, scale, {\n\t\t\t\tinitialShape: snapshot.shape,\n\t\t\t\tinitialBounds: snapshot.bounds,\n\t\t\t\tinitialPageTransform: snapshot.pageTransform,\n\t\t\t\tdragHandle,\n\t\t\t\tmode:\n\t\t\t\t\tselectedShapeIds.length === 1 && id === selectedShapeIds[0]\n\t\t\t\t\t\t? 'resize_bounds'\n\t\t\t\t\t\t: 'scale_shape',\n\t\t\t\tscaleOrigin: scaleOriginPage,\n\t\t\t\tisAspectRatioLocked,\n\t\t\t\tscaleAxisRotation: selectionRotation,\n\t\t\t\tskipStartAndEndCallbacks: true,\n\t\t\t})\n\t\t}\n\n\t\t// If there's only one shape snapshot and it's a frame and the user is holding ctrl,\n\t\t// then we preserve the position of the frame's children, almost like the user is cropping\n\t\t// the frame rather than resizing it.\n\t\tif (isHoldingAccel) {\n\t\t\tthis.didHoldCommand = true\n\n\t\t\tfor (const { id, children } of frames) {\n\t\t\t\tif (!children.length) continue\n\t\t\t\tconst initial = shapeSnapshots.get(id)!.shape\n\t\t\t\tconst current = this.editor.getShape(id)!\n\t\t\t\tif (!(initial && current)) continue\n\n\t\t\t\tconst dx = current.x - initial.x\n\t\t\t\tconst dy = current.y - initial.y\n\n\t\t\t\tconst delta = new Vec(dx, dy).rot(-initial.rotation)\n\n\t\t\t\tif (delta.x !== 0 || delta.y !== 0) {\n\t\t\t\t\tfor (const child of children) {\n\t\t\t\t\t\tthis.editor.updateShape({\n\t\t\t\t\t\t\tid: child.id,\n\t\t\t\t\t\t\ttype: child.type,\n\t\t\t\t\t\t\tx: child.x - delta.x,\n\t\t\t\t\t\t\ty: child.y - delta.y,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (this.didHoldCommand) {\n\t\t\t// If we're no longer holding the command key...\n\t\t\tthis.didHoldCommand = false\n\n\t\t\tfor (const { children } of frames) {\n\t\t\t\tif (!children.length) continue\n\t\t\t\tfor (const child of children) {\n\t\t\t\t\tthis.editor.updateShape({\n\t\t\t\t\t\tid: child.id,\n\t\t\t\t\t\ttype: child.type,\n\t\t\t\t\t\tx: child.x,\n\t\t\t\t\t\ty: child.y,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// ---\n\n\tprivate updateCursor({\n\t\tdragHandle,\n\t\tisFlippedX,\n\t\tisFlippedY,\n\t\trotation,\n\t}: {\n\t\tdragHandle: SelectionCorner | SelectionEdge\n\t\tisFlippedX: boolean\n\t\tisFlippedY: boolean\n\t\trotation: number\n\t}) {\n\t\tconst nextCursor = { ...this.editor.getInstanceState().cursor }\n\n\t\tswitch (dragHandle) {\n\t\t\tcase 'top_left':\n\t\t\tcase 'bottom_right': {\n\t\t\t\tnextCursor.type = 'nwse-resize'\n\t\t\t\tif (isFlippedX !== isFlippedY) {\n\t\t\t\t\tnextCursor.type = 'nesw-resize'\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'top_right':\n\t\t\tcase 'bottom_left': {\n\t\t\t\tnextCursor.type = 'nesw-resize'\n\t\t\t\tif (isFlippedX !== isFlippedY) {\n\t\t\t\t\tnextCursor.type = 'nwse-resize'\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tnextCursor.rotation = rotation\n\n\t\tthis.editor.setCursor(nextCursor)\n\t}\n\n\toverride onExit() {\n\t\tthis.parent.setCurrentToolIdMask(undefined)\n\t\tthis.editor.setCursor({ type: 'default', rotation: 0 })\n\t\tthis.editor.snaps.clearIndicators()\n\t}\n\n\tprivate _createSnapshot() {\n\t\tconst { editor } = this\n\t\tconst selectedShapeIds = editor.getSelectedShapeIds()\n\t\tconst selectionRotation = editor.getSelectionRotation()\n\t\tconst {\n\t\t\tinputs: { originPagePoint },\n\t\t} = editor\n\n\t\tconst selectionBounds = editor.getSelectionRotatedPageBounds()\n\t\tif (!selectionBounds) throw Error('Resizing but nothing is selected')\n\n\t\tconst dragHandlePoint = Vec.RotWith(\n\t\t\tselectionBounds.getHandlePoint(this.info.handle!),\n\t\t\tselectionBounds.point,\n\t\t\tselectionRotation\n\t\t)\n\n\t\tconst cursorHandleOffset = Vec.Sub(originPagePoint, dragHandlePoint)\n\n\t\tconst shapeSnapshots = new Map<\n\t\t\tTLShapeId,\n\t\t\t{\n\t\t\t\tshape: TLShape\n\t\t\t\tbounds: Box\n\t\t\t\tpageTransform: Mat\n\t\t\t\tpageRotation: number\n\t\t\t\tisAspectRatioLocked: boolean\n\t\t\t}\n\t\t>()\n\n\t\tconst frames: { id: TLShapeId; children: TLShape[] }[] = []\n\n\t\tconst populateResizingShapes = (shapeId: TLShapeId): false | undefined => {\n\t\t\tconst shape = editor.getShape(shapeId)\n\t\t\tif (!shape) return false\n\n\t\t\tconst util = editor.getShapeUtil(shape)\n\n\t\t\t// If the shape can resize, add it to the resizing shapes snapshots\n\t\t\tif (util.canResize(shape)) {\n\t\t\t\tconst pageTransform = editor.getShapePageTransform(shape)!\n\t\t\t\tshapeSnapshots.set(shape.id, {\n\t\t\t\t\tshape,\n\t\t\t\t\tbounds: editor.getShapeGeometry(shape).bounds,\n\t\t\t\t\tpageTransform,\n\t\t\t\t\tpageRotation: Mat.Decompose(pageTransform).rotation,\n\t\t\t\t\tisAspectRatioLocked: util.isAspectRatioLocked(shape),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// Special case:\n\t\t\t// For frames, we don't want to resize children but we DO want to get a snapshot of their children so that we can restore their\n\t\t\t// positions with the accel key behavior. We could break this further into APIs, for example by collecting snapshots of all\n\t\t\t// descendants (easy) but also flagging with behavior like \"resize\" or \"keep absolute position\" or \"reposition only with accel key\",\n\t\t\t// though I'm not sure where that would be defined; perhaps better handled with onResizeStart / onResize callbacks on the util, and\n\t\t\t// pass `accelKeyIsPressed` as well as `accelKeyWasPressed`?\n\t\t\tif (editor.isShapeOfType<TLFrameShape>(shape, 'frame')) {\n\t\t\t\tframes.push({\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\tchildren: compact(\n\t\t\t\t\t\teditor.getSortedChildIdsForParent(shape).map((id) => editor.getShape(id))\n\t\t\t\t\t),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// This will stop the traversal of descendants\n\t\t\tif (!util.canResizeChildren(shape)) return false\n\t\t}\n\n\t\tselectedShapeIds.forEach((shapeId) => {\n\t\t\tconst keepDescending = populateResizingShapes(shapeId)\n\t\t\tif (keepDescending === false) return\n\t\t\teditor.visitDescendants(shapeId, populateResizingShapes)\n\t\t})\n\n\t\tconst canShapesDeform = ![...shapeSnapshots.values()].some(\n\t\t\t(shape) =>\n\t\t\t\t!areAnglesCompatible(shape.pageRotation, selectionRotation) || shape.isAspectRatioLocked\n\t\t)\n\n\t\treturn {\n\t\t\tshapeSnapshots,\n\t\t\tselectionBounds,\n\t\t\tcursorHandleOffset,\n\t\t\tselectionRotation,\n\t\t\tselectedShapeIds,\n\t\t\tcanShapesDeform,\n\t\t\tinitialSelectionPageBounds: this.editor.getSelectionPageBounds()!,\n\t\t\tframes,\n\t\t}\n\t}\n}\n\ntype Snapshot = ReturnType<Resizing['_createSnapshot']>\n\nconst ORDERED_SELECTION_HANDLES: (SelectionEdge | SelectionCorner)[] = [\n\t'top',\n\t'top_right',\n\t'right',\n\t'bottom_right',\n\t'bottom',\n\t'bottom_left',\n\t'left',\n\t'top_left',\n]\n\nexport function rotateSelectionHandle(handle: SelectionEdge | SelectionCorner, rotation: number) {\n\t// first find out how many tau we need to rotate by\n\trotation = rotation % PI2\n\tconst numSteps = Math.round(rotation / (PI / 4))\n\n\tconst currentIndex = ORDERED_SELECTION_HANDLES.indexOf(handle)\n\treturn ORDERED_SELECTION_HANDLES[(currentIndex + numSteps) % ORDERED_SELECTION_HANDLES.length]\n}\n"],
|
|
5
|
-
"mappings": "AAAA;AAAA,EAEC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAGA;AAAA,EAQA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AAYA,MAAM,iBAAiB,UAAU;AAAA,EACvC,OAAgB,KAAK;AAAA,EAErB,OAAO,CAAC;AAAA,EAER,SAAS;AAAA;AAAA,EAGD,iBAAiB;AAAA;AAAA;AAAA;AAAA,EAKzB,uBAAuB,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,EAE5B,WAAW,CAAC;AAAA,EAEX,QAAQ,MAAoB;AACpC,UAAM,EAAE,aAAa,OAAO,gBAAgB,uBAAuB,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE,IAAI;AAEtF,SAAK,OAAO;AACZ,SAAK,iBAAiB;AAEtB,
|
|
4
|
+
"sourcesContent": ["import {\n\tBox,\n\tHALF_PI,\n\tMat,\n\tPI,\n\tPI2,\n\tSelectionCorner,\n\tSelectionEdge,\n\tStateNode,\n\tTLFrameShape,\n\tTLPointerEventInfo,\n\tTLShape,\n\tTLShapeId,\n\tTLShapePartial,\n\tTLTextShape,\n\tTLTickEventInfo,\n\tVec,\n\tVecLike,\n\tareAnglesCompatible,\n\tcompact,\n\tisAccelKey,\n\tkickoutOccludedShapes,\n} from '@tldraw/editor'\n\nexport type ResizingInfo = TLPointerEventInfo & {\n\ttarget: 'selection'\n\thandle: SelectionEdge | SelectionCorner\n\tisCreating?: boolean\n\tcreatingMarkId?: string\n\tonCreate?(shape: TLShape | null): void\n\tcreationCursorOffset?: VecLike\n\tonInteractionEnd?: string | (() => void)\n}\n\nexport class Resizing extends StateNode {\n\tstatic override id = 'resizing'\n\n\tinfo = {} as ResizingInfo\n\n\tmarkId = ''\n\n\t// A switch to detect when the user is holding ctrl\n\tprivate didHoldCommand = false\n\n\t// we transition into the resizing state from the geo pointing state, which starts with a shape of size w: 1, h: 1,\n\t// so if the user drags x: +50, y: +50 after mouseDown, the shape will be w: 51, h: 51, which is too many pixels, alas\n\t// so we allow passing a further offset into this state to negate such issues\n\tcreationCursorOffset = { x: 0, y: 0 } as VecLike\n\n\tprivate snapshot = {} as any as Snapshot\n\n\toverride onEnter(info: ResizingInfo) {\n\t\tconst { isCreating = false, creatingMarkId, creationCursorOffset = { x: 0, y: 0 } } = info\n\n\t\tthis.info = info\n\t\tthis.didHoldCommand = false\n\n\t\tif (typeof info.onInteractionEnd === 'string') {\n\t\t\tthis.parent.setCurrentToolIdMask(info.onInteractionEnd)\n\t\t}\n\t\tthis.creationCursorOffset = creationCursorOffset\n\n\t\ttry {\n\t\t\t// On rare and mysterious occasions, the user can enter the resizing state with no shapes selected\n\t\t\tthis.snapshot = this._createSnapshot()\n\t\t} catch (e) {\n\t\t\tconsole.error(e)\n\t\t\tthis.cancel()\n\t\t\treturn\n\t\t}\n\n\t\tthis.markId = ''\n\n\t\tif (isCreating) {\n\t\t\tif (creatingMarkId) {\n\t\t\t\tthis.markId = creatingMarkId\n\t\t\t} else {\n\t\t\t\t// handle legacy implicit `creating:{shapeId}` marks\n\t\t\t\tconst markId = this.editor.getMarkIdMatching(\n\t\t\t\t\t`creating:${this.editor.getOnlySelectedShapeId()}`\n\t\t\t\t)\n\t\t\t\tif (markId) {\n\t\t\t\t\tthis.markId = markId\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.markId = this.editor.markHistoryStoppingPoint('starting resizing')\n\t\t}\n\n\t\tif (isCreating) {\n\t\t\tthis.editor.setCursor({ type: 'cross', rotation: 0 })\n\t\t}\n\n\t\tthis.handleResizeStart()\n\t\tthis.updateShapes()\n\t}\n\n\toverride onTick({ elapsed }: TLTickEventInfo) {\n\t\tconst { editor } = this\n\t\teditor.edgeScrollManager.updateEdgeScrolling(elapsed)\n\t}\n\n\toverride onPointerMove() {\n\t\tthis.updateShapes()\n\t}\n\n\toverride onKeyDown() {\n\t\tthis.updateShapes()\n\t}\n\toverride onKeyUp() {\n\t\tthis.updateShapes()\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onComplete() {\n\t\tthis.complete()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\tprivate cancel() {\n\t\t// Call onResizeCancel callback before resetting\n\t\tconst { shapeSnapshots } = this.snapshot\n\n\t\tshapeSnapshots.forEach(({ shape }) => {\n\t\t\tconst current = this.editor.getShape(shape.id)\n\t\t\tif (current) {\n\t\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\t\tutil.onResizeCancel?.(shape, current)\n\t\t\t}\n\t\t})\n\n\t\tthis.editor.bailToMark(this.markId)\n\n\t\tconst { onInteractionEnd } = this.info\n\t\tif (onInteractionEnd) {\n\t\t\tif (typeof onInteractionEnd === 'string') {\n\t\t\t\tthis.editor.setCurrentTool(onInteractionEnd, {})\n\t\t\t} else {\n\t\t\t\tonInteractionEnd()\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tthis.parent.transition('idle')\n\t}\n\n\tprivate complete() {\n\t\tkickoutOccludedShapes(this.editor, this.snapshot.selectedShapeIds)\n\n\t\tthis.handleResizeEnd()\n\n\t\tif (this.info.isCreating && this.info.onCreate) {\n\t\t\tthis.info.onCreate?.(this.editor.getOnlySelectedShape())\n\t\t\treturn\n\t\t}\n\n\t\tconst { onInteractionEnd } = this.info\n\t\tif (onInteractionEnd) {\n\t\t\tif (typeof onInteractionEnd === 'string') {\n\t\t\t\tif (this.editor.getInstanceState().isToolLocked) {\n\t\t\t\t\tthis.editor.setCurrentTool(onInteractionEnd, {})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tonInteractionEnd()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tthis.parent.transition('idle')\n\t}\n\n\tprivate handleResizeStart() {\n\t\tconst { shapeSnapshots } = this.snapshot\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tshapeSnapshots.forEach(({ shape }) => {\n\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\tconst change = util.onResizeStart?.(shape)\n\t\t\tif (change) {\n\t\t\t\tchanges.push(change)\n\t\t\t}\n\t\t})\n\n\t\tif (changes.length > 0) {\n\t\t\tthis.editor.updateShapes(changes)\n\t\t}\n\t}\n\n\tprivate handleResizeEnd() {\n\t\tconst { shapeSnapshots } = this.snapshot\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tshapeSnapshots.forEach(({ shape }) => {\n\t\t\tconst current = this.editor.getShape(shape.id)!\n\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\tconst change = util.onResizeEnd?.(shape, current)\n\t\t\tif (change) {\n\t\t\t\tchanges.push(change)\n\t\t\t}\n\t\t})\n\n\t\tif (changes.length > 0) {\n\t\t\tthis.editor.updateShapes(changes)\n\t\t}\n\t}\n\n\tprivate updateShapes() {\n\t\tconst { altKey, shiftKey } = this.editor.inputs\n\t\tconst {\n\t\t\tframes,\n\t\t\tshapeSnapshots,\n\t\t\tselectionBounds,\n\t\t\tcursorHandleOffset,\n\t\t\tselectedShapeIds,\n\t\t\tselectionRotation,\n\t\t\tcanShapesDeform,\n\t\t} = this.snapshot\n\n\t\tlet isAspectRatioLocked = shiftKey || !canShapesDeform\n\n\t\tif (shapeSnapshots.size === 1) {\n\t\t\tconst onlySnapshot = [...shapeSnapshots.values()][0]!\n\t\t\tif (this.editor.isShapeOfType<TLTextShape>(onlySnapshot.shape, 'text')) {\n\t\t\t\tisAspectRatioLocked = !(this.info.handle === 'left' || this.info.handle === 'right')\n\t\t\t}\n\t\t}\n\n\t\t// first negate the 'cursor handle offset'\n\t\t// we need to do this because we do grid snapping based on the page point of the handle\n\t\t// rather than the page point of the cursor, so it's easier to pretend that the cursor\n\t\t// is really where the handle actually is\n\t\t//\n\t\t// *** Massively zoomed-in diagram of the initial mouseDown ***\n\t\t//\n\t\t//\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502corner handle\n\t\t// \u250C\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2510\n\t\t// selection \u2502 \u2502\n\t\t// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 x\u25C4\u2500\u2500\u253C\u2500\u2500\u2500\u2500 drag handle point \u25B2\n\t\t// \u2502 \u2502 \u2502\n\t\t// \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u251C\u2500 cursorHandleOffset.y\n\t\t// \u2502\n\t\t// originPagePoint\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25BAx\u2500\u2510 \u25BC\n\t\t// \u2502 \u2514\u2500\u2510\n\t\t// \u2502 \u2514\u2500\u2510\n\t\t// \u2502 \u2502 mouse (sorry)\n\t\t// \u2514\u2500\u2500\u2510 \u250C\u2518\n\t\t// \u2502 \u2502\n\t\t// \u2514\u2500\u2518\n\t\t// \u25C4\u2500\u2500\u252C\u2500\u2500\u25BA\n\t\t// \u2502\n\t\t// cursorHandleOffset.x\n\n\t\tconst isHoldingAccel = isAccelKey(this.editor.inputs)\n\n\t\tconst currentPagePoint = this.editor.inputs.currentPagePoint\n\t\t\t.clone()\n\t\t\t.sub(cursorHandleOffset)\n\t\t\t.sub(this.creationCursorOffset)\n\n\t\tconst originPagePoint = this.editor.inputs.originPagePoint.clone().sub(cursorHandleOffset)\n\n\t\tif (this.editor.getInstanceState().isGridMode && !isHoldingAccel) {\n\t\t\tconst { gridSize } = this.editor.getDocumentSettings()\n\t\t\tcurrentPagePoint.snapToGrid(gridSize)\n\t\t}\n\n\t\tconst dragHandle = this.info.handle as SelectionCorner | SelectionEdge\n\t\tconst scaleOriginHandle = rotateSelectionHandle(dragHandle, Math.PI)\n\n\t\tthis.editor.snaps.clearIndicators()\n\n\t\tconst shouldSnap = this.editor.user.getIsSnapMode() ? !isHoldingAccel : isHoldingAccel\n\n\t\tif (shouldSnap && selectionRotation % HALF_PI === 0) {\n\t\t\tconst { nudge } = this.editor.snaps.shapeBounds.snapResizeShapes({\n\t\t\t\tdragDelta: Vec.Sub(currentPagePoint, originPagePoint),\n\t\t\t\tinitialSelectionPageBounds: this.snapshot.initialSelectionPageBounds,\n\t\t\t\thandle: rotateSelectionHandle(dragHandle, selectionRotation),\n\t\t\t\tisAspectRatioLocked,\n\t\t\t\tisResizingFromCenter: altKey,\n\t\t\t})\n\n\t\t\tcurrentPagePoint.add(nudge)\n\t\t}\n\n\t\t// get the page point of the selection handle opposite to the drag handle\n\t\t// or the center of the selection box if altKey is pressed\n\t\tconst scaleOriginPage = Vec.RotWith(\n\t\t\taltKey ? selectionBounds.center : selectionBounds.getHandlePoint(scaleOriginHandle),\n\t\t\tselectionBounds.point,\n\t\t\tselectionRotation\n\t\t)\n\n\t\t// calculate the scale by measuring the current distance between the drag handle and the scale origin\n\t\t// and dividing by the original distance between the drag handle and the scale origin\n\n\t\t// bug: for edges, the page point doesn't matter, the\n\n\t\tconst distanceFromScaleOriginNow = Vec.Sub(currentPagePoint, scaleOriginPage).rot(\n\t\t\t-selectionRotation\n\t\t)\n\n\t\tconst distanceFromScaleOriginAtStart = Vec.Sub(originPagePoint, scaleOriginPage).rot(\n\t\t\t-selectionRotation\n\t\t)\n\n\t\tconst scale = Vec.DivV(distanceFromScaleOriginNow, distanceFromScaleOriginAtStart)\n\n\t\tif (!Number.isFinite(scale.x)) scale.x = 1\n\t\tif (!Number.isFinite(scale.y)) scale.y = 1\n\n\t\tconst isXLocked = dragHandle === 'top' || dragHandle === 'bottom'\n\t\tconst isYLocked = dragHandle === 'left' || dragHandle === 'right'\n\n\t\t// lock an axis if required\n\t\tif (isAspectRatioLocked) {\n\t\t\tif (isYLocked) {\n\t\t\t\t// holding shift and dragging either the left or the right edge\n\t\t\t\tscale.y = Math.abs(scale.x)\n\t\t\t} else if (isXLocked) {\n\t\t\t\t// holding shift and dragging either the top or the bottom edge\n\t\t\t\tscale.x = Math.abs(scale.y)\n\t\t\t} else if (Math.abs(scale.x) > Math.abs(scale.y)) {\n\t\t\t\t// holding shift and the drag has moved further in the x dimension\n\t\t\t\tscale.y = Math.abs(scale.x) * (scale.y < 0 ? -1 : 1)\n\t\t\t} else {\n\t\t\t\t// holding shift and the drag has moved further in the y dimension\n\t\t\t\tscale.x = Math.abs(scale.y) * (scale.x < 0 ? -1 : 1)\n\t\t\t}\n\t\t} else {\n\t\t\t// not holding shift, but still need to lock axes if dragging an edge\n\t\t\tif (isXLocked) {\n\t\t\t\tscale.x = 1\n\t\t\t}\n\t\t\tif (isYLocked) {\n\t\t\t\tscale.y = 1\n\t\t\t}\n\t\t}\n\n\t\tif (!this.info.isCreating) {\n\t\t\tthis.updateCursor({\n\t\t\t\tdragHandle,\n\t\t\t\tisFlippedX: scale.x < 0,\n\t\t\t\tisFlippedY: scale.y < 0,\n\t\t\t\trotation: selectionRotation,\n\t\t\t})\n\t\t}\n\n\t\tfor (const id of shapeSnapshots.keys()) {\n\t\t\tconst snapshot = shapeSnapshots.get(id)!\n\n\t\t\tthis.editor.resizeShape(id, scale, {\n\t\t\t\tinitialShape: snapshot.shape,\n\t\t\t\tinitialBounds: snapshot.bounds,\n\t\t\t\tinitialPageTransform: snapshot.pageTransform,\n\t\t\t\tdragHandle,\n\t\t\t\tmode:\n\t\t\t\t\tselectedShapeIds.length === 1 && id === selectedShapeIds[0]\n\t\t\t\t\t\t? 'resize_bounds'\n\t\t\t\t\t\t: 'scale_shape',\n\t\t\t\tscaleOrigin: scaleOriginPage,\n\t\t\t\tisAspectRatioLocked,\n\t\t\t\tscaleAxisRotation: selectionRotation,\n\t\t\t\tskipStartAndEndCallbacks: true,\n\t\t\t})\n\t\t}\n\n\t\t// If there's only one shape snapshot and it's a frame and the user is holding ctrl,\n\t\t// then we preserve the position of the frame's children, almost like the user is cropping\n\t\t// the frame rather than resizing it.\n\t\tif (isHoldingAccel) {\n\t\t\tthis.didHoldCommand = true\n\n\t\t\tfor (const { id, children } of frames) {\n\t\t\t\tif (!children.length) continue\n\t\t\t\tconst initial = shapeSnapshots.get(id)!.shape\n\t\t\t\tconst current = this.editor.getShape(id)!\n\t\t\t\tif (!(initial && current)) continue\n\n\t\t\t\tconst dx = current.x - initial.x\n\t\t\t\tconst dy = current.y - initial.y\n\n\t\t\t\tconst delta = new Vec(dx, dy).rot(-initial.rotation)\n\n\t\t\t\tif (delta.x !== 0 || delta.y !== 0) {\n\t\t\t\t\tfor (const child of children) {\n\t\t\t\t\t\tthis.editor.updateShape({\n\t\t\t\t\t\t\tid: child.id,\n\t\t\t\t\t\t\ttype: child.type,\n\t\t\t\t\t\t\tx: child.x - delta.x,\n\t\t\t\t\t\t\ty: child.y - delta.y,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (this.didHoldCommand) {\n\t\t\t// If we're no longer holding the command key...\n\t\t\tthis.didHoldCommand = false\n\n\t\t\tfor (const { children } of frames) {\n\t\t\t\tif (!children.length) continue\n\t\t\t\tfor (const child of children) {\n\t\t\t\t\tthis.editor.updateShape({\n\t\t\t\t\t\tid: child.id,\n\t\t\t\t\t\ttype: child.type,\n\t\t\t\t\t\tx: child.x,\n\t\t\t\t\t\ty: child.y,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// ---\n\n\tprivate updateCursor({\n\t\tdragHandle,\n\t\tisFlippedX,\n\t\tisFlippedY,\n\t\trotation,\n\t}: {\n\t\tdragHandle: SelectionCorner | SelectionEdge\n\t\tisFlippedX: boolean\n\t\tisFlippedY: boolean\n\t\trotation: number\n\t}) {\n\t\tconst nextCursor = { ...this.editor.getInstanceState().cursor }\n\n\t\tswitch (dragHandle) {\n\t\t\tcase 'top_left':\n\t\t\tcase 'bottom_right': {\n\t\t\t\tnextCursor.type = 'nwse-resize'\n\t\t\t\tif (isFlippedX !== isFlippedY) {\n\t\t\t\t\tnextCursor.type = 'nesw-resize'\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'top_right':\n\t\t\tcase 'bottom_left': {\n\t\t\t\tnextCursor.type = 'nesw-resize'\n\t\t\t\tif (isFlippedX !== isFlippedY) {\n\t\t\t\t\tnextCursor.type = 'nwse-resize'\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tnextCursor.rotation = rotation\n\n\t\tthis.editor.setCursor(nextCursor)\n\t}\n\n\toverride onExit() {\n\t\tthis.parent.setCurrentToolIdMask(undefined)\n\t\tthis.editor.setCursor({ type: 'default', rotation: 0 })\n\t\tthis.editor.snaps.clearIndicators()\n\t}\n\n\tprivate _createSnapshot() {\n\t\tconst { editor } = this\n\t\tconst selectedShapeIds = editor.getSelectedShapeIds()\n\t\tconst selectionRotation = editor.getSelectionRotation()\n\t\tconst {\n\t\t\tinputs: { originPagePoint },\n\t\t} = editor\n\n\t\tconst selectionBounds = editor.getSelectionRotatedPageBounds()\n\t\tif (!selectionBounds) throw Error('Resizing but nothing is selected')\n\n\t\tconst dragHandlePoint = Vec.RotWith(\n\t\t\tselectionBounds.getHandlePoint(this.info.handle!),\n\t\t\tselectionBounds.point,\n\t\t\tselectionRotation\n\t\t)\n\n\t\tconst cursorHandleOffset = Vec.Sub(originPagePoint, dragHandlePoint)\n\n\t\tconst shapeSnapshots = new Map<\n\t\t\tTLShapeId,\n\t\t\t{\n\t\t\t\tshape: TLShape\n\t\t\t\tbounds: Box\n\t\t\t\tpageTransform: Mat\n\t\t\t\tpageRotation: number\n\t\t\t\tisAspectRatioLocked: boolean\n\t\t\t}\n\t\t>()\n\n\t\tconst frames: { id: TLShapeId; children: TLShape[] }[] = []\n\n\t\tconst populateResizingShapes = (shapeId: TLShapeId): false | undefined => {\n\t\t\tconst shape = editor.getShape(shapeId)\n\t\t\tif (!shape) return false\n\n\t\t\tconst util = editor.getShapeUtil(shape)\n\n\t\t\t// If the shape can resize, add it to the resizing shapes snapshots\n\t\t\tif (util.canResize(shape)) {\n\t\t\t\tconst pageTransform = editor.getShapePageTransform(shape)!\n\t\t\t\tshapeSnapshots.set(shape.id, {\n\t\t\t\t\tshape,\n\t\t\t\t\tbounds: editor.getShapeGeometry(shape).bounds,\n\t\t\t\t\tpageTransform,\n\t\t\t\t\tpageRotation: Mat.Decompose(pageTransform).rotation,\n\t\t\t\t\tisAspectRatioLocked: util.isAspectRatioLocked(shape),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// Special case:\n\t\t\t// For frames, we don't want to resize children but we DO want to get a snapshot of their children so that we can restore their\n\t\t\t// positions with the accel key behavior. We could break this further into APIs, for example by collecting snapshots of all\n\t\t\t// descendants (easy) but also flagging with behavior like \"resize\" or \"keep absolute position\" or \"reposition only with accel key\",\n\t\t\t// though I'm not sure where that would be defined; perhaps better handled with onResizeStart / onResize callbacks on the util, and\n\t\t\t// pass `accelKeyIsPressed` as well as `accelKeyWasPressed`?\n\t\t\tif (editor.isShapeOfType<TLFrameShape>(shape, 'frame')) {\n\t\t\t\tframes.push({\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\tchildren: compact(\n\t\t\t\t\t\teditor.getSortedChildIdsForParent(shape).map((id) => editor.getShape(id))\n\t\t\t\t\t),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// This will stop the traversal of descendants\n\t\t\tif (!util.canResizeChildren(shape)) return false\n\t\t}\n\n\t\tselectedShapeIds.forEach((shapeId) => {\n\t\t\tconst keepDescending = populateResizingShapes(shapeId)\n\t\t\tif (keepDescending === false) return\n\t\t\teditor.visitDescendants(shapeId, populateResizingShapes)\n\t\t})\n\n\t\tconst canShapesDeform = ![...shapeSnapshots.values()].some(\n\t\t\t(shape) =>\n\t\t\t\t!areAnglesCompatible(shape.pageRotation, selectionRotation) || shape.isAspectRatioLocked\n\t\t)\n\n\t\treturn {\n\t\t\tshapeSnapshots,\n\t\t\tselectionBounds,\n\t\t\tcursorHandleOffset,\n\t\t\tselectionRotation,\n\t\t\tselectedShapeIds,\n\t\t\tcanShapesDeform,\n\t\t\tinitialSelectionPageBounds: this.editor.getSelectionPageBounds()!,\n\t\t\tframes,\n\t\t}\n\t}\n}\n\ntype Snapshot = ReturnType<Resizing['_createSnapshot']>\n\nconst ORDERED_SELECTION_HANDLES: (SelectionEdge | SelectionCorner)[] = [\n\t'top',\n\t'top_right',\n\t'right',\n\t'bottom_right',\n\t'bottom',\n\t'bottom_left',\n\t'left',\n\t'top_left',\n]\n\nexport function rotateSelectionHandle(handle: SelectionEdge | SelectionCorner, rotation: number) {\n\t// first find out how many tau we need to rotate by\n\trotation = rotation % PI2\n\tconst numSteps = Math.round(rotation / (PI / 4))\n\n\tconst currentIndex = ORDERED_SELECTION_HANDLES.indexOf(handle)\n\treturn ORDERED_SELECTION_HANDLES[(currentIndex + numSteps) % ORDERED_SELECTION_HANDLES.length]\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -16,7 +16,9 @@ class Rotating extends StateNode {
|
|
|
16
16
|
markId = "";
|
|
17
17
|
onEnter(info) {
|
|
18
18
|
this.info = info;
|
|
19
|
-
|
|
19
|
+
if (typeof info.onInteractionEnd === "string") {
|
|
20
|
+
this.parent.setCurrentToolIdMask(info.onInteractionEnd);
|
|
21
|
+
}
|
|
20
22
|
this.markId = this.editor.markHistoryStoppingPoint("rotate start");
|
|
21
23
|
const snapshot = getRotationSnapshot({
|
|
22
24
|
editor: this.editor,
|
|
@@ -87,11 +89,16 @@ class Rotating extends StateNode {
|
|
|
87
89
|
}
|
|
88
90
|
});
|
|
89
91
|
this.editor.bailToMark(this.markId);
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
const { onInteractionEnd } = this.info;
|
|
93
|
+
if (onInteractionEnd) {
|
|
94
|
+
if (typeof onInteractionEnd === "string") {
|
|
95
|
+
this.editor.setCurrentTool(onInteractionEnd, this.info);
|
|
96
|
+
} else {
|
|
97
|
+
onInteractionEnd();
|
|
98
|
+
}
|
|
99
|
+
return;
|
|
94
100
|
}
|
|
101
|
+
this.parent.transition("idle", this.info);
|
|
95
102
|
}
|
|
96
103
|
complete() {
|
|
97
104
|
applyRotationToSnapshotShapes({
|
|
@@ -104,11 +111,16 @@ class Rotating extends StateNode {
|
|
|
104
111
|
this.editor,
|
|
105
112
|
this.snapshot.shapeSnapshots.map((s) => s.shape.id)
|
|
106
113
|
);
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
114
|
+
const { onInteractionEnd } = this.info;
|
|
115
|
+
if (onInteractionEnd) {
|
|
116
|
+
if (typeof onInteractionEnd === "string") {
|
|
117
|
+
this.editor.setCurrentTool(onInteractionEnd, this.info);
|
|
118
|
+
} else {
|
|
119
|
+
onInteractionEnd();
|
|
120
|
+
}
|
|
121
|
+
return;
|
|
111
122
|
}
|
|
123
|
+
this.parent.transition("idle", this.info);
|
|
112
124
|
}
|
|
113
125
|
_getRotationFromPointerPosition({ snapToNearestDegree }) {
|
|
114
126
|
const {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/tools/SelectTool/childStates/Rotating.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\tRotateCorner,\n\tStateNode,\n\tTLPointerEventInfo,\n\tTLRotationSnapshot,\n\tapplyRotationToSnapshotShapes,\n\tdegreesToRadians,\n\tgetRotationSnapshot,\n\tkickoutOccludedShapes,\n\tshortAngleDist,\n\tsnapAngle,\n} from '@tldraw/editor'\nimport { CursorTypeMap } from './PointingResizeHandle'\n\nconst ONE_DEGREE = Math.PI / 180\n\nexport class Rotating extends StateNode {\n\tstatic override id = 'rotating'\n\n\tsnapshot = {} as TLRotationSnapshot\n\n\tinfo = {} as Extract<TLPointerEventInfo, { target: 'selection' }> & {
|
|
5
|
-
"mappings": "AAAA;AAAA,EAEC;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,qBAAqB;AAE9B,MAAM,aAAa,KAAK,KAAK;AAEtB,MAAM,iBAAiB,UAAU;AAAA,EACvC,OAAgB,KAAK;AAAA,EAErB,WAAW,CAAC;AAAA,EAEZ,OAAO,CAAC;AAAA,
|
|
4
|
+
"sourcesContent": ["import {\n\tRotateCorner,\n\tStateNode,\n\tTLPointerEventInfo,\n\tTLRotationSnapshot,\n\tapplyRotationToSnapshotShapes,\n\tdegreesToRadians,\n\tgetRotationSnapshot,\n\tkickoutOccludedShapes,\n\tshortAngleDist,\n\tsnapAngle,\n} from '@tldraw/editor'\nimport { CursorTypeMap } from './PointingResizeHandle'\n\nconst ONE_DEGREE = Math.PI / 180\n\nexport class Rotating extends StateNode {\n\tstatic override id = 'rotating'\n\n\tsnapshot = {} as TLRotationSnapshot\n\n\tinfo = {} as Extract<TLPointerEventInfo, { target: 'selection' }> & {\n\t\tonInteractionEnd?: string | (() => void)\n\t}\n\n\tmarkId = ''\n\n\toverride onEnter(\n\t\tinfo: TLPointerEventInfo & { target: 'selection'; onInteractionEnd?: string | (() => void) }\n\t) {\n\t\t// Store the event information\n\t\tthis.info = info\n\t\tif (typeof info.onInteractionEnd === 'string') {\n\t\t\tthis.parent.setCurrentToolIdMask(info.onInteractionEnd)\n\t\t}\n\n\t\tthis.markId = this.editor.markHistoryStoppingPoint('rotate start')\n\n\t\tconst snapshot = getRotationSnapshot({\n\t\t\teditor: this.editor,\n\t\t\tids: this.editor.getSelectedShapeIds(),\n\t\t})\n\t\tif (!snapshot) return this.parent.transition('idle', this.info)\n\t\tthis.snapshot = snapshot\n\n\t\t// Trigger a pointer move\n\t\tconst newSelectionRotation = this._getRotationFromPointerPosition({\n\t\t\tsnapToNearestDegree: false,\n\t\t})\n\n\t\tapplyRotationToSnapshotShapes({\n\t\t\teditor: this.editor,\n\t\t\tdelta: this._getRotationFromPointerPosition({ snapToNearestDegree: false }),\n\t\t\tsnapshot: this.snapshot,\n\t\t\tstage: 'start',\n\t\t})\n\n\t\t// Update cursor\n\t\tthis.editor.setCursor({\n\t\t\ttype: CursorTypeMap[this.info.handle as RotateCorner],\n\t\t\trotation: newSelectionRotation + this.snapshot.initialShapesRotation,\n\t\t})\n\t}\n\n\toverride onExit() {\n\t\tthis.editor.setCursor({ type: 'default', rotation: 0 })\n\t\tthis.parent.setCurrentToolIdMask(undefined)\n\n\t\tthis.snapshot = {} as TLRotationSnapshot\n\t}\n\n\toverride onPointerMove() {\n\t\tthis.update()\n\t}\n\n\toverride onKeyDown() {\n\t\tthis.update()\n\t}\n\n\toverride onKeyUp() {\n\t\tthis.update()\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onComplete() {\n\t\tthis.complete()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\t// ---\n\n\tprivate update() {\n\t\tconst newSelectionRotation = this._getRotationFromPointerPosition({\n\t\t\tsnapToNearestDegree: false,\n\t\t})\n\n\t\tapplyRotationToSnapshotShapes({\n\t\t\teditor: this.editor,\n\t\t\tdelta: newSelectionRotation,\n\t\t\tsnapshot: this.snapshot,\n\t\t\tstage: 'update',\n\t\t})\n\n\t\t// Update cursor\n\t\tthis.editor.setCursor({\n\t\t\ttype: CursorTypeMap[this.info.handle as RotateCorner],\n\t\t\trotation: newSelectionRotation + this.snapshot.initialShapesRotation,\n\t\t})\n\t}\n\n\tprivate cancel() {\n\t\t// Call onRotateCancel callback before bailing to mark\n\t\tconst { shapeSnapshots } = this.snapshot\n\n\t\tshapeSnapshots.forEach(({ shape }) => {\n\t\t\tconst current = this.editor.getShape(shape.id)\n\t\t\tif (current) {\n\t\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\t\tutil.onRotateCancel?.(shape, current)\n\t\t\t}\n\t\t})\n\n\t\tthis.editor.bailToMark(this.markId)\n\t\tconst { onInteractionEnd } = this.info\n\t\tif (onInteractionEnd) {\n\t\t\tif (typeof onInteractionEnd === 'string') {\n\t\t\t\tthis.editor.setCurrentTool(onInteractionEnd, this.info)\n\t\t\t} else {\n\t\t\t\tonInteractionEnd()\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tthis.parent.transition('idle', this.info)\n\t}\n\n\tprivate complete() {\n\t\tapplyRotationToSnapshotShapes({\n\t\t\teditor: this.editor,\n\t\t\tdelta: this._getRotationFromPointerPosition({ snapToNearestDegree: true }),\n\t\t\tsnapshot: this.snapshot,\n\t\t\tstage: 'end',\n\t\t})\n\t\tkickoutOccludedShapes(\n\t\t\tthis.editor,\n\t\t\tthis.snapshot.shapeSnapshots.map((s) => s.shape.id)\n\t\t)\n\t\tconst { onInteractionEnd } = this.info\n\t\tif (onInteractionEnd) {\n\t\t\tif (typeof onInteractionEnd === 'string') {\n\t\t\t\tthis.editor.setCurrentTool(onInteractionEnd, this.info)\n\t\t\t} else {\n\t\t\t\tonInteractionEnd()\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tthis.parent.transition('idle', this.info)\n\t}\n\n\t_getRotationFromPointerPosition({ snapToNearestDegree }: { snapToNearestDegree: boolean }) {\n\t\tconst {\n\t\t\tinputs: { shiftKey, currentPagePoint },\n\t\t} = this.editor\n\t\tconst { initialCursorAngle, initialShapesRotation, initialPageCenter } = this.snapshot\n\n\t\t// The delta is the difference between the current angle and the initial angle\n\t\tconst preSnapRotationDelta = initialPageCenter.angle(currentPagePoint) - initialCursorAngle\n\t\tlet newSelectionRotation = initialShapesRotation + preSnapRotationDelta\n\n\t\tif (shiftKey) {\n\t\t\tnewSelectionRotation = snapAngle(newSelectionRotation, 24)\n\t\t} else if (snapToNearestDegree) {\n\t\t\tnewSelectionRotation = Math.round(newSelectionRotation / ONE_DEGREE) * ONE_DEGREE\n\n\t\t\tif (this.editor.getInstanceState().isCoarsePointer) {\n\t\t\t\tconst snappedToRightAngle = snapAngle(newSelectionRotation, 4)\n\t\t\t\tconst angleToRightAngle = shortAngleDist(newSelectionRotation, snappedToRightAngle)\n\t\t\t\tif (Math.abs(angleToRightAngle) < degreesToRadians(5)) {\n\t\t\t\t\tnewSelectionRotation = snappedToRightAngle\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn newSelectionRotation - initialShapesRotation\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -85,7 +85,9 @@ class Translating extends (_a = StateNode, _updateParentTransforms_dec = [bind],
|
|
|
85
85
|
return;
|
|
86
86
|
}
|
|
87
87
|
this.info = info;
|
|
88
|
-
|
|
88
|
+
if (typeof info.onInteractionEnd === "string") {
|
|
89
|
+
this.parent.setCurrentToolIdMask(info.onInteractionEnd);
|
|
90
|
+
}
|
|
89
91
|
this.isCreating = isCreating;
|
|
90
92
|
this.markId = "";
|
|
91
93
|
if (isCreating) {
|
|
@@ -185,15 +187,23 @@ class Translating extends (_a = StateNode, _updateParentTransforms_dec = [bind],
|
|
|
185
187
|
this.editor,
|
|
186
188
|
this.snapshot.movingShapes.map((s) => s.id)
|
|
187
189
|
);
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
190
|
+
const { onInteractionEnd } = this.info;
|
|
191
|
+
if (onInteractionEnd) {
|
|
192
|
+
if (typeof onInteractionEnd === "string") {
|
|
193
|
+
if (this.editor.getInstanceState().isToolLocked) {
|
|
194
|
+
this.editor.setCurrentTool(onInteractionEnd);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
193
197
|
} else {
|
|
194
|
-
|
|
198
|
+
onInteractionEnd();
|
|
199
|
+
return;
|
|
195
200
|
}
|
|
196
201
|
}
|
|
202
|
+
if (this.isCreating) {
|
|
203
|
+
this.onCreate?.(this.editor.getOnlySelectedShape());
|
|
204
|
+
} else {
|
|
205
|
+
this.parent.transition("idle");
|
|
206
|
+
}
|
|
197
207
|
}
|
|
198
208
|
cancel() {
|
|
199
209
|
const { movingShapes } = this.snapshot;
|
|
@@ -205,11 +215,16 @@ class Translating extends (_a = StateNode, _updateParentTransforms_dec = [bind],
|
|
|
205
215
|
}
|
|
206
216
|
});
|
|
207
217
|
this.reset();
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
218
|
+
const { onInteractionEnd } = this.info;
|
|
219
|
+
if (onInteractionEnd) {
|
|
220
|
+
if (typeof onInteractionEnd === "string") {
|
|
221
|
+
this.editor.setCurrentTool(onInteractionEnd);
|
|
222
|
+
} else {
|
|
223
|
+
onInteractionEnd();
|
|
224
|
+
}
|
|
225
|
+
return;
|
|
212
226
|
}
|
|
227
|
+
this.parent.transition("idle", this.info);
|
|
213
228
|
}
|
|
214
229
|
handleStart() {
|
|
215
230
|
const { movingShapes } = this.snapshot;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/tools/SelectTool/childStates/Translating.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\tBoundsSnapPoint,\n\tEditor,\n\tMat,\n\tMatModel,\n\tPageRecordType,\n\tStateNode,\n\tTLNoteShape,\n\tTLPointerEventInfo,\n\tTLShape,\n\tTLShapePartial,\n\tTLTickEventInfo,\n\tVec,\n\tbind,\n\tcompact,\n\tisPageId,\n\tkickoutOccludedShapes,\n} from '@tldraw/editor'\nimport {\n\tNOTE_ADJACENT_POSITION_SNAP_RADIUS,\n\tNOTE_CENTER_OFFSET,\n\tgetAvailableNoteAdjacentPositions,\n} from '../../../shapes/note/noteHelpers'\nimport { DragAndDropManager } from '../DragAndDropManager'\n\nexport type TranslatingInfo = TLPointerEventInfo & {\n\ttarget: 'shape'\n\tisCreating?: boolean\n\tcreatingMarkId?: string\n\tonCreate?(): void\n\tonInteractionEnd?: string\n}\n\nexport class Translating extends StateNode {\n\tstatic override id = 'translating'\n\n\tinfo = {} as TranslatingInfo\n\n\tselectionSnapshot: TranslatingSnapshot = {} as any\n\n\tsnapshot: TranslatingSnapshot = {} as any\n\n\tmarkId = ''\n\n\tisCloning = false\n\tisCreating = false\n\tonCreate(_shape: TLShape | null): void {\n\t\treturn\n\t}\n\n\tdragAndDropManager = new DragAndDropManager(this.editor)\n\n\toverride onEnter(info: TranslatingInfo) {\n\t\tconst { isCreating = false, creatingMarkId, onCreate = () => void null } = info\n\n\t\tif (!this.editor.getSelectedShapeIds()?.length) {\n\t\t\tthis.parent.transition('idle')\n\t\t\treturn\n\t\t}\n\n\t\tthis.info = info\n\t\tthis.parent.setCurrentToolIdMask(info.onInteractionEnd)\n\t\tthis.isCreating = isCreating\n\n\t\tthis.markId = ''\n\n\t\tif (isCreating) {\n\t\t\tif (creatingMarkId) {\n\t\t\t\tthis.markId = creatingMarkId\n\t\t\t} else {\n\t\t\t\t// handle legacy implicit `creating:{shapeId}` marks\n\t\t\t\tconst markId = this.editor.getMarkIdMatching(\n\t\t\t\t\t`creating:${this.editor.getOnlySelectedShapeId()}`\n\t\t\t\t)\n\t\t\t\tif (markId) {\n\t\t\t\t\tthis.markId = markId\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.markId = this.editor.markHistoryStoppingPoint('translating')\n\t\t}\n\n\t\tthis.onCreate = onCreate\n\n\t\tthis.isCloning = false\n\t\tthis.info = info\n\n\t\tthis.editor.setCursor({ type: 'move', rotation: 0 })\n\t\tthis.selectionSnapshot = getTranslatingSnapshot(this.editor)\n\n\t\t// Don't clone on create; otherwise clone on altKey\n\t\tif (!this.isCreating) {\n\t\t\tif (this.editor.inputs.altKey) {\n\t\t\t\tthis.startCloning()\n\t\t\t\tif (this.isCloning) return\n\t\t\t}\n\t\t}\n\n\t\tthis.snapshot = this.selectionSnapshot\n\t\tthis.handleStart()\n\t\tthis.updateShapes()\n\t}\n\n\toverride onExit() {\n\t\tthis.parent.setCurrentToolIdMask(undefined)\n\t\tthis.selectionSnapshot = {} as any\n\t\tthis.snapshot = {} as any\n\t\tthis.editor.snaps.clearIndicators()\n\t\tthis.editor.setCursor({ type: 'default', rotation: 0 })\n\t\tthis.dragAndDropManager.clear()\n\t}\n\n\toverride onTick({ elapsed }: TLTickEventInfo) {\n\t\tconst { editor } = this\n\t\teditor.edgeScrollManager.updateEdgeScrolling(elapsed)\n\t}\n\n\toverride onPointerMove() {\n\t\tthis.updateShapes()\n\t}\n\n\toverride onKeyDown() {\n\t\tif (this.editor.inputs.altKey && !this.isCloning) {\n\t\t\tthis.startCloning()\n\t\t\tif (this.isCloning) return\n\t\t}\n\n\t\t// need to update in case user pressed a different modifier key\n\t\tthis.updateShapes()\n\t}\n\n\toverride onKeyUp() {\n\t\tif (!this.editor.inputs.altKey && this.isCloning) {\n\t\t\tthis.stopCloning()\n\t\t\treturn\n\t\t}\n\n\t\t// need to update in case user pressed a different modifier key\n\t\tthis.updateShapes()\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onComplete() {\n\t\tthis.complete()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\tprotected startCloning() {\n\t\tif (this.isCreating) return\n\t\tconst shapeIds = Array.from(this.editor.getSelectedShapeIds())\n\n\t\t// If we can't create the shapes, don't even start cloning\n\t\tif (!this.editor.canCreateShapes(shapeIds)) return\n\n\t\tthis.isCloning = true\n\t\tthis.reset()\n\t\tthis.markId = this.editor.markHistoryStoppingPoint('translate cloning')\n\n\t\tthis.editor.duplicateShapes(Array.from(this.editor.getSelectedShapeIds()))\n\n\t\tthis.snapshot = getTranslatingSnapshot(this.editor)\n\t\tthis.handleStart()\n\t\tthis.updateShapes()\n\t}\n\n\tprotected stopCloning() {\n\t\tthis.isCloning = false\n\t\tthis.snapshot = this.selectionSnapshot\n\t\tthis.reset()\n\t\tthis.markId = this.editor.markHistoryStoppingPoint('translate')\n\t\tthis.updateShapes()\n\t}\n\n\treset() {\n\t\tthis.editor.bailToMark(this.markId)\n\t}\n\n\tprotected complete() {\n\t\tthis.updateShapes()\n\t\tthis.dragAndDropManager.dropShapes(this.snapshot.movingShapes)\n\t\tthis.handleEnd()\n\t\tkickoutOccludedShapes(\n\t\t\tthis.editor,\n\t\t\tthis.snapshot.movingShapes.map((s) => s.id)\n\t\t)\n\n\t\tif (this.editor.getInstanceState().isToolLocked && this.info.onInteractionEnd) {\n\t\t\tthis.editor.setCurrentTool(this.info.onInteractionEnd)\n\t\t} else {\n\t\t\tif (this.isCreating) {\n\t\t\t\tthis.onCreate?.(this.editor.getOnlySelectedShape())\n\t\t\t} else {\n\t\t\t\tthis.parent.transition('idle')\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate cancel() {\n\t\t// Call onTranslateCancel callback before resetting\n\t\tconst { movingShapes } = this.snapshot\n\n\t\tmovingShapes.forEach((shape) => {\n\t\t\tconst current = this.editor.getShape(shape.id)\n\t\t\tif (current) {\n\t\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\t\tutil.onTranslateCancel?.(shape, current)\n\t\t\t}\n\t\t})\n\n\t\tthis.reset()\n\t\tif (this.info.onInteractionEnd) {\n\t\t\tthis.editor.setCurrentTool(this.info.onInteractionEnd)\n\t\t} else {\n\t\t\tthis.parent.transition('idle', this.info)\n\t\t}\n\t}\n\n\tprotected handleStart() {\n\t\tconst { movingShapes } = this.snapshot\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tmovingShapes.forEach((shape) => {\n\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\tconst change = util.onTranslateStart?.(shape)\n\t\t\tif (change) {\n\t\t\t\tchanges.push(change)\n\t\t\t}\n\t\t})\n\n\t\tif (changes.length > 0) {\n\t\t\tthis.editor.updateShapes(changes)\n\t\t}\n\n\t\tthis.dragAndDropManager.startDraggingShapes(\n\t\t\t// Get fresh shapes from the snapshot, in case onTranslateStart mutates the shape\n\t\t\tcompact(this.snapshot.movingShapes.map((s) => this.editor.getShape(s.id))),\n\t\t\t// Start from the place where the user started dragging\n\t\t\tthis.editor.inputs.originPagePoint,\n\t\t\tthis.updateParentTransforms\n\t\t)\n\n\t\tthis.editor.setHoveredShape(null)\n\t}\n\n\tprotected handleEnd() {\n\t\tconst { movingShapes } = this.snapshot\n\n\t\tif (this.isCloning && movingShapes.length > 0) {\n\t\t\tconst currentAveragePagePoint = Vec.Average(\n\t\t\t\tmovingShapes.map((s) => this.editor.getShapePageTransform(s.id)!.point())\n\t\t\t)\n\t\t\tconst offset = Vec.Sub(currentAveragePagePoint, this.selectionSnapshot.averagePagePoint)\n\t\t\tif (!Vec.IsNaN(offset)) {\n\t\t\t\tthis.editor.updateInstanceState({\n\t\t\t\t\tduplicateProps: {\n\t\t\t\t\t\tshapeIds: movingShapes.map((s) => s.id),\n\t\t\t\t\t\toffset: { x: offset.x, y: offset.y },\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tmovingShapes.forEach((shape) => {\n\t\t\tconst current = this.editor.getShape(shape.id)!\n\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\tconst change = util.onTranslateEnd?.(shape, current)\n\t\t\tif (change) {\n\t\t\t\tchanges.push(change)\n\t\t\t}\n\t\t})\n\n\t\tif (changes.length > 0) {\n\t\t\tthis.editor.updateShapes(changes)\n\t\t}\n\t}\n\n\tprotected updateShapes() {\n\t\tconst { snapshot } = this\n\n\t\t// We should have started already, but hey\n\t\tthis.dragAndDropManager.startDraggingShapes(\n\t\t\tsnapshot.movingShapes,\n\t\t\tthis.editor.inputs.originPagePoint,\n\t\t\tthis.updateParentTransforms\n\t\t)\n\n\t\tmoveShapesToPoint({\n\t\t\teditor: this.editor,\n\t\t\tsnapshot,\n\t\t})\n\n\t\tconst { movingShapes } = snapshot\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tmovingShapes.forEach((shape) => {\n\t\t\tconst current = this.editor.getShape(shape.id)!\n\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\tconst change = util.onTranslate?.(shape, current)\n\t\t\tif (change) {\n\t\t\t\tchanges.push(change)\n\t\t\t}\n\t\t})\n\n\t\tif (changes.length > 0) {\n\t\t\tthis.editor.updateShapes(changes)\n\t\t}\n\t}\n\n\t@bind\n\tprotected updateParentTransforms() {\n\t\tconst {\n\t\t\teditor,\n\t\t\tsnapshot: { shapeSnapshots },\n\t\t} = this\n\t\tconst movingShapes: TLShape[] = []\n\n\t\tshapeSnapshots.forEach((shapeSnapshot) => {\n\t\t\tconst shape = editor.getShape(shapeSnapshot.shape.id)\n\t\t\tif (!shape) return null\n\t\t\tmovingShapes.push(shape)\n\n\t\t\tconst parentTransform = isPageId(shape.parentId)\n\t\t\t\t? null\n\t\t\t\t: Mat.Inverse(editor.getShapePageTransform(shape.parentId)!)\n\n\t\t\tshapeSnapshot.parentTransform = parentTransform\n\t\t})\n\t}\n}\n\nfunction getTranslatingSnapshot(editor: Editor) {\n\tconst movingShapes: TLShape[] = []\n\tconst pagePoints: Vec[] = []\n\n\tconst selectedShapeIds = editor.getSelectedShapeIds()\n\tconst shapeSnapshots = compact(\n\t\tselectedShapeIds.map((id): null | MovingShapeSnapshot => {\n\t\t\tconst shape = editor.getShape(id)\n\t\t\tif (!shape) return null\n\t\t\tmovingShapes.push(shape)\n\n\t\t\tconst pageTransform = editor.getShapePageTransform(id)\n\t\t\tconst pagePoint = pageTransform.point()\n\t\t\tconst pageRotation = pageTransform.rotation()\n\n\t\t\tpagePoints.push(pagePoint)\n\n\t\t\tconst parentTransform = PageRecordType.isId(shape.parentId)\n\t\t\t\t? null\n\t\t\t\t: Mat.Inverse(editor.getShapePageTransform(shape.parentId)!)\n\n\t\t\treturn {\n\t\t\t\tshape,\n\t\t\t\tpagePoint,\n\t\t\t\tpageRotation,\n\t\t\t\tparentTransform,\n\t\t\t}\n\t\t})\n\t)\n\n\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\n\tlet initialSnapPoints: BoundsSnapPoint[] = []\n\n\tif (onlySelectedShape) {\n\t\tinitialSnapPoints = editor.snaps.shapeBounds.getSnapPoints(onlySelectedShape.id)!\n\t} else {\n\t\tconst selectionPageBounds = editor.getSelectionPageBounds()\n\t\tif (selectionPageBounds) {\n\t\t\tinitialSnapPoints = selectionPageBounds.cornersAndCenter.map((p, i) => ({\n\t\t\t\tid: 'selection:' + i,\n\t\t\t\tx: p.x,\n\t\t\t\ty: p.y,\n\t\t\t}))\n\t\t}\n\t}\n\n\tlet noteAdjacentPositions: Vec[] | undefined\n\tlet noteSnapshot: (MovingShapeSnapshot & { shape: TLNoteShape }) | undefined\n\n\tconst { originPagePoint } = editor.inputs\n\n\tconst allHoveredNotes = shapeSnapshots.filter(\n\t\t(s) =>\n\t\t\teditor.isShapeOfType<TLNoteShape>(s.shape, 'note') &&\n\t\t\teditor.isPointInShape(s.shape, originPagePoint)\n\t) as (MovingShapeSnapshot & { shape: TLNoteShape })[]\n\n\tif (allHoveredNotes.length === 0) {\n\t\t// noop\n\t} else if (allHoveredNotes.length === 1) {\n\t\t// just one, easy\n\t\tnoteSnapshot = allHoveredNotes[0]\n\t} else {\n\t\t// More than one under the cursor, so we need to find the highest shape in z-order\n\t\tconst allShapesSorted = editor.getCurrentPageShapesSorted()\n\t\tnoteSnapshot = allHoveredNotes\n\t\t\t.map((s) => ({\n\t\t\t\tsnapshot: s,\n\t\t\t\tindex: allShapesSorted.findIndex((shape) => shape.id === s.shape.id),\n\t\t\t}))\n\t\t\t.sort((a, b) => b.index - a.index)[0]?.snapshot // highest up first\n\t}\n\n\tif (noteSnapshot) {\n\t\tnoteAdjacentPositions = getAvailableNoteAdjacentPositions(\n\t\t\teditor,\n\t\t\tnoteSnapshot.pageRotation,\n\t\t\tnoteSnapshot.shape.props.scale,\n\t\t\tnoteSnapshot.shape.props.growY ?? 0\n\t\t)\n\t}\n\n\treturn {\n\t\taveragePagePoint: Vec.Average(pagePoints),\n\t\tmovingShapes,\n\t\tshapeSnapshots,\n\t\tinitialPageBounds: editor.getSelectionPageBounds()!,\n\t\tinitialSnapPoints,\n\t\tnoteAdjacentPositions,\n\t\tnoteSnapshot,\n\t}\n}\n\nexport type TranslatingSnapshot = ReturnType<typeof getTranslatingSnapshot>\n\nexport interface MovingShapeSnapshot {\n\tshape: TLShape\n\tpagePoint: Vec\n\tpageRotation: number\n\tparentTransform: MatModel | null\n}\n\nexport function moveShapesToPoint({\n\teditor,\n\tsnapshot,\n}: {\n\teditor: Editor\n\tsnapshot: TranslatingSnapshot\n}) {\n\tconst { inputs } = editor\n\n\tconst {\n\t\tnoteSnapshot,\n\t\tnoteAdjacentPositions,\n\t\tinitialPageBounds,\n\t\tinitialSnapPoints,\n\t\tshapeSnapshots,\n\t\taveragePagePoint,\n\t} = snapshot\n\n\tconst isGridMode = editor.getInstanceState().isGridMode\n\n\tconst gridSize = editor.getDocumentSettings().gridSize\n\n\tconst delta = Vec.Sub(inputs.currentPagePoint, inputs.originPagePoint)\n\n\tconst flatten: 'x' | 'y' | null = editor.inputs.shiftKey\n\t\t? Math.abs(delta.x) < Math.abs(delta.y)\n\t\t\t? 'x'\n\t\t\t: 'y'\n\t\t: null\n\n\tif (flatten === 'x') {\n\t\tdelta.x = 0\n\t} else if (flatten === 'y') {\n\t\tdelta.y = 0\n\t}\n\n\t// Provisional snapping\n\teditor.snaps.clearIndicators()\n\n\t// If the user isn't moving super quick\n\tconst isSnapping = editor.user.getIsSnapMode() ? !inputs.ctrlKey : inputs.ctrlKey\n\tlet snappedToPit = false\n\tif (isSnapping && editor.inputs.pointerVelocity.len() < 0.5) {\n\t\t// snapping\n\t\tconst { nudge } = editor.snaps.shapeBounds.snapTranslateShapes({\n\t\t\tdragDelta: delta,\n\t\t\tinitialSelectionPageBounds: initialPageBounds,\n\t\t\tlockedAxis: flatten,\n\t\t\tinitialSelectionSnapPoints: initialSnapPoints,\n\t\t})\n\n\t\tdelta.add(nudge)\n\t} else {\n\t\t// for sticky notes, snap to grid position next to other notes\n\t\tif (noteSnapshot && noteAdjacentPositions) {\n\t\t\tconst { scale } = noteSnapshot.shape.props\n\t\t\tconst pageCenter = noteSnapshot.pagePoint\n\t\t\t\t.clone()\n\t\t\t\t.add(delta)\n\t\t\t\t// use the middle of the note, disregarding extra height\n\t\t\t\t.add(NOTE_CENTER_OFFSET.clone().mul(scale).rot(noteSnapshot.pageRotation))\n\n\t\t\t// Find the pit with the center closest to the put center\n\t\t\tlet min = NOTE_ADJACENT_POSITION_SNAP_RADIUS / editor.getZoomLevel() // in screen space\n\t\t\tlet offset = new Vec(0, 0)\n\t\t\tfor (const pit of noteAdjacentPositions) {\n\t\t\t\t// We've already filtered pits with the same page rotation\n\t\t\t\tconst deltaToPit = Vec.Sub(pageCenter, pit)\n\t\t\t\tconst dist = deltaToPit.len()\n\t\t\t\tif (dist < min) {\n\t\t\t\t\tsnappedToPit = true\n\t\t\t\t\tmin = dist\n\t\t\t\t\toffset = deltaToPit\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdelta.sub(offset)\n\t\t}\n\t}\n\n\tconst averageSnappedPoint = Vec.Add(averagePagePoint, delta)\n\n\t// we don't want to snap to the grid if we're holding the ctrl key, if we've already snapped into a pit, or if we're showing snapping indicators\n\tconst snapIndicators = editor.snaps.getIndicators()\n\tif (isGridMode && !inputs.ctrlKey && !snappedToPit && snapIndicators.length === 0) {\n\t\taverageSnappedPoint.snapToGrid(gridSize)\n\t}\n\n\tconst averageSnap = Vec.Sub(averageSnappedPoint, averagePagePoint)\n\n\teditor.updateShapes(\n\t\tcompact(\n\t\t\tshapeSnapshots.map(({ shape, pagePoint, parentTransform }): TLShapePartial | null => {\n\t\t\t\tconst newPagePoint = Vec.Add(pagePoint, averageSnap)\n\n\t\t\t\tconst newLocalPoint = parentTransform\n\t\t\t\t\t? Mat.applyToPoint(parentTransform, newPagePoint)\n\t\t\t\t\t: newPagePoint\n\n\t\t\t\treturn {\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: shape.type,\n\t\t\t\t\tx: newLocalPoint.x,\n\t\t\t\t\ty: newLocalPoint.y,\n\t\t\t\t}\n\t\t\t})\n\t\t)\n\t)\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA,EAGC;AAAA,EAEA;AAAA,EACA;AAAA,EAMA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,0BAA0B;AAU5B,MAAM,qBAAoB,
|
|
4
|
+
"sourcesContent": ["import {\n\tBoundsSnapPoint,\n\tEditor,\n\tMat,\n\tMatModel,\n\tPageRecordType,\n\tStateNode,\n\tTLNoteShape,\n\tTLPointerEventInfo,\n\tTLShape,\n\tTLShapePartial,\n\tTLTickEventInfo,\n\tVec,\n\tbind,\n\tcompact,\n\tisPageId,\n\tkickoutOccludedShapes,\n} from '@tldraw/editor'\nimport {\n\tNOTE_ADJACENT_POSITION_SNAP_RADIUS,\n\tNOTE_CENTER_OFFSET,\n\tgetAvailableNoteAdjacentPositions,\n} from '../../../shapes/note/noteHelpers'\nimport { DragAndDropManager } from '../DragAndDropManager'\n\nexport type TranslatingInfo = TLPointerEventInfo & {\n\ttarget: 'shape'\n\tisCreating?: boolean\n\tcreatingMarkId?: string\n\tonCreate?(): void\n\tonInteractionEnd?: string | (() => void)\n}\n\nexport class Translating extends StateNode {\n\tstatic override id = 'translating'\n\n\tinfo = {} as TranslatingInfo\n\n\tselectionSnapshot: TranslatingSnapshot = {} as any\n\n\tsnapshot: TranslatingSnapshot = {} as any\n\n\tmarkId = ''\n\n\tisCloning = false\n\tisCreating = false\n\tonCreate(_shape: TLShape | null): void {\n\t\treturn\n\t}\n\n\tdragAndDropManager = new DragAndDropManager(this.editor)\n\n\toverride onEnter(info: TranslatingInfo) {\n\t\tconst { isCreating = false, creatingMarkId, onCreate = () => void null } = info\n\n\t\tif (!this.editor.getSelectedShapeIds()?.length) {\n\t\t\tthis.parent.transition('idle')\n\t\t\treturn\n\t\t}\n\n\t\tthis.info = info\n\t\tif (typeof info.onInteractionEnd === 'string') {\n\t\t\tthis.parent.setCurrentToolIdMask(info.onInteractionEnd)\n\t\t}\n\t\tthis.isCreating = isCreating\n\n\t\tthis.markId = ''\n\n\t\tif (isCreating) {\n\t\t\tif (creatingMarkId) {\n\t\t\t\tthis.markId = creatingMarkId\n\t\t\t} else {\n\t\t\t\t// handle legacy implicit `creating:{shapeId}` marks\n\t\t\t\tconst markId = this.editor.getMarkIdMatching(\n\t\t\t\t\t`creating:${this.editor.getOnlySelectedShapeId()}`\n\t\t\t\t)\n\t\t\t\tif (markId) {\n\t\t\t\t\tthis.markId = markId\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.markId = this.editor.markHistoryStoppingPoint('translating')\n\t\t}\n\n\t\tthis.onCreate = onCreate\n\n\t\tthis.isCloning = false\n\t\tthis.info = info\n\n\t\tthis.editor.setCursor({ type: 'move', rotation: 0 })\n\t\tthis.selectionSnapshot = getTranslatingSnapshot(this.editor)\n\n\t\t// Don't clone on create; otherwise clone on altKey\n\t\tif (!this.isCreating) {\n\t\t\tif (this.editor.inputs.altKey) {\n\t\t\t\tthis.startCloning()\n\t\t\t\tif (this.isCloning) return\n\t\t\t}\n\t\t}\n\n\t\tthis.snapshot = this.selectionSnapshot\n\t\tthis.handleStart()\n\t\tthis.updateShapes()\n\t}\n\n\toverride onExit() {\n\t\tthis.parent.setCurrentToolIdMask(undefined)\n\t\tthis.selectionSnapshot = {} as any\n\t\tthis.snapshot = {} as any\n\t\tthis.editor.snaps.clearIndicators()\n\t\tthis.editor.setCursor({ type: 'default', rotation: 0 })\n\t\tthis.dragAndDropManager.clear()\n\t}\n\n\toverride onTick({ elapsed }: TLTickEventInfo) {\n\t\tconst { editor } = this\n\t\teditor.edgeScrollManager.updateEdgeScrolling(elapsed)\n\t}\n\n\toverride onPointerMove() {\n\t\tthis.updateShapes()\n\t}\n\n\toverride onKeyDown() {\n\t\tif (this.editor.inputs.altKey && !this.isCloning) {\n\t\t\tthis.startCloning()\n\t\t\tif (this.isCloning) return\n\t\t}\n\n\t\t// need to update in case user pressed a different modifier key\n\t\tthis.updateShapes()\n\t}\n\n\toverride onKeyUp() {\n\t\tif (!this.editor.inputs.altKey && this.isCloning) {\n\t\t\tthis.stopCloning()\n\t\t\treturn\n\t\t}\n\n\t\t// need to update in case user pressed a different modifier key\n\t\tthis.updateShapes()\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onComplete() {\n\t\tthis.complete()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\tprotected startCloning() {\n\t\tif (this.isCreating) return\n\t\tconst shapeIds = Array.from(this.editor.getSelectedShapeIds())\n\n\t\t// If we can't create the shapes, don't even start cloning\n\t\tif (!this.editor.canCreateShapes(shapeIds)) return\n\n\t\tthis.isCloning = true\n\t\tthis.reset()\n\t\tthis.markId = this.editor.markHistoryStoppingPoint('translate cloning')\n\n\t\tthis.editor.duplicateShapes(Array.from(this.editor.getSelectedShapeIds()))\n\n\t\tthis.snapshot = getTranslatingSnapshot(this.editor)\n\t\tthis.handleStart()\n\t\tthis.updateShapes()\n\t}\n\n\tprotected stopCloning() {\n\t\tthis.isCloning = false\n\t\tthis.snapshot = this.selectionSnapshot\n\t\tthis.reset()\n\t\tthis.markId = this.editor.markHistoryStoppingPoint('translate')\n\t\tthis.updateShapes()\n\t}\n\n\treset() {\n\t\tthis.editor.bailToMark(this.markId)\n\t}\n\n\tprotected complete() {\n\t\tthis.updateShapes()\n\t\tthis.dragAndDropManager.dropShapes(this.snapshot.movingShapes)\n\t\tthis.handleEnd()\n\t\tkickoutOccludedShapes(\n\t\t\tthis.editor,\n\t\t\tthis.snapshot.movingShapes.map((s) => s.id)\n\t\t)\n\n\t\tconst { onInteractionEnd } = this.info\n\t\tif (onInteractionEnd) {\n\t\t\tif (typeof onInteractionEnd === 'string') {\n\t\t\t\tif (this.editor.getInstanceState().isToolLocked) {\n\t\t\t\t\tthis.editor.setCurrentTool(onInteractionEnd)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tonInteractionEnd()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif (this.isCreating) {\n\t\t\tthis.onCreate?.(this.editor.getOnlySelectedShape())\n\t\t} else {\n\t\t\tthis.parent.transition('idle')\n\t\t}\n\t}\n\n\tprivate cancel() {\n\t\t// Call onTranslateCancel callback before resetting\n\t\tconst { movingShapes } = this.snapshot\n\n\t\tmovingShapes.forEach((shape) => {\n\t\t\tconst current = this.editor.getShape(shape.id)\n\t\t\tif (current) {\n\t\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\t\tutil.onTranslateCancel?.(shape, current)\n\t\t\t}\n\t\t})\n\n\t\tthis.reset()\n\t\tconst { onInteractionEnd } = this.info\n\t\tif (onInteractionEnd) {\n\t\t\tif (typeof onInteractionEnd === 'string') {\n\t\t\t\tthis.editor.setCurrentTool(onInteractionEnd)\n\t\t\t} else {\n\t\t\t\tonInteractionEnd()\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tthis.parent.transition('idle', this.info)\n\t}\n\n\tprotected handleStart() {\n\t\tconst { movingShapes } = this.snapshot\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tmovingShapes.forEach((shape) => {\n\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\tconst change = util.onTranslateStart?.(shape)\n\t\t\tif (change) {\n\t\t\t\tchanges.push(change)\n\t\t\t}\n\t\t})\n\n\t\tif (changes.length > 0) {\n\t\t\tthis.editor.updateShapes(changes)\n\t\t}\n\n\t\tthis.dragAndDropManager.startDraggingShapes(\n\t\t\t// Get fresh shapes from the snapshot, in case onTranslateStart mutates the shape\n\t\t\tcompact(this.snapshot.movingShapes.map((s) => this.editor.getShape(s.id))),\n\t\t\t// Start from the place where the user started dragging\n\t\t\tthis.editor.inputs.originPagePoint,\n\t\t\tthis.updateParentTransforms\n\t\t)\n\n\t\tthis.editor.setHoveredShape(null)\n\t}\n\n\tprotected handleEnd() {\n\t\tconst { movingShapes } = this.snapshot\n\n\t\tif (this.isCloning && movingShapes.length > 0) {\n\t\t\tconst currentAveragePagePoint = Vec.Average(\n\t\t\t\tmovingShapes.map((s) => this.editor.getShapePageTransform(s.id)!.point())\n\t\t\t)\n\t\t\tconst offset = Vec.Sub(currentAveragePagePoint, this.selectionSnapshot.averagePagePoint)\n\t\t\tif (!Vec.IsNaN(offset)) {\n\t\t\t\tthis.editor.updateInstanceState({\n\t\t\t\t\tduplicateProps: {\n\t\t\t\t\t\tshapeIds: movingShapes.map((s) => s.id),\n\t\t\t\t\t\toffset: { x: offset.x, y: offset.y },\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tmovingShapes.forEach((shape) => {\n\t\t\tconst current = this.editor.getShape(shape.id)!\n\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\tconst change = util.onTranslateEnd?.(shape, current)\n\t\t\tif (change) {\n\t\t\t\tchanges.push(change)\n\t\t\t}\n\t\t})\n\n\t\tif (changes.length > 0) {\n\t\t\tthis.editor.updateShapes(changes)\n\t\t}\n\t}\n\n\tprotected updateShapes() {\n\t\tconst { snapshot } = this\n\n\t\t// We should have started already, but hey\n\t\tthis.dragAndDropManager.startDraggingShapes(\n\t\t\tsnapshot.movingShapes,\n\t\t\tthis.editor.inputs.originPagePoint,\n\t\t\tthis.updateParentTransforms\n\t\t)\n\n\t\tmoveShapesToPoint({\n\t\t\teditor: this.editor,\n\t\t\tsnapshot,\n\t\t})\n\n\t\tconst { movingShapes } = snapshot\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tmovingShapes.forEach((shape) => {\n\t\t\tconst current = this.editor.getShape(shape.id)!\n\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\tconst change = util.onTranslate?.(shape, current)\n\t\t\tif (change) {\n\t\t\t\tchanges.push(change)\n\t\t\t}\n\t\t})\n\n\t\tif (changes.length > 0) {\n\t\t\tthis.editor.updateShapes(changes)\n\t\t}\n\t}\n\n\t@bind\n\tprotected updateParentTransforms() {\n\t\tconst {\n\t\t\teditor,\n\t\t\tsnapshot: { shapeSnapshots },\n\t\t} = this\n\t\tconst movingShapes: TLShape[] = []\n\n\t\tshapeSnapshots.forEach((shapeSnapshot) => {\n\t\t\tconst shape = editor.getShape(shapeSnapshot.shape.id)\n\t\t\tif (!shape) return null\n\t\t\tmovingShapes.push(shape)\n\n\t\t\tconst parentTransform = isPageId(shape.parentId)\n\t\t\t\t? null\n\t\t\t\t: Mat.Inverse(editor.getShapePageTransform(shape.parentId)!)\n\n\t\t\tshapeSnapshot.parentTransform = parentTransform\n\t\t})\n\t}\n}\n\nfunction getTranslatingSnapshot(editor: Editor) {\n\tconst movingShapes: TLShape[] = []\n\tconst pagePoints: Vec[] = []\n\n\tconst selectedShapeIds = editor.getSelectedShapeIds()\n\tconst shapeSnapshots = compact(\n\t\tselectedShapeIds.map((id): null | MovingShapeSnapshot => {\n\t\t\tconst shape = editor.getShape(id)\n\t\t\tif (!shape) return null\n\t\t\tmovingShapes.push(shape)\n\n\t\t\tconst pageTransform = editor.getShapePageTransform(id)\n\t\t\tconst pagePoint = pageTransform.point()\n\t\t\tconst pageRotation = pageTransform.rotation()\n\n\t\t\tpagePoints.push(pagePoint)\n\n\t\t\tconst parentTransform = PageRecordType.isId(shape.parentId)\n\t\t\t\t? null\n\t\t\t\t: Mat.Inverse(editor.getShapePageTransform(shape.parentId)!)\n\n\t\t\treturn {\n\t\t\t\tshape,\n\t\t\t\tpagePoint,\n\t\t\t\tpageRotation,\n\t\t\t\tparentTransform,\n\t\t\t}\n\t\t})\n\t)\n\n\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\n\tlet initialSnapPoints: BoundsSnapPoint[] = []\n\n\tif (onlySelectedShape) {\n\t\tinitialSnapPoints = editor.snaps.shapeBounds.getSnapPoints(onlySelectedShape.id)!\n\t} else {\n\t\tconst selectionPageBounds = editor.getSelectionPageBounds()\n\t\tif (selectionPageBounds) {\n\t\t\tinitialSnapPoints = selectionPageBounds.cornersAndCenter.map((p, i) => ({\n\t\t\t\tid: 'selection:' + i,\n\t\t\t\tx: p.x,\n\t\t\t\ty: p.y,\n\t\t\t}))\n\t\t}\n\t}\n\n\tlet noteAdjacentPositions: Vec[] | undefined\n\tlet noteSnapshot: (MovingShapeSnapshot & { shape: TLNoteShape }) | undefined\n\n\tconst { originPagePoint } = editor.inputs\n\n\tconst allHoveredNotes = shapeSnapshots.filter(\n\t\t(s) =>\n\t\t\teditor.isShapeOfType<TLNoteShape>(s.shape, 'note') &&\n\t\t\teditor.isPointInShape(s.shape, originPagePoint)\n\t) as (MovingShapeSnapshot & { shape: TLNoteShape })[]\n\n\tif (allHoveredNotes.length === 0) {\n\t\t// noop\n\t} else if (allHoveredNotes.length === 1) {\n\t\t// just one, easy\n\t\tnoteSnapshot = allHoveredNotes[0]\n\t} else {\n\t\t// More than one under the cursor, so we need to find the highest shape in z-order\n\t\tconst allShapesSorted = editor.getCurrentPageShapesSorted()\n\t\tnoteSnapshot = allHoveredNotes\n\t\t\t.map((s) => ({\n\t\t\t\tsnapshot: s,\n\t\t\t\tindex: allShapesSorted.findIndex((shape) => shape.id === s.shape.id),\n\t\t\t}))\n\t\t\t.sort((a, b) => b.index - a.index)[0]?.snapshot // highest up first\n\t}\n\n\tif (noteSnapshot) {\n\t\tnoteAdjacentPositions = getAvailableNoteAdjacentPositions(\n\t\t\teditor,\n\t\t\tnoteSnapshot.pageRotation,\n\t\t\tnoteSnapshot.shape.props.scale,\n\t\t\tnoteSnapshot.shape.props.growY ?? 0\n\t\t)\n\t}\n\n\treturn {\n\t\taveragePagePoint: Vec.Average(pagePoints),\n\t\tmovingShapes,\n\t\tshapeSnapshots,\n\t\tinitialPageBounds: editor.getSelectionPageBounds()!,\n\t\tinitialSnapPoints,\n\t\tnoteAdjacentPositions,\n\t\tnoteSnapshot,\n\t}\n}\n\nexport type TranslatingSnapshot = ReturnType<typeof getTranslatingSnapshot>\n\nexport interface MovingShapeSnapshot {\n\tshape: TLShape\n\tpagePoint: Vec\n\tpageRotation: number\n\tparentTransform: MatModel | null\n}\n\nexport function moveShapesToPoint({\n\teditor,\n\tsnapshot,\n}: {\n\teditor: Editor\n\tsnapshot: TranslatingSnapshot\n}) {\n\tconst { inputs } = editor\n\n\tconst {\n\t\tnoteSnapshot,\n\t\tnoteAdjacentPositions,\n\t\tinitialPageBounds,\n\t\tinitialSnapPoints,\n\t\tshapeSnapshots,\n\t\taveragePagePoint,\n\t} = snapshot\n\n\tconst isGridMode = editor.getInstanceState().isGridMode\n\n\tconst gridSize = editor.getDocumentSettings().gridSize\n\n\tconst delta = Vec.Sub(inputs.currentPagePoint, inputs.originPagePoint)\n\n\tconst flatten: 'x' | 'y' | null = editor.inputs.shiftKey\n\t\t? Math.abs(delta.x) < Math.abs(delta.y)\n\t\t\t? 'x'\n\t\t\t: 'y'\n\t\t: null\n\n\tif (flatten === 'x') {\n\t\tdelta.x = 0\n\t} else if (flatten === 'y') {\n\t\tdelta.y = 0\n\t}\n\n\t// Provisional snapping\n\teditor.snaps.clearIndicators()\n\n\t// If the user isn't moving super quick\n\tconst isSnapping = editor.user.getIsSnapMode() ? !inputs.ctrlKey : inputs.ctrlKey\n\tlet snappedToPit = false\n\tif (isSnapping && editor.inputs.pointerVelocity.len() < 0.5) {\n\t\t// snapping\n\t\tconst { nudge } = editor.snaps.shapeBounds.snapTranslateShapes({\n\t\t\tdragDelta: delta,\n\t\t\tinitialSelectionPageBounds: initialPageBounds,\n\t\t\tlockedAxis: flatten,\n\t\t\tinitialSelectionSnapPoints: initialSnapPoints,\n\t\t})\n\n\t\tdelta.add(nudge)\n\t} else {\n\t\t// for sticky notes, snap to grid position next to other notes\n\t\tif (noteSnapshot && noteAdjacentPositions) {\n\t\t\tconst { scale } = noteSnapshot.shape.props\n\t\t\tconst pageCenter = noteSnapshot.pagePoint\n\t\t\t\t.clone()\n\t\t\t\t.add(delta)\n\t\t\t\t// use the middle of the note, disregarding extra height\n\t\t\t\t.add(NOTE_CENTER_OFFSET.clone().mul(scale).rot(noteSnapshot.pageRotation))\n\n\t\t\t// Find the pit with the center closest to the put center\n\t\t\tlet min = NOTE_ADJACENT_POSITION_SNAP_RADIUS / editor.getZoomLevel() // in screen space\n\t\t\tlet offset = new Vec(0, 0)\n\t\t\tfor (const pit of noteAdjacentPositions) {\n\t\t\t\t// We've already filtered pits with the same page rotation\n\t\t\t\tconst deltaToPit = Vec.Sub(pageCenter, pit)\n\t\t\t\tconst dist = deltaToPit.len()\n\t\t\t\tif (dist < min) {\n\t\t\t\t\tsnappedToPit = true\n\t\t\t\t\tmin = dist\n\t\t\t\t\toffset = deltaToPit\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdelta.sub(offset)\n\t\t}\n\t}\n\n\tconst averageSnappedPoint = Vec.Add(averagePagePoint, delta)\n\n\t// we don't want to snap to the grid if we're holding the ctrl key, if we've already snapped into a pit, or if we're showing snapping indicators\n\tconst snapIndicators = editor.snaps.getIndicators()\n\tif (isGridMode && !inputs.ctrlKey && !snappedToPit && snapIndicators.length === 0) {\n\t\taverageSnappedPoint.snapToGrid(gridSize)\n\t}\n\n\tconst averageSnap = Vec.Sub(averageSnappedPoint, averagePagePoint)\n\n\teditor.updateShapes(\n\t\tcompact(\n\t\t\tshapeSnapshots.map(({ shape, pagePoint, parentTransform }): TLShapePartial | null => {\n\t\t\t\tconst newPagePoint = Vec.Add(pagePoint, averageSnap)\n\n\t\t\t\tconst newLocalPoint = parentTransform\n\t\t\t\t\t? Mat.applyToPoint(parentTransform, newPagePoint)\n\t\t\t\t\t: newPagePoint\n\n\t\t\t\treturn {\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: shape.type,\n\t\t\t\t\tx: newLocalPoint.x,\n\t\t\t\t\ty: newLocalPoint.y,\n\t\t\t\t}\n\t\t\t})\n\t\t)\n\t)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -168,12 +168,12 @@ function DefaultDebugMenuContent() {
|
|
|
168
168
|
function DebugFlags() {
|
|
169
169
|
const items = Object.values(debugFlags);
|
|
170
170
|
if (!items.length) return null;
|
|
171
|
-
return /* @__PURE__ */ jsx(TldrawUiMenuSubmenu, { id: "debug flags", label: "Debug
|
|
171
|
+
return /* @__PURE__ */ jsx(TldrawUiMenuSubmenu, { id: "debug flags", label: "Debug flags", children: /* @__PURE__ */ jsx(TldrawUiMenuGroup, { id: "debug flags", children: items.map((flag) => /* @__PURE__ */ jsx(DebugFlagToggle, { flag }, flag.name)) }) });
|
|
172
172
|
}
|
|
173
173
|
function FeatureFlags() {
|
|
174
174
|
const items = Object.values(featureFlags);
|
|
175
175
|
if (!items.length) return null;
|
|
176
|
-
return /* @__PURE__ */ jsx(TldrawUiMenuSubmenu, { id: "feature flags", label: "Feature
|
|
176
|
+
return /* @__PURE__ */ jsx(TldrawUiMenuSubmenu, { id: "feature flags", label: "Feature flags", children: /* @__PURE__ */ jsx(TldrawUiMenuGroup, { id: "feature flags", children: items.map((flag) => /* @__PURE__ */ jsx(DebugFlagToggle, { flag }, flag.name)) }) });
|
|
177
177
|
}
|
|
178
178
|
function ExampleDialog({
|
|
179
179
|
title = "title",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/ui/components/DebugMenu/DefaultDebugMenuContent.tsx"],
|
|
4
|
-
"sourcesContent": ["import {\n\tDebugFlag,\n\tEditor,\n\tTLShapePartial,\n\tcreateShapeId,\n\tdebugFlags,\n\tfeatureFlags,\n\thardResetEditor,\n\ttrack,\n\tuniqueId,\n\tuseEditor,\n} from '@tldraw/editor'\nimport React from 'react'\nimport { useDialogs } from '../../context/dialogs'\nimport { useToasts } from '../../context/toasts'\nimport { untranslated } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from '../primitives/Button/TldrawUiButton'\nimport { TldrawUiButtonCheck } from '../primitives/Button/TldrawUiButtonCheck'\nimport { TldrawUiButtonLabel } from '../primitives/Button/TldrawUiButtonLabel'\nimport {\n\tTldrawUiDialogBody,\n\tTldrawUiDialogCloseButton,\n\tTldrawUiDialogFooter,\n\tTldrawUiDialogHeader,\n\tTldrawUiDialogTitle,\n} from '../primitives/TldrawUiDialog'\nimport { TldrawUiMenuCheckboxItem } from '../primitives/menus/TldrawUiMenuCheckboxItem'\nimport { TldrawUiMenuGroup } from '../primitives/menus/TldrawUiMenuGroup'\nimport { TldrawUiMenuItem } from '../primitives/menus/TldrawUiMenuItem'\nimport { TldrawUiMenuSubmenu } from '../primitives/menus/TldrawUiMenuSubmenu'\n\n/** @public @react */\nexport function DefaultDebugMenuContent() {\n\tconst editor = useEditor()\n\tconst { addToast } = useToasts()\n\tconst { addDialog } = useDialogs()\n\tconst [error, setError] = React.useState<boolean>(false)\n\n\treturn (\n\t\t<>\n\t\t\t<TldrawUiMenuGroup id=\"items\">\n\t\t\t\t<TldrawUiMenuItem id=\"hard-reset\" onSelect={hardResetEditor} label={'Hard reset'} />\n\t\t\t\t<TldrawUiMenuItem\n\t\t\t\t\tid=\"add-toast\"\n\t\t\t\t\tonSelect={() => {\n\t\t\t\t\t\taddToast({\n\t\t\t\t\t\t\tid: uniqueId(),\n\t\t\t\t\t\t\ttitle: 'Something good happened',\n\t\t\t\t\t\t\tdescription: 'Hey, attend to this thing over here. It might be important!',\n\t\t\t\t\t\t\tkeepOpen: true,\n\t\t\t\t\t\t\tseverity: 'success',\n\t\t\t\t\t\t})\n\t\t\t\t\t\taddToast({\n\t\t\t\t\t\t\tid: uniqueId(),\n\t\t\t\t\t\t\ttitle: 'Something happened',\n\t\t\t\t\t\t\tdescription: 'Hey, attend to this thing over here. It might be important!',\n\t\t\t\t\t\t\tkeepOpen: true,\n\t\t\t\t\t\t\tseverity: 'info',\n\t\t\t\t\t\t\tactions: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlabel: 'Primary',\n\t\t\t\t\t\t\t\t\ttype: 'primary',\n\t\t\t\t\t\t\t\t\tonClick: () => {\n\t\t\t\t\t\t\t\t\t\tvoid null\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlabel: 'Normal',\n\t\t\t\t\t\t\t\t\ttype: 'normal',\n\t\t\t\t\t\t\t\t\tonClick: () => {\n\t\t\t\t\t\t\t\t\t\tvoid null\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlabel: 'Danger',\n\t\t\t\t\t\t\t\t\ttype: 'danger',\n\t\t\t\t\t\t\t\t\tonClick: () => {\n\t\t\t\t\t\t\t\t\t\tvoid null\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t})\n\t\t\t\t\t\taddToast({\n\t\t\t\t\t\t\tid: uniqueId(),\n\t\t\t\t\t\t\ttitle: 'Something maybe bad happened',\n\t\t\t\t\t\t\tdescription: 'Hey, attend to this thing over here. It might be important!',\n\t\t\t\t\t\t\tkeepOpen: true,\n\t\t\t\t\t\t\tseverity: 'warning',\n\t\t\t\t\t\t\tactions: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlabel: 'Primary',\n\t\t\t\t\t\t\t\t\ttype: 'primary',\n\t\t\t\t\t\t\t\t\tonClick: () => {\n\t\t\t\t\t\t\t\t\t\tvoid null\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlabel: 'Normal',\n\t\t\t\t\t\t\t\t\ttype: 'normal',\n\t\t\t\t\t\t\t\t\tonClick: () => {\n\t\t\t\t\t\t\t\t\t\tvoid null\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlabel: 'Danger',\n\t\t\t\t\t\t\t\t\ttype: 'danger',\n\t\t\t\t\t\t\t\t\tonClick: () => {\n\t\t\t\t\t\t\t\t\t\tvoid null\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t})\n\t\t\t\t\t\taddToast({\n\t\t\t\t\t\t\tid: uniqueId(),\n\t\t\t\t\t\t\ttitle: 'Something bad happened',\n\t\t\t\t\t\t\tseverity: 'error',\n\t\t\t\t\t\t\tkeepOpen: true,\n\t\t\t\t\t\t})\n\t\t\t\t\t}}\n\t\t\t\t\tlabel={untranslated('Show toast')}\n\t\t\t\t/>\n\t\t\t\t<TldrawUiMenuItem\n\t\t\t\t\tid=\"show-dialog\"\n\t\t\t\t\tlabel={'Show dialog'}\n\t\t\t\t\tonSelect={() => {\n\t\t\t\t\t\taddDialog({\n\t\t\t\t\t\t\tcomponent: ({ onClose }) => (\n\t\t\t\t\t\t\t\t<ExampleDialog\n\t\t\t\t\t\t\t\t\tdisplayDontShowAgain\n\t\t\t\t\t\t\t\t\tonCancel={() => onClose()}\n\t\t\t\t\t\t\t\t\tonContinue={() => onClose()}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tonClose: () => {\n\t\t\t\t\t\t\t\tvoid null\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t})\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t\t<TldrawUiMenuItem\n\t\t\t\t\tid=\"create-shapes\"\n\t\t\t\t\tlabel={'Create 100 shapes'}\n\t\t\t\t\tonSelect={() => createNShapes(editor, 100)}\n\t\t\t\t/>\n\t\t\t\t<TldrawUiMenuItem\n\t\t\t\t\tid=\"count-nodes\"\n\t\t\t\t\tlabel={'Count shapes / nodes'}\n\t\t\t\t\tonSelect={() => {\n\t\t\t\t\t\tconst selectedShapes = editor.getSelectedShapes()\n\t\t\t\t\t\tconst shapes =\n\t\t\t\t\t\t\tselectedShapes.length === 0 ? editor.getRenderingShapes() : selectedShapes\n\t\t\t\t\t\twindow.alert(\n\t\t\t\t\t\t\t`Shapes ${shapes.length}, DOM nodes:${document.querySelector('.tl-shapes')!.querySelectorAll('*')?.length}`\n\t\t\t\t\t\t)\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t\t{(() => {\n\t\t\t\t\tif (error) throw Error('oh no!')\n\t\t\t\t\treturn null\n\t\t\t\t})()}\n\t\t\t\t<TldrawUiMenuItem id=\"throw-error\" onSelect={() => setError(true)} label={'Throw error'} />\n\t\t\t</TldrawUiMenuGroup>\n\t\t\t<TldrawUiMenuGroup id=\"flags\">\n\t\t\t\t<DebugFlags />\n\t\t\t\t<FeatureFlags />\n\t\t\t</TldrawUiMenuGroup>\n\t\t</>\n\t)\n}\n/** @public @react */\nexport function DebugFlags() {\n\tconst items = Object.values(debugFlags)\n\tif (!items.length) return null\n\treturn (\n\t\t<TldrawUiMenuSubmenu id=\"debug flags\" label=\"Debug
|
|
4
|
+
"sourcesContent": ["import {\n\tDebugFlag,\n\tEditor,\n\tTLShapePartial,\n\tcreateShapeId,\n\tdebugFlags,\n\tfeatureFlags,\n\thardResetEditor,\n\ttrack,\n\tuniqueId,\n\tuseEditor,\n} from '@tldraw/editor'\nimport React from 'react'\nimport { useDialogs } from '../../context/dialogs'\nimport { useToasts } from '../../context/toasts'\nimport { untranslated } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from '../primitives/Button/TldrawUiButton'\nimport { TldrawUiButtonCheck } from '../primitives/Button/TldrawUiButtonCheck'\nimport { TldrawUiButtonLabel } from '../primitives/Button/TldrawUiButtonLabel'\nimport {\n\tTldrawUiDialogBody,\n\tTldrawUiDialogCloseButton,\n\tTldrawUiDialogFooter,\n\tTldrawUiDialogHeader,\n\tTldrawUiDialogTitle,\n} from '../primitives/TldrawUiDialog'\nimport { TldrawUiMenuCheckboxItem } from '../primitives/menus/TldrawUiMenuCheckboxItem'\nimport { TldrawUiMenuGroup } from '../primitives/menus/TldrawUiMenuGroup'\nimport { TldrawUiMenuItem } from '../primitives/menus/TldrawUiMenuItem'\nimport { TldrawUiMenuSubmenu } from '../primitives/menus/TldrawUiMenuSubmenu'\n\n/** @public @react */\nexport function DefaultDebugMenuContent() {\n\tconst editor = useEditor()\n\tconst { addToast } = useToasts()\n\tconst { addDialog } = useDialogs()\n\tconst [error, setError] = React.useState<boolean>(false)\n\n\treturn (\n\t\t<>\n\t\t\t<TldrawUiMenuGroup id=\"items\">\n\t\t\t\t<TldrawUiMenuItem id=\"hard-reset\" onSelect={hardResetEditor} label={'Hard reset'} />\n\t\t\t\t<TldrawUiMenuItem\n\t\t\t\t\tid=\"add-toast\"\n\t\t\t\t\tonSelect={() => {\n\t\t\t\t\t\taddToast({\n\t\t\t\t\t\t\tid: uniqueId(),\n\t\t\t\t\t\t\ttitle: 'Something good happened',\n\t\t\t\t\t\t\tdescription: 'Hey, attend to this thing over here. It might be important!',\n\t\t\t\t\t\t\tkeepOpen: true,\n\t\t\t\t\t\t\tseverity: 'success',\n\t\t\t\t\t\t})\n\t\t\t\t\t\taddToast({\n\t\t\t\t\t\t\tid: uniqueId(),\n\t\t\t\t\t\t\ttitle: 'Something happened',\n\t\t\t\t\t\t\tdescription: 'Hey, attend to this thing over here. It might be important!',\n\t\t\t\t\t\t\tkeepOpen: true,\n\t\t\t\t\t\t\tseverity: 'info',\n\t\t\t\t\t\t\tactions: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlabel: 'Primary',\n\t\t\t\t\t\t\t\t\ttype: 'primary',\n\t\t\t\t\t\t\t\t\tonClick: () => {\n\t\t\t\t\t\t\t\t\t\tvoid null\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlabel: 'Normal',\n\t\t\t\t\t\t\t\t\ttype: 'normal',\n\t\t\t\t\t\t\t\t\tonClick: () => {\n\t\t\t\t\t\t\t\t\t\tvoid null\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlabel: 'Danger',\n\t\t\t\t\t\t\t\t\ttype: 'danger',\n\t\t\t\t\t\t\t\t\tonClick: () => {\n\t\t\t\t\t\t\t\t\t\tvoid null\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t})\n\t\t\t\t\t\taddToast({\n\t\t\t\t\t\t\tid: uniqueId(),\n\t\t\t\t\t\t\ttitle: 'Something maybe bad happened',\n\t\t\t\t\t\t\tdescription: 'Hey, attend to this thing over here. It might be important!',\n\t\t\t\t\t\t\tkeepOpen: true,\n\t\t\t\t\t\t\tseverity: 'warning',\n\t\t\t\t\t\t\tactions: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlabel: 'Primary',\n\t\t\t\t\t\t\t\t\ttype: 'primary',\n\t\t\t\t\t\t\t\t\tonClick: () => {\n\t\t\t\t\t\t\t\t\t\tvoid null\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlabel: 'Normal',\n\t\t\t\t\t\t\t\t\ttype: 'normal',\n\t\t\t\t\t\t\t\t\tonClick: () => {\n\t\t\t\t\t\t\t\t\t\tvoid null\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlabel: 'Danger',\n\t\t\t\t\t\t\t\t\ttype: 'danger',\n\t\t\t\t\t\t\t\t\tonClick: () => {\n\t\t\t\t\t\t\t\t\t\tvoid null\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t})\n\t\t\t\t\t\taddToast({\n\t\t\t\t\t\t\tid: uniqueId(),\n\t\t\t\t\t\t\ttitle: 'Something bad happened',\n\t\t\t\t\t\t\tseverity: 'error',\n\t\t\t\t\t\t\tkeepOpen: true,\n\t\t\t\t\t\t})\n\t\t\t\t\t}}\n\t\t\t\t\tlabel={untranslated('Show toast')}\n\t\t\t\t/>\n\t\t\t\t<TldrawUiMenuItem\n\t\t\t\t\tid=\"show-dialog\"\n\t\t\t\t\tlabel={'Show dialog'}\n\t\t\t\t\tonSelect={() => {\n\t\t\t\t\t\taddDialog({\n\t\t\t\t\t\t\tcomponent: ({ onClose }) => (\n\t\t\t\t\t\t\t\t<ExampleDialog\n\t\t\t\t\t\t\t\t\tdisplayDontShowAgain\n\t\t\t\t\t\t\t\t\tonCancel={() => onClose()}\n\t\t\t\t\t\t\t\t\tonContinue={() => onClose()}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tonClose: () => {\n\t\t\t\t\t\t\t\tvoid null\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t})\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t\t<TldrawUiMenuItem\n\t\t\t\t\tid=\"create-shapes\"\n\t\t\t\t\tlabel={'Create 100 shapes'}\n\t\t\t\t\tonSelect={() => createNShapes(editor, 100)}\n\t\t\t\t/>\n\t\t\t\t<TldrawUiMenuItem\n\t\t\t\t\tid=\"count-nodes\"\n\t\t\t\t\tlabel={'Count shapes / nodes'}\n\t\t\t\t\tonSelect={() => {\n\t\t\t\t\t\tconst selectedShapes = editor.getSelectedShapes()\n\t\t\t\t\t\tconst shapes =\n\t\t\t\t\t\t\tselectedShapes.length === 0 ? editor.getRenderingShapes() : selectedShapes\n\t\t\t\t\t\twindow.alert(\n\t\t\t\t\t\t\t`Shapes ${shapes.length}, DOM nodes:${document.querySelector('.tl-shapes')!.querySelectorAll('*')?.length}`\n\t\t\t\t\t\t)\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t\t{(() => {\n\t\t\t\t\tif (error) throw Error('oh no!')\n\t\t\t\t\treturn null\n\t\t\t\t})()}\n\t\t\t\t<TldrawUiMenuItem id=\"throw-error\" onSelect={() => setError(true)} label={'Throw error'} />\n\t\t\t</TldrawUiMenuGroup>\n\t\t\t<TldrawUiMenuGroup id=\"flags\">\n\t\t\t\t<DebugFlags />\n\t\t\t\t<FeatureFlags />\n\t\t\t</TldrawUiMenuGroup>\n\t\t</>\n\t)\n}\n/** @public @react */\nexport function DebugFlags() {\n\tconst items = Object.values(debugFlags)\n\tif (!items.length) return null\n\treturn (\n\t\t<TldrawUiMenuSubmenu id=\"debug flags\" label=\"Debug flags\">\n\t\t\t<TldrawUiMenuGroup id=\"debug flags\">\n\t\t\t\t{items.map((flag) => (\n\t\t\t\t\t<DebugFlagToggle key={flag.name} flag={flag} />\n\t\t\t\t))}\n\t\t\t</TldrawUiMenuGroup>\n\t\t</TldrawUiMenuSubmenu>\n\t)\n}\n/** @public @react */\nexport function FeatureFlags() {\n\tconst items = Object.values(featureFlags)\n\tif (!items.length) return null\n\treturn (\n\t\t<TldrawUiMenuSubmenu id=\"feature flags\" label=\"Feature flags\">\n\t\t\t<TldrawUiMenuGroup id=\"feature flags\">\n\t\t\t\t{items.map((flag) => (\n\t\t\t\t\t<DebugFlagToggle key={flag.name} flag={flag} />\n\t\t\t\t))}\n\t\t\t</TldrawUiMenuGroup>\n\t\t</TldrawUiMenuSubmenu>\n\t)\n}\n\n/** @public */\nexport interface ExampleDialogProps {\n\ttitle?: string\n\tbody?: React.ReactNode\n\tcancel?: string\n\tconfirm?: string\n\tdisplayDontShowAgain?: boolean\n\tmaxWidth?: string\n\tonCancel(): void\n\tonContinue(): void\n}\n\n/** @public @react */\nexport function ExampleDialog({\n\ttitle = 'title',\n\tbody = 'hello hello hello',\n\tcancel = 'Cancel',\n\tconfirm = 'Continue',\n\tdisplayDontShowAgain = false,\n\tmaxWidth = '350',\n\tonCancel,\n\tonContinue,\n}: ExampleDialogProps) {\n\tconst [dontShowAgain, setDontShowAgain] = React.useState(false)\n\n\treturn (\n\t\t<>\n\t\t\t<TldrawUiDialogHeader>\n\t\t\t\t<TldrawUiDialogTitle>{title}</TldrawUiDialogTitle>\n\t\t\t\t<TldrawUiDialogCloseButton />\n\t\t\t</TldrawUiDialogHeader>\n\t\t\t<TldrawUiDialogBody style={{ maxWidth }}>{body}</TldrawUiDialogBody>\n\t\t\t<TldrawUiDialogFooter className=\"tlui-dialog__footer__actions\">\n\t\t\t\t{displayDontShowAgain && (\n\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\ttype=\"normal\"\n\t\t\t\t\t\tonClick={() => setDontShowAgain(!dontShowAgain)}\n\t\t\t\t\t\tstyle={{ marginRight: 'auto' }}\n\t\t\t\t\t>\n\t\t\t\t\t\t<TldrawUiButtonCheck checked={dontShowAgain} />\n\t\t\t\t\t\t<TldrawUiButtonLabel>Don\u2019t show again</TldrawUiButtonLabel>\n\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t)}\n\t\t\t\t<TldrawUiButton type=\"normal\" onClick={onCancel}>\n\t\t\t\t\t<TldrawUiButtonLabel>{cancel}</TldrawUiButtonLabel>\n\t\t\t\t</TldrawUiButton>\n\t\t\t\t<TldrawUiButton type=\"primary\" onClick={async () => onContinue()}>\n\t\t\t\t\t<TldrawUiButtonLabel>{confirm}</TldrawUiButtonLabel>\n\t\t\t\t</TldrawUiButton>\n\t\t\t</TldrawUiDialogFooter>\n\t\t</>\n\t)\n}\n\nconst DebugFlagToggle = track(function DebugFlagToggle({\n\tflag,\n\tonChange,\n}: {\n\tflag: DebugFlag<boolean>\n\tonChange?(newValue: boolean): void\n}) {\n\tconst value = flag.get()\n\treturn (\n\t\t<TldrawUiMenuCheckboxItem\n\t\t\tid={flag.name}\n\t\t\ttitle={flag.name}\n\t\t\tlabel={flag.name\n\t\t\t\t.replace(/([a-z0-9])([A-Z])/g, (m) => `${m[0]} ${m[1].toLowerCase()}`)\n\t\t\t\t.replace(/^[a-z]/, (m) => m.toUpperCase())}\n\t\t\tchecked={value}\n\t\t\tonSelect={() => {\n\t\t\t\tflag.set(!value)\n\t\t\t\tonChange?.(!value)\n\t\t\t}}\n\t\t/>\n\t)\n})\n\nlet t = 0\n\nfunction createNShapes(editor: Editor, n: number) {\n\tconst gap = editor.options.adjacentShapeMargin\n\tconst shapesToCreate: TLShapePartial[] = Array(n)\n\tconst cols = Math.floor(Math.sqrt(n))\n\n\tfor (let i = 0; i < n; i++) {\n\t\tt++\n\t\tshapesToCreate[i] = {\n\t\t\tid: createShapeId('box' + t),\n\t\t\ttype: 'geo',\n\t\t\tx: (i % cols) * (100 + gap),\n\t\t\ty: Math.floor(i / cols) * (100 + gap),\n\t\t}\n\t}\n\n\teditor.run(() => {\n\t\t// allow this to trigger the max shapes alert\n\t\teditor.createShapes(shapesToCreate).setSelectedShapes(shapesToCreate.map((s) => s.id))\n\t})\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["DebugFlagToggle"]
|
|
7
7
|
}
|
|
@@ -348,11 +348,11 @@ function MoveToPageMenu() {
|
|
|
348
348
|
const toPage = editor.getPage(page.id);
|
|
349
349
|
if (toPage) {
|
|
350
350
|
addToast({
|
|
351
|
-
title: "Changed
|
|
351
|
+
title: "Changed page",
|
|
352
352
|
description: `Moved to ${toPage.name}.`,
|
|
353
353
|
actions: [
|
|
354
354
|
{
|
|
355
|
-
label: "Go
|
|
355
|
+
label: "Go back",
|
|
356
356
|
type: "primary",
|
|
357
357
|
onClick: () => {
|
|
358
358
|
editor.markHistoryStoppingPoint("change-page");
|