@tldraw/editor 4.3.0-next.82cfddd7ee89 → 4.3.0-next.842fb21476f2
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 +498 -155
- package/dist-cjs/index.js +6 -1
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/components/ErrorBoundary.js.map +1 -1
- package/dist-cjs/lib/components/GeometryDebuggingView.js +1 -17
- package/dist-cjs/lib/components/GeometryDebuggingView.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js +3 -3
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
- package/dist-cjs/lib/constants.js +1 -3
- package/dist-cjs/lib/constants.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +292 -286
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/bindings/BindingUtil.js.map +2 -2
- package/dist-cjs/lib/editor/derivations/bindingsIndex.js.map +2 -2
- package/dist-cjs/lib/editor/derivations/notVisibleShapes.js +18 -17
- package/dist-cjs/lib/editor/derivations/notVisibleShapes.js.map +3 -3
- package/dist-cjs/lib/editor/derivations/parentsToChildren.js +12 -3
- package/dist-cjs/lib/editor/derivations/parentsToChildren.js.map +2 -2
- package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js +1 -1
- package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js +5 -6
- package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js +591 -0
- package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js +1 -1
- package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/TickManager/TickManager.js +1 -22
- package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/BaseBoxShapeUtil.js.map +1 -1
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js +31 -23
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/group/DashedOutlineBox.js +1 -1
- package/dist-cjs/lib/editor/shapes/group/DashedOutlineBox.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.js.map +2 -2
- package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js +3 -3
- package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js.map +2 -2
- package/dist-cjs/lib/editor/types/emit-types.js.map +1 -1
- package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
- package/dist-cjs/lib/exports/parseCss.js +1 -1
- package/dist-cjs/lib/exports/parseCss.js.map +2 -2
- package/dist-cjs/lib/globals/environment.js +45 -9
- package/dist-cjs/lib/globals/environment.js.map +2 -2
- package/dist-cjs/lib/globals/menus.js +1 -1
- package/dist-cjs/lib/globals/menus.js.map +2 -2
- package/dist-cjs/lib/hooks/useCoarsePointer.js +14 -29
- package/dist-cjs/lib/hooks/useCoarsePointer.js.map +2 -2
- package/dist-cjs/lib/hooks/useEvent.js +1 -1
- package/dist-cjs/lib/hooks/useEvent.js.map +2 -2
- package/dist-cjs/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useGestureEvents.js +1 -1
- package/dist-cjs/lib/hooks/useGestureEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/usePassThroughMouseOverEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useScreenBounds.js.map +2 -2
- package/dist-cjs/lib/hooks/useStateAttribute.js +4 -1
- package/dist-cjs/lib/hooks/useStateAttribute.js.map +2 -2
- package/dist-cjs/lib/hooks/useTransform.js.map +1 -1
- package/dist-cjs/lib/hooks/useZoomCss.js +4 -8
- package/dist-cjs/lib/hooks/useZoomCss.js.map +2 -2
- package/dist-cjs/lib/options.js +6 -1
- package/dist-cjs/lib/options.js.map +2 -2
- package/dist-cjs/lib/primitives/Box.js +3 -0
- package/dist-cjs/lib/primitives/Box.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js +1 -0
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
- package/dist-cjs/lib/utils/reparenting.js.map +2 -2
- package/dist-cjs/lib/utils/rotation.js +1 -1
- package/dist-cjs/lib/utils/rotation.js.map +2 -2
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +498 -155
- package/dist-esm/index.mjs +7 -2
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/components/ErrorBoundary.mjs.map +1 -1
- package/dist-esm/lib/components/GeometryDebuggingView.mjs +1 -17
- package/dist-esm/lib/components/GeometryDebuggingView.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +3 -3
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
- package/dist-esm/lib/constants.mjs +1 -3
- package/dist-esm/lib/constants.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +293 -289
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/bindings/BindingUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/derivations/bindingsIndex.mjs.map +2 -2
- package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs +18 -17
- package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs.map +3 -3
- package/dist-esm/lib/editor/derivations/parentsToChildren.mjs +13 -4
- package/dist-esm/lib/editor/derivations/parentsToChildren.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs +1 -1
- package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs +5 -6
- package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs +573 -0
- package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs +1 -1
- package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs +1 -22
- package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/BaseBoxShapeUtil.mjs.map +1 -1
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +31 -23
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/group/DashedOutlineBox.mjs +1 -1
- package/dist-esm/lib/editor/shapes/group/DashedOutlineBox.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.mjs.map +2 -2
- package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs +3 -3
- package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
- package/dist-esm/lib/exports/parseCss.mjs +1 -1
- package/dist-esm/lib/exports/parseCss.mjs.map +2 -2
- package/dist-esm/lib/globals/environment.mjs +45 -9
- package/dist-esm/lib/globals/environment.mjs.map +2 -2
- package/dist-esm/lib/globals/menus.mjs +1 -1
- package/dist-esm/lib/globals/menus.mjs.map +2 -2
- package/dist-esm/lib/hooks/useCoarsePointer.mjs +15 -30
- package/dist-esm/lib/hooks/useCoarsePointer.mjs.map +2 -2
- package/dist-esm/lib/hooks/useEvent.mjs +1 -1
- package/dist-esm/lib/hooks/useEvent.mjs.map +2 -2
- package/dist-esm/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useGestureEvents.mjs +1 -1
- package/dist-esm/lib/hooks/useGestureEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/usePassThroughMouseOverEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useScreenBounds.mjs.map +2 -2
- package/dist-esm/lib/hooks/useStateAttribute.mjs +4 -1
- package/dist-esm/lib/hooks/useStateAttribute.mjs.map +2 -2
- package/dist-esm/lib/hooks/useTransform.mjs.map +1 -1
- package/dist-esm/lib/hooks/useZoomCss.mjs +4 -8
- package/dist-esm/lib/hooks/useZoomCss.mjs.map +2 -2
- package/dist-esm/lib/options.mjs +6 -1
- package/dist-esm/lib/options.mjs.map +2 -2
- package/dist-esm/lib/primitives/Box.mjs +3 -0
- package/dist-esm/lib/primitives/Box.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +1 -0
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
- package/dist-esm/lib/utils/reparenting.mjs.map +2 -2
- package/dist-esm/lib/utils/rotation.mjs +1 -1
- package/dist-esm/lib/utils/rotation.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +14 -12
- package/package.json +18 -16
- package/src/index.ts +4 -1
- package/src/lib/components/ErrorBoundary.tsx +1 -1
- package/src/lib/components/GeometryDebuggingView.tsx +1 -19
- package/src/lib/components/default-components/DefaultCanvas.tsx +4 -3
- package/src/lib/config/TLUserPreferences.test.ts +40 -0
- package/src/lib/constants.ts +0 -2
- package/src/lib/editor/Editor.test.ts +150 -10
- package/src/lib/editor/Editor.ts +459 -379
- package/src/lib/editor/bindings/BindingUtil.ts +15 -9
- package/src/lib/editor/derivations/bindingsIndex.ts +2 -2
- package/src/lib/editor/derivations/notVisibleShapes.ts +37 -23
- package/src/lib/editor/derivations/parentsToChildren.ts +18 -7
- package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +17 -31
- package/src/lib/editor/managers/ClickManager/ClickManager.ts +1 -1
- package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.test.ts +129 -79
- package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.ts +10 -6
- package/src/lib/editor/managers/FontManager/FontManager.test.ts +14 -4
- package/src/lib/editor/managers/InputsManager/InputsManager.ts +566 -0
- package/src/lib/editor/managers/ScribbleManager/ScribbleManager.test.ts +0 -4
- package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +12 -0
- package/src/lib/editor/managers/SnapManager/SnapManager.ts +4 -4
- package/src/lib/editor/managers/TickManager/TickManager.test.ts +40 -107
- package/src/lib/editor/managers/TickManager/TickManager.ts +2 -32
- package/src/lib/editor/shapes/BaseBoxShapeUtil.tsx +2 -2
- package/src/lib/editor/shapes/ShapeUtil.ts +72 -32
- package/src/lib/editor/shapes/group/DashedOutlineBox.tsx +1 -1
- package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +1 -3
- package/src/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.ts +2 -1
- package/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts +6 -6
- package/src/lib/editor/types/emit-types.ts +3 -1
- package/src/lib/exports/getSvgJsx.test.ts +10 -19
- package/src/lib/exports/getSvgJsx.tsx +2 -5
- package/src/lib/exports/parseCss.test.ts +1 -0
- package/src/lib/exports/parseCss.ts +1 -1
- package/src/lib/globals/environment.ts +65 -10
- package/src/lib/globals/menus.ts +1 -1
- package/src/lib/hooks/useCoarsePointer.ts +16 -59
- package/src/lib/hooks/useEvent.tsx +1 -1
- package/src/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.ts +1 -1
- package/src/lib/hooks/useGestureEvents.ts +2 -2
- package/src/lib/hooks/usePassThroughMouseOverEvents.ts +1 -1
- package/src/lib/hooks/usePassThroughWheelEvents.ts +1 -1
- package/src/lib/hooks/useScreenBounds.ts +1 -1
- package/src/lib/hooks/useStateAttribute.ts +4 -1
- package/src/lib/hooks/useTransform.ts +1 -1
- package/src/lib/hooks/useZoomCss.ts +3 -8
- package/src/lib/options.ts +32 -0
- package/src/lib/primitives/Box.ts +9 -0
- package/src/lib/primitives/geometry/Geometry2d.ts +1 -0
- package/src/lib/utils/reparenting.ts +5 -5
- package/src/lib/utils/rotation.ts +1 -1
- package/src/version.ts +3 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/editor/managers/SnapManager/SnapManager.ts"],
|
|
4
|
-
"sourcesContent": ["import { EMPTY_ARRAY, atom, computed } from '@tldraw/state'\nimport {
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA4C;AAC5C,
|
|
4
|
+
"sourcesContent": ["import { EMPTY_ARRAY, atom, computed } from '@tldraw/state'\nimport { TLParentId, TLShapeId, isShapeId } from '@tldraw/tlschema'\nimport { Vec, VecLike } from '../../../primitives/Vec'\nimport type { Editor } from '../../Editor'\nimport { BoundsSnaps } from './BoundsSnaps'\nimport { HandleSnaps } from './HandleSnaps'\n\n/** @public */\nexport interface PointsSnapIndicator {\n\tid: string\n\ttype: 'points'\n\tpoints: VecLike[]\n}\n\n/** @public */\nexport interface GapsSnapIndicator {\n\tid: string\n\ttype: 'gaps'\n\tdirection: 'horizontal' | 'vertical'\n\tgaps: Array<{\n\t\tstartEdge: [VecLike, VecLike]\n\t\tendEdge: [VecLike, VecLike]\n\t}>\n}\n\n/** @public */\nexport type SnapIndicator = PointsSnapIndicator | GapsSnapIndicator\n\n/** @public */\nexport interface SnapData {\n\tnudge: Vec\n}\n\n/** @public */\nexport class SnapManager {\n\treadonly shapeBounds: BoundsSnaps\n\treadonly handles: HandleSnaps\n\n\tprivate _snapIndicators = atom<SnapIndicator[] | undefined>('snapLines', undefined)\n\n\tconstructor(public readonly editor: Editor) {\n\t\tthis.shapeBounds = new BoundsSnaps(this)\n\t\tthis.handles = new HandleSnaps(this)\n\t}\n\n\tgetIndicators() {\n\t\treturn this._snapIndicators.get() ?? (EMPTY_ARRAY as SnapIndicator[])\n\t}\n\n\tclearIndicators() {\n\t\tif (this.getIndicators().length) {\n\t\t\tthis._snapIndicators.set(undefined)\n\t\t}\n\t}\n\n\tsetIndicators(indicators: SnapIndicator[]) {\n\t\tthis._snapIndicators.set(indicators)\n\t}\n\n\t@computed getSnapThreshold() {\n\t\treturn this.editor.options.snapThreshold / this.editor.getZoomLevel()\n\t}\n\n\t// TODO: make this an incremental derivation\n\t@computed getSnappableShapes(): Set<TLShapeId> {\n\t\tconst { editor } = this\n\t\tconst renderingBounds = editor.getViewportPageBounds()\n\t\tconst selectedShapeIds = editor.getSelectedShapeIds()\n\n\t\tconst snappableShapes: Set<TLShapeId> = new Set()\n\n\t\tconst collectSnappableShapesFromParent = (parentId: TLParentId) => {\n\t\t\tif (isShapeId(parentId)) {\n\t\t\t\tconst parent = editor.getShape(parentId)\n\t\t\t\tif (parent && editor.isShapeOfType(parent, 'frame')) {\n\t\t\t\t\tsnappableShapes.add(parentId)\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst sortedChildIds = editor.getSortedChildIdsForParent(parentId)\n\t\t\tfor (const childId of sortedChildIds) {\n\t\t\t\t// Skip any selected ids\n\t\t\t\tif (selectedShapeIds.includes(childId)) continue\n\t\t\t\tconst childShape = editor.getShape(childId)\n\t\t\t\tif (!childShape) continue\n\t\t\t\tconst util = editor.getShapeUtil(childShape)\n\t\t\t\t// Skip any shapes that don't allow snapping\n\t\t\t\tif (!util.canSnap(childShape)) continue\n\t\t\t\t// Only consider shapes if they're inside of the viewport page bounds\n\t\t\t\tconst pageBounds = editor.getShapePageBounds(childId)\n\t\t\t\tif (!(pageBounds && renderingBounds.includes(pageBounds))) continue\n\t\t\t\t// Snap to children of groups but not group itself\n\t\t\t\tif (editor.isShapeOfType(childShape, 'group')) {\n\t\t\t\t\tcollectSnappableShapesFromParent(childId)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tsnappableShapes.add(childId)\n\t\t\t}\n\t\t}\n\n\t\tcollectSnappableShapesFromParent(this.getCurrentCommonAncestor() ?? editor.getCurrentPageId())\n\n\t\treturn snappableShapes\n\t}\n\n\t// This needs to be external from any expensive work\n\t@computed getCurrentCommonAncestor() {\n\t\treturn this.editor.findCommonAncestor(this.editor.getSelectedShapes())\n\t}\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA4C;AAC5C,sBAAiD;AAGjD,yBAA4B;AAC5B,yBAA4B;AAL5B;AA2DC,yBAAC,wBAKD,2BAAC,wBAyCD,iCAAC;AAvEK,MAAM,YAAY;AAAA,EAMxB,YAA4B,QAAgB;AAAhB;AANtB;AACN,wBAAS;AACT,wBAAS;AAET,wBAAQ,uBAAkB,mBAAkC,aAAa,MAAS;AAGjF,SAAK,cAAc,IAAI,+BAAY,IAAI;AACvC,SAAK,UAAU,IAAI,+BAAY,IAAI;AAAA,EACpC;AAAA,EAEA,gBAAgB;AACf,WAAO,KAAK,gBAAgB,IAAI,KAAM;AAAA,EACvC;AAAA,EAEA,kBAAkB;AACjB,QAAI,KAAK,cAAc,EAAE,QAAQ;AAChC,WAAK,gBAAgB,IAAI,MAAS;AAAA,IACnC;AAAA,EACD;AAAA,EAEA,cAAc,YAA6B;AAC1C,SAAK,gBAAgB,IAAI,UAAU;AAAA,EACpC;AAAA,EAEU,mBAAmB;AAC5B,WAAO,KAAK,OAAO,QAAQ,gBAAgB,KAAK,OAAO,aAAa;AAAA,EACrE;AAAA,EAGU,qBAAqC;AAC9C,UAAM,EAAE,OAAO,IAAI;AACnB,UAAM,kBAAkB,OAAO,sBAAsB;AACrD,UAAM,mBAAmB,OAAO,oBAAoB;AAEpD,UAAM,kBAAkC,oBAAI,IAAI;AAEhD,UAAM,mCAAmC,CAAC,aAAyB;AAClE,cAAI,2BAAU,QAAQ,GAAG;AACxB,cAAM,SAAS,OAAO,SAAS,QAAQ;AACvC,YAAI,UAAU,OAAO,cAAc,QAAQ,OAAO,GAAG;AACpD,0BAAgB,IAAI,QAAQ;AAAA,QAC7B;AAAA,MACD;AACA,YAAM,iBAAiB,OAAO,2BAA2B,QAAQ;AACjE,iBAAW,WAAW,gBAAgB;AAErC,YAAI,iBAAiB,SAAS,OAAO,EAAG;AACxC,cAAM,aAAa,OAAO,SAAS,OAAO;AAC1C,YAAI,CAAC,WAAY;AACjB,cAAM,OAAO,OAAO,aAAa,UAAU;AAE3C,YAAI,CAAC,KAAK,QAAQ,UAAU,EAAG;AAE/B,cAAM,aAAa,OAAO,mBAAmB,OAAO;AACpD,YAAI,EAAE,cAAc,gBAAgB,SAAS,UAAU,GAAI;AAE3D,YAAI,OAAO,cAAc,YAAY,OAAO,GAAG;AAC9C,2CAAiC,OAAO;AACxC;AAAA,QACD;AACA,wBAAgB,IAAI,OAAO;AAAA,MAC5B;AAAA,IACD;AAEA,qCAAiC,KAAK,yBAAyB,KAAK,OAAO,iBAAiB,CAAC;AAE7F,WAAO;AAAA,EACR;AAAA,EAGU,2BAA2B;AACpC,WAAO,KAAK,OAAO,mBAAmB,KAAK,OAAO,kBAAkB,CAAC;AAAA,EACtE;AACD;AA1EO;AAyBI,gDAAV,uBAzBY;AA8BF,kDAAV,yBA9BY;AAuEF,wDAAV,+BAvEY;AAAN,2BAAM;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -68,7 +68,6 @@ __export(TickManager_exports, {
|
|
|
68
68
|
});
|
|
69
69
|
module.exports = __toCommonJS(TickManager_exports);
|
|
70
70
|
var import_utils = require("@tldraw/utils");
|
|
71
|
-
var import_Vec = require("../../../primitives/Vec");
|
|
72
71
|
var _dispose_dec, _tick_dec, _init;
|
|
73
72
|
const throttleToNextFrame = typeof process !== "undefined" && process.env.NODE_ENV === "test" ? (
|
|
74
73
|
// At test time we should use actual raf and not throttle, because throttle was set up to evaluate immediately during tests, which causes stack overflow
|
|
@@ -86,7 +85,6 @@ class TickManager {
|
|
|
86
85
|
__publicField(this, "cancelRaf");
|
|
87
86
|
__publicField(this, "isPaused", true);
|
|
88
87
|
__publicField(this, "now", 0);
|
|
89
|
-
__publicField(this, "prevPoint", new import_Vec.Vec());
|
|
90
88
|
this.editor.disposables.add(this.dispose);
|
|
91
89
|
this.start();
|
|
92
90
|
}
|
|
@@ -103,7 +101,7 @@ class TickManager {
|
|
|
103
101
|
const now = Date.now();
|
|
104
102
|
const elapsed = now - this.now;
|
|
105
103
|
this.now = now;
|
|
106
|
-
this.updatePointerVelocity(elapsed);
|
|
104
|
+
this.editor.inputs.updatePointerVelocity(elapsed);
|
|
107
105
|
this.editor.emit("frame", elapsed);
|
|
108
106
|
this.editor.emit("tick", elapsed);
|
|
109
107
|
this.cancelRaf = throttleToNextFrame(this.tick);
|
|
@@ -112,25 +110,6 @@ class TickManager {
|
|
|
112
110
|
this.isPaused = true;
|
|
113
111
|
this.cancelRaf?.();
|
|
114
112
|
}
|
|
115
|
-
updatePointerVelocity(elapsed) {
|
|
116
|
-
const {
|
|
117
|
-
prevPoint,
|
|
118
|
-
editor: {
|
|
119
|
-
inputs: { currentScreenPoint, pointerVelocity }
|
|
120
|
-
}
|
|
121
|
-
} = this;
|
|
122
|
-
if (elapsed === 0) return;
|
|
123
|
-
const delta = import_Vec.Vec.Sub(currentScreenPoint, prevPoint);
|
|
124
|
-
this.prevPoint = currentScreenPoint.clone();
|
|
125
|
-
const length = delta.len();
|
|
126
|
-
const direction = length ? delta.div(length) : new import_Vec.Vec(0, 0);
|
|
127
|
-
const next = pointerVelocity.clone().lrp(direction.mul(length / elapsed), 0.5);
|
|
128
|
-
if (Math.abs(next.x) < 0.01) next.x = 0;
|
|
129
|
-
if (Math.abs(next.y) < 0.01) next.y = 0;
|
|
130
|
-
if (!pointerVelocity.equals(next)) {
|
|
131
|
-
this.editor.inputs.pointerVelocity = next;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
113
|
}
|
|
135
114
|
_init = __decoratorStart(null);
|
|
136
115
|
__decorateElement(_init, 1, "tick", _tick_dec, TickManager);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/editor/managers/TickManager/TickManager.ts"],
|
|
4
|
-
"sourcesContent": ["import { throttleToNextFrame as _throttleToNextFrame, bind } from '@tldraw/utils'\nimport {
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkE;
|
|
4
|
+
"sourcesContent": ["import { throttleToNextFrame as _throttleToNextFrame, bind } from '@tldraw/utils'\nimport { Editor } from '../../Editor'\n\nconst throttleToNextFrame =\n\ttypeof process !== 'undefined' && process.env.NODE_ENV === 'test'\n\t\t? // At test time we should use actual raf and not throttle, because throttle was set up to evaluate immediately during tests, which causes stack overflow\n\t\t\t// for the tick manager since it sets up a raf loop.\n\t\t\tfunction mockThrottle(cb: any) {\n\t\t\t\t// eslint-disable-next-line no-restricted-globals\n\t\t\t\tconst frame = requestAnimationFrame(cb)\n\t\t\t\treturn () => cancelAnimationFrame(frame)\n\t\t\t}\n\t\t: _throttleToNextFrame\n\n/** @internal */\nexport class TickManager {\n\tconstructor(public editor: Editor) {\n\t\tthis.editor.disposables.add(this.dispose)\n\t\tthis.start()\n\t}\n\n\tcancelRaf?: null | (() => void)\n\tisPaused = true\n\tnow = 0\n\n\tstart() {\n\t\tthis.isPaused = false\n\t\tthis.cancelRaf?.()\n\t\tthis.cancelRaf = throttleToNextFrame(this.tick)\n\t\tthis.now = Date.now()\n\t}\n\n\t@bind\n\ttick() {\n\t\tif (this.isPaused) {\n\t\t\treturn\n\t\t}\n\n\t\tconst now = Date.now()\n\t\tconst elapsed = now - this.now\n\t\tthis.now = now\n\n\t\tthis.editor.inputs.updatePointerVelocity(elapsed)\n\t\tthis.editor.emit('frame', elapsed)\n\t\tthis.editor.emit('tick', elapsed)\n\t\tthis.cancelRaf = throttleToNextFrame(this.tick)\n\t}\n\n\t// Clear the listener\n\t@bind\n\tdispose() {\n\t\tthis.isPaused = true\n\n\t\tthis.cancelRaf?.()\n\t}\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkE;AAAlE;AAGA,MAAM,sBACL,OAAO,YAAY,eAAe,QAAQ,IAAI,aAAa;AAAA;AAAA;AAAA,EAGzD,SAAS,aAAa,IAAS;AAE9B,UAAM,QAAQ,sBAAsB,EAAE;AACtC,WAAO,MAAM,qBAAqB,KAAK;AAAA,EACxC;AAAA,IACC,aAAAA;AAoBH,aAAC,oBAiBD,gBAAC;AAlCK,MAAM,YAAY;AAAA,EACxB,YAAmB,QAAgB;AAAhB;AADb;AAMN;AACA,oCAAW;AACX,+BAAM;AANL,SAAK,OAAO,YAAY,IAAI,KAAK,OAAO;AACxC,SAAK,MAAM;AAAA,EACZ;AAAA,EAMA,QAAQ;AACP,SAAK,WAAW;AAChB,SAAK,YAAY;AACjB,SAAK,YAAY,oBAAoB,KAAK,IAAI;AAC9C,SAAK,MAAM,KAAK,IAAI;AAAA,EACrB;AAAA,EAGA,OAAO;AACN,QAAI,KAAK,UAAU;AAClB;AAAA,IACD;AAEA,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,UAAU,MAAM,KAAK;AAC3B,SAAK,MAAM;AAEX,SAAK,OAAO,OAAO,sBAAsB,OAAO;AAChD,SAAK,OAAO,KAAK,SAAS,OAAO;AACjC,SAAK,OAAO,KAAK,QAAQ,OAAO;AAChC,SAAK,YAAY,oBAAoB,KAAK,IAAI;AAAA,EAC/C;AAAA,EAIA,UAAU;AACT,SAAK,WAAW;AAEhB,SAAK,YAAY;AAAA,EAClB;AACD;AAxCO;AAkBN,oCADA,WAjBY;AAmCZ,uCADA,cAlCY;AAAN,2BAAM;",
|
|
6
6
|
"names": ["_throttleToNextFrame"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/editor/shapes/BaseBoxShapeUtil.tsx"],
|
|
4
|
-
"sourcesContent": ["import {
|
|
4
|
+
"sourcesContent": ["import { ExtractShapeByProps } from '@tldraw/tlschema'\nimport { lerp } from '@tldraw/utils'\nimport { Geometry2d } from '../../primitives/geometry/Geometry2d'\nimport { Rectangle2d } from '../../primitives/geometry/Rectangle2d'\nimport { HandleSnapGeometry } from '../managers/SnapManager/HandleSnaps'\nimport { ShapeUtil, TLResizeInfo } from './ShapeUtil'\nimport { resizeBox } from './shared/resizeBox'\n\n/** @public */\nexport type TLBaseBoxShape = ExtractShapeByProps<{ w: number; h: number }>\n\n/** @public */\nexport abstract class BaseBoxShapeUtil<Shape extends TLBaseBoxShape> extends ShapeUtil<Shape> {\n\tgetGeometry(shape: Shape): Geometry2d {\n\t\treturn new Rectangle2d({\n\t\t\twidth: shape.props.w,\n\t\t\theight: shape.props.h,\n\t\t\tisFilled: true,\n\t\t})\n\t}\n\n\toverride onResize(shape: any, info: TLResizeInfo<any>) {\n\t\treturn resizeBox(shape, info)\n\t}\n\n\toverride getHandleSnapGeometry(shape: Shape): HandleSnapGeometry {\n\t\treturn {\n\t\t\tpoints: this.getGeometry(shape).bounds.cornersAndCenter,\n\t\t}\n\t}\n\n\toverride getInterpolatedProps(startShape: Shape, endShape: Shape, t: number): Shape['props'] {\n\t\treturn {\n\t\t\t...endShape.props,\n\t\t\tw: lerp(startShape.props.w, endShape.props.w, t),\n\t\t\th: lerp(startShape.props.h, endShape.props.h, t),\n\t\t}\n\t}\n}\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAAqB;AAErB,yBAA4B;AAE5B,uBAAwC;AACxC,uBAA0B;AAMnB,MAAe,yBAAuD,2BAAiB;AAAA,EAC7F,YAAY,OAA0B;AACrC,WAAO,IAAI,+BAAY;AAAA,MACtB,OAAO,MAAM,MAAM;AAAA,MACnB,QAAQ,MAAM,MAAM;AAAA,MACpB,UAAU;AAAA,IACX,CAAC;AAAA,EACF;AAAA,EAES,SAAS,OAAY,MAAyB;AACtD,eAAO,4BAAU,OAAO,IAAI;AAAA,EAC7B;AAAA,EAES,sBAAsB,OAAkC;AAChE,WAAO;AAAA,MACN,QAAQ,KAAK,YAAY,KAAK,EAAE,OAAO;AAAA,IACxC;AAAA,EACD;AAAA,EAES,qBAAqB,YAAmB,UAAiB,GAA2B;AAC5F,WAAO;AAAA,MACN,GAAG,SAAS;AAAA,MACZ,OAAG,mBAAK,WAAW,MAAM,GAAG,SAAS,MAAM,GAAG,CAAC;AAAA,MAC/C,OAAG,mBAAK,WAAW,MAAM,GAAG,SAAS,MAAM,GAAG,CAAC;AAAA,IAChD;AAAA,EACD;AACD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -95,7 +95,7 @@ class ShapeUtil {
|
|
|
95
95
|
* @param shape - The shape.
|
|
96
96
|
* @public
|
|
97
97
|
*/
|
|
98
|
-
canSnap(
|
|
98
|
+
canSnap(shape) {
|
|
99
99
|
return true;
|
|
100
100
|
}
|
|
101
101
|
/**
|
|
@@ -104,7 +104,7 @@ class ShapeUtil {
|
|
|
104
104
|
* @param shape - The shape.
|
|
105
105
|
* @public
|
|
106
106
|
*/
|
|
107
|
-
canTabTo(
|
|
107
|
+
canTabTo(shape) {
|
|
108
108
|
return true;
|
|
109
109
|
}
|
|
110
110
|
/**
|
|
@@ -112,7 +112,7 @@ class ShapeUtil {
|
|
|
112
112
|
*
|
|
113
113
|
* @public
|
|
114
114
|
*/
|
|
115
|
-
canScroll(
|
|
115
|
+
canScroll(shape) {
|
|
116
116
|
return false;
|
|
117
117
|
}
|
|
118
118
|
/**
|
|
@@ -128,7 +128,7 @@ class ShapeUtil {
|
|
|
128
128
|
*
|
|
129
129
|
* @public
|
|
130
130
|
*/
|
|
131
|
-
canEdit(
|
|
131
|
+
canEdit(shape, info) {
|
|
132
132
|
return false;
|
|
133
133
|
}
|
|
134
134
|
/**
|
|
@@ -136,7 +136,7 @@ class ShapeUtil {
|
|
|
136
136
|
*
|
|
137
137
|
* @public
|
|
138
138
|
*/
|
|
139
|
-
canResize(
|
|
139
|
+
canResize(shape) {
|
|
140
140
|
return true;
|
|
141
141
|
}
|
|
142
142
|
/**
|
|
@@ -144,7 +144,7 @@ class ShapeUtil {
|
|
|
144
144
|
*
|
|
145
145
|
* @public
|
|
146
146
|
*/
|
|
147
|
-
canResizeChildren(
|
|
147
|
+
canResizeChildren(shape) {
|
|
148
148
|
return true;
|
|
149
149
|
}
|
|
150
150
|
/**
|
|
@@ -152,7 +152,15 @@ class ShapeUtil {
|
|
|
152
152
|
*
|
|
153
153
|
* @public
|
|
154
154
|
*/
|
|
155
|
-
canEditInReadonly(
|
|
155
|
+
canEditInReadonly(shape) {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Whether the shape can be edited while locked or while an ancestor is locked.
|
|
160
|
+
*
|
|
161
|
+
* @public
|
|
162
|
+
*/
|
|
163
|
+
canEditWhileLocked(shape) {
|
|
156
164
|
return false;
|
|
157
165
|
}
|
|
158
166
|
/**
|
|
@@ -160,7 +168,7 @@ class ShapeUtil {
|
|
|
160
168
|
*
|
|
161
169
|
* @public
|
|
162
170
|
*/
|
|
163
|
-
canCrop(
|
|
171
|
+
canCrop(shape) {
|
|
164
172
|
return false;
|
|
165
173
|
}
|
|
166
174
|
/**
|
|
@@ -172,7 +180,7 @@ class ShapeUtil {
|
|
|
172
180
|
*
|
|
173
181
|
* @public
|
|
174
182
|
*/
|
|
175
|
-
canBeLaidOut(
|
|
183
|
+
canBeLaidOut(shape, info) {
|
|
176
184
|
return true;
|
|
177
185
|
}
|
|
178
186
|
/**
|
|
@@ -182,7 +190,7 @@ class ShapeUtil {
|
|
|
182
190
|
*
|
|
183
191
|
* @param shape - The shape.
|
|
184
192
|
*/
|
|
185
|
-
canCull(
|
|
193
|
+
canCull(shape) {
|
|
186
194
|
return true;
|
|
187
195
|
}
|
|
188
196
|
/**
|
|
@@ -194,7 +202,7 @@ class ShapeUtil {
|
|
|
194
202
|
*
|
|
195
203
|
* @internal
|
|
196
204
|
*/
|
|
197
|
-
providesBackgroundForChildren(
|
|
205
|
+
providesBackgroundForChildren(shape) {
|
|
198
206
|
return false;
|
|
199
207
|
}
|
|
200
208
|
/**
|
|
@@ -202,7 +210,7 @@ class ShapeUtil {
|
|
|
202
210
|
*
|
|
203
211
|
* @public
|
|
204
212
|
*/
|
|
205
|
-
hideResizeHandles(
|
|
213
|
+
hideResizeHandles(shape) {
|
|
206
214
|
return false;
|
|
207
215
|
}
|
|
208
216
|
/**
|
|
@@ -210,7 +218,7 @@ class ShapeUtil {
|
|
|
210
218
|
*
|
|
211
219
|
* @public
|
|
212
220
|
*/
|
|
213
|
-
hideRotateHandle(
|
|
221
|
+
hideRotateHandle(shape) {
|
|
214
222
|
return false;
|
|
215
223
|
}
|
|
216
224
|
/**
|
|
@@ -218,7 +226,7 @@ class ShapeUtil {
|
|
|
218
226
|
*
|
|
219
227
|
* @public
|
|
220
228
|
*/
|
|
221
|
-
hideSelectionBoundsBg(
|
|
229
|
+
hideSelectionBoundsBg(shape) {
|
|
222
230
|
return false;
|
|
223
231
|
}
|
|
224
232
|
/**
|
|
@@ -226,7 +234,7 @@ class ShapeUtil {
|
|
|
226
234
|
*
|
|
227
235
|
* @public
|
|
228
236
|
*/
|
|
229
|
-
hideSelectionBoundsFg(
|
|
237
|
+
hideSelectionBoundsFg(shape) {
|
|
230
238
|
return false;
|
|
231
239
|
}
|
|
232
240
|
/**
|
|
@@ -234,7 +242,7 @@ class ShapeUtil {
|
|
|
234
242
|
*
|
|
235
243
|
* @public
|
|
236
244
|
*/
|
|
237
|
-
isAspectRatioLocked(
|
|
245
|
+
isAspectRatioLocked(shape) {
|
|
238
246
|
return false;
|
|
239
247
|
}
|
|
240
248
|
/**
|
|
@@ -244,10 +252,10 @@ class ShapeUtil {
|
|
|
244
252
|
* useful in cases like annotating on top of an image, where you usually want to avoid extra
|
|
245
253
|
* padding around the image if you don't need it.
|
|
246
254
|
*
|
|
247
|
-
* @param
|
|
255
|
+
* @param shape - The shape to check
|
|
248
256
|
* @returns True if this shape should be treated as an export bounds container
|
|
249
257
|
*/
|
|
250
|
-
isExportBoundsContainer(
|
|
258
|
+
isExportBoundsContainer(shape) {
|
|
251
259
|
return false;
|
|
252
260
|
}
|
|
253
261
|
/**
|
|
@@ -257,7 +265,7 @@ class ShapeUtil {
|
|
|
257
265
|
* @param type - The shape type.
|
|
258
266
|
* @public
|
|
259
267
|
*/
|
|
260
|
-
canReceiveNewChildrenOfType(
|
|
268
|
+
canReceiveNewChildrenOfType(shape, _type) {
|
|
261
269
|
return false;
|
|
262
270
|
}
|
|
263
271
|
/** @internal */
|
|
@@ -279,20 +287,20 @@ class ShapeUtil {
|
|
|
279
287
|
* Get the geometry to use when snapping to this this shape in translate/resize operations. See
|
|
280
288
|
* {@link BoundsSnapGeometry} for details.
|
|
281
289
|
*/
|
|
282
|
-
getBoundsSnapGeometry(
|
|
290
|
+
getBoundsSnapGeometry(shape) {
|
|
283
291
|
return {};
|
|
284
292
|
}
|
|
285
293
|
/**
|
|
286
294
|
* Get the geometry to use when snapping handles to this shape. See {@link HandleSnapGeometry}
|
|
287
295
|
* for details.
|
|
288
296
|
*/
|
|
289
|
-
getHandleSnapGeometry(
|
|
297
|
+
getHandleSnapGeometry(shape) {
|
|
290
298
|
return {};
|
|
291
299
|
}
|
|
292
|
-
getText(
|
|
300
|
+
getText(shape) {
|
|
293
301
|
return void 0;
|
|
294
302
|
}
|
|
295
|
-
getAriaDescriptor(
|
|
303
|
+
getAriaDescriptor(shape) {
|
|
296
304
|
return void 0;
|
|
297
305
|
}
|
|
298
306
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/editor/shapes/ShapeUtil.ts"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable @typescript-eslint/no-unused-vars */\nimport { EMPTY_ARRAY } from '@tldraw/state'\nimport { LegacyMigrations, MigrationSequence } from '@tldraw/store'\nimport {\n\tRecordProps,\n\tTLHandle,\n\tTLParentId,\n\tTLPropsMigrations,\n\tTLShape,\n\tTLShapeCrop,\n\tTLShapeId,\n\tTLShapePartial,\n\tTLUnknownShape,\n} from '@tldraw/tlschema'\nimport { IndexKey } from '@tldraw/utils'\nimport { ReactElement } from 'react'\nimport { Box, SelectionHandle } from '../../primitives/Box'\nimport { Vec } from '../../primitives/Vec'\nimport { Geometry2d } from '../../primitives/geometry/Geometry2d'\nimport type { Editor } from '../Editor'\nimport { TLFontFace } from '../managers/FontManager/FontManager'\nimport { BoundsSnapGeometry } from '../managers/SnapManager/BoundsSnaps'\nimport { HandleSnapGeometry } from '../managers/SnapManager/HandleSnaps'\nimport { SvgExportContext } from '../types/SvgExportContext'\nimport { TLClickEventInfo } from '../types/event-types'\nimport { TLResizeHandle } from '../types/selection-types'\n\n/** @public */\nexport interface TLShapeUtilConstructor<\n\tT extends TLUnknownShape,\n\tU extends ShapeUtil<T> = ShapeUtil<T>,\n> {\n\tnew (editor: Editor): U\n\ttype: T['type']\n\tprops?: RecordProps<T>\n\tmigrations?: LegacyMigrations | TLPropsMigrations | MigrationSequence\n}\n\n/**\n * Options passed to {@link ShapeUtil.canBind}. A binding that could be made. At least one of\n * `fromShapeType` or `toShapeType` will belong to this shape util.\n *\n * @public\n */\nexport interface TLShapeUtilCanBindOpts<Shape extends TLUnknownShape = TLUnknownShape> {\n\t/** The type of shape referenced by the `fromId` of the binding. */\n\tfromShapeType: string\n\t/** The type of shape referenced by the `toId` of the binding. */\n\ttoShapeType: string\n\t/** The type of binding. */\n\tbindingType: string\n}\n\n/**\n * Options passed to {@link ShapeUtil.canBeLaidOut}.\n *\n * @public\n */\nexport interface TLShapeUtilCanBeLaidOutOpts {\n\t/** The type of action causing the layout. */\n\ttype?: 'align' | 'distribute' | 'pack' | 'stack' | 'flip' | 'stretch'\n\t/** The other shapes being laid out */\n\tshapes?: TLShape[]\n}\n\n/** Additional options for the {@link ShapeUtil.getGeometry} method.\n *\n * @public\n */\nexport interface TLGeometryOpts {\n\t/** The context in which the geometry is being requested. */\n\tcontext?: string\n}\n\n/** @public */\nexport interface TLShapeUtilCanvasSvgDef {\n\tkey: string\n\tcomponent: React.ComponentType\n}\n\n/** @public */\nexport abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {\n\t/** Configure this shape utils {@link ShapeUtil.options | `options`}. */\n\tstatic configure<T extends TLShapeUtilConstructor<any, any>>(\n\t\tthis: T,\n\t\toptions: T extends new (...args: any[]) => { options: infer Options } ? Partial<Options> : never\n\t): T {\n\t\t// @ts-expect-error -- typescript has no idea what's going on here but it's fine\n\t\treturn class extends this {\n\t\t\t// @ts-expect-error\n\t\t\toptions = { ...this.options, ...options }\n\t\t}\n\t}\n\n\tconstructor(public editor: Editor) {}\n\n\t/**\n\t * Options for this shape util. If you're implementing a custom shape util, you can override\n\t * this to provide customization options for your shape. If using an existing shape util, you\n\t * can customizing this by calling {@link ShapeUtil.configure}.\n\t */\n\toptions = {}\n\n\t/**\n\t * Props allow you to define the shape's properties in a way that the editor can understand.\n\t * This has two main uses:\n\t *\n\t * 1. Validation. Shapes will be validated using these props to stop bad data from being saved.\n\t * 2. Styles. Each {@link @tldraw/tlschema#StyleProp} in the props can be set on many shapes at\n\t * once, and will be remembered from one shape to the next.\n\t *\n\t * @example\n\t * ```tsx\n\t * import {T, TLBaseShape, TLDefaultColorStyle, DefaultColorStyle, ShapeUtil} from 'tldraw'\n\t *\n\t * type MyShape = TLBaseShape<'mine', {\n\t * color: TLDefaultColorStyle,\n\t * text: string,\n\t * }>\n\t *\n\t * class MyShapeUtil extends ShapeUtil<MyShape> {\n\t * static props = {\n\t * // we use tldraw's built-in color style:\n\t * color: DefaultColorStyle,\n\t * // validate that the text prop is a string:\n\t * text: T.string,\n\t * }\n\t * }\n\t * ```\n\t */\n\tstatic props?: RecordProps<TLUnknownShape>\n\n\t/**\n\t * Migrations allow you to make changes to a shape's props over time. Read the\n\t * {@link https://www.tldraw.dev/docs/persistence#Shape-props-migrations | shape prop migrations}\n\t * guide for more information.\n\t */\n\tstatic migrations?: LegacyMigrations | TLPropsMigrations | MigrationSequence\n\n\t/**\n\t * The type of the shape util, which should match the shape's type.\n\t *\n\t * @public\n\t */\n\tstatic type: string\n\n\t/**\n\t * Get the default props for a shape.\n\t *\n\t * @public\n\t */\n\tabstract getDefaultProps(): Shape['props']\n\n\t/**\n\t * Get the shape's geometry.\n\t *\n\t * @param shape - The shape.\n\t * @param opts - Additional options for the request.\n\t * @public\n\t */\n\tabstract getGeometry(shape: Shape, opts?: TLGeometryOpts): Geometry2d\n\n\t/**\n\t * Get a JSX element for the shape (as an HTML element).\n\t *\n\t * @param shape - The shape.\n\t * @public\n\t */\n\tabstract component(shape: Shape): any\n\n\t/**\n\t * Get JSX describing the shape's indicator (as an SVG element).\n\t *\n\t * @param shape - The shape.\n\t * @public\n\t */\n\tabstract indicator(shape: Shape): any\n\n\t/**\n\t * Get the font faces that should be rendered in the document in order for this shape to render\n\t * correctly.\n\t *\n\t * @param shape - The shape.\n\t * @public\n\t */\n\tgetFontFaces(shape: Shape): TLFontFace[] {\n\t\treturn EMPTY_ARRAY\n\t}\n\n\t/**\n\t * Whether the shape can be snapped to by another shape.\n\t *\n\t * @param shape - The shape.\n\t * @public\n\t */\n\tcanSnap(_shape: Shape): boolean {\n\t\treturn true\n\t}\n\n\t/**\n\t * Whether the shape can be tabbed to.\n\t *\n\t * @param shape - The shape.\n\t * @public\n\t */\n\tcanTabTo(_shape: Shape): boolean {\n\t\treturn true\n\t}\n\n\t/**\n\t * Whether the shape can be scrolled while editing.\n\t *\n\t * @public\n\t */\n\tcanScroll(_shape: Shape): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * Whether the shape can be bound to. See {@link TLShapeUtilCanBindOpts} for details.\n\t *\n\t * @public\n\t */\n\tcanBind(_opts: TLShapeUtilCanBindOpts): boolean {\n\t\treturn true\n\t}\n\n\t/**\n\t * Whether the shape can be double clicked to edit.\n\t *\n\t * @public\n\t */\n\tcanEdit(_shape: Shape): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * Whether the shape can be resized.\n\t *\n\t * @public\n\t */\n\tcanResize(_shape: Shape): boolean {\n\t\treturn true\n\t}\n\n\t/**\n\t * When the shape is resized, whether the shape's children should also be resized.\n\t *\n\t * @public\n\t */\n\tcanResizeChildren(_shape: Shape): boolean {\n\t\treturn true\n\t}\n\n\t/**\n\t * Whether the shape can be edited in read-only mode.\n\t *\n\t * @public\n\t */\n\tcanEditInReadonly(_shape: Shape): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * Whether the shape can be cropped.\n\t *\n\t * @public\n\t */\n\tcanCrop(_shape: Shape): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * Whether the shape can participate in layout functions such as alignment or distribution.\n\t *\n\t * @param shape - The shape.\n\t * @param info - Additional context information: the type of action causing the layout and the\n\t * @public\n\t *\n\t * @public\n\t */\n\tcanBeLaidOut(_shape: Shape, _info: TLShapeUtilCanBeLaidOutOpts): boolean {\n\t\treturn true\n\t}\n\n\t/**\n\t * Whether this shape can be culled. By default, shapes are culled for\n\t * performance reasons when they are outside of the viewport. Culled shapes are still rendered\n\t * to the DOM, but have their `display` property set to `none`.\n\t *\n\t * @param shape - The shape.\n\t */\n\tcanCull(_shape: Shape): boolean {\n\t\treturn true\n\t}\n\n\t/**\n\t * Does this shape provide a background for its children? If this is true,\n\t * then any children with a `renderBackground` method will have their\n\t * backgrounds rendered _above_ this shape. Otherwise, the children's\n\t * backgrounds will be rendered above either the next ancestor that provides\n\t * a background, or the canvas background.\n\t *\n\t * @internal\n\t */\n\tprovidesBackgroundForChildren(_shape: Shape): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * Get the clip path to apply to this shape's children.\n\t *\n\t * @param shape - The shape to get the clip path for\n\t * @returns Array of points defining the clipping polygon in local coordinates, or undefined if no clipping\n\t * @public\n\t */\n\tgetClipPath?(shape: Shape): Vec[] | undefined\n\n\t/**\n\t * Whether a specific child shape should be clipped by this shape.\n\t * Only called if getClipPath returns a valid polygon.\n\t *\n\t * If not defined, the default behavior is to clip all children.\n\t *\n\t * @param child - The child shape to check\n\t * @returns boolean indicating if this child should be clipped\n\t * @public\n\t */\n\tshouldClipChild?(child: TLShape): boolean\n\n\t/**\n\t * Whether a specific shape should hide in the minimap.\n\t *\n\t * If not defined, the default behavior is to show all shapes in the minimap.\n\t *\n\t * @returns boolean indicating if this shape should hide in the minimap\n\t * @public\n\t */\n\thideInMinimap?(_shape: Shape): boolean\n\n\t/**\n\t * Whether the shape should hide its resize handles when selected.\n\t *\n\t * @public\n\t */\n\thideResizeHandles(_shape: Shape): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * Whether the shape should hide its rotation handles when selected.\n\t *\n\t * @public\n\t */\n\thideRotateHandle(_shape: Shape): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * Whether the shape should hide its selection bounds background when selected.\n\t *\n\t * @public\n\t */\n\thideSelectionBoundsBg(_shape: Shape): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * Whether the shape should hide its selection bounds foreground when selected.\n\t *\n\t * @public\n\t */\n\thideSelectionBoundsFg(_shape: Shape): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * Whether the shape's aspect ratio is locked.\n\t *\n\t * @public\n\t */\n\tisAspectRatioLocked(_shape: Shape): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * By default, the bounds of an image export are the bounds of all the shapes it contains, plus\n\t * some padding. If an export includes a shape where `isExportBoundsContainer` is true, then the\n\t * padding is skipped _if the bounds of that shape contains all the other shapes_. This is\n\t * useful in cases like annotating on top of an image, where you usually want to avoid extra\n\t * padding around the image if you don't need it.\n\t *\n\t * @param _shape - The shape to check\n\t * @returns True if this shape should be treated as an export bounds container\n\t */\n\tisExportBoundsContainer(_shape: Shape): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * Get a JSX element for the shape (as an HTML element) to be rendered as part of the canvas background - behind any other shape content.\n\t *\n\t * @param shape - The shape.\n\t * @internal\n\t */\n\tbackgroundComponent?(shape: Shape): any\n\n\t/**\n\t * Get the interpolated props for an animating shape. This is an optional method.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * util.getInterpolatedProps?.(startShape, endShape, t)\n\t * ```\n\t *\n\t * @param startShape - The initial shape.\n\t * @param endShape - The initial shape.\n\t * @param progress - The normalized progress between zero (start) and 1 (end).\n\t * @public\n\t */\n\tgetInterpolatedProps?(startShape: Shape, endShape: Shape, progress: number): Shape['props']\n\n\t/**\n\t * Get an array of handle models for the shape. This is an optional method.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * util.getHandles?.(myShape)\n\t * ```\n\t *\n\t * @param shape - The shape.\n\t * @public\n\t */\n\tgetHandles?(shape: Shape): TLHandle[]\n\n\t/**\n\t * Get whether the shape can receive children of a given type.\n\t *\n\t * @param shape - The shape.\n\t * @param type - The shape type.\n\t * @public\n\t */\n\tcanReceiveNewChildrenOfType(_shape: Shape, _type: TLShape['type']) {\n\t\treturn false\n\t}\n\n\t/**\n\t * Get the shape as an SVG object.\n\t *\n\t * @param shape - The shape.\n\t * @param ctx - The export context for the SVG - used for adding e.g. \\<def\\>s\n\t * @returns An SVG element.\n\t * @public\n\t */\n\ttoSvg?(shape: Shape, ctx: SvgExportContext): ReactElement | null | Promise<ReactElement | null>\n\n\t/**\n\t * Get the shape's background layer as an SVG object.\n\t *\n\t * @param shape - The shape.\n\t * @param ctx - ctx - The export context for the SVG - used for adding e.g. \\<def\\>s\n\t * @returns An SVG element.\n\t * @public\n\t */\n\ttoBackgroundSvg?(\n\t\tshape: Shape,\n\t\tctx: SvgExportContext\n\t): ReactElement | null | Promise<ReactElement | null>\n\n\t/** @internal */\n\texpandSelectionOutlinePx(shape: Shape): number | Box {\n\t\treturn 0\n\t}\n\n\t/**\n\t * Return elements to be added to the \\<defs\\> section of the canvases SVG context. This can be\n\t * used to define SVG content (e.g. patterns & masks) that can be referred to by ID from svg\n\t * elements returned by `component`.\n\t *\n\t * Each def should have a unique `key`. If multiple defs from different shapes all have the same\n\t * key, only one will be used.\n\t */\n\tgetCanvasSvgDefs(): TLShapeUtilCanvasSvgDef[] {\n\t\treturn []\n\t}\n\n\t/**\n\t * Get the geometry to use when snapping to this this shape in translate/resize operations. See\n\t * {@link BoundsSnapGeometry} for details.\n\t */\n\tgetBoundsSnapGeometry(_shape: Shape): BoundsSnapGeometry {\n\t\treturn {}\n\t}\n\n\t/**\n\t * Get the geometry to use when snapping handles to this shape. See {@link HandleSnapGeometry}\n\t * for details.\n\t */\n\tgetHandleSnapGeometry(_shape: Shape): HandleSnapGeometry {\n\t\treturn {}\n\t}\n\n\tgetText(_shape: Shape): string | undefined {\n\t\treturn undefined\n\t}\n\n\tgetAriaDescriptor(_shape: Shape): string | undefined {\n\t\treturn undefined\n\t}\n\n\t// Events\n\n\t/**\n\t * A callback called just before a shape is created. This method provides a last chance to modify\n\t * the created shape.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * onBeforeCreate = (next) => {\n\t * \treturn { ...next, x: next.x + 1 }\n\t * }\n\t * ```\n\t *\n\t * @param next - The next shape.\n\t * @returns The next shape or void.\n\t * @public\n\t */\n\tonBeforeCreate?(next: Shape): Shape | void\n\n\t/**\n\t * A callback called just before a shape is updated. This method provides a last chance to modify\n\t * the updated shape.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * onBeforeUpdate = (prev, next) => {\n\t * \tif (prev.x === next.x) {\n\t * \t\treturn { ...next, x: next.x + 1 }\n\t * \t}\n\t * }\n\t * ```\n\t *\n\t * @param prev - The previous shape.\n\t * @param next - The next shape.\n\t * @returns The next shape or void.\n\t * @public\n\t */\n\tonBeforeUpdate?(prev: Shape, next: Shape): Shape | void\n\n\t/**\n\t * A callback called when a shape changes from a crop.\n\t *\n\t * @param shape - The shape at the start of the crop.\n\t * @param info - Info about the crop.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonCrop?(\n\t\tshape: Shape,\n\t\tinfo: TLCropInfo<Shape>\n\t): Omit<TLShapePartial<Shape>, 'id' | 'type'> | undefined | void\n\n\t/**\n\t * A callback called when some other shapes are dragged into this one. This fires when the shapes are dragged over the shape for the first time.\n\t *\n\t * @param shape - The shape.\n\t * @param shapes - The shapes that are being dragged in.\n\t * @public\n\t */\n\tonDragShapesIn?(shape: Shape, shapes: TLShape[], info: TLDragShapesInInfo): void\n\n\t/**\n\t * A callback called when some other shapes are dragged over this one. This fires when the shapes are dragged over the shape for the first time (after the onDragShapesIn callback), and again on every update while the shapes are being dragged.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * onDragShapesOver = (shape, shapes) => {\n\t * \tthis.editor.reparentShapes(shapes, shape.id)\n\t * }\n\t * ```\n\t *\n\t * @param shape - The shape.\n\t * @param shapes - The shapes that are being dragged over this one.\n\t * @public\n\t */\n\tonDragShapesOver?(shape: Shape, shapes: TLShape[], info: TLDragShapesOverInfo): void\n\n\t/**\n\t * A callback called when some other shapes are dragged out of this one.\n\t *\n\t * @param shape - The shape.\n\t * @param shapes - The shapes that are being dragged out.\n\t * @public\n\t */\n\tonDragShapesOut?(shape: Shape, shapes: TLShape[], info: TLDragShapesOutInfo): void\n\n\t/**\n\t * A callback called when some other shapes are dropped over this one.\n\t *\n\t * @param shape - The shape.\n\t * @param shapes - The shapes that are being dropped over this one.\n\t * @public\n\t */\n\tonDropShapesOver?(shape: Shape, shapes: TLShape[], info: TLDropShapesOverInfo): void\n\n\t/**\n\t * A callback called when a shape starts being resized.\n\t *\n\t * @param shape - The shape.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonResizeStart?(shape: Shape): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape changes from a resize.\n\t *\n\t * @param shape - The shape at the start of the resize.\n\t * @param info - Info about the resize.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonResize?(\n\t\tshape: Shape,\n\t\tinfo: TLResizeInfo<Shape>\n\t): Omit<TLShapePartial<Shape>, 'id' | 'type'> | undefined | void\n\n\t/**\n\t * A callback called when a shape finishes resizing.\n\t *\n\t * @param initial - The shape at the start of the resize.\n\t * @param current - The current shape.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonResizeEnd?(initial: Shape, current: Shape): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape resize is cancelled.\n\t *\n\t * @param initial - The shape at the start of the resize.\n\t * @param current - The current shape.\n\t * @public\n\t */\n\tonResizeCancel?(initial: Shape, current: Shape): void\n\n\t/**\n\t * A callback called when a shape starts being translated.\n\t *\n\t * @param shape - The shape.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonTranslateStart?(shape: Shape): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape changes from a translation.\n\t *\n\t * @param initial - The shape at the start of the translation.\n\t * @param current - The current shape.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonTranslate?(initial: Shape, current: Shape): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape finishes translating.\n\t *\n\t * @param initial - The shape at the start of the translation.\n\t * @param current - The current shape.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonTranslateEnd?(initial: Shape, current: Shape): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape translation is cancelled.\n\t *\n\t * @param initial - The shape at the start of the translation.\n\t * @param current - The current shape.\n\t * @public\n\t */\n\tonTranslateCancel?(initial: Shape, current: Shape): void\n\n\t/**\n\t * A callback called when a shape's handle starts being dragged.\n\t *\n\t * @param shape - The shape.\n\t * @param info - An object containing the handle and whether the handle is 'precise' or not.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonHandleDragStart?(shape: Shape, info: TLHandleDragInfo<Shape>): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape's handle changes.\n\t *\n\t * @param shape - The current shape.\n\t * @param info - An object containing the handle and whether the handle is 'precise' or not.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonHandleDrag?(shape: Shape, info: TLHandleDragInfo<Shape>): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape's handle finishes being dragged.\n\t *\n\t * @param current - The current shape.\n\t * @param info - An object containing the handle and whether the handle is 'precise' or not.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonHandleDragEnd?(current: Shape, info: TLHandleDragInfo<Shape>): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape's handle drag is cancelled.\n\t *\n\t * @param current - The current shape.\n\t * @param info - An object containing the handle and whether the handle is 'precise' or not.\n\t * @public\n\t */\n\tonHandleDragCancel?(current: Shape, info: TLHandleDragInfo<Shape>): void\n\n\t/**\n\t * A callback called when a shape starts being rotated.\n\t *\n\t * @param shape - The shape.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonRotateStart?(shape: Shape): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape changes from a rotation.\n\t *\n\t * @param initial - The shape at the start of the rotation.\n\t * @param current - The current shape.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonRotate?(initial: Shape, current: Shape): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape finishes rotating.\n\t *\n\t * @param initial - The shape at the start of the rotation.\n\t * @param current - The current shape.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonRotateEnd?(initial: Shape, current: Shape): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape rotation is cancelled.\n\t *\n\t * @param initial - The shape at the start of the rotation.\n\t * @param current - The current shape.\n\t * @public\n\t */\n\tonRotateCancel?(initial: Shape, current: Shape): void\n\n\t/**\n\t * Not currently used.\n\t *\n\t * @internal\n\t */\n\tonBindingChange?(shape: Shape): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape's children change.\n\t *\n\t * @param shape - The shape.\n\t * @returns An array of shape updates, or void.\n\t * @public\n\t */\n\tonChildrenChange?(shape: Shape): TLShapePartial[] | void\n\n\t/**\n\t * A callback called when a shape's handle is double clicked.\n\t *\n\t * @param shape - The shape.\n\t * @param handle - The handle that is double-clicked.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonDoubleClickHandle?(shape: Shape, handle: TLHandle): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape's edge is double clicked.\n\t *\n\t * @param shape - The shape.\n\t * @param info - Info about the edge.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonDoubleClickEdge?(shape: Shape, info: TLClickEventInfo): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape's corner is double clicked.\n\t *\n\t * @param shape - The shape.\n\t * @param info - Info about the corner.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonDoubleClickCorner?(shape: Shape, info: TLClickEventInfo): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape is double clicked.\n\t *\n\t * @param shape - The shape.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonDoubleClick?(shape: Shape): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape is clicked.\n\t *\n\t * @param shape - The shape.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonClick?(shape: Shape): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape starts being edited.\n\t *\n\t * @param shape - The shape.\n\t * @public\n\t */\n\tonEditStart?(shape: Shape): void\n\n\t/**\n\t * A callback called when a shape finishes being edited.\n\t *\n\t * @param shape - The shape.\n\t * @public\n\t */\n\tonEditEnd?(shape: Shape): void\n}\n\n/**\n * Info about a crop.\n * @param handle - The handle being dragged.\n * @param change - The distance the handle is moved.\n * @param initialShape - The shape at the start of the resize.\n * @public\n */\nexport interface TLCropInfo<T extends TLShape> {\n\thandle: SelectionHandle\n\tchange: Vec\n\tcrop: TLShapeCrop\n\tuncroppedSize: { w: number; h: number }\n\tinitialShape: T\n\taspectRatioLocked?: boolean\n}\n\n/** @public */\nexport interface TLDragShapesInInfo {\n\tinitialDraggingOverShapeId: TLShapeId | null\n\tprevDraggingOverShapeId: TLShapeId | null\n\tinitialParentIds: Map<TLShapeId, TLParentId>\n\tinitialIndices: Map<TLShapeId, IndexKey>\n}\n\n/** @public */\nexport interface TLDragShapesOverInfo {\n\tinitialDraggingOverShapeId: TLShapeId | null\n\tinitialParentIds: Map<TLShapeId, TLParentId>\n\tinitialIndices: Map<TLShapeId, IndexKey>\n}\n\n/** @public */\nexport interface TLDragShapesOutInfo {\n\tnextDraggingOverShapeId: TLShapeId | null\n\tinitialDraggingOverShapeId: TLShapeId | null\n\tinitialParentIds: Map<TLShapeId, TLParentId>\n\tinitialIndices: Map<TLShapeId, IndexKey>\n}\n\n/** @public */\nexport interface TLDropShapesOverInfo {\n\tinitialDraggingOverShapeId: TLShapeId | null\n\tinitialParentIds: Map<TLShapeId, TLParentId>\n\tinitialIndices: Map<TLShapeId, IndexKey>\n}\n\n/**\n * The type of resize.\n *\n * 'scale_shape' - The shape is being scaled, usually as part of a larger selection.\n *\n * 'resize_bounds' - The user is directly manipulating an individual shape's bounds using a resize\n * handle. It is up to shape util implementers to decide how they want to handle the two\n * situations.\n *\n * @public\n */\nexport type TLResizeMode = 'scale_shape' | 'resize_bounds'\n\n/**\n * Info about a resize.\n * @param newPoint - The new local position of the shape.\n * @param handle - The handle being dragged.\n * @param mode - The type of resize.\n * @param scaleX - The scale in the x-axis.\n * @param scaleY - The scale in the y-axis.\n * @param initialBounds - The bounds of the shape at the start of the resize.\n * @param initialShape - The shape at the start of the resize.\n * @public\n */\nexport interface TLResizeInfo<T extends TLShape> {\n\tnewPoint: Vec\n\thandle: TLResizeHandle\n\tmode: TLResizeMode\n\tscaleX: number\n\tscaleY: number\n\tinitialBounds: Box\n\tinitialShape: T\n}\n\n/* -------------------- Dragging -------------------- */\n\n/** @public */\nexport interface TLHandleDragInfo<T extends TLShape> {\n\thandle: TLHandle\n\tisPrecise: boolean\n\tisCreatingShape: boolean\n\tinitial?: T | undefined\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAA4B;
|
|
4
|
+
"sourcesContent": ["/* eslint-disable @typescript-eslint/no-unused-vars */\nimport { EMPTY_ARRAY } from '@tldraw/state'\nimport { LegacyMigrations, MigrationSequence } from '@tldraw/store'\nimport {\n\tRecordProps,\n\tTLHandle,\n\tTLParentId,\n\tTLPropsMigrations,\n\tTLShape,\n\tTLShapeCrop,\n\tTLShapeId,\n\tTLShapePartial,\n\tTLUnknownShape,\n} from '@tldraw/tlschema'\nimport { IndexKey } from '@tldraw/utils'\nimport { ReactElement } from 'react'\nimport { Box, SelectionHandle } from '../../primitives/Box'\nimport { Vec } from '../../primitives/Vec'\nimport { Geometry2d } from '../../primitives/geometry/Geometry2d'\nimport type { Editor } from '../Editor'\nimport { TLFontFace } from '../managers/FontManager/FontManager'\nimport { BoundsSnapGeometry } from '../managers/SnapManager/BoundsSnaps'\nimport { HandleSnapGeometry } from '../managers/SnapManager/HandleSnaps'\nimport { SvgExportContext } from '../types/SvgExportContext'\nimport { TLClickEventInfo } from '../types/event-types'\nimport { TLResizeHandle } from '../types/selection-types'\n\n/** @public */\nexport interface TLShapeUtilConstructor<T extends TLShape, U extends ShapeUtil<T> = ShapeUtil<T>> {\n\tnew (editor: Editor): U\n\ttype: T['type']\n\tprops?: RecordProps<T>\n\tmigrations?: LegacyMigrations | TLPropsMigrations | MigrationSequence\n}\n\n/**\n * Options passed to {@link ShapeUtil.canBind}. A binding that could be made. At least one of\n * `fromShapeType` or `toShapeType` will belong to this shape util.\n *\n * @public\n */\nexport interface TLShapeUtilCanBindOpts<Shape extends TLShape = TLShape> {\n\t/** The type of shape referenced by the `fromId` of the binding. */\n\tfromShapeType: TLShape['type']\n\t/** The type of shape referenced by the `toId` of the binding. */\n\ttoShapeType: TLShape['type']\n\t/** The type of binding. */\n\tbindingType: string\n}\n\n/**\n * Options passed to {@link ShapeUtil.canBeLaidOut}.\n *\n * @public\n */\nexport interface TLShapeUtilCanBeLaidOutOpts {\n\t/** The type of action causing the layout. */\n\ttype?: 'align' | 'distribute' | 'pack' | 'stack' | 'flip' | 'stretch'\n\t/** The other shapes being laid out */\n\tshapes?: TLShape[]\n}\n\n/** Additional options for the {@link ShapeUtil.getGeometry} method.\n *\n * @public\n */\nexport interface TLGeometryOpts {\n\t/** The context in which the geometry is being requested. */\n\tcontext?: string\n}\n\n/** @public */\nexport interface TLShapeUtilCanvasSvgDef {\n\tkey: string\n\tcomponent: React.ComponentType\n}\n\n/** @public */\nexport abstract class ShapeUtil<Shape extends TLShape = TLShape> {\n\t/** Configure this shape utils {@link ShapeUtil.options | `options`}. */\n\tstatic configure<T extends TLShapeUtilConstructor<any, any>>(\n\t\tthis: T,\n\t\toptions: T extends new (...args: any[]) => { options: infer Options } ? Partial<Options> : never\n\t): T {\n\t\t// @ts-expect-error -- typescript has no idea what's going on here but it's fine\n\t\treturn class extends this {\n\t\t\t// @ts-expect-error\n\t\t\toptions = { ...this.options, ...options }\n\t\t}\n\t}\n\n\tconstructor(public editor: Editor) {}\n\n\t/**\n\t * Options for this shape util. If you're implementing a custom shape util, you can override\n\t * this to provide customization options for your shape. If using an existing shape util, you\n\t * can customizing this by calling {@link ShapeUtil.configure}.\n\t */\n\toptions = {}\n\n\t/**\n\t * Props allow you to define the shape's properties in a way that the editor can understand.\n\t * This has two main uses:\n\t *\n\t * 1. Validation. Shapes will be validated using these props to stop bad data from being saved.\n\t * 2. Styles. Each {@link @tldraw/tlschema#StyleProp} in the props can be set on many shapes at\n\t * once, and will be remembered from one shape to the next.\n\t *\n\t * @example\n\t * ```tsx\n\t * import {T, TLBaseShape, TLDefaultColorStyle, DefaultColorStyle, ShapeUtil} from 'tldraw'\n\t *\n\t * type MyShape = TLBaseShape<'mine', {\n\t * color: TLDefaultColorStyle,\n\t * text: string,\n\t * }>\n\t *\n\t * class MyShapeUtil extends ShapeUtil<MyShape> {\n\t * static props = {\n\t * // we use tldraw's built-in color style:\n\t * color: DefaultColorStyle,\n\t * // validate that the text prop is a string:\n\t * text: T.string,\n\t * }\n\t * }\n\t * ```\n\t */\n\tstatic props?: RecordProps<TLUnknownShape>\n\n\t/**\n\t * Migrations allow you to make changes to a shape's props over time. Read the\n\t * {@link https://www.tldraw.dev/docs/persistence#Shape-props-migrations | shape prop migrations}\n\t * guide for more information.\n\t */\n\tstatic migrations?: LegacyMigrations | TLPropsMigrations | MigrationSequence\n\n\t/**\n\t * The type of the shape util, which should match the shape's type.\n\t *\n\t * @public\n\t */\n\tstatic type: string\n\n\t/**\n\t * Get the default props for a shape.\n\t *\n\t * @public\n\t */\n\tabstract getDefaultProps(): Shape['props']\n\n\t/**\n\t * Get the shape's geometry.\n\t *\n\t * @param shape - The shape.\n\t * @param opts - Additional options for the request.\n\t * @public\n\t */\n\tabstract getGeometry(shape: Shape, opts?: TLGeometryOpts): Geometry2d\n\n\t/**\n\t * Get a JSX element for the shape (as an HTML element).\n\t *\n\t * @param shape - The shape.\n\t * @public\n\t */\n\tabstract component(shape: Shape): any\n\n\t/**\n\t * Get JSX describing the shape's indicator (as an SVG element).\n\t *\n\t * @param shape - The shape.\n\t * @public\n\t */\n\tabstract indicator(shape: Shape): any\n\n\t/**\n\t * Get the font faces that should be rendered in the document in order for this shape to render\n\t * correctly.\n\t *\n\t * @param shape - The shape.\n\t * @public\n\t */\n\tgetFontFaces(shape: Shape): TLFontFace[] {\n\t\treturn EMPTY_ARRAY\n\t}\n\n\t/**\n\t * Whether the shape can be snapped to by another shape.\n\t *\n\t * @param shape - The shape.\n\t * @public\n\t */\n\tcanSnap(shape: Shape): boolean {\n\t\treturn true\n\t}\n\n\t/**\n\t * Whether the shape can be tabbed to.\n\t *\n\t * @param shape - The shape.\n\t * @public\n\t */\n\tcanTabTo(shape: Shape): boolean {\n\t\treturn true\n\t}\n\n\t/**\n\t * Whether the shape can be scrolled while editing.\n\t *\n\t * @public\n\t */\n\tcanScroll(shape: Shape): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * Whether the shape can be bound to. See {@link TLShapeUtilCanBindOpts} for details.\n\t *\n\t * @public\n\t */\n\tcanBind(_opts: TLShapeUtilCanBindOpts): boolean {\n\t\treturn true\n\t}\n\n\t/**\n\t * Whether the shape can be double clicked to edit.\n\t *\n\t * @public\n\t */\n\tcanEdit(shape: Shape, info: TLEditStartInfo): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * Whether the shape can be resized.\n\t *\n\t * @public\n\t */\n\tcanResize(shape: Shape): boolean {\n\t\treturn true\n\t}\n\n\t/**\n\t * When the shape is resized, whether the shape's children should also be resized.\n\t *\n\t * @public\n\t */\n\tcanResizeChildren(shape: Shape): boolean {\n\t\treturn true\n\t}\n\n\t/**\n\t * Whether the shape can be edited in read-only mode.\n\t *\n\t * @public\n\t */\n\tcanEditInReadonly(shape: Shape): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * Whether the shape can be edited while locked or while an ancestor is locked.\n\t *\n\t * @public\n\t */\n\tcanEditWhileLocked(shape: Shape): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * Whether the shape can be cropped.\n\t *\n\t * @public\n\t */\n\tcanCrop(shape: Shape): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * Whether the shape can participate in layout functions such as alignment or distribution.\n\t *\n\t * @param shape - The shape.\n\t * @param info - Additional context information: the type of action causing the layout and the\n\t * @public\n\t *\n\t * @public\n\t */\n\tcanBeLaidOut(shape: Shape, info: TLShapeUtilCanBeLaidOutOpts): boolean {\n\t\treturn true\n\t}\n\n\t/**\n\t * Whether this shape can be culled. By default, shapes are culled for\n\t * performance reasons when they are outside of the viewport. Culled shapes are still rendered\n\t * to the DOM, but have their `display` property set to `none`.\n\t *\n\t * @param shape - The shape.\n\t */\n\tcanCull(shape: Shape): boolean {\n\t\treturn true\n\t}\n\n\t/**\n\t * Does this shape provide a background for its children? If this is true,\n\t * then any children with a `renderBackground` method will have their\n\t * backgrounds rendered _above_ this shape. Otherwise, the children's\n\t * backgrounds will be rendered above either the next ancestor that provides\n\t * a background, or the canvas background.\n\t *\n\t * @internal\n\t */\n\tprovidesBackgroundForChildren(shape: Shape): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * Get the clip path to apply to this shape's children.\n\t *\n\t * The returned points should define the **inner** clip boundary - the area where\n\t * children will be visible. If your shape has a stroke, you should inset the clip\n\t * path by half the stroke width so children are clipped to the inner edge of the\n\t * stroke rather than its center line.\n\t *\n\t * @example\n\t * ```ts\n\t * override getClipPath(shape: MyShape): Vec[] | undefined {\n\t * const strokeWidth = 2\n\t * const inset = strokeWidth / 2\n\t * // Return points inset by half the stroke width\n\t * return [\n\t * new Vec(inset, inset),\n\t * new Vec(shape.props.w - inset, inset),\n\t * new Vec(shape.props.w - inset, shape.props.h - inset),\n\t * new Vec(inset, shape.props.h - inset),\n\t * ]\n\t * }\n\t * ```\n\t *\n\t * @param shape - The shape to get the clip path for\n\t * @returns Array of points defining the clipping polygon in local coordinates, or undefined if no clipping\n\t * @public\n\t */\n\tgetClipPath?(shape: Shape): Vec[] | undefined\n\n\t/**\n\t * Whether a specific child shape should be clipped by this shape.\n\t * Only called if getClipPath returns a valid polygon.\n\t *\n\t * If not defined, the default behavior is to clip all children.\n\t *\n\t * @param child - The child shape to check\n\t * @returns boolean indicating if this child should be clipped\n\t * @public\n\t */\n\tshouldClipChild?(child: TLShape): boolean\n\n\t/**\n\t * Whether a specific shape should hide in the minimap.\n\t *\n\t * If not defined, the default behavior is to show all shapes in the minimap.\n\t *\n\t * @returns boolean indicating if this shape should hide in the minimap\n\t * @public\n\t */\n\thideInMinimap?(shape: Shape): boolean\n\n\t/**\n\t * Whether the shape should hide its resize handles when selected.\n\t *\n\t * @public\n\t */\n\thideResizeHandles(shape: Shape): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * Whether the shape should hide its rotation handles when selected.\n\t *\n\t * @public\n\t */\n\thideRotateHandle(shape: Shape): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * Whether the shape should hide its selection bounds background when selected.\n\t *\n\t * @public\n\t */\n\thideSelectionBoundsBg(shape: Shape): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * Whether the shape should hide its selection bounds foreground when selected.\n\t *\n\t * @public\n\t */\n\thideSelectionBoundsFg(shape: Shape): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * Whether the shape's aspect ratio is locked.\n\t *\n\t * @public\n\t */\n\tisAspectRatioLocked(shape: Shape): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * By default, the bounds of an image export are the bounds of all the shapes it contains, plus\n\t * some padding. If an export includes a shape where `isExportBoundsContainer` is true, then the\n\t * padding is skipped _if the bounds of that shape contains all the other shapes_. This is\n\t * useful in cases like annotating on top of an image, where you usually want to avoid extra\n\t * padding around the image if you don't need it.\n\t *\n\t * @param shape - The shape to check\n\t * @returns True if this shape should be treated as an export bounds container\n\t */\n\tisExportBoundsContainer(shape: Shape): boolean {\n\t\treturn false\n\t}\n\n\t/**\n\t * Get a JSX element for the shape (as an HTML element) to be rendered as part of the canvas background - behind any other shape content.\n\t *\n\t * @param shape - The shape.\n\t * @internal\n\t */\n\tbackgroundComponent?(shape: Shape): any\n\n\t/**\n\t * Get the interpolated props for an animating shape. This is an optional method.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * util.getInterpolatedProps?.(startShape, endShape, t)\n\t * ```\n\t *\n\t * @param startShape - The initial shape.\n\t * @param endShape - The initial shape.\n\t * @param progress - The normalized progress between zero (start) and 1 (end).\n\t * @public\n\t */\n\tgetInterpolatedProps?(startShape: Shape, endShape: Shape, progress: number): Shape['props']\n\n\t/**\n\t * Get an array of handle models for the shape. This is an optional method.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * util.getHandles?.(myShape)\n\t * ```\n\t *\n\t * @param shape - The shape.\n\t * @public\n\t */\n\tgetHandles?(shape: Shape): TLHandle[]\n\n\t/**\n\t * Get whether the shape can receive children of a given type.\n\t *\n\t * @param shape - The shape.\n\t * @param type - The shape type.\n\t * @public\n\t */\n\tcanReceiveNewChildrenOfType(shape: Shape, _type: TLShape['type']) {\n\t\treturn false\n\t}\n\n\t/**\n\t * Get the shape as an SVG object.\n\t *\n\t * @param shape - The shape.\n\t * @param ctx - The export context for the SVG - used for adding e.g. \\<def\\>s\n\t * @returns An SVG element.\n\t * @public\n\t */\n\ttoSvg?(shape: Shape, ctx: SvgExportContext): ReactElement | null | Promise<ReactElement | null>\n\n\t/**\n\t * Get the shape's background layer as an SVG object.\n\t *\n\t * @param shape - The shape.\n\t * @param ctx - ctx - The export context for the SVG - used for adding e.g. \\<def\\>s\n\t * @returns An SVG element.\n\t * @public\n\t */\n\ttoBackgroundSvg?(\n\t\tshape: Shape,\n\t\tctx: SvgExportContext\n\t): ReactElement | null | Promise<ReactElement | null>\n\n\t/** @internal */\n\texpandSelectionOutlinePx(shape: Shape): number | Box {\n\t\treturn 0\n\t}\n\n\t/**\n\t * Return elements to be added to the \\<defs\\> section of the canvases SVG context. This can be\n\t * used to define SVG content (e.g. patterns & masks) that can be referred to by ID from svg\n\t * elements returned by `component`.\n\t *\n\t * Each def should have a unique `key`. If multiple defs from different shapes all have the same\n\t * key, only one will be used.\n\t */\n\tgetCanvasSvgDefs(): TLShapeUtilCanvasSvgDef[] {\n\t\treturn []\n\t}\n\n\t/**\n\t * Get the geometry to use when snapping to this this shape in translate/resize operations. See\n\t * {@link BoundsSnapGeometry} for details.\n\t */\n\tgetBoundsSnapGeometry(shape: Shape): BoundsSnapGeometry {\n\t\treturn {}\n\t}\n\n\t/**\n\t * Get the geometry to use when snapping handles to this shape. See {@link HandleSnapGeometry}\n\t * for details.\n\t */\n\tgetHandleSnapGeometry(shape: Shape): HandleSnapGeometry {\n\t\treturn {}\n\t}\n\n\tgetText(shape: Shape): string | undefined {\n\t\treturn undefined\n\t}\n\n\tgetAriaDescriptor(shape: Shape): string | undefined {\n\t\treturn undefined\n\t}\n\n\t// Events\n\n\t/**\n\t * A callback called just before a shape is created. This method provides a last chance to modify\n\t * the created shape.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * onBeforeCreate = (next) => {\n\t * \treturn { ...next, x: next.x + 1 }\n\t * }\n\t * ```\n\t *\n\t * @param next - The next shape.\n\t * @returns The next shape or void.\n\t * @public\n\t */\n\tonBeforeCreate?(next: Shape): Shape | void\n\n\t/**\n\t * A callback called just before a shape is updated. This method provides a last chance to modify\n\t * the updated shape.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * onBeforeUpdate = (prev, next) => {\n\t * \tif (prev.x === next.x) {\n\t * \t\treturn { ...next, x: next.x + 1 }\n\t * \t}\n\t * }\n\t * ```\n\t *\n\t * @param prev - The previous shape.\n\t * @param next - The next shape.\n\t * @returns The next shape or void.\n\t * @public\n\t */\n\tonBeforeUpdate?(prev: Shape, next: Shape): Shape | void\n\n\t/**\n\t * A callback called when a shape changes from a crop.\n\t *\n\t * @param shape - The shape at the start of the crop.\n\t * @param info - Info about the crop.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonCrop?(\n\t\tshape: Shape,\n\t\tinfo: TLCropInfo<Shape>\n\t): Omit<TLShapePartial<Shape>, 'id' | 'type'> | undefined | void\n\n\t/**\n\t * A callback called when some other shapes are dragged into this one. This fires when the shapes are dragged over the shape for the first time.\n\t *\n\t * @param shape - The shape.\n\t * @param shapes - The shapes that are being dragged in.\n\t * @public\n\t */\n\tonDragShapesIn?(shape: Shape, shapes: TLShape[], info: TLDragShapesInInfo): void\n\n\t/**\n\t * A callback called when some other shapes are dragged over this one. This fires when the shapes are dragged over the shape for the first time (after the onDragShapesIn callback), and again on every update while the shapes are being dragged.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * onDragShapesOver = (shape, shapes) => {\n\t * \tthis.editor.reparentShapes(shapes, shape.id)\n\t * }\n\t * ```\n\t *\n\t * @param shape - The shape.\n\t * @param shapes - The shapes that are being dragged over this one.\n\t * @public\n\t */\n\tonDragShapesOver?(shape: Shape, shapes: TLShape[], info: TLDragShapesOverInfo): void\n\n\t/**\n\t * A callback called when some other shapes are dragged out of this one.\n\t *\n\t * @param shape - The shape.\n\t * @param shapes - The shapes that are being dragged out.\n\t * @public\n\t */\n\tonDragShapesOut?(shape: Shape, shapes: TLShape[], info: TLDragShapesOutInfo): void\n\n\t/**\n\t * A callback called when some other shapes are dropped over this one.\n\t *\n\t * @param shape - The shape.\n\t * @param shapes - The shapes that are being dropped over this one.\n\t * @public\n\t */\n\tonDropShapesOver?(shape: Shape, shapes: TLShape[], info: TLDropShapesOverInfo): void\n\n\t/**\n\t * A callback called when a shape starts being resized.\n\t *\n\t * @param shape - The shape.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonResizeStart?(shape: Shape): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape changes from a resize.\n\t *\n\t * @param shape - The shape at the start of the resize.\n\t * @param info - Info about the resize.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonResize?(\n\t\tshape: Shape,\n\t\tinfo: TLResizeInfo<Shape>\n\t): Omit<TLShapePartial<Shape>, 'id' | 'type'> | undefined | void\n\n\t/**\n\t * A callback called when a shape finishes resizing.\n\t *\n\t * @param initial - The shape at the start of the resize.\n\t * @param current - The current shape.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonResizeEnd?(initial: Shape, current: Shape): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape resize is cancelled.\n\t *\n\t * @param initial - The shape at the start of the resize.\n\t * @param current - The current shape.\n\t * @public\n\t */\n\tonResizeCancel?(initial: Shape, current: Shape): void\n\n\t/**\n\t * A callback called when a shape starts being translated.\n\t *\n\t * @param shape - The shape.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonTranslateStart?(shape: Shape): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape changes from a translation.\n\t *\n\t * @param initial - The shape at the start of the translation.\n\t * @param current - The current shape.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonTranslate?(initial: Shape, current: Shape): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape finishes translating.\n\t *\n\t * @param initial - The shape at the start of the translation.\n\t * @param current - The current shape.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonTranslateEnd?(initial: Shape, current: Shape): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape translation is cancelled.\n\t *\n\t * @param initial - The shape at the start of the translation.\n\t * @param current - The current shape.\n\t * @public\n\t */\n\tonTranslateCancel?(initial: Shape, current: Shape): void\n\n\t/**\n\t * A callback called when a shape's handle starts being dragged.\n\t *\n\t * @param shape - The shape.\n\t * @param info - An object containing the handle and whether the handle is 'precise' or not.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonHandleDragStart?(shape: Shape, info: TLHandleDragInfo<Shape>): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape's handle changes.\n\t *\n\t * @param shape - The current shape.\n\t * @param info - An object containing the handle and whether the handle is 'precise' or not.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonHandleDrag?(shape: Shape, info: TLHandleDragInfo<Shape>): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape's handle finishes being dragged.\n\t *\n\t * @param current - The current shape.\n\t * @param info - An object containing the handle and whether the handle is 'precise' or not.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonHandleDragEnd?(current: Shape, info: TLHandleDragInfo<Shape>): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape's handle drag is cancelled.\n\t *\n\t * @param current - The current shape.\n\t * @param info - An object containing the handle and whether the handle is 'precise' or not.\n\t * @public\n\t */\n\tonHandleDragCancel?(current: Shape, info: TLHandleDragInfo<Shape>): void\n\n\t/**\n\t * A callback called when a shape starts being rotated.\n\t *\n\t * @param shape - The shape.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonRotateStart?(shape: Shape): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape changes from a rotation.\n\t *\n\t * @param initial - The shape at the start of the rotation.\n\t * @param current - The current shape.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonRotate?(initial: Shape, current: Shape): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape finishes rotating.\n\t *\n\t * @param initial - The shape at the start of the rotation.\n\t * @param current - The current shape.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonRotateEnd?(initial: Shape, current: Shape): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape rotation is cancelled.\n\t *\n\t * @param initial - The shape at the start of the rotation.\n\t * @param current - The current shape.\n\t * @public\n\t */\n\tonRotateCancel?(initial: Shape, current: Shape): void\n\n\t/**\n\t * Not currently used.\n\t *\n\t * @internal\n\t */\n\tonBindingChange?(shape: Shape): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape's children change.\n\t *\n\t * @param shape - The shape.\n\t * @returns An array of shape updates, or void.\n\t * @public\n\t */\n\tonChildrenChange?(shape: Shape): TLShapePartial[] | void\n\n\t/**\n\t * A callback called when a shape's handle is double clicked.\n\t *\n\t * @param shape - The shape.\n\t * @param handle - The handle that is double-clicked.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonDoubleClickHandle?(shape: Shape, handle: TLHandle): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape's edge is double clicked.\n\t *\n\t * @param shape - The shape.\n\t * @param info - Info about the edge.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonDoubleClickEdge?(shape: Shape, info: TLClickEventInfo): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape's corner is double clicked.\n\t *\n\t * @param shape - The shape.\n\t * @param info - Info about the corner.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonDoubleClickCorner?(shape: Shape, info: TLClickEventInfo): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape is double clicked.\n\t *\n\t * @param shape - The shape.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonDoubleClick?(shape: Shape): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape is clicked.\n\t *\n\t * @param shape - The shape.\n\t * @returns A change to apply to the shape, or void.\n\t * @public\n\t */\n\tonClick?(shape: Shape): TLShapePartial<Shape> | void\n\n\t/**\n\t * A callback called when a shape starts being edited.\n\t *\n\t * @param shape - The shape.\n\t * @public\n\t */\n\tonEditStart?(shape: Shape): void\n\n\t/**\n\t * A callback called when a shape finishes being edited.\n\t *\n\t * @param shape - The shape.\n\t * @public\n\t */\n\tonEditEnd?(shape: Shape): void\n}\n\n/**\n * Info about a crop.\n * @param handle - The handle being dragged.\n * @param change - The distance the handle is moved.\n * @param initialShape - The shape at the start of the resize.\n * @public\n */\nexport interface TLCropInfo<T extends TLShape> {\n\thandle: SelectionHandle\n\tchange: Vec\n\tcrop: TLShapeCrop\n\tuncroppedSize: { w: number; h: number }\n\tinitialShape: T\n\taspectRatioLocked?: boolean\n}\n\n/** @public */\nexport interface TLDragShapesInInfo {\n\tinitialDraggingOverShapeId: TLShapeId | null\n\tprevDraggingOverShapeId: TLShapeId | null\n\tinitialParentIds: Map<TLShapeId, TLParentId>\n\tinitialIndices: Map<TLShapeId, IndexKey>\n}\n\n/** @public */\nexport interface TLDragShapesOverInfo {\n\tinitialDraggingOverShapeId: TLShapeId | null\n\tinitialParentIds: Map<TLShapeId, TLParentId>\n\tinitialIndices: Map<TLShapeId, IndexKey>\n}\n\n/** @public */\nexport interface TLDragShapesOutInfo {\n\tnextDraggingOverShapeId: TLShapeId | null\n\tinitialDraggingOverShapeId: TLShapeId | null\n\tinitialParentIds: Map<TLShapeId, TLParentId>\n\tinitialIndices: Map<TLShapeId, IndexKey>\n}\n\n/** @public */\nexport interface TLDropShapesOverInfo {\n\tinitialDraggingOverShapeId: TLShapeId | null\n\tinitialParentIds: Map<TLShapeId, TLParentId>\n\tinitialIndices: Map<TLShapeId, IndexKey>\n}\n\n/**\n * The type of resize.\n *\n * 'scale_shape' - The shape is being scaled, usually as part of a larger selection.\n *\n * 'resize_bounds' - The user is directly manipulating an individual shape's bounds using a resize\n * handle. It is up to shape util implementers to decide how they want to handle the two\n * situations.\n *\n * @public\n */\nexport type TLResizeMode = 'scale_shape' | 'resize_bounds'\n\n/**\n * Info about a resize.\n * @param newPoint - The new local position of the shape.\n * @param handle - The handle being dragged.\n * @param mode - The type of resize.\n * @param scaleX - The scale in the x-axis.\n * @param scaleY - The scale in the y-axis.\n * @param initialBounds - The bounds of the shape at the start of the resize.\n * @param initialShape - The shape at the start of the resize.\n * @public\n */\nexport interface TLResizeInfo<T extends TLShape> {\n\tnewPoint: Vec\n\thandle: TLResizeHandle\n\tmode: TLResizeMode\n\tscaleX: number\n\tscaleY: number\n\tinitialBounds: Box\n\tinitialShape: T\n}\n\n/* -------------------- Dragging -------------------- */\n\n/** @public */\nexport interface TLHandleDragInfo<T extends TLShape> {\n\thandle: TLHandle\n\tisPrecise: boolean\n\tisCreatingShape: boolean\n\tinitial?: T | undefined\n}\n\n/* --------------------------------- Editing -------------------------------- */\n\n/** @public */\nexport interface TLEditStartInfo {\n\ttype:\n\t\t| 'press_enter'\n\t\t| 'click'\n\t\t| 'double-click'\n\t\t| 'double-click-edge'\n\t\t| 'double-click-corner'\n\t\t| 'click-header'\n\t\t| 'unknown'\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -27,7 +27,7 @@ var import_useEditor = require("../../../hooks/useEditor");
|
|
|
27
27
|
var import_getPerfectDashProps = require("../shared/getPerfectDashProps");
|
|
28
28
|
function DashedOutlineBox({ bounds, className }) {
|
|
29
29
|
const editor = (0, import_useEditor.useEditor)();
|
|
30
|
-
const zoomLevel = (0, import_state_react.useValue)("zoom level", () => editor.
|
|
30
|
+
const zoomLevel = (0, import_state_react.useValue)("zoom level", () => editor.getEfficientZoomLevel(), [editor]);
|
|
31
31
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { className, pointerEvents: "none", strokeLinecap: "round", strokeLinejoin: "round", children: bounds.sides.map((side, i) => {
|
|
32
32
|
const { strokeDasharray, strokeDashoffset } = (0, import_getPerfectDashProps.getPerfectDashProps)(
|
|
33
33
|
side[0].dist(side[1]),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/editor/shapes/group/DashedOutlineBox.tsx"],
|
|
4
|
-
"sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { useEditor } from '../../../hooks/useEditor'\nimport { Box } from '../../../primitives/Box'\nimport { getPerfectDashProps } from '../shared/getPerfectDashProps'\n\nexport function DashedOutlineBox({ bounds, className }: { bounds: Box; className: string }) {\n\tconst editor = useEditor()\n\n\tconst zoomLevel = useValue('zoom level', () => editor.
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBK;AAvBL,yBAAyB;AACzB,uBAA0B;AAE1B,iCAAoC;AAE7B,SAAS,iBAAiB,EAAE,QAAQ,UAAU,GAAuC;AAC3F,QAAM,aAAS,4BAAU;AAEzB,QAAM,gBAAY,6BAAS,cAAc,MAAM,OAAO,
|
|
4
|
+
"sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { useEditor } from '../../../hooks/useEditor'\nimport { Box } from '../../../primitives/Box'\nimport { getPerfectDashProps } from '../shared/getPerfectDashProps'\n\nexport function DashedOutlineBox({ bounds, className }: { bounds: Box; className: string }) {\n\tconst editor = useEditor()\n\n\tconst zoomLevel = useValue('zoom level', () => editor.getEfficientZoomLevel(), [editor])\n\n\treturn (\n\t\t<g className={className} pointerEvents=\"none\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n\t\t\t{bounds.sides.map((side, i) => {\n\t\t\t\tconst { strokeDasharray, strokeDashoffset } = getPerfectDashProps(\n\t\t\t\t\tside[0].dist(side[1]),\n\t\t\t\t\t1 / zoomLevel,\n\t\t\t\t\t{\n\t\t\t\t\t\tstyle: 'dashed',\n\t\t\t\t\t\tlengthRatio: 4,\n\t\t\t\t\t}\n\t\t\t\t)\n\n\t\t\t\treturn (\n\t\t\t\t\t<line\n\t\t\t\t\t\tkey={i}\n\t\t\t\t\t\tx1={side[0].x}\n\t\t\t\t\t\ty1={side[0].y}\n\t\t\t\t\t\tx2={side[1].x}\n\t\t\t\t\t\ty2={side[1].y}\n\t\t\t\t\t\tstrokeDasharray={strokeDasharray}\n\t\t\t\t\t\tstrokeDashoffset={strokeDashoffset}\n\t\t\t\t\t/>\n\t\t\t\t)\n\t\t\t})}\n\t\t</g>\n\t)\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBK;AAvBL,yBAAyB;AACzB,uBAA0B;AAE1B,iCAAoC;AAE7B,SAAS,iBAAiB,EAAE,QAAQ,UAAU,GAAuC;AAC3F,QAAM,aAAS,4BAAU;AAEzB,QAAM,gBAAY,6BAAS,cAAc,MAAM,OAAO,sBAAsB,GAAG,CAAC,MAAM,CAAC;AAEvF,SACC,4CAAC,OAAE,WAAsB,eAAc,QAAO,eAAc,SAAQ,gBAAe,SACjF,iBAAO,MAAM,IAAI,CAAC,MAAM,MAAM;AAC9B,UAAM,EAAE,iBAAiB,iBAAiB,QAAI;AAAA,MAC7C,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC;AAAA,MACpB,IAAI;AAAA,MACJ;AAAA,QACC,OAAO;AAAA,QACP,aAAa;AAAA,MACd;AAAA,IACD;AAEA,WACC;AAAA,MAAC;AAAA;AAAA,QAEA,IAAI,KAAK,CAAC,EAAE;AAAA,QACZ,IAAI,KAAK,CAAC,EAAE;AAAA,QACZ,IAAI,KAAK,CAAC,EAAE;AAAA,QACZ,IAAI,KAAK,CAAC,EAAE;AAAA,QACZ;AAAA,QACA;AAAA;AAAA,MANK;AAAA,IAON;AAAA,EAEF,CAAC,GACF;AAEF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/editor/shapes/group/GroupShapeUtil.tsx"],
|
|
4
|
-
"sourcesContent": ["import { TLGroupShape, groupShapeMigrations, groupShapeProps } from '@tldraw/tlschema'\nimport { SVGContainer } from '../../../components/SVGContainer'\nimport { Geometry2d } from '../../../primitives/geometry/Geometry2d'\nimport { Group2d } from '../../../primitives/geometry/Group2d'\nimport { Rectangle2d } from '../../../primitives/geometry/Rectangle2d'\nimport { ShapeUtil } from '../ShapeUtil'\nimport { DashedOutlineBox } from './DashedOutlineBox'\n\n/** @public */\nexport class GroupShapeUtil extends ShapeUtil<TLGroupShape> {\n\tstatic override type = 'group' as const\n\tstatic override props = groupShapeProps\n\tstatic override migrations = groupShapeMigrations\n\n\toverride hideSelectionBoundsFg() {\n\t\treturn true\n\t}\n\n\toverride canBind() {\n\t\treturn false\n\t}\n\n\tcanResize() {\n\t\treturn true\n\t}\n\n\tcanResizeChildren() {\n\t\treturn true\n\t}\n\n\tgetDefaultProps(): TLGroupShape['props'] {\n\t\treturn {}\n\t}\n\n\tgetGeometry(shape: TLGroupShape): Geometry2d {\n\t\tconst children = this.editor.getSortedChildIdsForParent(shape.id)\n\t\tif (children.length === 0) {\n\t\t\treturn new Rectangle2d({ width: 1, height: 1, isFilled: false })\n\t\t}\n\n\t\treturn new Group2d({\n\t\t\tchildren: children.map((childId) => {\n\t\t\t\tconst shape = this.editor.getShape(childId)!\n\t\t\t\treturn this.editor\n\t\t\t\t\t.getShapeGeometry(childId)\n\t\t\t\t\t.transform(this.editor.getShapeLocalTransform(shape)!, { isLabel: false })\n\t\t\t}),\n\t\t})\n\t}\n\n\tcomponent(shape: TLGroupShape) {\n\t\tconst isErasing = this.editor.getErasingShapeIds().includes(shape.id)\n\n\t\tconst { hintingShapeIds } = this.editor.getCurrentPageState()\n\t\tconst isHintingOtherGroup =\n\t\t\thintingShapeIds.length > 0 &&\n\t\t\thintingShapeIds.some(\n\t\t\t\t(id)
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["import { TLGroupShape, groupShapeMigrations, groupShapeProps } from '@tldraw/tlschema'\nimport { SVGContainer } from '../../../components/SVGContainer'\nimport { Geometry2d } from '../../../primitives/geometry/Geometry2d'\nimport { Group2d } from '../../../primitives/geometry/Group2d'\nimport { Rectangle2d } from '../../../primitives/geometry/Rectangle2d'\nimport { ShapeUtil } from '../ShapeUtil'\nimport { DashedOutlineBox } from './DashedOutlineBox'\n\n/** @public */\nexport class GroupShapeUtil extends ShapeUtil<TLGroupShape> {\n\tstatic override type = 'group' as const\n\tstatic override props = groupShapeProps\n\tstatic override migrations = groupShapeMigrations\n\n\toverride hideSelectionBoundsFg() {\n\t\treturn true\n\t}\n\n\toverride canBind() {\n\t\treturn false\n\t}\n\n\tcanResize() {\n\t\treturn true\n\t}\n\n\tcanResizeChildren() {\n\t\treturn true\n\t}\n\n\tgetDefaultProps(): TLGroupShape['props'] {\n\t\treturn {}\n\t}\n\n\tgetGeometry(shape: TLGroupShape): Geometry2d {\n\t\tconst children = this.editor.getSortedChildIdsForParent(shape.id)\n\t\tif (children.length === 0) {\n\t\t\treturn new Rectangle2d({ width: 1, height: 1, isFilled: false })\n\t\t}\n\n\t\treturn new Group2d({\n\t\t\tchildren: children.map((childId) => {\n\t\t\t\tconst shape = this.editor.getShape(childId)!\n\t\t\t\treturn this.editor\n\t\t\t\t\t.getShapeGeometry(childId)\n\t\t\t\t\t.transform(this.editor.getShapeLocalTransform(shape)!, { isLabel: false })\n\t\t\t}),\n\t\t})\n\t}\n\n\tcomponent(shape: TLGroupShape) {\n\t\tconst isErasing = this.editor.getErasingShapeIds().includes(shape.id)\n\n\t\tconst { hintingShapeIds } = this.editor.getCurrentPageState()\n\t\tconst isHintingOtherGroup =\n\t\t\thintingShapeIds.length > 0 &&\n\t\t\thintingShapeIds.some(\n\t\t\t\t(id) => id !== shape.id && this.editor.isShapeOfType(this.editor.getShape(id)!, 'group')\n\t\t\t)\n\n\t\tconst isFocused = this.editor.getCurrentPageState().focusedGroupId !== shape.id\n\n\t\tif (\n\t\t\t!isErasing && // always show the outline while we're erasing the group\n\t\t\t// show the outline while the group is focused unless something outside of the group is being hinted\n\t\t\t// this happens dropping shapes from a group onto some outside group\n\t\t\t(isFocused || isHintingOtherGroup)\n\t\t) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst bounds = this.editor.getShapeGeometry(shape).bounds\n\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<DashedOutlineBox className=\"tl-group\" bounds={bounds} />\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\tindicator(shape: TLGroupShape) {\n\t\t// Not a class component, but eslint can't tell that :(\n\t\tconst bounds = this.editor.getShapeGeometry(shape).bounds\n\t\treturn <DashedOutlineBox className=\"\" bounds={bounds} />\n\t}\n\n\toverride onChildrenChange(group: TLGroupShape) {\n\t\tconst children = this.editor.getSortedChildIdsForParent(group.id)\n\t\tif (children.length === 0) {\n\t\t\tif (this.editor.getCurrentPageState().focusedGroupId === group.id) {\n\t\t\t\tthis.editor.popFocusedGroupId()\n\t\t\t}\n\t\t\tthis.editor.deleteShapes([group.id])\n\t\t\treturn\n\t\t} else if (children.length === 1) {\n\t\t\tif (this.editor.getCurrentPageState().focusedGroupId === group.id) {\n\t\t\t\tthis.editor.popFocusedGroupId()\n\t\t\t}\n\t\t\tthis.editor.reparentShapes(children, group.parentId)\n\t\t\tthis.editor.deleteShapes([group.id])\n\t\t\treturn\n\t\t}\n\t}\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA2EI;AA3EJ,sBAAoE;AACpE,0BAA6B;AAE7B,qBAAwB;AACxB,yBAA4B;AAC5B,uBAA0B;AAC1B,8BAAiC;AAG1B,MAAM,uBAAuB,2BAAwB;AAAA,EAC3D,OAAgB,OAAO;AAAA,EACvB,OAAgB,QAAQ;AAAA,EACxB,OAAgB,aAAa;AAAA,EAEpB,wBAAwB;AAChC,WAAO;AAAA,EACR;AAAA,EAES,UAAU;AAClB,WAAO;AAAA,EACR;AAAA,EAEA,YAAY;AACX,WAAO;AAAA,EACR;AAAA,EAEA,oBAAoB;AACnB,WAAO;AAAA,EACR;AAAA,EAEA,kBAAyC;AACxC,WAAO,CAAC;AAAA,EACT;AAAA,EAEA,YAAY,OAAiC;AAC5C,UAAM,WAAW,KAAK,OAAO,2BAA2B,MAAM,EAAE;AAChE,QAAI,SAAS,WAAW,GAAG;AAC1B,aAAO,IAAI,+BAAY,EAAE,OAAO,GAAG,QAAQ,GAAG,UAAU,MAAM,CAAC;AAAA,IAChE;AAEA,WAAO,IAAI,uBAAQ;AAAA,MAClB,UAAU,SAAS,IAAI,CAAC,YAAY;AACnC,cAAMA,SAAQ,KAAK,OAAO,SAAS,OAAO;AAC1C,eAAO,KAAK,OACV,iBAAiB,OAAO,EACxB,UAAU,KAAK,OAAO,uBAAuBA,MAAK,GAAI,EAAE,SAAS,MAAM,CAAC;AAAA,MAC3E,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AAAA,EAEA,UAAU,OAAqB;AAC9B,UAAM,YAAY,KAAK,OAAO,mBAAmB,EAAE,SAAS,MAAM,EAAE;AAEpE,UAAM,EAAE,gBAAgB,IAAI,KAAK,OAAO,oBAAoB;AAC5D,UAAM,sBACL,gBAAgB,SAAS,KACzB,gBAAgB;AAAA,MACf,CAAC,OAAO,OAAO,MAAM,MAAM,KAAK,OAAO,cAAc,KAAK,OAAO,SAAS,EAAE,GAAI,OAAO;AAAA,IACxF;AAED,UAAM,YAAY,KAAK,OAAO,oBAAoB,EAAE,mBAAmB,MAAM;AAE7E,QACC,CAAC;AAAA;AAAA;AAAA,KAGA,aAAa,sBACb;AACD,aAAO;AAAA,IACR;AAEA,UAAM,SAAS,KAAK,OAAO,iBAAiB,KAAK,EAAE;AAEnD,WACC,4CAAC,oCACA,sDAAC,4CAAiB,WAAU,YAAW,QAAgB,GACxD;AAAA,EAEF;AAAA,EAEA,UAAU,OAAqB;AAE9B,UAAM,SAAS,KAAK,OAAO,iBAAiB,KAAK,EAAE;AACnD,WAAO,4CAAC,4CAAiB,WAAU,IAAG,QAAgB;AAAA,EACvD;AAAA,EAES,iBAAiB,OAAqB;AAC9C,UAAM,WAAW,KAAK,OAAO,2BAA2B,MAAM,EAAE;AAChE,QAAI,SAAS,WAAW,GAAG;AAC1B,UAAI,KAAK,OAAO,oBAAoB,EAAE,mBAAmB,MAAM,IAAI;AAClE,aAAK,OAAO,kBAAkB;AAAA,MAC/B;AACA,WAAK,OAAO,aAAa,CAAC,MAAM,EAAE,CAAC;AACnC;AAAA,IACD,WAAW,SAAS,WAAW,GAAG;AACjC,UAAI,KAAK,OAAO,oBAAoB,EAAE,mBAAmB,MAAM,IAAI;AAClE,aAAK,OAAO,kBAAkB;AAAA,MAC/B;AACA,WAAK,OAAO,eAAe,UAAU,MAAM,QAAQ;AACnD,WAAK,OAAO,aAAa,CAAC,MAAM,EAAE,CAAC;AACnC;AAAA,IACD;AAAA,EACD;AACD;",
|
|
6
6
|
"names": ["shape"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.ts"],
|
|
4
|
-
"sourcesContent": ["import { TLShape } from '@tldraw/tlschema'\nimport { StateNode, TLStateNodeConstructor } from '../StateNode'\nimport { Idle } from './children/Idle'\nimport { Pointing } from './children/Pointing'\n\n/** @public */\nexport abstract class BaseBoxShapeTool extends StateNode {\n\tstatic override id = 'box'\n\tstatic override initial = 'idle'\n\tstatic override children(): TLStateNodeConstructor[] {\n\t\treturn [Idle, Pointing]\n\t}\n\n\tabstract override shapeType:
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["import { TLShape } from '@tldraw/tlschema'\nimport { TLBaseBoxShape } from '../../shapes/BaseBoxShapeUtil'\nimport { StateNode, TLStateNodeConstructor } from '../StateNode'\nimport { Idle } from './children/Idle'\nimport { Pointing } from './children/Pointing'\n\n/** @public */\nexport abstract class BaseBoxShapeTool extends StateNode {\n\tstatic override id = 'box'\n\tstatic override initial = 'idle'\n\tstatic override children(): TLStateNodeConstructor[] {\n\t\treturn [Idle, Pointing]\n\t}\n\n\tabstract override shapeType: TLBaseBoxShape['type']\n\n\tonCreate?(_shape: TLShape | null): void | null\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,uBAAkD;AAClD,kBAAqB;AACrB,sBAAyB;AAGlB,MAAe,yBAAyB,2BAAU;AAAA,EACxD,OAAgB,KAAK;AAAA,EACrB,OAAgB,UAAU;AAAA,EAC1B,OAAgB,WAAqC;AACpD,WAAO,CAAC,kBAAM,wBAAQ;AAAA,EACvB;AAKD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -30,8 +30,8 @@ class Pointing extends import_StateNode.StateNode {
|
|
|
30
30
|
static id = "pointing";
|
|
31
31
|
onPointerMove(info) {
|
|
32
32
|
const { editor } = this;
|
|
33
|
-
if (editor.inputs.
|
|
34
|
-
const
|
|
33
|
+
if (editor.inputs.getIsDragging()) {
|
|
34
|
+
const originPagePoint = editor.inputs.getOriginPagePoint();
|
|
35
35
|
const shapeType = this.parent.shapeType;
|
|
36
36
|
const id = (0, import_tlschema.createShapeId)();
|
|
37
37
|
const creatingMarkId = editor.markHistoryStoppingPoint(`creating_box:${id}`);
|
|
@@ -84,7 +84,7 @@ class Pointing extends import_StateNode.StateNode {
|
|
|
84
84
|
this.cancel();
|
|
85
85
|
}
|
|
86
86
|
complete() {
|
|
87
|
-
const
|
|
87
|
+
const originPagePoint = this.editor.inputs.getOriginPagePoint();
|
|
88
88
|
const shapeType = this.parent.shapeType;
|
|
89
89
|
const id = (0, import_tlschema.createShapeId)();
|
|
90
90
|
this.editor.markHistoryStoppingPoint(`creating_box:${id}`);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts"],
|
|
4
|
-
"sourcesContent": ["import { TLShape, createShapeId } from '@tldraw/tlschema'\nimport { structuredClone } from '@tldraw/utils'\nimport { Vec } from '../../../../primitives/Vec'\nimport { Editor } from '../../../Editor'\nimport { TLBaseBoxShape } from '../../../shapes/BaseBoxShapeUtil'\nimport { TLPointerEventInfo } from '../../../types/event-types'\nimport { StateNode } from '../../StateNode'\nimport { BaseBoxShapeTool } from '../BaseBoxShapeTool'\n\nexport class Pointing extends StateNode {\n\tstatic override id = 'pointing'\n\n\toverride onPointerMove(info: TLPointerEventInfo) {\n\t\tconst { editor } = this\n\t\tif (editor.inputs.
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAuC;AACvC,mBAAgC;AAChC,iBAAoB;AAIpB,uBAA0B;AAGnB,MAAM,iBAAiB,2BAAU;AAAA,EACvC,OAAgB,KAAK;AAAA,EAEZ,cAAc,MAA0B;AAChD,UAAM,EAAE,OAAO,IAAI;AACnB,QAAI,OAAO,OAAO,
|
|
4
|
+
"sourcesContent": ["import { TLShape, createShapeId } from '@tldraw/tlschema'\nimport { structuredClone } from '@tldraw/utils'\nimport { Vec } from '../../../../primitives/Vec'\nimport { Editor } from '../../../Editor'\nimport { TLBaseBoxShape } from '../../../shapes/BaseBoxShapeUtil'\nimport { TLPointerEventInfo } from '../../../types/event-types'\nimport { StateNode } from '../../StateNode'\nimport { BaseBoxShapeTool } from '../BaseBoxShapeTool'\n\nexport class Pointing extends StateNode {\n\tstatic override id = 'pointing'\n\n\toverride onPointerMove(info: TLPointerEventInfo) {\n\t\tconst { editor } = this\n\t\tif (editor.inputs.getIsDragging()) {\n\t\t\tconst originPagePoint = editor.inputs.getOriginPagePoint()\n\n\t\t\tconst shapeType = (this.parent as BaseBoxShapeTool)!.shapeType\n\n\t\t\tconst id = createShapeId()\n\n\t\t\tconst creatingMarkId = editor.markHistoryStoppingPoint(`creating_box:${id}`)\n\t\t\tconst newPoint = maybeSnapToGrid(originPagePoint, editor)\n\n\t\t\t// Allow this to trigger the max shapes reached alert\n\t\t\tthis.editor.createShapes([\n\t\t\t\t{\n\t\t\t\t\tid,\n\t\t\t\t\ttype: shapeType,\n\t\t\t\t\tx: newPoint.x,\n\t\t\t\t\ty: newPoint.y,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tw: 1,\n\t\t\t\t\t\th: 1,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t])\n\t\t\tconst shape = editor.getShape(id)\n\t\t\tif (!shape) {\n\t\t\t\tthis.cancel()\n\t\t\t\treturn\n\t\t\t}\n\t\t\teditor.select(id)\n\n\t\t\tconst parent = this.parent as BaseBoxShapeTool\n\t\t\tthis.editor.setCurrentTool(\n\t\t\t\t'select.resizing',\n\t\t\t\t{\n\t\t\t\t\t...info,\n\t\t\t\t\ttarget: 'selection',\n\t\t\t\t\thandle: 'bottom_right',\n\t\t\t\t\tisCreating: true,\n\t\t\t\t\tcreatingMarkId,\n\t\t\t\t\tcreationCursorOffset: { x: 1, y: 1 },\n\t\t\t\t\tonInteractionEnd: this.parent.id,\n\t\t\t\t\tonCreate: parent.onCreate\n\t\t\t\t\t\t? (shape: TLShape | null) => parent.onCreate?.(shape)\n\t\t\t\t\t\t: undefined,\n\t\t\t\t} /** satisfies ResizingInfo, defined in main tldraw package \uD83D\uDE27 */\n\t\t\t)\n\t\t}\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\toverride onComplete() {\n\t\tthis.complete()\n\t}\n\n\toverride onInterrupt() {\n\t\tthis.cancel()\n\t}\n\n\tcomplete() {\n\t\tconst originPagePoint = this.editor.inputs.getOriginPagePoint()\n\n\t\tconst shapeType = (this.parent as BaseBoxShapeTool)!.shapeType as TLBaseBoxShape['type']\n\n\t\tconst id = createShapeId()\n\n\t\tthis.editor.markHistoryStoppingPoint(`creating_box:${id}`)\n\n\t\t// Allow this to trigger the max shapes reached alert\n\t\t// todo: add scale here when dynamic size is enabled (is this still needed?)\n\t\tthis.editor.createShapes([\n\t\t\t{\n\t\t\t\tid,\n\t\t\t\ttype: shapeType,\n\t\t\t\tx: originPagePoint.x,\n\t\t\t\ty: originPagePoint.y,\n\t\t\t},\n\t\t])\n\n\t\tconst shape = this.editor.getShape<TLBaseBoxShape>(id)!\n\t\tif (!shape) {\n\t\t\tthis.cancel()\n\t\t\treturn\n\t\t}\n\n\t\tlet { w, h } = shape.props\n\t\tconst delta = new Vec(w / 2, h / 2)\n\t\tconst parentTransform = this.editor.getShapeParentTransform(shape)\n\t\tif (parentTransform) delta.rot(-parentTransform.rotation())\n\t\tlet scale = 1\n\n\t\tif (this.editor.user.getIsDynamicResizeMode()) {\n\t\t\tscale = 1 / this.editor.getZoomLevel()\n\t\t\tw *= scale\n\t\t\th *= scale\n\t\t\tdelta.mul(scale)\n\t\t}\n\n\t\tconst next = structuredClone(shape)\n\t\tconst newPoint = maybeSnapToGrid(new Vec(shape.x - delta.x, shape.y - delta.y), this.editor)\n\t\tnext.x = newPoint.x\n\t\tnext.y = newPoint.y\n\t\tnext.props.w = w\n\t\tnext.props.h = h\n\n\t\tif ('scale' in shape.props) {\n\t\t\t;(next as TLBaseBoxShape & { props: { scale: number } }).props.scale = scale\n\t\t}\n\n\t\tthis.editor.updateShape(next)\n\n\t\tthis.editor.setSelectedShapes([id])\n\n\t\tif (this.editor.getInstanceState().isToolLocked) {\n\t\t\tthis.parent.transition('idle')\n\t\t} else {\n\t\t\tthis.editor.setCurrentTool('select.idle')\n\t\t}\n\t}\n\n\tcancel() {\n\t\tthis.parent.transition('idle')\n\t}\n}\n\n/**\n * Checks if grid mode is enabled and snaps a point to the grid if so\n *\n * @public\n */\nexport function maybeSnapToGrid(point: Vec, editor: Editor): Vec {\n\tconst isGridMode = editor.getInstanceState().isGridMode\n\tconst gridSize = editor.getDocumentSettings().gridSize\n\tif (isGridMode) return point.clone().snapToGrid(gridSize)\n\treturn point.clone()\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["shape"]
|
|
7
7
|
}
|