@tldraw/editor 5.4.0-next.ebc95cf01337 → 5.4.0
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 +67 -1
- package/dist-cjs/index.js +4 -1
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawEditor.js +7 -2
- package/dist-cjs/lib/TldrawEditor.js.map +2 -2
- package/dist-cjs/lib/components/MenuClickCapture.js +6 -8
- package/dist-cjs/lib/components/MenuClickCapture.js.map +2 -2
- package/dist-cjs/lib/components/default-components/CanvasOverlays.js +1 -3
- package/dist-cjs/lib/components/default-components/CanvasOverlays.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +1 -1
- package/dist-cjs/lib/config/TLUserPreferences.js +6 -2
- package/dist-cjs/lib/config/TLUserPreferences.js.map +2 -2
- package/dist-cjs/lib/config/createTLStore.js +1 -1
- package/dist-cjs/lib/config/createTLStore.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +164 -280
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js +3 -3
- package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.js +8 -8
- package/dist-cjs/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/FontManager/FontManager.js +2 -1
- package/dist-cjs/lib/editor/managers/FontManager/FontManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js +79 -6
- package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js +7 -0
- package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js +0 -2
- package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js.map +2 -2
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js +1 -2
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/TickManager/TickManager.js +6 -3
- package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +12 -1
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
- package/dist-cjs/lib/editor/overlays/OverlayManager.js +3 -7
- package/dist-cjs/lib/editor/overlays/OverlayManager.js.map +2 -2
- package/dist-cjs/lib/editor/overlays/strokeShapeIndicators.js +0 -1
- package/dist-cjs/lib/editor/overlays/strokeShapeIndicators.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/BaseFrameLikeShapeUtil.js +3 -1
- package/dist-cjs/lib/editor/shapes/BaseFrameLikeShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/shared/getPerfectDashProps.js +1 -0
- package/dist-cjs/lib/editor/shapes/shared/getPerfectDashProps.js.map +2 -2
- package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js +1 -1
- package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js.map +2 -2
- package/dist-cjs/lib/editor/tools/StateNode.js +3 -2
- package/dist-cjs/lib/editor/tools/StateNode.js.map +2 -2
- package/dist-cjs/lib/globals/editors.js +57 -0
- package/dist-cjs/lib/globals/editors.js.map +7 -0
- package/dist-cjs/lib/globals/menus.js +9 -4
- package/dist-cjs/lib/globals/menus.js.map +2 -2
- package/dist-cjs/lib/hooks/useCanvasEvents.js +2 -0
- package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useDocumentEvents.js +39 -9
- package/dist-cjs/lib/hooks/useDocumentEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useLocalStore.js +10 -6
- package/dist-cjs/lib/hooks/useLocalStore.js.map +2 -2
- package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js +1 -0
- package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/usePeerIds.js +2 -1
- package/dist-cjs/lib/hooks/usePeerIds.js.map +2 -2
- package/dist-cjs/lib/license/LicenseManager.js +9 -2
- package/dist-cjs/lib/license/LicenseManager.js.map +2 -2
- package/dist-cjs/lib/license/LicenseProvider.js +16 -3
- package/dist-cjs/lib/license/LicenseProvider.js.map +2 -2
- package/dist-cjs/lib/license/useLicenseManagerState.js +5 -4
- package/dist-cjs/lib/license/useLicenseManagerState.js.map +2 -2
- package/dist-cjs/lib/primitives/Box.js +2 -1
- package/dist-cjs/lib/primitives/Box.js.map +2 -2
- package/dist-cjs/lib/primitives/Vec.js +4 -3
- package/dist-cjs/lib/primitives/Vec.js.map +2 -2
- package/dist-cjs/lib/primitives/utils.js +2 -1
- package/dist-cjs/lib/primitives/utils.js.map +2 -2
- package/dist-cjs/lib/utils/deepLinks.js +5 -1
- package/dist-cjs/lib/utils/deepLinks.js.map +2 -2
- package/dist-cjs/lib/utils/rotation.js +1 -9
- package/dist-cjs/lib/utils/rotation.js.map +2 -2
- package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js +17 -0
- package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js.map +2 -2
- package/dist-cjs/lib/utils/sync/alerts.js +1 -1
- package/dist-cjs/lib/utils/sync/alerts.js.map +1 -1
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +67 -1
- package/dist-esm/index.mjs +9 -2
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawEditor.mjs +9 -4
- package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
- package/dist-esm/lib/components/MenuClickCapture.mjs +6 -8
- package/dist-esm/lib/components/MenuClickCapture.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/CanvasOverlays.mjs +1 -3
- package/dist-esm/lib/components/default-components/CanvasOverlays.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +1 -1
- package/dist-esm/lib/config/TLUserPreferences.mjs +6 -2
- package/dist-esm/lib/config/TLUserPreferences.mjs.map +2 -2
- package/dist-esm/lib/config/createTLStore.mjs +1 -1
- package/dist-esm/lib/config/createTLStore.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +172 -281
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs +3 -3
- package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.mjs +9 -9
- package/dist-esm/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs +2 -1
- package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs +81 -8
- package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs +7 -0
- package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs +0 -2
- package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs +2 -3
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs +6 -3
- package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +12 -1
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
- package/dist-esm/lib/editor/overlays/OverlayManager.mjs +3 -7
- package/dist-esm/lib/editor/overlays/OverlayManager.mjs.map +2 -2
- package/dist-esm/lib/editor/overlays/strokeShapeIndicators.mjs +0 -1
- package/dist-esm/lib/editor/overlays/strokeShapeIndicators.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/BaseFrameLikeShapeUtil.mjs +3 -1
- package/dist-esm/lib/editor/shapes/BaseFrameLikeShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs +1 -0
- package/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs.map +2 -2
- package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs +1 -1
- package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs.map +2 -2
- package/dist-esm/lib/editor/tools/StateNode.mjs +3 -2
- package/dist-esm/lib/editor/tools/StateNode.mjs.map +2 -2
- package/dist-esm/lib/globals/editors.mjs +37 -0
- package/dist-esm/lib/globals/editors.mjs.map +7 -0
- package/dist-esm/lib/globals/menus.mjs +9 -4
- package/dist-esm/lib/globals/menus.mjs.map +2 -2
- package/dist-esm/lib/hooks/useCanvasEvents.mjs +2 -0
- package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useDocumentEvents.mjs +40 -10
- package/dist-esm/lib/hooks/useDocumentEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useLocalStore.mjs +11 -7
- package/dist-esm/lib/hooks/useLocalStore.mjs.map +2 -2
- package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs +1 -0
- package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/usePeerIds.mjs +2 -1
- package/dist-esm/lib/hooks/usePeerIds.mjs.map +2 -2
- package/dist-esm/lib/license/LicenseManager.mjs +9 -2
- package/dist-esm/lib/license/LicenseManager.mjs.map +2 -2
- package/dist-esm/lib/license/LicenseProvider.mjs +16 -3
- package/dist-esm/lib/license/LicenseProvider.mjs.map +2 -2
- package/dist-esm/lib/license/useLicenseManagerState.mjs +5 -4
- package/dist-esm/lib/license/useLicenseManagerState.mjs.map +2 -2
- package/dist-esm/lib/primitives/Box.mjs +2 -1
- package/dist-esm/lib/primitives/Box.mjs.map +2 -2
- package/dist-esm/lib/primitives/Vec.mjs +4 -3
- package/dist-esm/lib/primitives/Vec.mjs.map +2 -2
- package/dist-esm/lib/primitives/utils.mjs +2 -1
- package/dist-esm/lib/primitives/utils.mjs.map +2 -2
- package/dist-esm/lib/utils/deepLinks.mjs +5 -1
- package/dist-esm/lib/utils/deepLinks.mjs.map +2 -2
- package/dist-esm/lib/utils/rotation.mjs +1 -9
- package/dist-esm/lib/utils/rotation.mjs.map +2 -2
- package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs +17 -0
- package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map +2 -2
- package/dist-esm/lib/utils/sync/alerts.mjs +1 -1
- package/dist-esm/lib/utils/sync/alerts.mjs.map +1 -1
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/package.json +13 -7
- package/src/index.ts +6 -1
- package/src/lib/TldrawEditor.tsx +16 -4
- package/src/lib/components/MenuClickCapture.tsx +19 -18
- package/src/lib/components/default-components/CanvasOverlays.tsx +1 -3
- package/src/lib/components/default-components/DefaultErrorFallback.tsx +1 -1
- package/src/lib/config/TLUserPreferences.test.ts +18 -1
- package/src/lib/config/TLUserPreferences.ts +8 -4
- package/src/lib/config/createTLStore.ts +1 -1
- package/src/lib/editor/Editor.ts +241 -359
- package/src/lib/editor/managers/ClickManager/ClickManager.ts +5 -3
- package/src/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.ts +9 -9
- package/src/lib/editor/managers/FontManager/FontManager.ts +2 -1
- package/src/lib/editor/managers/InputsManager/InputsManager.test.ts +199 -3
- package/src/lib/editor/managers/InputsManager/InputsManager.ts +128 -9
- package/src/lib/editor/managers/ScribbleManager/ScribbleManager.ts +12 -1
- package/src/lib/editor/managers/SnapManager/BoundsSnaps.ts +0 -2
- package/src/lib/editor/managers/TextManager/TextManager.ts +2 -6
- package/src/lib/editor/managers/TickManager/TickManager.test.ts +13 -0
- package/src/lib/editor/managers/TickManager/TickManager.ts +9 -3
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +64 -3
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +18 -1
- package/src/lib/editor/overlays/OverlayManager.ts +3 -7
- package/src/lib/editor/overlays/strokeShapeIndicators.ts +0 -1
- package/src/lib/editor/shapes/BaseFrameLikeShapeUtil.tsx +5 -1
- package/src/lib/editor/shapes/shared/getPerfectDashProps.ts +3 -0
- package/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts +4 -1
- package/src/lib/editor/tools/StateNode.test.ts +64 -0
- package/src/lib/editor/tools/StateNode.ts +12 -2
- package/src/lib/globals/editors.test.ts +76 -0
- package/src/lib/globals/editors.ts +53 -0
- package/src/lib/globals/menus.test.ts +33 -0
- package/src/lib/globals/menus.ts +11 -4
- package/src/lib/hooks/useCanvasEvents.ts +2 -0
- package/src/lib/hooks/useDocumentEvents.ts +60 -16
- package/src/lib/hooks/useLocalStore.ts +16 -8
- package/src/lib/hooks/usePassThroughWheelEvents.ts +3 -0
- package/src/lib/hooks/usePeerIds.ts +2 -1
- package/src/lib/license/LicenseManager.test.ts +160 -0
- package/src/lib/license/LicenseManager.ts +13 -4
- package/src/lib/license/LicenseProvider.tsx +24 -3
- package/src/lib/license/useLicenseManagerState.ts +8 -6
- package/src/lib/primitives/Box.test.ts +9 -1
- package/src/lib/primitives/Box.ts +3 -1
- package/src/lib/primitives/Vec.test.ts +10 -0
- package/src/lib/primitives/Vec.ts +4 -4
- package/src/lib/primitives/geometry/Arc2d.test.ts +226 -3
- package/src/lib/primitives/geometry/CubicBezier2d.test.ts +173 -3
- package/src/lib/primitives/geometry/CubicSpline2d.test.ts +160 -3
- package/src/lib/primitives/geometry/Ellipse2d.test.ts +243 -3
- package/src/lib/primitives/geometry/Geometry2d.test.ts +553 -1
- package/src/lib/primitives/geometry/Group2d.test.ts +398 -3
- package/src/lib/primitives/geometry/Polyline2d.test.ts +207 -0
- package/src/lib/primitives/geometry/Stadium2d.test.ts +191 -3
- package/src/lib/primitives/utils.test.ts +10 -1
- package/src/lib/primitives/utils.ts +4 -1
- package/src/lib/test/useCanvasEvents.test.tsx +74 -0
- package/src/lib/test/useDocumentEvents.test.tsx +107 -0
- package/src/lib/test/usePassThroughWheelEvents.test.tsx +25 -2
- package/src/lib/utils/deepLinks.test.ts +15 -0
- package/src/lib/utils/deepLinks.ts +7 -1
- package/src/lib/utils/rotation.ts +4 -12
- package/src/lib/utils/sync/TLLocalSyncClient.test.ts +56 -0
- package/src/lib/utils/sync/TLLocalSyncClient.ts +24 -0
- package/src/lib/utils/sync/alerts.ts +1 -1
- package/src/version.ts +3 -3
- package/src/lib/primitives/geometry/Polyline.test.ts +0 -5
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
Result,
|
|
40
40
|
ZERO_INDEX_KEY,
|
|
41
41
|
annotateError,
|
|
42
|
+
areArraysShallowEqual,
|
|
42
43
|
assert,
|
|
43
44
|
assertExists,
|
|
44
45
|
bind,
|
|
@@ -83,6 +84,7 @@ import {
|
|
|
83
84
|
import { getOwnerWindow } from "../exports/domUtils.mjs";
|
|
84
85
|
import { exportToSvg } from "../exports/exportToSvg.mjs";
|
|
85
86
|
import { getSvgAsImageWithOptions, trimSvgToContent } from "../exports/getSvgAsImage.mjs";
|
|
87
|
+
import { registerMountedEditor, unregisterMountedEditor } from "../globals/editors.mjs";
|
|
86
88
|
import { tlmenus } from "../globals/menus.mjs";
|
|
87
89
|
import { tltime } from "../globals/time.mjs";
|
|
88
90
|
import { defaultTldrawOptions } from "../options.mjs";
|
|
@@ -91,7 +93,13 @@ import { EASINGS } from "../primitives/easings.mjs";
|
|
|
91
93
|
import { Group2d } from "../primitives/geometry/Group2d.mjs";
|
|
92
94
|
import { intersectPolygonPolygon } from "../primitives/intersect.mjs";
|
|
93
95
|
import { Mat } from "../primitives/Mat.mjs";
|
|
94
|
-
import {
|
|
96
|
+
import {
|
|
97
|
+
HALF_PI,
|
|
98
|
+
approximately,
|
|
99
|
+
areAnglesCompatible,
|
|
100
|
+
clamp,
|
|
101
|
+
pointInPolygon
|
|
102
|
+
} from "../primitives/utils.mjs";
|
|
95
103
|
import { Vec } from "../primitives/Vec.mjs";
|
|
96
104
|
import { areShapesContentEqual } from "../utils/areShapesContentEqual.mjs";
|
|
97
105
|
import { dataUrlToFile } from "../utils/assets.mjs";
|
|
@@ -289,6 +297,10 @@ class Editor extends EventEmitter {
|
|
|
289
297
|
if (!nextPageState) nextPageState = { ...prevPageState };
|
|
290
298
|
nextPageState.editingShapeId = null;
|
|
291
299
|
}
|
|
300
|
+
if (prevPageState.croppingShapeId && shapesNoLongerInPage.has(prevPageState.croppingShapeId)) {
|
|
301
|
+
if (!nextPageState) nextPageState = { ...prevPageState };
|
|
302
|
+
nextPageState.croppingShapeId = null;
|
|
303
|
+
}
|
|
292
304
|
const hintingShapeIds = prevPageState.hintingShapeIds.filter(
|
|
293
305
|
(id) => !shapesNoLongerInPage.has(id)
|
|
294
306
|
);
|
|
@@ -531,10 +543,11 @@ class Editor extends EventEmitter {
|
|
|
531
543
|
this.cancelDoubleClick();
|
|
532
544
|
}
|
|
533
545
|
if (prev?.selectedShapeIds !== next?.selectedShapeIds) {
|
|
546
|
+
const selectedShapeIds = new Set(next.selectedShapeIds);
|
|
534
547
|
const filtered = next.selectedShapeIds.filter((id) => {
|
|
535
548
|
let parentId = this.getShape(id)?.parentId;
|
|
536
549
|
while (isShapeId(parentId)) {
|
|
537
|
-
if (
|
|
550
|
+
if (selectedShapeIds.has(parentId)) {
|
|
538
551
|
return false;
|
|
539
552
|
}
|
|
540
553
|
parentId = this.getShape(parentId)?.parentId;
|
|
@@ -604,9 +617,11 @@ class Editor extends EventEmitter {
|
|
|
604
617
|
this.on("tick", this._flushEventsForTick);
|
|
605
618
|
this.on("mount", () => {
|
|
606
619
|
this._isMounted.set(true);
|
|
620
|
+
registerMountedEditor(this);
|
|
607
621
|
});
|
|
608
622
|
this.on("unmount", () => {
|
|
609
623
|
this._isMounted.set(false);
|
|
624
|
+
unregisterMountedEditor(this);
|
|
610
625
|
});
|
|
611
626
|
this.timers.requestAnimationFrame(() => {
|
|
612
627
|
this._tickManager.start();
|
|
@@ -616,7 +631,10 @@ class Editor extends EventEmitter {
|
|
|
616
631
|
const mode = this.store.props.collaboration.mode;
|
|
617
632
|
this.disposables.add(
|
|
618
633
|
react("update collaboration mode", () => {
|
|
619
|
-
|
|
634
|
+
const isReadonly = mode.get() === "readonly";
|
|
635
|
+
unsafe__withoutCapture(
|
|
636
|
+
() => this._updateInstanceState({ isReadonly }, { history: "ignore" })
|
|
637
|
+
);
|
|
620
638
|
})
|
|
621
639
|
);
|
|
622
640
|
}
|
|
@@ -646,6 +664,14 @@ class Editor extends EventEmitter {
|
|
|
646
664
|
);
|
|
647
665
|
}
|
|
648
666
|
options;
|
|
667
|
+
/**
|
|
668
|
+
* The license manager whose feature flags apply to this editor. Assigned by `<TldrawEditor />`
|
|
669
|
+
* when it creates the editor, so that UI rendered outside the editor tree can resolve the
|
|
670
|
+
* editor's license through the editor instance. Undefined for editors created directly.
|
|
671
|
+
*
|
|
672
|
+
* @internal
|
|
673
|
+
*/
|
|
674
|
+
licenseManager;
|
|
649
675
|
contextId = uniqueId();
|
|
650
676
|
/**
|
|
651
677
|
* The editor's store
|
|
@@ -840,6 +866,7 @@ class Editor extends EventEmitter {
|
|
|
840
866
|
if (this._isMounted.get()) {
|
|
841
867
|
this.emit("unmount");
|
|
842
868
|
}
|
|
869
|
+
unregisterMountedEditor(this);
|
|
843
870
|
this.stopCameraAnimation();
|
|
844
871
|
if (this.getInstanceState().followingUserId) {
|
|
845
872
|
this.stopFollowingUser();
|
|
@@ -965,7 +992,7 @@ class Editor extends EventEmitter {
|
|
|
965
992
|
getShapeUtil(arg) {
|
|
966
993
|
const type = typeof arg === "string" ? arg : arg.type;
|
|
967
994
|
const shapeUtil = getOwnProperty(this.shapeUtils, type);
|
|
968
|
-
|
|
995
|
+
if (!shapeUtil) throw new Error(`No shape util found for type "${type}"`);
|
|
969
996
|
return shapeUtil;
|
|
970
997
|
}
|
|
971
998
|
hasShapeUtil(arg) {
|
|
@@ -1754,7 +1781,9 @@ class Editor extends EventEmitter {
|
|
|
1754
1781
|
const selectedShapes = this.getSelectedShapes();
|
|
1755
1782
|
if (!selectedShapes.length) return;
|
|
1756
1783
|
const selectedShape = selectedShapes[0];
|
|
1757
|
-
const children =
|
|
1784
|
+
const children = compact(
|
|
1785
|
+
this.getSortedChildIdsForParent(selectedShape.id).map((id) => this.getShape(id))
|
|
1786
|
+
);
|
|
1758
1787
|
const sortedChildren = this._getShapesInReadingOrder(children);
|
|
1759
1788
|
if (sortedChildren.length === 0) return;
|
|
1760
1789
|
this._selectShapesAndZoom([sortedChildren[0].id]);
|
|
@@ -1821,18 +1850,13 @@ class Editor extends EventEmitter {
|
|
|
1821
1850
|
* @internal
|
|
1822
1851
|
*/
|
|
1823
1852
|
getShapesSharedRotation(shapeIds) {
|
|
1824
|
-
let foundFirst = false;
|
|
1825
1853
|
let rotation = 0;
|
|
1826
1854
|
for (let i = 0, n = shapeIds.length; i < n; i++) {
|
|
1827
|
-
const
|
|
1828
|
-
if (
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
}
|
|
1833
|
-
} else {
|
|
1834
|
-
foundFirst = true;
|
|
1835
|
-
rotation = pageTransform.rotation();
|
|
1855
|
+
const pageRotation = this.getShapePageTransform(shapeIds[i]).rotation();
|
|
1856
|
+
if (i === 0) {
|
|
1857
|
+
rotation = pageRotation;
|
|
1858
|
+
} else if (pageRotation !== rotation) {
|
|
1859
|
+
return 0;
|
|
1836
1860
|
}
|
|
1837
1861
|
}
|
|
1838
1862
|
return rotation;
|
|
@@ -1858,11 +1882,9 @@ class Editor extends EventEmitter {
|
|
|
1858
1882
|
return bounds;
|
|
1859
1883
|
}
|
|
1860
1884
|
const boxFromRotatedVertices = Box.FromPoints(
|
|
1861
|
-
shapeIds.flatMap(
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
return pageTransform.applyToPoints(this.getShapeGeometry(id).bounds.corners);
|
|
1865
|
-
}).map((p) => p.rot(-selectionRotation))
|
|
1885
|
+
shapeIds.flatMap(
|
|
1886
|
+
(id) => this.getShapePageTransform(id).applyToPoints(this.getShapeGeometry(id).bounds.corners)
|
|
1887
|
+
).map((p) => p.rot(-selectionRotation))
|
|
1866
1888
|
);
|
|
1867
1889
|
boxFromRotatedVertices.point = boxFromRotatedVertices.point.rot(selectionRotation);
|
|
1868
1890
|
return boxFromRotatedVertices;
|
|
@@ -1873,9 +1895,14 @@ class Editor extends EventEmitter {
|
|
|
1873
1895
|
getSelectionRotatedScreenBounds() {
|
|
1874
1896
|
const bounds = this.getSelectionRotatedPageBounds();
|
|
1875
1897
|
if (!bounds) return void 0;
|
|
1876
|
-
const
|
|
1877
|
-
const zoom = this.
|
|
1878
|
-
return new Box(
|
|
1898
|
+
const screenBounds = this.getViewportScreenBounds();
|
|
1899
|
+
const { x: cx, y: cy, z: zoom } = this.getCamera();
|
|
1900
|
+
return new Box(
|
|
1901
|
+
(bounds.x + cx) * zoom + screenBounds.x,
|
|
1902
|
+
(bounds.y + cy) * zoom + screenBounds.y,
|
|
1903
|
+
bounds.width * zoom,
|
|
1904
|
+
bounds.height * zoom
|
|
1905
|
+
);
|
|
1879
1906
|
}
|
|
1880
1907
|
getFocusedGroupId() {
|
|
1881
1908
|
return this.getCurrentPageState().focusedGroupId ?? this.getCurrentPageId();
|
|
@@ -1976,42 +2003,28 @@ class Editor extends EventEmitter {
|
|
|
1976
2003
|
*/
|
|
1977
2004
|
setEditingShape(shape) {
|
|
1978
2005
|
const id = typeof shape === "string" ? shape : shape?.id ?? null;
|
|
1979
|
-
if (!id)
|
|
2006
|
+
if (id && !this.canEditShape(id)) return this;
|
|
2007
|
+
this.run(() => {
|
|
2008
|
+
const prevEditingShapeId = this.getEditingShapeId();
|
|
2009
|
+
if (prevEditingShapeId) {
|
|
2010
|
+
const prevEditingShape = this.getShape(prevEditingShapeId);
|
|
2011
|
+
if (prevEditingShape) {
|
|
2012
|
+
this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape);
|
|
2013
|
+
}
|
|
2014
|
+
}
|
|
1980
2015
|
this.run(
|
|
1981
2016
|
() => {
|
|
1982
|
-
const prevEditingShapeId = this.getEditingShapeId();
|
|
1983
|
-
if (prevEditingShapeId) {
|
|
1984
|
-
const prevEditingShape = this.getShape(prevEditingShapeId);
|
|
1985
|
-
if (prevEditingShape) {
|
|
1986
|
-
this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape);
|
|
1987
|
-
}
|
|
1988
|
-
}
|
|
1989
2017
|
this._updateCurrentPageState({ editingShapeId: null });
|
|
1990
2018
|
this._currentRichTextEditor.set(null);
|
|
2019
|
+
if (!id) return;
|
|
2020
|
+
this.select(id);
|
|
2021
|
+
this._updateCurrentPageState({ editingShapeId: id });
|
|
2022
|
+
const nextEditingShape = this.getShape(id);
|
|
2023
|
+
this.getShapeUtil(nextEditingShape).onEditStart?.(nextEditingShape);
|
|
1991
2024
|
},
|
|
1992
2025
|
{ history: "ignore" }
|
|
1993
2026
|
);
|
|
1994
|
-
|
|
1995
|
-
}
|
|
1996
|
-
if (!this.canEditShape(id)) return this;
|
|
1997
|
-
this.run(
|
|
1998
|
-
() => {
|
|
1999
|
-
const prevEditingShapeId = this.getEditingShapeId();
|
|
2000
|
-
if (prevEditingShapeId) {
|
|
2001
|
-
const prevEditingShape = this.getShape(prevEditingShapeId);
|
|
2002
|
-
if (prevEditingShape) {
|
|
2003
|
-
this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape);
|
|
2004
|
-
}
|
|
2005
|
-
}
|
|
2006
|
-
this._updateCurrentPageState({ editingShapeId: null });
|
|
2007
|
-
this._currentRichTextEditor.set(null);
|
|
2008
|
-
this.select(id);
|
|
2009
|
-
this._updateCurrentPageState({ editingShapeId: id });
|
|
2010
|
-
const nextEditingShape = this.getShape(id);
|
|
2011
|
-
this.getShapeUtil(nextEditingShape).onEditStart?.(nextEditingShape);
|
|
2012
|
-
},
|
|
2013
|
-
{ history: "ignore" }
|
|
2014
|
-
);
|
|
2027
|
+
});
|
|
2015
2028
|
return this;
|
|
2016
2029
|
}
|
|
2017
2030
|
// Rich text editor
|
|
@@ -2117,19 +2130,12 @@ class Editor extends EventEmitter {
|
|
|
2117
2130
|
* @public
|
|
2118
2131
|
*/
|
|
2119
2132
|
setErasingShapes(shapes) {
|
|
2120
|
-
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((shape) => shape.id);
|
|
2133
|
+
const ids = typeof shapes[0] === "string" ? shapes.slice() : shapes.map((shape) => shape.id);
|
|
2121
2134
|
ids.sort();
|
|
2122
2135
|
const erasingShapeIds = this.getErasingShapeIds();
|
|
2123
2136
|
this.run(
|
|
2124
2137
|
() => {
|
|
2125
|
-
if (ids
|
|
2126
|
-
for (let i = 0; i < ids.length; i++) {
|
|
2127
|
-
if (ids[i] !== erasingShapeIds[i]) {
|
|
2128
|
-
this._updateCurrentPageState({ erasingShapeIds: ids });
|
|
2129
|
-
break;
|
|
2130
|
-
}
|
|
2131
|
-
}
|
|
2132
|
-
} else {
|
|
2138
|
+
if (!areArraysShallowEqual(ids, erasingShapeIds)) {
|
|
2133
2139
|
this._updateCurrentPageState({ erasingShapeIds: ids });
|
|
2134
2140
|
}
|
|
2135
2141
|
},
|
|
@@ -2162,6 +2168,7 @@ class Editor extends EventEmitter {
|
|
|
2162
2168
|
if (!_shape) return false;
|
|
2163
2169
|
const util = this.getShapeUtil(_shape);
|
|
2164
2170
|
if (!util.canCrop(_shape)) return false;
|
|
2171
|
+
if (this.getIsReadonly()) return false;
|
|
2165
2172
|
if (this.isShapeOrAncestorLocked(_shape)) return false;
|
|
2166
2173
|
return true;
|
|
2167
2174
|
}
|
|
@@ -2226,11 +2233,11 @@ class Editor extends EventEmitter {
|
|
|
2226
2233
|
const collaborators = this.getCollaborators();
|
|
2227
2234
|
let leaderPresence = null;
|
|
2228
2235
|
while (targetUserId && !visited.includes(targetUserId)) {
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2236
|
+
const nextPresence = collaborators.find((c) => c.userId === targetUserId);
|
|
2237
|
+
if (!nextPresence) break;
|
|
2238
|
+
leaderPresence = nextPresence;
|
|
2239
|
+
targetUserId = nextPresence.followingUserId ?? null;
|
|
2240
|
+
visited.push(nextPresence.userId);
|
|
2234
2241
|
}
|
|
2235
2242
|
return leaderPresence;
|
|
2236
2243
|
}
|
|
@@ -2293,39 +2300,7 @@ class Editor extends EventEmitter {
|
|
|
2293
2300
|
*
|
|
2294
2301
|
* @public */
|
|
2295
2302
|
getInitialZoom() {
|
|
2296
|
-
|
|
2297
|
-
if (!cameraOptions.constraints) return 1;
|
|
2298
|
-
if (cameraOptions.constraints.initialZoom === "default") return 1;
|
|
2299
|
-
const { zx, zy } = getCameraFitXFitY(this, cameraOptions);
|
|
2300
|
-
switch (cameraOptions.constraints.initialZoom) {
|
|
2301
|
-
case "fit-min": {
|
|
2302
|
-
return Math.max(zx, zy);
|
|
2303
|
-
}
|
|
2304
|
-
case "fit-max": {
|
|
2305
|
-
return Math.min(zx, zy);
|
|
2306
|
-
}
|
|
2307
|
-
case "fit-x": {
|
|
2308
|
-
return zx;
|
|
2309
|
-
}
|
|
2310
|
-
case "fit-y": {
|
|
2311
|
-
return zy;
|
|
2312
|
-
}
|
|
2313
|
-
case "fit-min-100": {
|
|
2314
|
-
return Math.min(1, Math.max(zx, zy));
|
|
2315
|
-
}
|
|
2316
|
-
case "fit-max-100": {
|
|
2317
|
-
return Math.min(1, Math.min(zx, zy));
|
|
2318
|
-
}
|
|
2319
|
-
case "fit-x-100": {
|
|
2320
|
-
return Math.min(1, zx);
|
|
2321
|
-
}
|
|
2322
|
-
case "fit-y-100": {
|
|
2323
|
-
return Math.min(1, zy);
|
|
2324
|
-
}
|
|
2325
|
-
default: {
|
|
2326
|
-
throw exhaustiveSwitchError(cameraOptions.constraints.initialZoom);
|
|
2327
|
-
}
|
|
2328
|
-
}
|
|
2303
|
+
return this._getFitZoom(this.getCameraOptions().constraints?.initialZoom ?? "default");
|
|
2329
2304
|
}
|
|
2330
2305
|
/**
|
|
2331
2306
|
* Get the camera's base level for calculating actual zoom levels based on the zoom steps.
|
|
@@ -2337,11 +2312,13 @@ class Editor extends EventEmitter {
|
|
|
2337
2312
|
*
|
|
2338
2313
|
* @public */
|
|
2339
2314
|
getBaseZoom() {
|
|
2315
|
+
return this._getFitZoom(this.getCameraOptions().constraints?.baseZoom ?? "default");
|
|
2316
|
+
}
|
|
2317
|
+
_getFitZoom(fit) {
|
|
2340
2318
|
const cameraOptions = this.getCameraOptions();
|
|
2341
|
-
if (!cameraOptions.constraints) return 1;
|
|
2342
|
-
if (cameraOptions.constraints.baseZoom === "default") return 1;
|
|
2319
|
+
if (!cameraOptions.constraints || fit === "default") return 1;
|
|
2343
2320
|
const { zx, zy } = getCameraFitXFitY(this, cameraOptions);
|
|
2344
|
-
switch (
|
|
2321
|
+
switch (fit) {
|
|
2345
2322
|
case "fit-min": {
|
|
2346
2323
|
return Math.max(zx, zy);
|
|
2347
2324
|
}
|
|
@@ -2367,7 +2344,7 @@ class Editor extends EventEmitter {
|
|
|
2367
2344
|
return Math.min(1, zy);
|
|
2368
2345
|
}
|
|
2369
2346
|
default: {
|
|
2370
|
-
throw exhaustiveSwitchError(
|
|
2347
|
+
throw exhaustiveSwitchError(fit);
|
|
2371
2348
|
}
|
|
2372
2349
|
}
|
|
2373
2350
|
}
|
|
@@ -2401,7 +2378,7 @@ class Editor extends EventEmitter {
|
|
|
2401
2378
|
...this._cameraOptions.__unsafe__getWithoutCapture(),
|
|
2402
2379
|
...opts
|
|
2403
2380
|
});
|
|
2404
|
-
if (next.zoomSteps
|
|
2381
|
+
if (!next.zoomSteps || next.zoomSteps.length < 1) next.zoomSteps = [1];
|
|
2405
2382
|
this._cameraOptions.set(next);
|
|
2406
2383
|
this.setCamera(this.getCamera());
|
|
2407
2384
|
return this;
|
|
@@ -2422,8 +2399,8 @@ class Editor extends EventEmitter {
|
|
|
2422
2399
|
const vsb = this.getViewportScreenBounds();
|
|
2423
2400
|
if (cameraOptions.constraints) {
|
|
2424
2401
|
const { constraints } = cameraOptions;
|
|
2425
|
-
const
|
|
2426
|
-
const
|
|
2402
|
+
const px = Math.min(constraints.padding.x, vsb.w / 2);
|
|
2403
|
+
const py = Math.min(constraints.padding.y, vsb.h / 2);
|
|
2427
2404
|
const bounds = Box.From(cameraOptions.constraints.bounds);
|
|
2428
2405
|
const zx = (vsb.w - px * 2) / bounds.w;
|
|
2429
2406
|
const zy = (vsb.h - py * 2) / bounds.h;
|
|
@@ -2462,12 +2439,12 @@ class Editor extends EventEmitter {
|
|
|
2462
2439
|
break;
|
|
2463
2440
|
}
|
|
2464
2441
|
case "inside": {
|
|
2465
|
-
if (z < zx) x = clamp(x, minX, (vsb.w - px) / z - bounds.w);
|
|
2442
|
+
if (z < zx) x = clamp(x, minX, (vsb.w - px) / z - bounds.w - bounds.x);
|
|
2466
2443
|
else x = clamp(x, minX + freeW, minX);
|
|
2467
2444
|
break;
|
|
2468
2445
|
}
|
|
2469
2446
|
case "outside": {
|
|
2470
|
-
x = clamp(x, px / z - bounds.w, (vsb.w - px) / z);
|
|
2447
|
+
x = clamp(x, px / z - bounds.w - bounds.x, (vsb.w - px) / z - bounds.x);
|
|
2471
2448
|
break;
|
|
2472
2449
|
}
|
|
2473
2450
|
case "free": {
|
|
@@ -2488,12 +2465,12 @@ class Editor extends EventEmitter {
|
|
|
2488
2465
|
break;
|
|
2489
2466
|
}
|
|
2490
2467
|
case "inside": {
|
|
2491
|
-
if (z < zy) y = clamp(y, minY, (vsb.h - py) / z - bounds.h);
|
|
2468
|
+
if (z < zy) y = clamp(y, minY, (vsb.h - py) / z - bounds.h - bounds.y);
|
|
2492
2469
|
else y = clamp(y, minY + freeH, minY);
|
|
2493
2470
|
break;
|
|
2494
2471
|
}
|
|
2495
2472
|
case "outside": {
|
|
2496
|
-
y = clamp(y, py / z - bounds.h, (vsb.h - py) / z);
|
|
2473
|
+
y = clamp(y, py / z - bounds.h - bounds.y, (vsb.h - py) / z - bounds.y);
|
|
2497
2474
|
break;
|
|
2498
2475
|
}
|
|
2499
2476
|
case "free": {
|
|
@@ -2861,9 +2838,9 @@ class Editor extends EventEmitter {
|
|
|
2861
2838
|
}
|
|
2862
2839
|
const remaining = duration - elapsed;
|
|
2863
2840
|
const t = easing(1 - remaining / duration);
|
|
2864
|
-
const left = start.minX
|
|
2865
|
-
const top = start.minY
|
|
2866
|
-
const right = start.maxX
|
|
2841
|
+
const left = lerp(start.minX, end.minX, t);
|
|
2842
|
+
const top = lerp(start.minY, end.minY, t);
|
|
2843
|
+
const right = lerp(start.maxX, end.maxX, t);
|
|
2867
2844
|
this._setCamera(new Vec(-left, -top, this.getViewportScreenBounds().width / (right - left)), {
|
|
2868
2845
|
force: true
|
|
2869
2846
|
});
|
|
@@ -2941,7 +2918,7 @@ class Editor extends EventEmitter {
|
|
|
2941
2918
|
let newCy = cy + dy;
|
|
2942
2919
|
let newCz = cz;
|
|
2943
2920
|
if (dirZ !== 0) {
|
|
2944
|
-
newCz = cz * (
|
|
2921
|
+
newCz = cz * Math.exp(dirZ * currentSpeed * elapsed);
|
|
2945
2922
|
const center = this.getViewportScreenCenter();
|
|
2946
2923
|
newCx += center.x / newCz - center.x / cz;
|
|
2947
2924
|
newCy += center.y / newCz - center.y / cz;
|
|
@@ -3379,12 +3356,12 @@ class Editor extends EventEmitter {
|
|
|
3379
3356
|
const renderingShapes = [];
|
|
3380
3357
|
let nextIndex = this.options.maxShapesPerPage * 2;
|
|
3381
3358
|
let nextBackgroundIndex = this.options.maxShapesPerPage;
|
|
3382
|
-
const erasingShapeIds = this.getErasingShapeIds();
|
|
3359
|
+
const erasingShapeIds = new Set(this.getErasingShapeIds());
|
|
3383
3360
|
const addShapeById = (id, opacity, isAncestorErasing) => {
|
|
3384
3361
|
const shape = this.getShape(id);
|
|
3385
3362
|
if (!shape) return;
|
|
3386
3363
|
if (this.isShapeHidden(shape)) {
|
|
3387
|
-
const isErasing = isAncestorErasing || erasingShapeIds.
|
|
3364
|
+
const isErasing = isAncestorErasing || erasingShapeIds.has(id);
|
|
3388
3365
|
for (const childId of this.getSortedChildIdsForParent(id)) {
|
|
3389
3366
|
addShapeById(childId, opacity, isErasing);
|
|
3390
3367
|
}
|
|
@@ -3394,7 +3371,7 @@ class Editor extends EventEmitter {
|
|
|
3394
3371
|
let isShapeErasing = false;
|
|
3395
3372
|
const util = this.getShapeUtil(shape);
|
|
3396
3373
|
if (useEditorState) {
|
|
3397
|
-
isShapeErasing = !isAncestorErasing && erasingShapeIds.
|
|
3374
|
+
isShapeErasing = !isAncestorErasing && erasingShapeIds.has(id);
|
|
3398
3375
|
if (isShapeErasing) {
|
|
3399
3376
|
opacity *= 0.32;
|
|
3400
3377
|
}
|
|
@@ -3986,10 +3963,8 @@ class Editor extends EventEmitter {
|
|
|
3986
3963
|
}
|
|
3987
3964
|
_getShapePageBoundsCache() {
|
|
3988
3965
|
return this.store.createComputedCache("pageBoundsCache", (shape) => {
|
|
3989
|
-
const pageTransform = this.getShapePageTransform(shape);
|
|
3990
|
-
if (!pageTransform) return void 0;
|
|
3991
3966
|
return Box.FromPoints(
|
|
3992
|
-
|
|
3967
|
+
this.getShapePageTransform(shape).applyToPoints(this.getShapeGeometry(shape).boundsVertices)
|
|
3993
3968
|
);
|
|
3994
3969
|
});
|
|
3995
3970
|
}
|
|
@@ -4107,7 +4082,9 @@ class Editor extends EventEmitter {
|
|
|
4107
4082
|
if (pageMask) {
|
|
4108
4083
|
if (pageMask.length === 0) return void 0;
|
|
4109
4084
|
const { corners } = pageBounds;
|
|
4110
|
-
if (corners.every((p, i) =>
|
|
4085
|
+
if (pageMask.length === corners.length && corners.every((p, i) => Vec.Equals(p, pageMask[i]))) {
|
|
4086
|
+
return pageBounds.clone();
|
|
4087
|
+
}
|
|
4111
4088
|
const intersection = intersectPolygonPolygon(pageMask, corners);
|
|
4112
4089
|
if (!intersection) return;
|
|
4113
4090
|
return Box.FromPoints(intersection);
|
|
@@ -4346,7 +4323,7 @@ class Editor extends EventEmitter {
|
|
|
4346
4323
|
const pointInShapeSpace = this.getPointInShapeSpace(shape, point);
|
|
4347
4324
|
const shapeUtil = this.getShapeUtil(shape);
|
|
4348
4325
|
const isShapeFrameLike = this.isShapeFrameLike(shape);
|
|
4349
|
-
if (isShapeFrameLike || (this.isShapeOfType(shape, "note") || this.isShapeOfType(shape, "arrow") || this.isShapeOfType(shape, "geo") && shape.props.fill === "none") && shapeUtil.getText(shape)?.trim()) {
|
|
4326
|
+
if (isGroup && (isShapeFrameLike || (this.isShapeOfType(shape, "note") || this.isShapeOfType(shape, "arrow") || this.isShapeOfType(shape, "geo") && shape.props.fill === "none") && shapeUtil.getText(shape)?.trim())) {
|
|
4350
4327
|
for (const childGeometry of geometry.children) {
|
|
4351
4328
|
if (childGeometry.isLabel && childGeometry.isPointInBounds(pointInShapeSpace)) {
|
|
4352
4329
|
return shape;
|
|
@@ -4538,9 +4515,7 @@ class Editor extends EventEmitter {
|
|
|
4538
4515
|
const freshShape = this.getShape(id);
|
|
4539
4516
|
if (!freshShape) return new Vec(0, 0);
|
|
4540
4517
|
if (isPageId(freshShape.parentId)) return Vec.From(point);
|
|
4541
|
-
|
|
4542
|
-
if (!parentTransform) return Vec.From(point);
|
|
4543
|
-
return parentTransform.clone().invert().applyToPoint(point);
|
|
4518
|
+
return this.getShapePageTransform(freshShape.parentId).clone().invert().applyToPoint(point);
|
|
4544
4519
|
}
|
|
4545
4520
|
getCurrentPageShapes() {
|
|
4546
4521
|
return Array.from(this.getCurrentPageShapeIds(), (id) => this.store.get(id));
|
|
@@ -4652,23 +4627,7 @@ class Editor extends EventEmitter {
|
|
|
4652
4627
|
* @public
|
|
4653
4628
|
*/
|
|
4654
4629
|
isShapeInPage(shape, pageId = this.getCurrentPageId()) {
|
|
4655
|
-
|
|
4656
|
-
const shapeToCheck = this.getShape(id);
|
|
4657
|
-
if (!shapeToCheck) return false;
|
|
4658
|
-
let shapeIsInPage = false;
|
|
4659
|
-
if (shapeToCheck.parentId === pageId) {
|
|
4660
|
-
shapeIsInPage = true;
|
|
4661
|
-
} else {
|
|
4662
|
-
let parent = this.getShape(shapeToCheck.parentId);
|
|
4663
|
-
isInPageSearch: while (parent) {
|
|
4664
|
-
if (parent.parentId === pageId) {
|
|
4665
|
-
shapeIsInPage = true;
|
|
4666
|
-
break isInPageSearch;
|
|
4667
|
-
}
|
|
4668
|
-
parent = this.getShape(parent.parentId);
|
|
4669
|
-
}
|
|
4670
|
-
}
|
|
4671
|
-
return shapeIsInPage;
|
|
4630
|
+
return this.getAncestorPageId(shape) === pageId;
|
|
4672
4631
|
}
|
|
4673
4632
|
/**
|
|
4674
4633
|
* Get the id of the containing page for a given shape.
|
|
@@ -4749,10 +4708,7 @@ class Editor extends EventEmitter {
|
|
|
4749
4708
|
for (let i = 0; i < shapesToReparent.length; i++) {
|
|
4750
4709
|
const shape = shapesToReparent[i];
|
|
4751
4710
|
const pageTransform = this.getShapePageTransform(shape);
|
|
4752
|
-
|
|
4753
|
-
const pagePoint = pageTransform.point();
|
|
4754
|
-
if (!pagePoint) continue;
|
|
4755
|
-
const newPoint = invertedParentTransform.applyToPoint(pagePoint);
|
|
4711
|
+
const newPoint = invertedParentTransform.applyToPoint(pageTransform.point());
|
|
4756
4712
|
const newRotation = pageTransform.rotation() - parentPageRotation;
|
|
4757
4713
|
if (shape.id === parentId) {
|
|
4758
4714
|
throw Error("Attempted to reparent a shape to itself!");
|
|
@@ -4841,7 +4797,7 @@ class Editor extends EventEmitter {
|
|
|
4841
4797
|
*/
|
|
4842
4798
|
getShapeAndDescendantIds(ids) {
|
|
4843
4799
|
const shapeIds = /* @__PURE__ */ new Set();
|
|
4844
|
-
for (const shape of ids.map((id) => this.getShape(id)).sort(sortByIndex)) {
|
|
4800
|
+
for (const shape of compact(ids.map((id) => this.getShape(id))).sort(sortByIndex)) {
|
|
4845
4801
|
shapeIds.add(shape.id);
|
|
4846
4802
|
this.visitDescendants(shape, (descendantId) => {
|
|
4847
4803
|
shapeIds.add(descendantId);
|
|
@@ -4863,11 +4819,12 @@ class Editor extends EventEmitter {
|
|
|
4863
4819
|
const draggingShapes = compact(droppingShapes.map((s) => this.getShape(s))).filter(
|
|
4864
4820
|
(s) => !s.isLocked && !this.isShapeHidden(s)
|
|
4865
4821
|
);
|
|
4822
|
+
const excludedIds = this.getShapeAndDescendantIds(draggingShapes.map((s) => s.id));
|
|
4866
4823
|
const maybeDraggingOverShapes = this.getShapesAtPoint(point, {
|
|
4867
4824
|
hitInside: true,
|
|
4868
4825
|
margin: 0
|
|
4869
4826
|
}).filter(
|
|
4870
|
-
(s) => !droppingShapes.includes(s) && !s.isLocked && !this.isShapeHidden(s) && !
|
|
4827
|
+
(s) => !droppingShapes.includes(s) && !s.isLocked && !this.isShapeHidden(s) && !excludedIds.has(s.id)
|
|
4871
4828
|
);
|
|
4872
4829
|
for (const maybeDraggingOverShape of maybeDraggingOverShapes) {
|
|
4873
4830
|
const shapeUtil = this.getShapeUtil(maybeDraggingOverShape);
|
|
@@ -5120,8 +5077,7 @@ class Editor extends EventEmitter {
|
|
|
5120
5077
|
for (const id of ids) {
|
|
5121
5078
|
const shape = this.getShape(id);
|
|
5122
5079
|
const localDelta = Vec.From(offset);
|
|
5123
|
-
|
|
5124
|
-
if (parentTransform) localDelta.rot(-parentTransform.rotation());
|
|
5080
|
+
localDelta.rot(-this.getShapeParentTransform(shape).rotation());
|
|
5125
5081
|
changes.push(this.getChangesToTranslateShape(shape, localDelta.add(shape)));
|
|
5126
5082
|
}
|
|
5127
5083
|
this.updateShapes(changes);
|
|
@@ -5176,7 +5132,7 @@ class Editor extends EventEmitter {
|
|
|
5176
5132
|
if (!originalShape) continue;
|
|
5177
5133
|
let ox = 0;
|
|
5178
5134
|
let oy = 0;
|
|
5179
|
-
if (offset && initialIds.has(originalId)) {
|
|
5135
|
+
if (offset && initialIds.has(originalId) && !shapeIdSet.has(originalShape.parentId)) {
|
|
5180
5136
|
const parentTransform = this.getShapeParentTransform(originalShape);
|
|
5181
5137
|
const vec = new Vec(offset.x, offset.y).rot(-parentTransform.rotation());
|
|
5182
5138
|
ox = vec.x;
|
|
@@ -5290,26 +5246,17 @@ class Editor extends EventEmitter {
|
|
|
5290
5246
|
toggleLock(shapes) {
|
|
5291
5247
|
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
5292
5248
|
if (this.getIsReadonly() || ids.length === 0) return this;
|
|
5293
|
-
let allLocked = true
|
|
5249
|
+
let allLocked = true;
|
|
5294
5250
|
const shapesToToggle = [];
|
|
5295
5251
|
for (const id of ids) {
|
|
5296
5252
|
const shape = this.getShape(id);
|
|
5297
5253
|
if (shape) {
|
|
5298
5254
|
shapesToToggle.push(shape);
|
|
5299
|
-
if (shape.isLocked)
|
|
5300
|
-
allUnlocked = false;
|
|
5301
|
-
} else {
|
|
5302
|
-
allLocked = false;
|
|
5303
|
-
}
|
|
5255
|
+
if (!shape.isLocked) allLocked = false;
|
|
5304
5256
|
}
|
|
5305
5257
|
}
|
|
5306
5258
|
this.run(() => {
|
|
5307
|
-
if (
|
|
5308
|
-
this.updateShapes(
|
|
5309
|
-
shapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))
|
|
5310
|
-
);
|
|
5311
|
-
this.setSelectedShapes([]);
|
|
5312
|
-
} else if (allLocked) {
|
|
5259
|
+
if (allLocked) {
|
|
5313
5260
|
this.updateShapes(
|
|
5314
5261
|
shapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: false }))
|
|
5315
5262
|
);
|
|
@@ -5317,6 +5264,7 @@ class Editor extends EventEmitter {
|
|
|
5317
5264
|
this.updateShapes(
|
|
5318
5265
|
shapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))
|
|
5319
5266
|
);
|
|
5267
|
+
this.setSelectedShapes([]);
|
|
5320
5268
|
}
|
|
5321
5269
|
});
|
|
5322
5270
|
return this;
|
|
@@ -5427,9 +5375,10 @@ class Editor extends EventEmitter {
|
|
|
5427
5375
|
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
5428
5376
|
let freshShapes = compact(ids.map((id) => this.getShape(id)));
|
|
5429
5377
|
if (opts?.filterAxisAligned) {
|
|
5430
|
-
freshShapes = freshShapes.filter(
|
|
5431
|
-
|
|
5432
|
-
|
|
5378
|
+
freshShapes = freshShapes.filter((s) => {
|
|
5379
|
+
const remainder = Math.abs(this.getShapePageTransform(s).rotation() % HALF_PI);
|
|
5380
|
+
return Math.min(remainder, HALF_PI - remainder) < 1e-9;
|
|
5381
|
+
});
|
|
5433
5382
|
}
|
|
5434
5383
|
const clusters = [];
|
|
5435
5384
|
const allBounds = [];
|
|
@@ -5594,9 +5543,9 @@ class Editor extends EventEmitter {
|
|
|
5594
5543
|
dim = "height";
|
|
5595
5544
|
}
|
|
5596
5545
|
let shapeGap = 0;
|
|
5546
|
+
shapeClustersToStack.sort((a, b) => a.pageBounds[min] - b.pageBounds[min]);
|
|
5597
5547
|
if (_gap === 0) {
|
|
5598
5548
|
const gaps = {};
|
|
5599
|
-
shapeClustersToStack.sort((a, b) => a.pageBounds[min] - b.pageBounds[min]);
|
|
5600
5549
|
for (let i = 0; i < len - 1; i++) {
|
|
5601
5550
|
const currCluster = shapeClustersToStack[i];
|
|
5602
5551
|
const nextCluster = shapeClustersToStack[i + 1];
|
|
@@ -5634,8 +5583,7 @@ class Editor extends EventEmitter {
|
|
|
5634
5583
|
const shapeDelta = delta.clone();
|
|
5635
5584
|
const parent = this.getShapeParent(shape);
|
|
5636
5585
|
if (parent) {
|
|
5637
|
-
|
|
5638
|
-
if (parentTransform) shapeDelta.rot(-parentTransform.rotation());
|
|
5586
|
+
shapeDelta.rot(-this.getShapePageTransform(parent).rotation());
|
|
5639
5587
|
}
|
|
5640
5588
|
shapeDelta.add(shape);
|
|
5641
5589
|
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
@@ -5673,7 +5621,7 @@ class Editor extends EventEmitter {
|
|
|
5673
5621
|
}
|
|
5674
5622
|
const commonBounds = Box.Common(allBounds);
|
|
5675
5623
|
const maxWidth = commonBounds.width;
|
|
5676
|
-
shapeClustersToPack.sort((a, b) =>
|
|
5624
|
+
shapeClustersToPack.sort((a, b) => b.pageBounds.width - a.pageBounds.width).sort((a, b) => b.pageBounds.height - a.pageBounds.height);
|
|
5677
5625
|
const startWidth = Math.max(Math.ceil(Math.sqrt(area / 0.95)), maxWidth);
|
|
5678
5626
|
const spaces = [new Box(commonBounds.x, commonBounds.y, startWidth, Infinity)];
|
|
5679
5627
|
let width = 0;
|
|
@@ -5721,8 +5669,7 @@ class Editor extends EventEmitter {
|
|
|
5721
5669
|
const shapeDelta = delta.clone();
|
|
5722
5670
|
const parent = this.getShapeParent(shape);
|
|
5723
5671
|
if (parent) {
|
|
5724
|
-
|
|
5725
|
-
if (parentTransform) shapeDelta.rot(-parentTransform.rotation());
|
|
5672
|
+
shapeDelta.rot(-this.getShapeParentTransform(shape).rotation());
|
|
5726
5673
|
}
|
|
5727
5674
|
shapeDelta.add(shape);
|
|
5728
5675
|
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
@@ -5788,8 +5735,7 @@ class Editor extends EventEmitter {
|
|
|
5788
5735
|
const shapeDelta = delta.clone();
|
|
5789
5736
|
const parent = this.getShapeParent(shape);
|
|
5790
5737
|
if (parent) {
|
|
5791
|
-
|
|
5792
|
-
if (parentTransform) shapeDelta.rot(-parentTransform.rotation());
|
|
5738
|
+
shapeDelta.rot(-this.getShapePageTransform(parent).rotation());
|
|
5793
5739
|
}
|
|
5794
5740
|
shapeDelta.add(shape);
|
|
5795
5741
|
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
@@ -5863,8 +5809,7 @@ class Editor extends EventEmitter {
|
|
|
5863
5809
|
const shapeDelta = delta.clone();
|
|
5864
5810
|
const parent = this.getShapeParent(shape);
|
|
5865
5811
|
if (parent) {
|
|
5866
|
-
|
|
5867
|
-
if (parentTransform) shapeDelta.rot(-parentTransform.rotation());
|
|
5812
|
+
shapeDelta.rot(-this.getShapePageTransform(parent).rotation());
|
|
5868
5813
|
}
|
|
5869
5814
|
shapeDelta.add(shape);
|
|
5870
5815
|
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
@@ -5919,8 +5864,7 @@ class Editor extends EventEmitter {
|
|
|
5919
5864
|
scale[val] = commonBounds[dim] / pageBounds[dim];
|
|
5920
5865
|
for (const shape of shapes2) {
|
|
5921
5866
|
const shapeLocalOffset = localOffset.clone();
|
|
5922
|
-
|
|
5923
|
-
if (parentTransform) shapeLocalOffset.rot(-parentTransform.rotation());
|
|
5867
|
+
shapeLocalOffset.rot(-this.getShapeParentTransform(shape).rotation());
|
|
5924
5868
|
shapeLocalOffset.add(shape);
|
|
5925
5869
|
const changes = this.getChangesToTranslateShape(shape, shapeLocalOffset);
|
|
5926
5870
|
this.updateShape(changes);
|
|
@@ -5976,8 +5920,7 @@ class Editor extends EventEmitter {
|
|
|
5976
5920
|
);
|
|
5977
5921
|
for (const shape of shapes2) {
|
|
5978
5922
|
const shapeLocalOffset = localOffset.clone();
|
|
5979
|
-
|
|
5980
|
-
if (parentTransform) shapeLocalOffset.rot(-parentTransform.rotation());
|
|
5923
|
+
shapeLocalOffset.rot(-this.getShapeParentTransform(shape).rotation());
|
|
5981
5924
|
shapeLocalOffset.add(shape);
|
|
5982
5925
|
const changes = this.getChangesToTranslateShape(shape, shapeLocalOffset);
|
|
5983
5926
|
this.updateShape(changes);
|
|
@@ -6026,9 +5969,7 @@ class Editor extends EventEmitter {
|
|
|
6026
5969
|
const scaleOrigin = opts.scaleOrigin ?? this.getShapePageBounds(id)?.center;
|
|
6027
5970
|
if (!scaleOrigin) return null;
|
|
6028
5971
|
const pageTransform = opts.initialPageTransform ? Mat.Cast(opts.initialPageTransform) : this.getShapePageTransform(id);
|
|
6029
|
-
if (!pageTransform) return null;
|
|
6030
5972
|
const pageRotation = pageTransform.rotation();
|
|
6031
|
-
if (pageRotation == null) return null;
|
|
6032
5973
|
const scaleAxisRotation = opts.scaleAxisRotation ?? pageRotation;
|
|
6033
5974
|
const initialBounds = opts.initialBounds ?? this.getShapeGeometry(id).bounds;
|
|
6034
5975
|
if (!initialBounds) return null;
|
|
@@ -6179,7 +6120,6 @@ class Editor extends EventEmitter {
|
|
|
6179
6120
|
const currentLocalBounds = this.getShapeGeometry(id).bounds;
|
|
6180
6121
|
const currentPageCenter = Mat.applyToPoint(pageTransform, currentLocalBounds.center);
|
|
6181
6122
|
const shapePageTransformOrigin = pageTransform.point();
|
|
6182
|
-
if (!currentPageCenter || !shapePageTransformOrigin) return this;
|
|
6183
6123
|
const pageDelta = Vec.Sub(postScaleShapePageCenter, currentPageCenter);
|
|
6184
6124
|
const postScaleShapePagePoint = Vec.Add(shapePageTransformOrigin, pageDelta);
|
|
6185
6125
|
const { x, y } = this.getPointInParentSpace(id, postScaleShapePagePoint);
|
|
@@ -6438,10 +6378,10 @@ class Editor extends EventEmitter {
|
|
|
6438
6378
|
if (animationIdForShape !== animationId) continue;
|
|
6439
6379
|
updates.push({
|
|
6440
6380
|
...end,
|
|
6441
|
-
x: start.x
|
|
6442
|
-
y: start.y
|
|
6443
|
-
opacity: start.opacity
|
|
6444
|
-
rotation: start.rotation
|
|
6381
|
+
x: lerp(start.x, end.x, t),
|
|
6382
|
+
y: lerp(start.y, end.y, t),
|
|
6383
|
+
opacity: lerp(start.opacity, end.opacity, t),
|
|
6384
|
+
rotation: lerp(start.rotation, end.rotation, t),
|
|
6445
6385
|
props: this.getShapeUtil(end).getInterpolatedProps?.(start, end, t) ?? end.props
|
|
6446
6386
|
});
|
|
6447
6387
|
}
|
|
@@ -6567,7 +6507,7 @@ class Editor extends EventEmitter {
|
|
|
6567
6507
|
* @public
|
|
6568
6508
|
*/
|
|
6569
6509
|
updateShapes(partials) {
|
|
6570
|
-
const compactedPartials =
|
|
6510
|
+
const compactedPartials = [];
|
|
6571
6511
|
for (let i = 0, n = partials.length; i < n; i++) {
|
|
6572
6512
|
const partial = partials[i];
|
|
6573
6513
|
if (!partial) continue;
|
|
@@ -6638,28 +6578,32 @@ class Editor extends EventEmitter {
|
|
|
6638
6578
|
}
|
|
6639
6579
|
/* --------------------- Styles --------------------- */
|
|
6640
6580
|
/**
|
|
6641
|
-
*
|
|
6581
|
+
* Groups have no styles of their own: a style read or write on a selection applies to the
|
|
6582
|
+
* non-group shapes beneath each group, however deeply nested. Returns those shapes.
|
|
6642
6583
|
*
|
|
6643
6584
|
* @internal
|
|
6644
6585
|
*/
|
|
6645
|
-
|
|
6646
|
-
|
|
6647
|
-
|
|
6648
|
-
if (
|
|
6649
|
-
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
|
|
6653
|
-
|
|
6654
|
-
|
|
6586
|
+
_getStyleableShapes(shapes) {
|
|
6587
|
+
const result = [];
|
|
6588
|
+
const visit = (shape) => {
|
|
6589
|
+
if (this.isShapeOfType(shape, "group")) {
|
|
6590
|
+
for (const childId of this.getSortedChildIdsForParent(shape.id)) {
|
|
6591
|
+
const child = this.getShape(childId);
|
|
6592
|
+
if (child) visit(child);
|
|
6593
|
+
}
|
|
6594
|
+
} else {
|
|
6595
|
+
result.push(shape);
|
|
6655
6596
|
}
|
|
6656
|
-
}
|
|
6597
|
+
};
|
|
6598
|
+
for (const shape of shapes) visit(shape);
|
|
6599
|
+
return result;
|
|
6657
6600
|
}
|
|
6658
6601
|
_getSelectionSharedStyles() {
|
|
6659
|
-
const selectedShapes = this.getSelectedShapes();
|
|
6660
6602
|
const sharedStyles = new SharedStyleMap();
|
|
6661
|
-
for (const
|
|
6662
|
-
|
|
6603
|
+
for (const shape of this._getStyleableShapes(this.getSelectedShapes())) {
|
|
6604
|
+
for (const [style, propKey] of this.styleProps[shape.type]) {
|
|
6605
|
+
sharedStyles.applyValue(style, getOwnProperty(shape.props, propKey));
|
|
6606
|
+
}
|
|
6663
6607
|
}
|
|
6664
6608
|
return sharedStyles;
|
|
6665
6609
|
}
|
|
@@ -6691,38 +6635,16 @@ class Editor extends EventEmitter {
|
|
|
6691
6635
|
const styles = new SharedStyleMap();
|
|
6692
6636
|
if (!currentTool) return styles;
|
|
6693
6637
|
if (currentTool.shapeType) {
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
if (style.id === "tldraw:color") continue;
|
|
6697
|
-
styles.applyValue(style, this.getStyleForNextShape(style));
|
|
6698
|
-
}
|
|
6699
|
-
} else {
|
|
6700
|
-
for (const style of this.styleProps[currentTool.shapeType].keys()) {
|
|
6701
|
-
styles.applyValue(style, this.getStyleForNextShape(style));
|
|
6702
|
-
}
|
|
6638
|
+
for (const style of this.styleProps[currentTool.shapeType].keys()) {
|
|
6639
|
+
styles.applyValue(style, this.getStyleForNextShape(style));
|
|
6703
6640
|
}
|
|
6704
6641
|
}
|
|
6705
6642
|
return styles;
|
|
6706
6643
|
}
|
|
6707
6644
|
getSharedOpacity() {
|
|
6708
6645
|
if (this.isIn("select") && this.getSelectedShapeIds().length > 0) {
|
|
6709
|
-
const shapesToCheck = [];
|
|
6710
|
-
const addShape = (shapeId) => {
|
|
6711
|
-
const shape = this.getShape(shapeId);
|
|
6712
|
-
if (!shape) return;
|
|
6713
|
-
if (this.isShapeOfType(shape, "group")) {
|
|
6714
|
-
for (const childId of this.getSortedChildIdsForParent(shape.id)) {
|
|
6715
|
-
addShape(childId);
|
|
6716
|
-
}
|
|
6717
|
-
} else {
|
|
6718
|
-
shapesToCheck.push(shape);
|
|
6719
|
-
}
|
|
6720
|
-
};
|
|
6721
|
-
for (const shapeId of this.getSelectedShapeIds()) {
|
|
6722
|
-
addShape(shapeId);
|
|
6723
|
-
}
|
|
6724
6646
|
let opacity = null;
|
|
6725
|
-
for (const shape of
|
|
6647
|
+
for (const shape of this._getStyleableShapes(this.getSelectedShapes())) {
|
|
6726
6648
|
if (opacity === null) {
|
|
6727
6649
|
opacity = shape.opacity;
|
|
6728
6650
|
} else if (opacity !== shape.opacity) {
|
|
@@ -6761,28 +6683,12 @@ class Editor extends EventEmitter {
|
|
|
6761
6683
|
setOpacityForSelectedShapes(opacity) {
|
|
6762
6684
|
const selectedShapes = this.getSelectedShapes();
|
|
6763
6685
|
if (selectedShapes.length > 0) {
|
|
6764
|
-
const shapesToUpdate = [];
|
|
6765
|
-
const addShapeById = (shape) => {
|
|
6766
|
-
if (this.isShapeOfType(shape, "group")) {
|
|
6767
|
-
const childIds = this.getSortedChildIdsForParent(shape);
|
|
6768
|
-
for (const childId of childIds) {
|
|
6769
|
-
addShapeById(this.getShape(childId));
|
|
6770
|
-
}
|
|
6771
|
-
} else {
|
|
6772
|
-
shapesToUpdate.push(shape);
|
|
6773
|
-
}
|
|
6774
|
-
};
|
|
6775
|
-
for (const id of selectedShapes) {
|
|
6776
|
-
addShapeById(id);
|
|
6777
|
-
}
|
|
6778
6686
|
this.updateShapes(
|
|
6779
|
-
|
|
6780
|
-
|
|
6781
|
-
|
|
6782
|
-
|
|
6783
|
-
|
|
6784
|
-
};
|
|
6785
|
-
})
|
|
6687
|
+
this._getStyleableShapes(selectedShapes).map((shape) => ({
|
|
6688
|
+
id: shape.id,
|
|
6689
|
+
type: shape.type,
|
|
6690
|
+
opacity
|
|
6691
|
+
}))
|
|
6786
6692
|
);
|
|
6787
6693
|
}
|
|
6788
6694
|
return this;
|
|
@@ -6827,33 +6733,17 @@ class Editor extends EventEmitter {
|
|
|
6827
6733
|
const selectedShapes = this.getSelectedShapes();
|
|
6828
6734
|
if (selectedShapes.length > 0) {
|
|
6829
6735
|
const updates = [];
|
|
6830
|
-
const
|
|
6831
|
-
|
|
6832
|
-
|
|
6833
|
-
|
|
6834
|
-
|
|
6835
|
-
|
|
6836
|
-
|
|
6837
|
-
|
|
6838
|
-
const stylePropKey = this.styleProps[shape.type].get(style);
|
|
6839
|
-
if (stylePropKey) {
|
|
6840
|
-
const shapePartial = {
|
|
6841
|
-
id: shape.id,
|
|
6842
|
-
type: shape.type,
|
|
6843
|
-
props: { [stylePropKey]: value }
|
|
6844
|
-
};
|
|
6845
|
-
updates.push({
|
|
6846
|
-
util,
|
|
6847
|
-
originalShape: shape,
|
|
6848
|
-
updatePartial: shapePartial
|
|
6849
|
-
});
|
|
6850
|
-
}
|
|
6736
|
+
for (const shape of this._getStyleableShapes(selectedShapes)) {
|
|
6737
|
+
const stylePropKey = this.styleProps[shape.type].get(style);
|
|
6738
|
+
if (stylePropKey) {
|
|
6739
|
+
updates.push({
|
|
6740
|
+
id: shape.id,
|
|
6741
|
+
type: shape.type,
|
|
6742
|
+
props: { [stylePropKey]: value }
|
|
6743
|
+
});
|
|
6851
6744
|
}
|
|
6852
|
-
};
|
|
6853
|
-
for (const shape of selectedShapes) {
|
|
6854
|
-
addShapeById(shape);
|
|
6855
6745
|
}
|
|
6856
|
-
this.updateShapes(updates
|
|
6746
|
+
this.updateShapes(updates);
|
|
6857
6747
|
}
|
|
6858
6748
|
return this;
|
|
6859
6749
|
}
|
|
@@ -7249,7 +7139,6 @@ class Editor extends EventEmitter {
|
|
|
7249
7139
|
if (shapeIdMap.has(newShape.parentId)) {
|
|
7250
7140
|
newShape.parentId = shapeIdMap.get(oldShape.parentId);
|
|
7251
7141
|
} else {
|
|
7252
|
-
rootShapeIds.push(newShape.id);
|
|
7253
7142
|
newShape.index = index;
|
|
7254
7143
|
index = getIndexAbove(index);
|
|
7255
7144
|
}
|
|
@@ -7274,8 +7163,11 @@ class Editor extends EventEmitter {
|
|
|
7274
7163
|
continue;
|
|
7275
7164
|
}
|
|
7276
7165
|
if (asset.type === "image" && asset.props.src?.startsWith("data:image") || asset.type === "video" && asset.props.src?.startsWith("data:video")) {
|
|
7277
|
-
assetsToUpdate.push(
|
|
7278
|
-
|
|
7166
|
+
assetsToUpdate.push(asset);
|
|
7167
|
+
const assetWithoutSrc = structuredClone(asset);
|
|
7168
|
+
assetWithoutSrc.props.src = null;
|
|
7169
|
+
assetsToCreate.push(assetWithoutSrc);
|
|
7170
|
+
continue;
|
|
7279
7171
|
}
|
|
7280
7172
|
assetsToCreate.push(asset);
|
|
7281
7173
|
}
|
|
@@ -8102,7 +7994,7 @@ class Editor extends EventEmitter {
|
|
|
8102
7994
|
if (info.type === "misc") {
|
|
8103
7995
|
if (info.name === "cancel" || info.name === "complete") {
|
|
8104
7996
|
this.inputs.setIsDragging(false);
|
|
8105
|
-
if (this.inputs.getIsPanning()) {
|
|
7997
|
+
if (this.inputs.getIsPanning() && !this.inputs.keys.has("Space")) {
|
|
8106
7998
|
this.inputs.setIsPanning(false);
|
|
8107
7999
|
this.inputs.setIsSpacebarPanning(false);
|
|
8108
8000
|
this.setCursor({ type: this._prevCursor, rotation: 0 });
|
|
@@ -8854,10 +8746,9 @@ function withIsolatedShapes(editor, shapeIds, callback) {
|
|
|
8854
8746
|
}
|
|
8855
8747
|
function getCameraFitXFitY(editor, cameraOptions) {
|
|
8856
8748
|
if (!cameraOptions.constraints) throw Error("Should have constraints here");
|
|
8857
|
-
const {
|
|
8858
|
-
padding: { x: px, y: py }
|
|
8859
|
-
} = cameraOptions.constraints;
|
|
8860
8749
|
const vsb = editor.getViewportScreenBounds();
|
|
8750
|
+
const px = Math.min(cameraOptions.constraints.padding.x, vsb.w / 2);
|
|
8751
|
+
const py = Math.min(cameraOptions.constraints.padding.y, vsb.h / 2);
|
|
8861
8752
|
const bounds = Box.From(cameraOptions.constraints.bounds);
|
|
8862
8753
|
const zx = (vsb.w - px * 2) / bounds.w;
|
|
8863
8754
|
const zy = (vsb.h - py * 2) / bounds.h;
|