@tldraw/editor 5.5.0-next.f9308d324e1c → 5.5.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 +49 -23
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawEditor.js +16 -12
- package/dist-cjs/lib/TldrawEditor.js.map +2 -2
- package/dist-cjs/lib/components/MenuClickCapture.js +42 -3
- package/dist-cjs/lib/components/MenuClickCapture.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js +5 -1
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js +2 -5
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +3 -3
- package/dist-cjs/lib/components/default-components/DefaultSpinner.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +168 -181
- package/dist-cjs/lib/editor/Editor.js.map +3 -3
- package/dist-cjs/lib/editor/derivations/bindingsIndex.js +2 -0
- package/dist-cjs/lib/editor/derivations/bindingsIndex.js.map +2 -2
- package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js +3 -2
- package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/EditorManager.js +11 -2
- package/dist-cjs/lib/editor/managers/EditorManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceManager.js +49 -63
- package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js +1 -1
- package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js +24 -24
- package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js.map +2 -2
- package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js +7 -1
- package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js.map +2 -2
- package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js +4 -3
- package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js +4 -4
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js +14 -6
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +3 -3
- package/dist-cjs/lib/editor/types/external-content.js.map +1 -1
- package/dist-cjs/lib/exports/ExportDelay.js +10 -2
- package/dist-cjs/lib/exports/ExportDelay.js.map +2 -2
- package/dist-cjs/lib/exports/FontEmbedder.js +25 -11
- package/dist-cjs/lib/exports/FontEmbedder.js.map +2 -2
- package/dist-cjs/lib/exports/StyleEmbedder.js +9 -4
- package/dist-cjs/lib/exports/StyleEmbedder.js.map +2 -2
- package/dist-cjs/lib/exports/fetchCache.js +3 -0
- package/dist-cjs/lib/exports/fetchCache.js.map +2 -2
- package/dist-cjs/lib/exports/getSvgAsImage.js +10 -4
- package/dist-cjs/lib/exports/getSvgAsImage.js.map +2 -2
- package/dist-cjs/lib/exports/getSvgJsx.js +18 -9
- 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 +1 -1
- package/dist-cjs/lib/hooks/EditorComponentsContext.js.map +2 -2
- package/dist-cjs/lib/hooks/useCanvasEvents.js +24 -0
- package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useIdentity.js +6 -2
- package/dist-cjs/lib/hooks/useIdentity.js.map +3 -3
- package/dist-cjs/lib/license/LicenseManager.js +9 -1
- package/dist-cjs/lib/license/LicenseManager.js.map +2 -2
- package/dist-cjs/lib/license/LicenseProvider.js +12 -4
- package/dist-cjs/lib/license/LicenseProvider.js.map +2 -2
- package/dist-cjs/lib/utils/debug-flags.js +0 -6
- package/dist-cjs/lib/utils/debug-flags.js.map +2 -2
- package/dist-cjs/lib/utils/deepLinks.js +2 -1
- package/dist-cjs/lib/utils/deepLinks.js.map +2 -2
- package/dist-cjs/lib/utils/sync/LocalIndexedDb.js +32 -25
- package/dist-cjs/lib/utils/sync/LocalIndexedDb.js.map +2 -2
- package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js +81 -40
- package/dist-cjs/lib/utils/sync/TLLocalSyncClient.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 +49 -23
- package/dist-esm/index.mjs +4 -2
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawEditor.mjs +17 -13
- package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
- package/dist-esm/lib/components/MenuClickCapture.mjs +42 -3
- package/dist-esm/lib/components/MenuClickCapture.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +5 -1
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs +2 -5
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +3 -3
- package/dist-esm/lib/components/default-components/DefaultSpinner.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +168 -181
- package/dist-esm/lib/editor/Editor.mjs.map +3 -3
- package/dist-esm/lib/editor/derivations/bindingsIndex.mjs +2 -0
- package/dist-esm/lib/editor/derivations/bindingsIndex.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs +3 -2
- package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/EditorManager.mjs +11 -2
- package/dist-esm/lib/editor/managers/EditorManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceManager.mjs +49 -63
- package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs +1 -1
- package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs +24 -24
- package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs +7 -1
- package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs +4 -3
- package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs +4 -4
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs +14 -6
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +3 -3
- package/dist-esm/lib/exports/ExportDelay.mjs +11 -3
- package/dist-esm/lib/exports/ExportDelay.mjs.map +2 -2
- package/dist-esm/lib/exports/FontEmbedder.mjs +25 -11
- package/dist-esm/lib/exports/FontEmbedder.mjs.map +2 -2
- package/dist-esm/lib/exports/StyleEmbedder.mjs +9 -4
- package/dist-esm/lib/exports/StyleEmbedder.mjs.map +2 -2
- package/dist-esm/lib/exports/fetchCache.mjs +3 -0
- package/dist-esm/lib/exports/fetchCache.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgAsImage.mjs +10 -4
- package/dist-esm/lib/exports/getSvgAsImage.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs +18 -9
- 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 +1 -1
- package/dist-esm/lib/hooks/EditorComponentsContext.mjs.map +2 -2
- package/dist-esm/lib/hooks/useCanvasEvents.mjs +24 -0
- package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useIdentity.mjs +7 -3
- package/dist-esm/lib/hooks/useIdentity.mjs.map +3 -3
- package/dist-esm/lib/license/LicenseManager.mjs +9 -1
- package/dist-esm/lib/license/LicenseManager.mjs.map +2 -2
- package/dist-esm/lib/license/LicenseProvider.mjs +13 -5
- package/dist-esm/lib/license/LicenseProvider.mjs.map +2 -2
- package/dist-esm/lib/utils/debug-flags.mjs +0 -6
- package/dist-esm/lib/utils/debug-flags.mjs.map +2 -2
- package/dist-esm/lib/utils/deepLinks.mjs +2 -1
- package/dist-esm/lib/utils/deepLinks.mjs.map +2 -2
- package/dist-esm/lib/utils/sync/LocalIndexedDb.mjs +32 -25
- package/dist-esm/lib/utils/sync/LocalIndexedDb.mjs.map +2 -2
- package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs +81 -40
- package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +9 -1
- package/package.json +8 -11
- package/src/index.ts +5 -1
- package/src/lib/TldrawEditor.tsx +35 -21
- package/src/lib/components/MenuClickCapture.tsx +55 -4
- package/src/lib/components/default-components/DefaultCanvas.tsx +7 -1
- package/src/lib/components/default-components/DefaultErrorFallback.tsx +13 -5
- package/src/lib/components/default-components/DefaultSpinner.tsx +4 -1
- package/src/lib/editor/Editor.test.ts +65 -0
- package/src/lib/editor/Editor.ts +261 -294
- package/src/lib/editor/derivations/bindingsIndex.ts +3 -0
- package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +1 -0
- package/src/lib/editor/managers/ClickManager/ClickManager.ts +3 -2
- package/src/lib/editor/managers/EditorManager.test.ts +32 -1
- package/src/lib/editor/managers/EditorManager.ts +15 -3
- package/src/lib/editor/managers/PerformanceManager/PerformanceManager.test.ts +80 -0
- package/src/lib/editor/managers/PerformanceManager/PerformanceManager.ts +54 -81
- package/src/lib/editor/managers/ScribbleManager/ScribbleManager.ts +1 -1
- package/src/lib/editor/managers/SnapManager/BoundsSnaps.ts +32 -36
- package/src/lib/editor/managers/SnapManager/HandleSnaps.ts +13 -2
- package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +13 -0
- package/src/lib/editor/managers/SnapManager/SnapManager.ts +6 -4
- package/src/lib/editor/managers/TextManager/TextManager.test.ts +74 -0
- package/src/lib/editor/managers/TextManager/TextManager.ts +6 -5
- package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +23 -8
- package/src/lib/editor/types/external-content.ts +5 -0
- package/src/lib/exports/ExportDelay.tsx +16 -4
- package/src/lib/exports/FontEmbedder.test.ts +99 -0
- package/src/lib/exports/FontEmbedder.ts +32 -11
- package/src/lib/exports/StyleEmbedder.ts +13 -4
- package/src/lib/exports/fetchCache.test.ts +22 -0
- package/src/lib/exports/fetchCache.ts +4 -0
- package/src/lib/exports/getSvgAsImage.ts +13 -5
- package/src/lib/exports/getSvgJsx.test.ts +43 -1
- package/src/lib/exports/getSvgJsx.tsx +28 -16
- package/src/lib/exports/parseCss.test.ts +4 -0
- package/src/lib/exports/parseCss.ts +2 -2
- package/src/lib/hooks/EditorComponentsContext.tsx +2 -1
- package/src/lib/hooks/useCanvasEvents.ts +42 -0
- package/src/lib/hooks/useIdentity.tsx +12 -1
- package/src/lib/license/LicenseManager.ts +13 -1
- package/src/lib/license/LicenseProvider.test.tsx +76 -0
- package/src/lib/license/LicenseProvider.tsx +19 -5
- package/src/lib/test/preserveFocus.test.tsx +81 -0
- package/src/lib/utils/debug-flags.ts +0 -6
- package/src/lib/utils/deepLinks.test.ts +15 -0
- package/src/lib/utils/deepLinks.ts +8 -3
- package/src/lib/utils/sync/LocalIndexedDb.test.ts +121 -1
- package/src/lib/utils/sync/LocalIndexedDb.ts +41 -28
- package/src/lib/utils/sync/TLLocalSyncClient.test.ts +257 -1
- package/src/lib/utils/sync/TLLocalSyncClient.ts +112 -54
- package/src/version.ts +3 -3
- package/dist-cjs/lib/primitives/geometry/geometry.bench.js +0 -133
- package/dist-cjs/lib/primitives/geometry/geometry.bench.js.map +0 -7
- package/dist-esm/lib/primitives/geometry/geometry.bench.mjs +0 -132
- package/dist-esm/lib/primitives/geometry/geometry.bench.mjs.map +0 -7
- package/src/lib/primitives/geometry/geometry.bench.ts +0 -179
|
@@ -95,6 +95,10 @@ var import_UserPreferencesManager = require("./managers/UserPreferencesManager/U
|
|
|
95
95
|
var import_OverlayManager = require("./overlays/OverlayManager");
|
|
96
96
|
var import_RootState = require("./tools/RootState");
|
|
97
97
|
const RENDERING_SHAPES_SORT_CACHE_THRESHOLD = 100;
|
|
98
|
+
const AXIS = {
|
|
99
|
+
horizontal: { val: "x", min: "minX", max: "maxX", dim: "width" },
|
|
100
|
+
vertical: { val: "y", min: "minY", max: "maxY", dim: "height" }
|
|
101
|
+
};
|
|
98
102
|
class Editor extends import_eventemitter3.default {
|
|
99
103
|
id = (0, import_utils.uniqueId)();
|
|
100
104
|
constructor({
|
|
@@ -421,7 +425,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
421
425
|
}
|
|
422
426
|
}
|
|
423
427
|
if (deleteBindingIds.length) {
|
|
424
|
-
this.
|
|
428
|
+
this.store.remove(deleteBindingIds);
|
|
425
429
|
}
|
|
426
430
|
}
|
|
427
431
|
},
|
|
@@ -1381,6 +1385,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
1381
1385
|
* @public
|
|
1382
1386
|
**/
|
|
1383
1387
|
updateDocumentSettings(settings) {
|
|
1388
|
+
if (this.getIsReadonly()) return this;
|
|
1384
1389
|
this.run(
|
|
1385
1390
|
() => {
|
|
1386
1391
|
this.store.put([{ ...this.getDocumentSettings(), ...settings }]);
|
|
@@ -1403,7 +1408,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
1403
1408
|
updateInstanceState(partial, historyOptions) {
|
|
1404
1409
|
this._updateInstanceState(partial, { history: "ignore", ...historyOptions });
|
|
1405
1410
|
if (partial.isChangingStyle !== void 0) {
|
|
1406
|
-
clearTimeout(this._isChangingStyleTimeout);
|
|
1411
|
+
this.timers.clearTimeout(this._isChangingStyleTimeout);
|
|
1407
1412
|
if (partial.isChangingStyle === true) {
|
|
1408
1413
|
this._isChangingStyleTimeout = this.timers.setTimeout(() => {
|
|
1409
1414
|
this._updateInstanceState({ isChangingStyle: false }, { history: "ignore" });
|
|
@@ -1540,7 +1545,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
1540
1545
|
* @public
|
|
1541
1546
|
*/
|
|
1542
1547
|
select(...shapes) {
|
|
1543
|
-
const ids =
|
|
1548
|
+
const ids = toShapeIds(shapes);
|
|
1544
1549
|
this.setSelectedShapes(ids);
|
|
1545
1550
|
return this;
|
|
1546
1551
|
}
|
|
@@ -1555,7 +1560,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
1555
1560
|
* @public
|
|
1556
1561
|
*/
|
|
1557
1562
|
deselect(...shapes) {
|
|
1558
|
-
const ids =
|
|
1563
|
+
const ids = toShapeIds(shapes);
|
|
1559
1564
|
const selectedShapeIds = this.getSelectedShapeIds();
|
|
1560
1565
|
if (selectedShapeIds.length > 0 && ids.length > 0) {
|
|
1561
1566
|
this.setSelectedShapes(selectedShapeIds.filter((id) => !ids.includes(id)));
|
|
@@ -1593,7 +1598,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
1593
1598
|
}
|
|
1594
1599
|
const ids = this.getSortedChildIdsForParent(parentToSelectWithinId);
|
|
1595
1600
|
if (ids.length <= 0) return this;
|
|
1596
|
-
this.setSelectedShapes(this.
|
|
1601
|
+
this.setSelectedShapes(ids.filter((id) => !this.getShape(id)?.isLocked));
|
|
1597
1602
|
return this;
|
|
1598
1603
|
}
|
|
1599
1604
|
/**
|
|
@@ -1610,12 +1615,15 @@ class Editor extends import_eventemitter3.default {
|
|
|
1610
1615
|
const selectedShapeIds = this.getSelectedShapeIds();
|
|
1611
1616
|
const firstParentId = selectedShapeIds[0] ? this.getShape(selectedShapeIds[0])?.parentId : null;
|
|
1612
1617
|
const isSelectedWithinContainer = firstParentId && selectedShapeIds.every((shapeId) => this.getShape(shapeId)?.parentId === firstParentId) && !(0, import_tlschema.isPageId)(firstParentId);
|
|
1613
|
-
const filteredShapes =
|
|
1614
|
-
|
|
1618
|
+
const filteredShapes = this.getCurrentPageShapes().filter(
|
|
1619
|
+
(shape2) => !this.isShapeOrAncestorLocked(shape2) && (isSelectedWithinContainer ? shape2.parentId === firstParentId : (0, import_tlschema.isPageId)(shape2.parentId))
|
|
1620
|
+
);
|
|
1621
|
+
const readingOrderShapes = this._getShapesInReadingOrder(filteredShapes);
|
|
1615
1622
|
const currentShapeId = selectedShapeIds.length === 1 ? selectedShapeIds[0] : readingOrderShapes.find((shape2) => selectedShapeIds.includes(shape2.id))?.id;
|
|
1616
1623
|
let adjacentShapeId;
|
|
1617
1624
|
if (direction === "next" || direction === "prev") {
|
|
1618
1625
|
const shapeIds = readingOrderShapes.map((shape2) => shape2.id);
|
|
1626
|
+
if (shapeIds.length === 0) return;
|
|
1619
1627
|
const currentIndex = currentShapeId ? shapeIds.indexOf(currentShapeId) : -1;
|
|
1620
1628
|
const startIndex = currentIndex === -1 && direction === "prev" ? 0 : currentIndex;
|
|
1621
1629
|
const adjacentIndex = (startIndex + (direction === "next" ? 1 : -1) + shapeIds.length) % shapeIds.length;
|
|
@@ -1717,13 +1725,14 @@ class Editor extends import_eventemitter3.default {
|
|
|
1717
1725
|
});
|
|
1718
1726
|
if (shapesInDirection.length === 0) return currentShapeId;
|
|
1719
1727
|
const lowestScoringShape = (0, import_utils.minBy)(shapesInDirection, ({ center }) => {
|
|
1720
|
-
const distance = import_Vec.Vec.
|
|
1728
|
+
const distance = import_Vec.Vec.Dist(currentCenter, center);
|
|
1721
1729
|
const dirProp = ["left", "right"].includes(direction) ? "x" : "y";
|
|
1722
1730
|
const directionalDistance = Math.abs(center[dirProp] - currentCenter[dirProp]);
|
|
1723
1731
|
const offProp = ["left", "right"].includes(direction) ? "y" : "x";
|
|
1724
1732
|
const offAxisDeviation = Math.abs(center[offProp] - currentCenter[offProp]);
|
|
1725
|
-
const angle =
|
|
1726
|
-
const
|
|
1733
|
+
const angle = (import_Vec.Vec.Angle(currentCenter, center) * (180 / Math.PI) + 360) % 360;
|
|
1734
|
+
const rawAngleDeviation = Math.abs(angle - directionToAngle[direction]);
|
|
1735
|
+
const angleDeviation = Math.min(rawAngleDeviation, 360 - rawAngleDeviation);
|
|
1727
1736
|
return distance * 1 + // Base distance
|
|
1728
1737
|
offAxisDeviation * 2 + // Heavy penalty for off-axis deviation
|
|
1729
1738
|
(distance - directionalDistance) * 1.5 + // Penalty for diagonal distance
|
|
@@ -2061,7 +2070,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
2061
2070
|
* @public
|
|
2062
2071
|
*/
|
|
2063
2072
|
setHintingShapes(shapes) {
|
|
2064
|
-
const ids =
|
|
2073
|
+
const ids = toShapeIds(shapes);
|
|
2065
2074
|
this.run(
|
|
2066
2075
|
() => {
|
|
2067
2076
|
this._updateCurrentPageState({ hintingShapeIds: (0, import_utils.dedupe)(ids) });
|
|
@@ -2091,7 +2100,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
2091
2100
|
* @public
|
|
2092
2101
|
*/
|
|
2093
2102
|
setErasingShapes(shapes) {
|
|
2094
|
-
const ids =
|
|
2103
|
+
const ids = toShapeIds(shapes).slice();
|
|
2095
2104
|
ids.sort();
|
|
2096
2105
|
const erasingShapeIds = this.getErasingShapeIds();
|
|
2097
2106
|
this.run(
|
|
@@ -2498,14 +2507,16 @@ class Editor extends import_eventemitter3.default {
|
|
|
2498
2507
|
setCamera(point, opts) {
|
|
2499
2508
|
const { isLocked } = this._cameraOptions.__unsafe__getWithoutCapture();
|
|
2500
2509
|
if (isLocked && !opts?.force) return this;
|
|
2510
|
+
const _point = new import_Vec.Vec(point.x, point.y, point.z ?? this.getZoomLevel());
|
|
2511
|
+
if (!Number.isFinite(_point.x) || !Number.isFinite(_point.y) || !Number.isFinite(_point.z)) {
|
|
2512
|
+
throw Error(
|
|
2513
|
+
`Editor.setCamera: expected finite values, got (${_point.x}, ${_point.y}, ${_point.z}).`
|
|
2514
|
+
);
|
|
2515
|
+
}
|
|
2501
2516
|
this.stopCameraAnimation();
|
|
2502
2517
|
if (this.getInstanceState().followingUserId) {
|
|
2503
2518
|
this.stopFollowingUser();
|
|
2504
2519
|
}
|
|
2505
|
-
const _point = import_Vec.Vec.Cast(point);
|
|
2506
|
-
if (!Number.isFinite(_point.x)) _point.x = 0;
|
|
2507
|
-
if (!Number.isFinite(_point.y)) _point.y = 0;
|
|
2508
|
-
if (_point.z === void 0 || !Number.isFinite(_point.z)) point.z = this.getZoomLevel();
|
|
2509
2520
|
const camera = this.getConstrainedCamera(_point, opts);
|
|
2510
2521
|
if (opts?.animation) {
|
|
2511
2522
|
const { width, height } = this.getViewportScreenBounds();
|
|
@@ -2790,11 +2801,14 @@ class Editor extends import_eventemitter3.default {
|
|
|
2790
2801
|
_animateViewport(ms) {
|
|
2791
2802
|
if (!this._viewportAnimation) return;
|
|
2792
2803
|
this._viewportAnimation.elapsed += ms;
|
|
2793
|
-
const { elapsed, easing, duration, start, end } = this._viewportAnimation;
|
|
2804
|
+
const { elapsed, easing, duration, start, end, opts } = this._viewportAnimation;
|
|
2794
2805
|
if (elapsed > duration) {
|
|
2795
2806
|
this.off("tick", this._animateViewport);
|
|
2796
2807
|
this._viewportAnimation = null;
|
|
2797
|
-
this._setCamera(
|
|
2808
|
+
this._setCamera(
|
|
2809
|
+
new import_Vec.Vec(-end.x, -end.y, this.getViewportScreenBounds().width / end.width),
|
|
2810
|
+
opts
|
|
2811
|
+
);
|
|
2798
2812
|
return;
|
|
2799
2813
|
}
|
|
2800
2814
|
const remaining = duration - elapsed;
|
|
@@ -2832,7 +2846,8 @@ class Editor extends import_eventemitter3.default {
|
|
|
2832
2846
|
duration: duration / animationSpeed,
|
|
2833
2847
|
easing,
|
|
2834
2848
|
start: viewportPageBounds.clone(),
|
|
2835
|
-
end: targetViewportPage.clone()
|
|
2849
|
+
end: targetViewportPage.clone(),
|
|
2850
|
+
opts: rest
|
|
2836
2851
|
};
|
|
2837
2852
|
this.once("stop-camera-animation", () => {
|
|
2838
2853
|
this.off("tick", this._animateViewport);
|
|
@@ -2918,6 +2933,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
2918
2933
|
}
|
|
2919
2934
|
const isOnSamePage = presence.currentPageId === this.getCurrentPageId();
|
|
2920
2935
|
if (!isOnSamePage) {
|
|
2936
|
+
this.markHistoryStoppingPoint("change-page");
|
|
2921
2937
|
this.setCurrentPage(presence.currentPageId);
|
|
2922
2938
|
}
|
|
2923
2939
|
if (opts && opts.animation && !isOnSamePage) {
|
|
@@ -3749,7 +3765,9 @@ class Editor extends import_eventemitter3.default {
|
|
|
3749
3765
|
if (ids.length <= 0) return this;
|
|
3750
3766
|
this.run(
|
|
3751
3767
|
() => {
|
|
3752
|
-
this.store.props.assets.remove?.(ids)
|
|
3768
|
+
Promise.resolve(this.store.props.assets.remove?.(ids)).catch(
|
|
3769
|
+
(err) => console.error("Error while removing assets from the asset store:", err)
|
|
3770
|
+
);
|
|
3753
3771
|
this.store.remove(ids);
|
|
3754
3772
|
},
|
|
3755
3773
|
{ history: "ignore" }
|
|
@@ -4131,7 +4149,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
4131
4149
|
if (shapes.length === 0) {
|
|
4132
4150
|
return;
|
|
4133
4151
|
}
|
|
4134
|
-
const ids =
|
|
4152
|
+
const ids = toShapeIds(shapes);
|
|
4135
4153
|
const freshShapes = (0, import_utils.compact)(ids.map((id) => this.getShape(id)));
|
|
4136
4154
|
if (freshShapes.length === 1) {
|
|
4137
4155
|
const parentId = freshShapes[0].parentId;
|
|
@@ -4228,12 +4246,14 @@ class Editor extends import_eventemitter3.default {
|
|
|
4228
4246
|
*/
|
|
4229
4247
|
getSelectedShapeAtPoint(point) {
|
|
4230
4248
|
const selectedShapeIds = this.getSelectedShapeIds();
|
|
4231
|
-
|
|
4249
|
+
if (selectedShapeIds.length === 0) return void 0;
|
|
4250
|
+
const selectedShapeIdSet = new Set(selectedShapeIds);
|
|
4251
|
+
const margin = this.getHitTestMargin();
|
|
4232
4252
|
const sortedShapes = this.getCurrentPageShapesSorted();
|
|
4233
4253
|
for (let i = sortedShapes.length - 1; i >= 0; i--) {
|
|
4234
4254
|
const shape = sortedShapes[i];
|
|
4235
4255
|
if (shape.type === "group") continue;
|
|
4236
|
-
if (!
|
|
4256
|
+
if (!selectedShapeIdSet.has(shape.id)) continue;
|
|
4237
4257
|
if (this.getShapeGeometry(shape).hitTestPoint(
|
|
4238
4258
|
this.getPointInShapeSpace(shape, point),
|
|
4239
4259
|
margin,
|
|
@@ -4331,7 +4351,6 @@ class Editor extends import_eventemitter3.default {
|
|
|
4331
4351
|
}
|
|
4332
4352
|
return inMarginClosestToEdgeHit || shape;
|
|
4333
4353
|
} else {
|
|
4334
|
-
if (this.getShapePageBounds(shape).contains(viewportPageBounds)) continue;
|
|
4335
4354
|
if (hitInside ? (
|
|
4336
4355
|
// On hitInside, the distance will be negative for hits inside
|
|
4337
4356
|
// If the distance is positive, check against the outer margin
|
|
@@ -4348,6 +4367,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
4348
4367
|
inMarginClosestToEdgeHit = shape;
|
|
4349
4368
|
}
|
|
4350
4369
|
} else if (!inMarginClosestToEdgeHit) {
|
|
4370
|
+
if (this.getShapePageBounds(shape).contains(viewportPageBounds)) continue;
|
|
4351
4371
|
const { area } = geometry;
|
|
4352
4372
|
if (area < inHollowSmallestArea) {
|
|
4353
4373
|
inHollowSmallestArea = area;
|
|
@@ -4358,6 +4378,9 @@ class Editor extends import_eventemitter3.default {
|
|
|
4358
4378
|
}
|
|
4359
4379
|
} else {
|
|
4360
4380
|
if (distance < this.getHitTestMargin()) {
|
|
4381
|
+
if (inMarginClosestToEdgeHit && inMarginClosestToEdgeDistance <= distance) {
|
|
4382
|
+
return inMarginClosestToEdgeHit;
|
|
4383
|
+
}
|
|
4361
4384
|
return shape;
|
|
4362
4385
|
}
|
|
4363
4386
|
}
|
|
@@ -4634,7 +4657,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
4634
4657
|
* @public
|
|
4635
4658
|
*/
|
|
4636
4659
|
reparentShapes(shapes, parentId, insertIndex) {
|
|
4637
|
-
const ids =
|
|
4660
|
+
const ids = toShapeIds(shapes);
|
|
4638
4661
|
if (ids.length === 0) return this;
|
|
4639
4662
|
const changes = [];
|
|
4640
4663
|
const parentTransform = (0, import_tlschema.isPageId)(parentId) ? import_Mat.Mat.Identity() : this.getShapePageTransform(parentId);
|
|
@@ -4863,6 +4886,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
4863
4886
|
* binding, but the `type`, `toId`, and `fromId` must all be provided.
|
|
4864
4887
|
*/
|
|
4865
4888
|
createBindings(partials) {
|
|
4889
|
+
if (this.getIsReadonly()) return this;
|
|
4866
4890
|
const bindings = [];
|
|
4867
4891
|
for (const partial of partials) {
|
|
4868
4892
|
const fromShape = this.getShape(partial.fromId);
|
|
@@ -4897,6 +4921,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
4897
4921
|
* binding is skipped. The changes from the partial are merged into the existing record.
|
|
4898
4922
|
*/
|
|
4899
4923
|
updateBindings(partials) {
|
|
4924
|
+
if (this.getIsReadonly()) return this;
|
|
4900
4925
|
const updated = [];
|
|
4901
4926
|
for (const partial of partials) {
|
|
4902
4927
|
if (!partial) continue;
|
|
@@ -4925,6 +4950,16 @@ class Editor extends import_eventemitter3.default {
|
|
|
4925
4950
|
* Delete several bindings by their IDs. If a binding ID doesn't exist, it's ignored.
|
|
4926
4951
|
*/
|
|
4927
4952
|
deleteBindings(bindings, { isolateShapes = false } = {}) {
|
|
4953
|
+
if (this.getIsReadonly()) return this;
|
|
4954
|
+
return this._deleteBindings(bindings, { isolateShapes });
|
|
4955
|
+
}
|
|
4956
|
+
/**
|
|
4957
|
+
* Unguarded so that withIsolatedShapes can transiently isolate shapes for copy and export in
|
|
4958
|
+
* readonly mode; the public deleteBindings is what readonly blocks.
|
|
4959
|
+
*
|
|
4960
|
+
* @internal
|
|
4961
|
+
*/
|
|
4962
|
+
_deleteBindings(bindings, { isolateShapes = false } = {}) {
|
|
4928
4963
|
const ids = bindings.map((binding) => typeof binding === "string" ? binding : binding.id);
|
|
4929
4964
|
if (isolateShapes) {
|
|
4930
4965
|
this.store.atomic(() => {
|
|
@@ -4983,7 +5018,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
4983
5018
|
* @param opts - The options for the rotation.
|
|
4984
5019
|
*/
|
|
4985
5020
|
rotateShapesBy(shapes, delta, opts) {
|
|
4986
|
-
const ids =
|
|
5021
|
+
const ids = toShapeIds(shapes);
|
|
4987
5022
|
if (ids.length <= 0) return this;
|
|
4988
5023
|
const snapshot = (0, import_rotation.getRotationSnapshot)({ editor: this, ids });
|
|
4989
5024
|
if (!snapshot) return this;
|
|
@@ -5020,6 +5055,14 @@ class Editor extends import_eventemitter3.default {
|
|
|
5020
5055
|
}
|
|
5021
5056
|
return workingShape;
|
|
5022
5057
|
}
|
|
5058
|
+
// Counter-rotates the page-space delta into the parent's space; without that a child of a rotated
|
|
5059
|
+
// frame or group would move along its parent's axes instead of the page's.
|
|
5060
|
+
// todo: a shape laid out together with its own parent moves twice, once with the parent and once
|
|
5061
|
+
// on its own; the layout commands should skip shapes whose ancestors are also being laid out
|
|
5062
|
+
getChangesToTranslateShapeByPageDelta(shape, pageDelta) {
|
|
5063
|
+
const localDelta = import_Vec.Vec.From(pageDelta).rot(-this.getShapeParentTransform(shape).rotation());
|
|
5064
|
+
return this.getChangesToTranslateShape(shape, localDelta.add(shape));
|
|
5065
|
+
}
|
|
5023
5066
|
/**
|
|
5024
5067
|
* Move shapes by a delta.
|
|
5025
5068
|
*
|
|
@@ -5032,14 +5075,12 @@ class Editor extends import_eventemitter3.default {
|
|
|
5032
5075
|
* @param offset - The offset to apply to the shapes.
|
|
5033
5076
|
*/
|
|
5034
5077
|
nudgeShapes(shapes, offset) {
|
|
5035
|
-
const ids =
|
|
5078
|
+
const ids = toShapeIds(shapes);
|
|
5036
5079
|
if (ids.length <= 0) return this;
|
|
5037
5080
|
const changes = [];
|
|
5038
5081
|
for (const id of ids) {
|
|
5039
5082
|
const shape = this.getShape(id);
|
|
5040
|
-
|
|
5041
|
-
localDelta.rot(-this.getShapeParentTransform(shape).rotation());
|
|
5042
|
-
changes.push(this.getChangesToTranslateShape(shape, localDelta.add(shape)));
|
|
5083
|
+
changes.push(this.getChangesToTranslateShapeByPageDelta(shape, offset));
|
|
5043
5084
|
}
|
|
5044
5085
|
this.updateShapes(changes);
|
|
5045
5086
|
return this;
|
|
@@ -5060,7 +5101,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
5060
5101
|
*/
|
|
5061
5102
|
duplicateShapes(shapes, offset) {
|
|
5062
5103
|
this.run(() => {
|
|
5063
|
-
const _ids =
|
|
5104
|
+
const _ids = toShapeIds(shapes);
|
|
5064
5105
|
const ids = this._shouldIgnoreShapeLock ? _ids : this._getUnlockedShapeIds(_ids);
|
|
5065
5106
|
if (ids.length <= 0) return this;
|
|
5066
5107
|
const initialIds = new Set(ids);
|
|
@@ -5169,7 +5210,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
5169
5210
|
* @public
|
|
5170
5211
|
*/
|
|
5171
5212
|
moveShapesToPage(shapes, pageId) {
|
|
5172
|
-
const ids =
|
|
5213
|
+
const ids = toShapeIds(shapes);
|
|
5173
5214
|
if (ids.length === 0) return this;
|
|
5174
5215
|
if (this.getIsReadonly()) return this;
|
|
5175
5216
|
const currentPageId = this.getCurrentPageId();
|
|
@@ -5205,7 +5246,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
5205
5246
|
* @public
|
|
5206
5247
|
*/
|
|
5207
5248
|
toggleLock(shapes) {
|
|
5208
|
-
const ids =
|
|
5249
|
+
const ids = toShapeIds(shapes);
|
|
5209
5250
|
if (this.getIsReadonly() || ids.length === 0) return this;
|
|
5210
5251
|
let allLocked = true;
|
|
5211
5252
|
const shapesToToggle = [];
|
|
@@ -5244,7 +5285,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
5244
5285
|
* @public
|
|
5245
5286
|
*/
|
|
5246
5287
|
sendToBack(shapes) {
|
|
5247
|
-
const ids =
|
|
5288
|
+
const ids = toShapeIds(shapes);
|
|
5248
5289
|
const changes = (0, import_reorderShapes.getReorderingShapesChanges)(this, "toBack", ids, {
|
|
5249
5290
|
considerAllShapes: true
|
|
5250
5291
|
});
|
|
@@ -5274,7 +5315,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
5274
5315
|
* @public
|
|
5275
5316
|
*/
|
|
5276
5317
|
sendBackward(shapes, opts = {}) {
|
|
5277
|
-
const ids =
|
|
5318
|
+
const ids = toShapeIds(shapes);
|
|
5278
5319
|
const changes = (0, import_reorderShapes.getReorderingShapesChanges)(this, "backward", ids, opts);
|
|
5279
5320
|
if (changes) this.updateShapes(changes);
|
|
5280
5321
|
return this;
|
|
@@ -5302,7 +5343,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
5302
5343
|
* @public
|
|
5303
5344
|
*/
|
|
5304
5345
|
bringForward(shapes, opts = {}) {
|
|
5305
|
-
const ids =
|
|
5346
|
+
const ids = toShapeIds(shapes);
|
|
5306
5347
|
const changes = (0, import_reorderShapes.getReorderingShapesChanges)(this, "forward", ids, opts);
|
|
5307
5348
|
if (changes) this.updateShapes(changes);
|
|
5308
5349
|
return this;
|
|
@@ -5321,7 +5362,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
5321
5362
|
* @public
|
|
5322
5363
|
*/
|
|
5323
5364
|
bringToFront(shapes) {
|
|
5324
|
-
const ids =
|
|
5365
|
+
const ids = toShapeIds(shapes);
|
|
5325
5366
|
const changes = (0, import_reorderShapes.getReorderingShapesChanges)(this, "toFront", ids);
|
|
5326
5367
|
if (changes) this.updateShapes(changes);
|
|
5327
5368
|
return this;
|
|
@@ -5333,7 +5374,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
5333
5374
|
* @internal
|
|
5334
5375
|
*/
|
|
5335
5376
|
getShapeClusters(shapes, type, opts) {
|
|
5336
|
-
const ids =
|
|
5377
|
+
const ids = toShapeIds(shapes);
|
|
5337
5378
|
let freshShapes = (0, import_utils.compact)(ids.map((id) => this.getShape(id)));
|
|
5338
5379
|
if (opts?.filterAxisAligned) {
|
|
5339
5380
|
freshShapes = freshShapes.filter((s) => {
|
|
@@ -5358,7 +5399,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
5358
5399
|
const shapesMovingTogether = [shape];
|
|
5359
5400
|
const boundsOfShapesMovingTogether = [shapePageBounds];
|
|
5360
5401
|
this.collectShapesViaArrowBindings({
|
|
5361
|
-
bindings: this.
|
|
5402
|
+
bindings: this.getBindingsInvolvingShape(shape.id, "arrow"),
|
|
5362
5403
|
initialShapes: freshShapes,
|
|
5363
5404
|
resultShapes: shapesMovingTogether,
|
|
5364
5405
|
resultBounds: boundsOfShapesMovingTogether,
|
|
@@ -5414,7 +5455,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
5414
5455
|
*/
|
|
5415
5456
|
flipShapes(shapes, operation) {
|
|
5416
5457
|
if (this.getIsReadonly()) return this;
|
|
5417
|
-
const ids =
|
|
5458
|
+
const ids = toShapeIds(shapes);
|
|
5418
5459
|
const shapesToFlipFirstPass = (0, import_utils.compact)(ids.map((id) => this.getShape(id)));
|
|
5419
5460
|
for (const shape of shapesToFlipFirstPass) {
|
|
5420
5461
|
if (this.isShapeOfType(shape, "group")) {
|
|
@@ -5488,21 +5529,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
5488
5529
|
const { clusters: shapeClustersToStack } = this.getShapeClusters(shapes, "stack");
|
|
5489
5530
|
const len = shapeClustersToStack.length;
|
|
5490
5531
|
if (_gap === 0 && len < 3 || len < 2) return this;
|
|
5491
|
-
|
|
5492
|
-
let min;
|
|
5493
|
-
let max;
|
|
5494
|
-
let dim;
|
|
5495
|
-
if (operation === "horizontal") {
|
|
5496
|
-
val = "x";
|
|
5497
|
-
min = "minX";
|
|
5498
|
-
max = "maxX";
|
|
5499
|
-
dim = "width";
|
|
5500
|
-
} else {
|
|
5501
|
-
val = "y";
|
|
5502
|
-
min = "minY";
|
|
5503
|
-
max = "maxY";
|
|
5504
|
-
dim = "height";
|
|
5505
|
-
}
|
|
5532
|
+
const { val, min, max, dim } = AXIS[operation];
|
|
5506
5533
|
let shapeGap = 0;
|
|
5507
5534
|
shapeClustersToStack.sort((a, b) => a.pageBounds[min] - b.pageBounds[min]);
|
|
5508
5535
|
if (_gap === 0) {
|
|
@@ -5541,13 +5568,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
5541
5568
|
const delta = new import_Vec.Vec();
|
|
5542
5569
|
delta[val] = v + shapeGap - pageBounds[val];
|
|
5543
5570
|
for (const shape of shapes2) {
|
|
5544
|
-
|
|
5545
|
-
const parent = this.getShapeParent(shape);
|
|
5546
|
-
if (parent) {
|
|
5547
|
-
shapeDelta.rot(-this.getShapePageTransform(parent).rotation());
|
|
5548
|
-
}
|
|
5549
|
-
shapeDelta.add(shape);
|
|
5550
|
-
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
5571
|
+
changes.push(this.getChangesToTranslateShapeByPageDelta(shape, delta));
|
|
5551
5572
|
}
|
|
5552
5573
|
v += pageBounds[dim] + shapeGap;
|
|
5553
5574
|
}
|
|
@@ -5627,13 +5648,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
5627
5648
|
for (const { shapes: shapes2, pageBounds, nextPageBounds } of shapeClustersToPack) {
|
|
5628
5649
|
const delta = import_Vec.Vec.Sub(nextPageBounds.point, pageBounds.point).add(centerDelta);
|
|
5629
5650
|
for (const shape of shapes2) {
|
|
5630
|
-
|
|
5631
|
-
const parent = this.getShapeParent(shape);
|
|
5632
|
-
if (parent) {
|
|
5633
|
-
shapeDelta.rot(-this.getShapeParentTransform(shape).rotation());
|
|
5634
|
-
}
|
|
5635
|
-
shapeDelta.add(shape);
|
|
5636
|
-
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
5651
|
+
changes.push(this.getChangesToTranslateShapeByPageDelta(shape, delta));
|
|
5637
5652
|
}
|
|
5638
5653
|
}
|
|
5639
5654
|
if (changes.length) {
|
|
@@ -5693,13 +5708,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
5693
5708
|
}
|
|
5694
5709
|
}
|
|
5695
5710
|
for (const shape of shapes2) {
|
|
5696
|
-
|
|
5697
|
-
const parent = this.getShapeParent(shape);
|
|
5698
|
-
if (parent) {
|
|
5699
|
-
shapeDelta.rot(-this.getShapePageTransform(parent).rotation());
|
|
5700
|
-
}
|
|
5701
|
-
shapeDelta.add(shape);
|
|
5702
|
-
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
5711
|
+
changes.push(this.getChangesToTranslateShapeByPageDelta(shape, delta));
|
|
5703
5712
|
}
|
|
5704
5713
|
});
|
|
5705
5714
|
this.updateShapes(changes);
|
|
@@ -5723,27 +5732,13 @@ class Editor extends import_eventemitter3.default {
|
|
|
5723
5732
|
if (this.getIsReadonly()) return this;
|
|
5724
5733
|
const { clusters: shapeClustersToDistribute } = this.getShapeClusters(shapes, "distribute");
|
|
5725
5734
|
if (shapeClustersToDistribute.length < 3) return this;
|
|
5726
|
-
|
|
5727
|
-
let min;
|
|
5728
|
-
let max;
|
|
5729
|
-
let dim;
|
|
5730
|
-
if (operation === "horizontal") {
|
|
5731
|
-
val = "x";
|
|
5732
|
-
min = "minX";
|
|
5733
|
-
max = "maxX";
|
|
5734
|
-
dim = "width";
|
|
5735
|
-
} else {
|
|
5736
|
-
val = "y";
|
|
5737
|
-
min = "minY";
|
|
5738
|
-
max = "maxY";
|
|
5739
|
-
dim = "height";
|
|
5740
|
-
}
|
|
5735
|
+
const { val, min, max, dim } = AXIS[operation];
|
|
5741
5736
|
const changes = [];
|
|
5742
5737
|
const first = shapeClustersToDistribute.sort((a, b) => a.pageBounds[min] - b.pageBounds[min])[0];
|
|
5743
5738
|
const last2 = shapeClustersToDistribute.sort((a, b) => b.pageBounds[max] - a.pageBounds[max])[0];
|
|
5744
5739
|
if (first === last2) {
|
|
5745
5740
|
const excludedShapeIds = new Set(first.shapes.map((s) => s.id));
|
|
5746
|
-
const ids =
|
|
5741
|
+
const ids = toShapeIds(shapes);
|
|
5747
5742
|
return this.distributeShapes(
|
|
5748
5743
|
ids.filter((id) => !excludedShapeIds.has(id)),
|
|
5749
5744
|
operation
|
|
@@ -5767,13 +5762,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
5767
5762
|
delta[val] = last2.pageBounds[max] - pageBounds[max] - 1;
|
|
5768
5763
|
}
|
|
5769
5764
|
for (const shape of shapes2) {
|
|
5770
|
-
|
|
5771
|
-
const parent = this.getShapeParent(shape);
|
|
5772
|
-
if (parent) {
|
|
5773
|
-
shapeDelta.rot(-this.getShapePageTransform(parent).rotation());
|
|
5774
|
-
}
|
|
5775
|
-
shapeDelta.add(shape);
|
|
5776
|
-
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
5765
|
+
changes.push(this.getChangesToTranslateShapeByPageDelta(shape, delta));
|
|
5777
5766
|
}
|
|
5778
5767
|
v += pageBounds[dim] + gap;
|
|
5779
5768
|
}
|
|
@@ -5803,32 +5792,17 @@ class Editor extends import_eventemitter3.default {
|
|
|
5803
5792
|
);
|
|
5804
5793
|
if (shapeClustersToStretch.length < 2) return this;
|
|
5805
5794
|
const commonBounds = import_Box.Box.Common(allBounds);
|
|
5806
|
-
|
|
5807
|
-
let min;
|
|
5808
|
-
let dim;
|
|
5809
|
-
if (operation === "horizontal") {
|
|
5810
|
-
val = "x";
|
|
5811
|
-
min = "minX";
|
|
5812
|
-
dim = "width";
|
|
5813
|
-
} else {
|
|
5814
|
-
val = "y";
|
|
5815
|
-
min = "minY";
|
|
5816
|
-
dim = "height";
|
|
5817
|
-
}
|
|
5795
|
+
const { val, min, dim } = AXIS[operation];
|
|
5818
5796
|
this.run(() => {
|
|
5819
5797
|
shapeClustersToStretch.forEach(({ shapes: shapes2, pageBounds }) => {
|
|
5820
|
-
const
|
|
5821
|
-
|
|
5798
|
+
const pageOffset = new import_Vec.Vec();
|
|
5799
|
+
pageOffset[val] = commonBounds[min] - pageBounds[min];
|
|
5822
5800
|
const scaleOrigin = pageBounds.center.clone();
|
|
5823
5801
|
scaleOrigin[val] = commonBounds[min];
|
|
5824
5802
|
const scale = new import_Vec.Vec(1, 1);
|
|
5825
5803
|
scale[val] = commonBounds[dim] / pageBounds[dim];
|
|
5826
5804
|
for (const shape of shapes2) {
|
|
5827
|
-
|
|
5828
|
-
shapeLocalOffset.rot(-this.getShapeParentTransform(shape).rotation());
|
|
5829
|
-
shapeLocalOffset.add(shape);
|
|
5830
|
-
const changes = this.getChangesToTranslateShape(shape, shapeLocalOffset);
|
|
5831
|
-
this.updateShape(changes);
|
|
5805
|
+
this.updateShape(this.getChangesToTranslateShapeByPageDelta(shape, pageOffset));
|
|
5832
5806
|
this.resizeShape(shape.id, scale, {
|
|
5833
5807
|
initialBounds: this.getShapeGeometry(shape).bounds,
|
|
5834
5808
|
scaleOrigin,
|
|
@@ -5871,7 +5845,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
5871
5845
|
const scaleY = targetBounds.height / commonBounds.height;
|
|
5872
5846
|
const scale = new import_Vec.Vec(scaleX, scaleY);
|
|
5873
5847
|
shapeClusters.forEach(({ shapes: shapes2, pageBounds }) => {
|
|
5874
|
-
const
|
|
5848
|
+
const pageOffset = new import_Vec.Vec(
|
|
5875
5849
|
targetBounds.minX - commonBounds.minX + (pageBounds.minX - commonBounds.minX) * (scaleX - 1),
|
|
5876
5850
|
targetBounds.minY - commonBounds.minY + (pageBounds.minY - commonBounds.minY) * (scaleY - 1)
|
|
5877
5851
|
);
|
|
@@ -5880,11 +5854,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
5880
5854
|
targetBounds.minY + (pageBounds.minY - commonBounds.minY) * scaleY
|
|
5881
5855
|
);
|
|
5882
5856
|
for (const shape of shapes2) {
|
|
5883
|
-
|
|
5884
|
-
shapeLocalOffset.rot(-this.getShapeParentTransform(shape).rotation());
|
|
5885
|
-
shapeLocalOffset.add(shape);
|
|
5886
|
-
const changes = this.getChangesToTranslateShape(shape, shapeLocalOffset);
|
|
5887
|
-
this.updateShape(changes);
|
|
5857
|
+
this.updateShape(this.getChangesToTranslateShapeByPageDelta(shape, pageOffset));
|
|
5888
5858
|
this.resizeShape(shape.id, scale, {
|
|
5889
5859
|
initialBounds: this.getShapeGeometry(shape).bounds,
|
|
5890
5860
|
scaleOrigin,
|
|
@@ -6303,12 +6273,17 @@ class Editor extends import_eventemitter3.default {
|
|
|
6303
6273
|
let remaining = duration;
|
|
6304
6274
|
let t;
|
|
6305
6275
|
const animations = [];
|
|
6276
|
+
const ignoreShapeLock = this._shouldIgnoreShapeLock;
|
|
6306
6277
|
let partial, result;
|
|
6307
6278
|
for (let i = 0, n = partials.length; i < n; i++) {
|
|
6308
6279
|
partial = partials[i];
|
|
6309
6280
|
if (!partial) continue;
|
|
6310
6281
|
const shape = this.getShape(partial.id);
|
|
6311
6282
|
if (!shape) continue;
|
|
6283
|
+
const unlocks = shape.isLocked && Object.hasOwn(partial, "isLocked") && !partial.isLocked;
|
|
6284
|
+
if (!ignoreShapeLock && !unlocks && this.isShapeOrAncestorLocked(shape)) {
|
|
6285
|
+
continue;
|
|
6286
|
+
}
|
|
6312
6287
|
result = {
|
|
6313
6288
|
start: (0, import_utils.structuredClone)(shape),
|
|
6314
6289
|
end: applyPartialToRecordWithProps((0, import_utils.structuredClone)(shape), partial)
|
|
@@ -6324,7 +6299,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
6324
6299
|
(p) => p && animatingShapes2.get(p.id) === animationId
|
|
6325
6300
|
);
|
|
6326
6301
|
if (partialsToUpdate.length) {
|
|
6327
|
-
this.updateShapes(partialsToUpdate);
|
|
6302
|
+
this.run(() => this.updateShapes(partialsToUpdate), { ignoreShapeLock });
|
|
6328
6303
|
}
|
|
6329
6304
|
this.off("tick", handleTick);
|
|
6330
6305
|
return;
|
|
@@ -6357,13 +6332,13 @@ class Editor extends import_eventemitter3.default {
|
|
|
6357
6332
|
throw Error("Editor.groupShapes: must provide an array of shapes or shape ids");
|
|
6358
6333
|
}
|
|
6359
6334
|
if (this.getIsReadonly()) return this;
|
|
6360
|
-
const ids =
|
|
6361
|
-
if (ids.length <= 1) return this;
|
|
6335
|
+
const ids = toShapeIds(shapes);
|
|
6362
6336
|
const shapesToGroup = (0, import_utils.compact)(
|
|
6363
6337
|
(this._shouldIgnoreShapeLock ? ids : this._getUnlockedShapeIds(ids)).map(
|
|
6364
6338
|
(id) => this.getShape(id)
|
|
6365
6339
|
)
|
|
6366
6340
|
);
|
|
6341
|
+
if (shapesToGroup.length <= 1) return this;
|
|
6367
6342
|
const sortedShapeIds = shapesToGroup.sort(import_utils.sortByIndex).map((s) => s.id);
|
|
6368
6343
|
const childBounds = (0, import_utils.compact)(shapesToGroup.map((shape) => this.getShapePageBounds(shape)));
|
|
6369
6344
|
const pageBounds = import_Box.Box.Common(childBounds);
|
|
@@ -6372,8 +6347,11 @@ class Editor extends import_eventemitter3.default {
|
|
|
6372
6347
|
}
|
|
6373
6348
|
const { x, y } = pageBounds.point;
|
|
6374
6349
|
const parentId = this.findCommonAncestor(shapesToGroup) ?? this.getCurrentPageId();
|
|
6375
|
-
if (this.
|
|
6376
|
-
|
|
6350
|
+
if (!this.canCreateShapes([groupId])) {
|
|
6351
|
+
alertMaxShapes(this);
|
|
6352
|
+
return this;
|
|
6353
|
+
}
|
|
6354
|
+
if (this.isIn("select") && !this.isIn("select.idle")) {
|
|
6377
6355
|
this.cancel();
|
|
6378
6356
|
}
|
|
6379
6357
|
const shapesWithRootParent = shapesToGroup.filter((shape) => shape.parentId === parentId).sort(import_utils.sortByIndex);
|
|
@@ -6401,15 +6379,14 @@ class Editor extends import_eventemitter3.default {
|
|
|
6401
6379
|
ungroupShapes(shapes, opts = {}) {
|
|
6402
6380
|
if (this.getIsReadonly()) return this;
|
|
6403
6381
|
const { select = true } = opts;
|
|
6404
|
-
const ids =
|
|
6382
|
+
const ids = toShapeIds(shapes);
|
|
6405
6383
|
const shapesToUngroup = (0, import_utils.compact)(
|
|
6406
6384
|
(this._shouldIgnoreShapeLock ? ids : this._getUnlockedShapeIds(ids)).map(
|
|
6407
6385
|
(id) => this.getShape(id)
|
|
6408
6386
|
)
|
|
6409
6387
|
);
|
|
6410
6388
|
if (shapesToUngroup.length === 0) return this;
|
|
6411
|
-
if (this.
|
|
6412
|
-
if (!this.isIn("select.idle")) {
|
|
6389
|
+
if (this.isIn("select") && !this.isIn("select.idle")) {
|
|
6413
6390
|
this.cancel();
|
|
6414
6391
|
}
|
|
6415
6392
|
const idsToSelect = /* @__PURE__ */ new Set();
|
|
@@ -6423,16 +6400,16 @@ class Editor extends import_eventemitter3.default {
|
|
|
6423
6400
|
});
|
|
6424
6401
|
if (groups.length === 0) return this;
|
|
6425
6402
|
this.run(() => {
|
|
6426
|
-
let group;
|
|
6427
6403
|
for (let i = 0, n = groups.length; i < n; i++) {
|
|
6428
|
-
group = groups[i];
|
|
6404
|
+
const group = this.getShape(groups[i].id);
|
|
6405
|
+
if (!group) continue;
|
|
6429
6406
|
const childIds = this.getSortedChildIdsForParent(group.id);
|
|
6430
6407
|
for (let j = 0, n2 = childIds.length; j < n2; j++) {
|
|
6431
6408
|
idsToSelect.add(childIds[j]);
|
|
6432
6409
|
}
|
|
6433
6410
|
this.reparentShapes(childIds, group.parentId, group.index);
|
|
6434
6411
|
}
|
|
6435
|
-
this.deleteShapes(groups.map((
|
|
6412
|
+
this.deleteShapes(groups.map((group) => group.id));
|
|
6436
6413
|
if (select) {
|
|
6437
6414
|
this.select(...idsToSelect);
|
|
6438
6415
|
}
|
|
@@ -6513,14 +6490,14 @@ class Editor extends import_eventemitter3.default {
|
|
|
6513
6490
|
}
|
|
6514
6491
|
/** @internal */
|
|
6515
6492
|
_getUnlockedShapeIds(ids) {
|
|
6516
|
-
return ids.filter((id) => !this.
|
|
6493
|
+
return ids.filter((id) => !this.isShapeOrAncestorLocked(id));
|
|
6517
6494
|
}
|
|
6518
6495
|
deleteShapes(_ids) {
|
|
6519
6496
|
if (this.getIsReadonly()) return this;
|
|
6520
6497
|
if (!Array.isArray(_ids)) {
|
|
6521
6498
|
throw Error("Editor.deleteShapes: must provide an array of shapes or shapeIds");
|
|
6522
6499
|
}
|
|
6523
|
-
const shapeIds =
|
|
6500
|
+
const shapeIds = toShapeIds(_ids);
|
|
6524
6501
|
const shapeIdsToDelete = this._shouldIgnoreShapeLock ? shapeIds : this._getUnlockedShapeIds(shapeIds);
|
|
6525
6502
|
if (shapeIdsToDelete.length === 0) return this;
|
|
6526
6503
|
const allShapeIdsToDelete = new Set(shapeIdsToDelete);
|
|
@@ -6865,7 +6842,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
6865
6842
|
* @public
|
|
6866
6843
|
*/
|
|
6867
6844
|
getContentFromCurrentPage(shapes) {
|
|
6868
|
-
const ids =
|
|
6845
|
+
const ids = toShapeIds(shapes);
|
|
6869
6846
|
if (!ids) return;
|
|
6870
6847
|
if (ids.length === 0) return;
|
|
6871
6848
|
const shapeIds = this.getShapeAndDescendantIds(ids);
|
|
@@ -6933,21 +6910,29 @@ class Editor extends import_eventemitter3.default {
|
|
|
6933
6910
|
await Promise.allSettled(
|
|
6934
6911
|
content.assets.map(async (asset) => {
|
|
6935
6912
|
if ((asset.type === "image" || asset.type === "video") && !asset.props.src?.startsWith("data:image") && !asset.props.src?.startsWith("data:video") && !asset.props.src?.startsWith("http")) {
|
|
6936
|
-
|
|
6937
|
-
|
|
6938
|
-
|
|
6939
|
-
|
|
6940
|
-
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
|
|
6946
|
-
|
|
6947
|
-
|
|
6948
|
-
|
|
6949
|
-
|
|
6913
|
+
try {
|
|
6914
|
+
const objectUrl = await this.store.props.assets.resolve(asset, {
|
|
6915
|
+
screenScale: 1,
|
|
6916
|
+
steppedScreenScale: 1,
|
|
6917
|
+
dpr: 1,
|
|
6918
|
+
networkEffectiveType: null,
|
|
6919
|
+
shouldResolveToOriginal: true
|
|
6920
|
+
});
|
|
6921
|
+
if (objectUrl) {
|
|
6922
|
+
const response = await (0, import_utils.fetch)(objectUrl);
|
|
6923
|
+
if (response.ok) {
|
|
6924
|
+
const assetWithDataUrl = (0, import_utils.structuredClone)(asset);
|
|
6925
|
+
assetWithDataUrl.props.src = await import_utils.FileHelpers.blobToDataUrl(await response.blob());
|
|
6926
|
+
assets.push(assetWithDataUrl);
|
|
6927
|
+
return;
|
|
6928
|
+
}
|
|
6929
|
+
console.warn(`Could not inline asset ${asset.id}: fetch returned ${response.status}`);
|
|
6930
|
+
}
|
|
6931
|
+
} catch (err) {
|
|
6932
|
+
console.warn(`Could not inline asset ${asset.id}`, err);
|
|
6933
|
+
}
|
|
6950
6934
|
}
|
|
6935
|
+
assets.push(asset);
|
|
6951
6936
|
})
|
|
6952
6937
|
);
|
|
6953
6938
|
content.assets = assets;
|
|
@@ -7241,7 +7226,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
7241
7226
|
* @public
|
|
7242
7227
|
*/
|
|
7243
7228
|
async getSvgElement(shapes, opts = {}) {
|
|
7244
|
-
const ids = shapes.length === 0 ? this.getCurrentPageShapeIdsSorted() :
|
|
7229
|
+
const ids = shapes.length === 0 ? this.getCurrentPageShapeIdsSorted() : toShapeIds(shapes);
|
|
7245
7230
|
if (ids.length === 0) return void 0;
|
|
7246
7231
|
await this.fonts.loadRequiredFontsForCurrentPage(this.options.maxFontsToLoadBeforeRender);
|
|
7247
7232
|
return (0, import_exportToSvg.exportToSvg)(this, ids, opts);
|
|
@@ -7837,22 +7822,22 @@ class Editor extends import_eventemitter3.default {
|
|
|
7837
7822
|
const releaseCtrl = this._ctrlKeyTimeout !== -1;
|
|
7838
7823
|
const releaseMeta = this._metaKeyTimeout !== -1;
|
|
7839
7824
|
if (releaseShift) {
|
|
7840
|
-
clearTimeout(this._shiftKeyTimeout);
|
|
7825
|
+
this.timers.clearTimeout(this._shiftKeyTimeout);
|
|
7841
7826
|
this._shiftKeyTimeout = -1;
|
|
7842
7827
|
this.inputs.setShiftKey(false);
|
|
7843
7828
|
}
|
|
7844
7829
|
if (releaseAlt) {
|
|
7845
|
-
clearTimeout(this._altKeyTimeout);
|
|
7830
|
+
this.timers.clearTimeout(this._altKeyTimeout);
|
|
7846
7831
|
this._altKeyTimeout = -1;
|
|
7847
7832
|
this.inputs.setAltKey(false);
|
|
7848
7833
|
}
|
|
7849
7834
|
if (releaseCtrl) {
|
|
7850
|
-
clearTimeout(this._ctrlKeyTimeout);
|
|
7835
|
+
this.timers.clearTimeout(this._ctrlKeyTimeout);
|
|
7851
7836
|
this._ctrlKeyTimeout = -1;
|
|
7852
7837
|
this.inputs.setCtrlKey(false);
|
|
7853
7838
|
}
|
|
7854
7839
|
if (releaseMeta) {
|
|
7855
|
-
clearTimeout(this._metaKeyTimeout);
|
|
7840
|
+
this.timers.clearTimeout(this._metaKeyTimeout);
|
|
7856
7841
|
this._metaKeyTimeout = -1;
|
|
7857
7842
|
this.inputs.setMetaKey(false);
|
|
7858
7843
|
}
|
|
@@ -7966,28 +7951,28 @@ class Editor extends import_eventemitter3.default {
|
|
|
7966
7951
|
return;
|
|
7967
7952
|
}
|
|
7968
7953
|
if (info.shiftKey) {
|
|
7969
|
-
clearTimeout(this._shiftKeyTimeout);
|
|
7954
|
+
this.timers.clearTimeout(this._shiftKeyTimeout);
|
|
7970
7955
|
this._shiftKeyTimeout = -1;
|
|
7971
7956
|
inputs.setShiftKey(true);
|
|
7972
7957
|
} else if (!info.shiftKey && inputs.getShiftKey() && this._shiftKeyTimeout === -1) {
|
|
7973
7958
|
this._shiftKeyTimeout = this.timers.setTimeout(this._releaseShiftKey, 150);
|
|
7974
7959
|
}
|
|
7975
7960
|
if (info.altKey) {
|
|
7976
|
-
clearTimeout(this._altKeyTimeout);
|
|
7961
|
+
this.timers.clearTimeout(this._altKeyTimeout);
|
|
7977
7962
|
this._altKeyTimeout = -1;
|
|
7978
7963
|
inputs.setAltKey(true);
|
|
7979
7964
|
} else if (!info.altKey && inputs.getAltKey() && this._altKeyTimeout === -1) {
|
|
7980
7965
|
this._altKeyTimeout = this.timers.setTimeout(this._releaseAltKey, 150);
|
|
7981
7966
|
}
|
|
7982
7967
|
if (info.ctrlKey) {
|
|
7983
|
-
clearTimeout(this._ctrlKeyTimeout);
|
|
7968
|
+
this.timers.clearTimeout(this._ctrlKeyTimeout);
|
|
7984
7969
|
this._ctrlKeyTimeout = -1;
|
|
7985
7970
|
inputs.setCtrlKey(true);
|
|
7986
7971
|
} else if (!info.ctrlKey && inputs.getCtrlKey() && this._ctrlKeyTimeout === -1) {
|
|
7987
7972
|
this._ctrlKeyTimeout = this.timers.setTimeout(this._releaseCtrlKey, 150);
|
|
7988
7973
|
}
|
|
7989
7974
|
if (info.metaKey && info.name !== "key_up") {
|
|
7990
|
-
clearTimeout(this._metaKeyTimeout);
|
|
7975
|
+
this.timers.clearTimeout(this._metaKeyTimeout);
|
|
7991
7976
|
this._metaKeyTimeout = -1;
|
|
7992
7977
|
inputs.setMetaKey(true);
|
|
7993
7978
|
} else if (!info.metaKey && inputs.getMetaKey() && this._metaKeyTimeout === -1) {
|
|
@@ -8001,8 +7986,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
8001
7986
|
const cameraOptions = this._cameraOptions.__unsafe__getWithoutCapture();
|
|
8002
7987
|
switch (type) {
|
|
8003
7988
|
case "pinch": {
|
|
8004
|
-
|
|
8005
|
-
clearTimeout(this._longPressTimeout);
|
|
7989
|
+
this.timers.clearTimeout(this._longPressTimeout);
|
|
8006
7990
|
this.inputs.updateFromEvent(info);
|
|
8007
7991
|
switch (info.name) {
|
|
8008
7992
|
case "pinch_start": {
|
|
@@ -8023,6 +8007,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
8023
8007
|
}
|
|
8024
8008
|
case "pinch": {
|
|
8025
8009
|
if (!inputs.getIsPinching()) return;
|
|
8010
|
+
if (cameraOptions.isLocked) return;
|
|
8026
8011
|
const {
|
|
8027
8012
|
point: { z = 1 },
|
|
8028
8013
|
delta: { x: dx, y: dy }
|
|
@@ -8078,7 +8063,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
8078
8063
|
const { panSpeed, zoomSpeed } = cameraOptions;
|
|
8079
8064
|
let wheelBehavior = cameraOptions.wheelBehavior;
|
|
8080
8065
|
const inputMode = this.user.getUserPreferences().inputMode;
|
|
8081
|
-
if (inputMode !== null) {
|
|
8066
|
+
if (inputMode !== null && wheelBehavior !== "none") {
|
|
8082
8067
|
wheelBehavior = inputMode === "trackpad" ? "pan" : "zoom";
|
|
8083
8068
|
}
|
|
8084
8069
|
if (wheelBehavior !== "none") {
|
|
@@ -8130,12 +8115,12 @@ class Editor extends import_eventemitter3.default {
|
|
|
8130
8115
|
}
|
|
8131
8116
|
case "pointer": {
|
|
8132
8117
|
if (inputs.getIsPinching()) return;
|
|
8133
|
-
this.inputs.updateFromEvent(info);
|
|
8134
8118
|
const { isPen } = info;
|
|
8135
8119
|
const { isPenMode } = instanceState;
|
|
8120
|
+
if (isPenMode && !isPen) return;
|
|
8121
|
+
this.inputs.updateFromEvent(info);
|
|
8136
8122
|
switch (info.name) {
|
|
8137
8123
|
case "pointer_down": {
|
|
8138
|
-
if (isPenMode && !isPen) return;
|
|
8139
8124
|
this._releaseDebouncedModifiers();
|
|
8140
8125
|
if (!this.inputs.getIsPanning()) {
|
|
8141
8126
|
this._longPressTimeout = this.timers.setTimeout(() => {
|
|
@@ -8159,11 +8144,12 @@ class Editor extends import_eventemitter3.default {
|
|
|
8159
8144
|
inputs.buttons.add(info.button);
|
|
8160
8145
|
inputs.setIsPointing(true);
|
|
8161
8146
|
inputs.setIsDragging(false);
|
|
8147
|
+
this.stopCameraAnimation();
|
|
8162
8148
|
if (!isPenMode && info.isPenDirect) {
|
|
8163
8149
|
this.updateInstanceState({ isPenMode: true });
|
|
8164
8150
|
this.interrupt();
|
|
8165
8151
|
}
|
|
8166
|
-
if (info.button === import_constants.STYLUS_ERASER_BUTTON) {
|
|
8152
|
+
if (info.button === import_constants.STYLUS_ERASER_BUTTON && this.getStateDescendant("eraser")) {
|
|
8167
8153
|
this._restoreToolId = this.getCurrentToolId();
|
|
8168
8154
|
this.complete();
|
|
8169
8155
|
this.setCurrentTool("eraser");
|
|
@@ -8172,10 +8158,10 @@ class Editor extends import_eventemitter3.default {
|
|
|
8172
8158
|
this._prevCursor = this.getInstanceState().cursor.type;
|
|
8173
8159
|
}
|
|
8174
8160
|
this.inputs.setIsPanning(true);
|
|
8175
|
-
clearTimeout(this._longPressTimeout);
|
|
8161
|
+
this.timers.clearTimeout(this._longPressTimeout);
|
|
8176
8162
|
} else if (info.button === import_constants.RIGHT_MOUSE_BUTTON && this.options.rightClickPanning) {
|
|
8177
8163
|
this.inputs.setIsRightPointing(true);
|
|
8178
|
-
clearTimeout(this._longPressTimeout);
|
|
8164
|
+
this.timers.clearTimeout(this._longPressTimeout);
|
|
8179
8165
|
return this;
|
|
8180
8166
|
}
|
|
8181
8167
|
if (this.inputs.getIsPanning()) {
|
|
@@ -8186,7 +8172,6 @@ class Editor extends import_eventemitter3.default {
|
|
|
8186
8172
|
break;
|
|
8187
8173
|
}
|
|
8188
8174
|
case "pointer_move": {
|
|
8189
|
-
if (!isPen && isPenMode) return;
|
|
8190
8175
|
const { x: cx, y: cy, z: cz } = (0, import_state.unsafe__withoutCapture)(() => this.getCamera());
|
|
8191
8176
|
if (this.inputs.getIsRightPointing() && !this.inputs.getIsPanning()) {
|
|
8192
8177
|
const currentScreenPoint = this.inputs.getCurrentScreenPoint();
|
|
@@ -8217,16 +8202,15 @@ class Editor extends import_eventemitter3.default {
|
|
|
8217
8202
|
}
|
|
8218
8203
|
if (inputs.getIsPointing() && !inputs.getIsDragging() && import_Vec.Vec.Dist2(inputs.getOriginPagePoint(), inputs.getCurrentPagePoint()) * this.getZoomLevel() > (instanceState.isCoarsePointer ? this.options.coarseDragDistanceSquared : this.options.dragDistanceSquared) / cz) {
|
|
8219
8204
|
inputs.setIsDragging(true);
|
|
8220
|
-
clearTimeout(this._longPressTimeout);
|
|
8205
|
+
this.timers.clearTimeout(this._longPressTimeout);
|
|
8221
8206
|
}
|
|
8222
8207
|
break;
|
|
8223
8208
|
}
|
|
8224
8209
|
case "pointer_up": {
|
|
8225
8210
|
inputs.setIsDragging(false);
|
|
8226
8211
|
inputs.setIsPointing(false);
|
|
8227
|
-
clearTimeout(this._longPressTimeout);
|
|
8212
|
+
this.timers.clearTimeout(this._longPressTimeout);
|
|
8228
8213
|
inputs.buttons.delete(info.button);
|
|
8229
|
-
if (instanceState.isPenMode && !isPen) return;
|
|
8230
8214
|
if (this.inputs.getIsRightPointing() && !this.inputs.getIsPanning()) {
|
|
8231
8215
|
this.inputs.setIsRightPointing(false);
|
|
8232
8216
|
this._selectedShapeIdsAtPointerDown = [];
|
|
@@ -8282,7 +8266,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
8282
8266
|
});
|
|
8283
8267
|
}
|
|
8284
8268
|
} else {
|
|
8285
|
-
if (info.button === import_constants.STYLUS_ERASER_BUTTON) {
|
|
8269
|
+
if (info.button === import_constants.STYLUS_ERASER_BUTTON && this.getStateDescendant("eraser")) {
|
|
8286
8270
|
this.complete();
|
|
8287
8271
|
this.setCurrentTool(this._restoreToolId);
|
|
8288
8272
|
}
|
|
@@ -8295,8 +8279,8 @@ class Editor extends import_eventemitter3.default {
|
|
|
8295
8279
|
break;
|
|
8296
8280
|
}
|
|
8297
8281
|
case "keyboard": {
|
|
8298
|
-
if (info.
|
|
8299
|
-
if (info.
|
|
8282
|
+
if (info.code === "ShiftRight") info.code = "ShiftLeft";
|
|
8283
|
+
if (info.code === "AltRight") info.code = "AltLeft";
|
|
8300
8284
|
if (info.code === "ControlRight") info.code = "ControlLeft";
|
|
8301
8285
|
if (info.code === "MetaRight") info.code = "MetaLeft";
|
|
8302
8286
|
switch (info.name) {
|
|
@@ -8309,7 +8293,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
8309
8293
|
}
|
|
8310
8294
|
this.inputs.setIsPanning(true);
|
|
8311
8295
|
this.inputs.setIsSpacebarPanning(true);
|
|
8312
|
-
clearTimeout(this._longPressTimeout);
|
|
8296
|
+
this.timers.clearTimeout(this._longPressTimeout);
|
|
8313
8297
|
this.setCursor({
|
|
8314
8298
|
type: this.inputs.getIsPointing() ? "grabbing" : "grab",
|
|
8315
8299
|
rotation: 0
|
|
@@ -8335,7 +8319,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
8335
8319
|
break;
|
|
8336
8320
|
}
|
|
8337
8321
|
}
|
|
8338
|
-
if (offset) {
|
|
8322
|
+
if (offset && !cameraOptions.isLocked) {
|
|
8339
8323
|
const bounds = this.getViewportPageBounds();
|
|
8340
8324
|
const next = bounds.clone().translate(offset.mulV({ x: bounds.w, y: bounds.h }));
|
|
8341
8325
|
this._animateToViewport(next, { animation: { duration: 320 } });
|
|
@@ -8375,7 +8359,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
8375
8359
|
this.setCurrentTool("select");
|
|
8376
8360
|
}
|
|
8377
8361
|
const { isPenMode } = this.store.unsafeGetWithoutCapture(import_tlschema.TLINSTANCE_ID);
|
|
8378
|
-
if (info.isPen
|
|
8362
|
+
if (!isPenMode || info.isPen) {
|
|
8379
8363
|
const clickInfo = this._clickManager.handlePointerEvent(info);
|
|
8380
8364
|
if (info.name !== clickInfo.name) {
|
|
8381
8365
|
this.root.handleEvent(info);
|
|
@@ -8397,7 +8381,7 @@ class Editor extends import_eventemitter3.default {
|
|
|
8397
8381
|
maybeTrackPerformance(name) {
|
|
8398
8382
|
if (import_debug_flags.debugFlags.measurePerformance.get()) {
|
|
8399
8383
|
if (this.performanceTracker.isStarted()) {
|
|
8400
|
-
clearTimeout(this.performanceTrackerTimeout);
|
|
8384
|
+
this.timers.clearTimeout(this.performanceTrackerTimeout);
|
|
8401
8385
|
} else {
|
|
8402
8386
|
this.performanceTracker.start(name);
|
|
8403
8387
|
}
|
|
@@ -8666,6 +8650,9 @@ function pushShapeWithDescendants(editor, id, result) {
|
|
|
8666
8650
|
pushShapeWithDescendants(editor, childIds[i], result);
|
|
8667
8651
|
}
|
|
8668
8652
|
}
|
|
8653
|
+
function toShapeIds(shapes) {
|
|
8654
|
+
return typeof shapes[0] === "string" ? shapes : shapes.map((shape) => shape.id);
|
|
8655
|
+
}
|
|
8669
8656
|
function withIsolatedShapes(editor, shapeIds, callback) {
|
|
8670
8657
|
let result;
|
|
8671
8658
|
editor.run(
|
|
@@ -8688,7 +8675,7 @@ function withIsolatedShapes(editor, shapeIds, callback) {
|
|
|
8688
8675
|
}
|
|
8689
8676
|
}
|
|
8690
8677
|
}
|
|
8691
|
-
editor.
|
|
8678
|
+
editor._deleteBindings([...bindingsToRemove], { isolateShapes: true });
|
|
8692
8679
|
try {
|
|
8693
8680
|
result = import_utils.Result.ok(callback(bindingsWithBoth));
|
|
8694
8681
|
} catch (error) {
|