@tldraw/editor 3.13.0-canary.3095a57e7c2c → 3.13.0-canary.324a049abe8f
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 +129 -113
- package/dist-cjs/index.js +7 -22
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawEditor.js +2 -1
- package/dist-cjs/lib/TldrawEditor.js.map +2 -2
- package/dist-cjs/lib/components/Shape.js +12 -8
- package/dist-cjs/lib/components/Shape.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js +37 -8
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js +14 -12
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +17 -11
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultSpinner.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultSpinner.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +110 -44
- package/dist-cjs/lib/editor/Editor.js.map +3 -3
- package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js.map +2 -2
- package/dist-cjs/lib/editor/managers/TextManager.js +10 -0
- package/dist-cjs/lib/editor/managers/TextManager.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js +1 -1
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js +0 -3
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/shared/getPerfectDashProps.js.map +2 -2
- package/dist-cjs/lib/exports/getSvgJsx.js +12 -3
- package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
- package/dist-cjs/lib/hooks/useDocumentEvents.js +3 -2
- package/dist-cjs/lib/hooks/useDocumentEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useEditorComponents.js +16 -16
- package/dist-cjs/lib/hooks/useEditorComponents.js.map +2 -2
- package/dist-cjs/lib/license/LicenseManager.js +8 -1
- package/dist-cjs/lib/license/LicenseManager.js.map +2 -2
- package/dist-cjs/lib/options.js.map +2 -2
- package/dist-cjs/lib/primitives/Box.js +16 -0
- package/dist-cjs/lib/primitives/Box.js.map +2 -2
- package/dist-cjs/lib/primitives/Mat.js +1 -1
- package/dist-cjs/lib/primitives/Mat.js.map +2 -2
- package/dist-cjs/lib/primitives/Vec.js +20 -0
- package/dist-cjs/lib/primitives/Vec.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Arc2d.js +2 -2
- package/dist-cjs/lib/primitives/geometry/Arc2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Circle2d.js +1 -1
- package/dist-cjs/lib/primitives/geometry/Circle2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js +1 -1
- package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/CubicSpline2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Edge2d.js +1 -1
- package/dist-cjs/lib/primitives/geometry/Edge2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Ellipse2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js +91 -20
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Group2d.js +55 -2
- package/dist-cjs/lib/primitives/geometry/Group2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Point2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Polyline2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Stadium2d.js.map +2 -2
- package/dist-cjs/lib/utils/areShapesContentEqual.js +25 -0
- package/dist-cjs/lib/utils/areShapesContentEqual.js.map +7 -0
- package/dist-cjs/lib/utils/debug-flags.js +5 -2
- package/dist-cjs/lib/utils/debug-flags.js.map +2 -2
- package/dist-cjs/lib/utils/dom.js +3 -3
- package/dist-cjs/lib/utils/dom.js.map +2 -2
- package/dist-cjs/lib/utils/nearestMultiple.js +34 -0
- package/dist-cjs/lib/utils/nearestMultiple.js.map +7 -0
- package/dist-cjs/lib/utils/rotation.js +5 -5
- package/dist-cjs/lib/utils/rotation.js.map +2 -2
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +129 -113
- package/dist-esm/index.mjs +9 -41
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawEditor.mjs +2 -1
- package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
- package/dist-esm/lib/components/Shape.mjs +12 -8
- package/dist-esm/lib/components/Shape.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +37 -8
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs +14 -12
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +17 -11
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultSpinner.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultSpinner.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +110 -44
- package/dist-esm/lib/editor/Editor.mjs.map +3 -3
- package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/TextManager.mjs +10 -0
- package/dist-esm/lib/editor/managers/TextManager.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +1 -1
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs +0 -3
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs +12 -3
- package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
- package/dist-esm/lib/hooks/useDocumentEvents.mjs +3 -2
- package/dist-esm/lib/hooks/useDocumentEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useEditorComponents.mjs +16 -18
- package/dist-esm/lib/hooks/useEditorComponents.mjs.map +2 -2
- package/dist-esm/lib/license/LicenseManager.mjs +8 -1
- package/dist-esm/lib/license/LicenseManager.mjs.map +2 -2
- package/dist-esm/lib/options.mjs.map +2 -2
- package/dist-esm/lib/primitives/Box.mjs +16 -0
- package/dist-esm/lib/primitives/Box.mjs.map +2 -2
- package/dist-esm/lib/primitives/Mat.mjs +1 -1
- package/dist-esm/lib/primitives/Mat.mjs.map +2 -2
- package/dist-esm/lib/primitives/Vec.mjs +20 -0
- package/dist-esm/lib/primitives/Vec.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Arc2d.mjs +2 -2
- package/dist-esm/lib/primitives/geometry/Arc2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Circle2d.mjs +1 -1
- package/dist-esm/lib/primitives/geometry/Circle2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs +1 -1
- package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Edge2d.mjs +1 -1
- package/dist-esm/lib/primitives/geometry/Edge2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +92 -21
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Group2d.mjs +55 -2
- package/dist-esm/lib/primitives/geometry/Group2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Point2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Polyline2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Stadium2d.mjs.map +2 -2
- package/dist-esm/lib/utils/areShapesContentEqual.mjs +5 -0
- package/dist-esm/lib/utils/areShapesContentEqual.mjs.map +7 -0
- package/dist-esm/lib/utils/debug-flags.mjs +5 -2
- package/dist-esm/lib/utils/debug-flags.mjs.map +2 -2
- package/dist-esm/lib/utils/dom.mjs +3 -3
- package/dist-esm/lib/utils/dom.mjs.map +2 -2
- package/dist-esm/lib/utils/nearestMultiple.mjs +14 -0
- package/dist-esm/lib/utils/nearestMultiple.mjs.map +7 -0
- package/dist-esm/lib/utils/rotation.mjs +5 -5
- package/dist-esm/lib/utils/rotation.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +47 -4
- package/package.json +7 -7
- package/src/index.ts +16 -31
- package/src/lib/TldrawEditor.tsx +6 -1
- package/src/lib/components/Shape.tsx +14 -10
- package/src/lib/components/default-components/DefaultCanvas.tsx +43 -8
- package/src/lib/components/default-components/DefaultErrorFallback.tsx +25 -14
- package/src/lib/components/default-components/DefaultShapeIndicator.tsx +17 -8
- package/src/lib/components/default-components/DefaultSpinner.tsx +1 -1
- package/src/lib/editor/Editor.test.ts +1 -1
- package/src/lib/editor/Editor.ts +118 -43
- package/src/lib/editor/managers/SnapManager/HandleSnaps.ts +0 -1
- package/src/lib/editor/managers/TextManager.ts +12 -0
- package/src/lib/editor/shapes/ShapeUtil.ts +23 -3
- package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +0 -4
- package/src/lib/editor/shapes/shared/getPerfectDashProps.ts +9 -9
- package/src/lib/exports/getSvgJsx.tsx +16 -7
- package/src/lib/hooks/useDocumentEvents.ts +7 -2
- package/src/lib/hooks/useEditorComponents.tsx +33 -32
- package/src/lib/license/LicenseManager.test.ts +40 -0
- package/src/lib/license/LicenseManager.ts +13 -1
- package/src/lib/options.ts +4 -0
- package/src/lib/primitives/Box.ts +20 -0
- package/src/lib/primitives/Mat.ts +5 -4
- package/src/lib/primitives/Vec.ts +23 -0
- package/src/lib/primitives/geometry/Arc2d.ts +5 -5
- package/src/lib/primitives/geometry/Circle2d.ts +4 -4
- package/src/lib/primitives/geometry/CubicBezier2d.ts +4 -4
- package/src/lib/primitives/geometry/CubicSpline2d.ts +3 -3
- package/src/lib/primitives/geometry/Edge2d.ts +3 -3
- package/src/lib/primitives/geometry/Ellipse2d.ts +3 -3
- package/src/lib/primitives/geometry/Geometry2d.test.ts +42 -0
- package/src/lib/primitives/geometry/Geometry2d.ts +123 -35
- package/src/lib/primitives/geometry/Group2d.ts +70 -7
- package/src/lib/primitives/geometry/Point2d.ts +2 -2
- package/src/lib/primitives/geometry/Polyline2d.ts +3 -3
- package/src/lib/primitives/geometry/Stadium2d.ts +3 -3
- package/src/lib/test/currentToolIdMask.test.ts +1 -1
- package/src/lib/test/user.test.ts +1 -1
- package/src/lib/utils/areShapesContentEqual.ts +4 -0
- package/src/lib/utils/debug-flags.ts +7 -2
- package/src/lib/utils/dom.ts +4 -4
- package/src/lib/utils/nearestMultiple.ts +13 -0
- package/src/lib/utils/rotation.ts +8 -6
- package/src/lib/utils/sync/LocalIndexedDb.test.ts +1 -1
- package/src/lib/utils/sync/TLLocalSyncClient.test.ts +1 -1
- package/src/version.ts +3 -3
|
@@ -132,6 +132,7 @@ import { Group2d } from "../primitives/geometry/Group2d.mjs";
|
|
|
132
132
|
import { intersectPolygonPolygon } from "../primitives/intersect.mjs";
|
|
133
133
|
import { PI, approximately, areAnglesCompatible, clamp, pointInPolygon } from "../primitives/utils.mjs";
|
|
134
134
|
import { SharedStyleMap } from "../utils/SharedStylesMap.mjs";
|
|
135
|
+
import { areShapesContentEqual } from "../utils/areShapesContentEqual.mjs";
|
|
135
136
|
import { dataUrlToFile } from "../utils/assets.mjs";
|
|
136
137
|
import { debugFlags } from "../utils/debug-flags.mjs";
|
|
137
138
|
import {
|
|
@@ -457,7 +458,6 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
457
458
|
) : getShapeVisibility;
|
|
458
459
|
this.options = { ...defaultTldrawOptions, ...options };
|
|
459
460
|
this.store = store;
|
|
460
|
-
this.disposables.add(this.store.dispose.bind(this.store));
|
|
461
461
|
this.history = new HistoryManager({
|
|
462
462
|
store,
|
|
463
463
|
annotateError: (error) => {
|
|
@@ -869,6 +869,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
869
869
|
dispose() {
|
|
870
870
|
this.disposables.forEach((dispose) => dispose());
|
|
871
871
|
this.disposables.clear();
|
|
872
|
+
this.store.dispose();
|
|
872
873
|
this.isDisposed = true;
|
|
873
874
|
}
|
|
874
875
|
getShapeUtil(arg) {
|
|
@@ -1381,8 +1382,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
1381
1382
|
return this.getCurrentPageState().selectedShapeIds;
|
|
1382
1383
|
}
|
|
1383
1384
|
getSelectedShapes() {
|
|
1384
|
-
|
|
1385
|
-
return compact(selectedShapeIds.map((id) => this.store.get(id)));
|
|
1385
|
+
return compact(this.getSelectedShapeIds().map((id) => this.store.get(id)));
|
|
1386
1386
|
}
|
|
1387
1387
|
/**
|
|
1388
1388
|
* Select one or more shapes.
|
|
@@ -1475,9 +1475,23 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
1475
1475
|
this.setSelectedShapes(this._getUnlockedShapeIds(ids));
|
|
1476
1476
|
return this;
|
|
1477
1477
|
}
|
|
1478
|
+
/**
|
|
1479
|
+
* Select the next shape in the reading order or in cardinal order.
|
|
1480
|
+
*
|
|
1481
|
+
* @example
|
|
1482
|
+
* ```ts
|
|
1483
|
+
* editor.selectAdjacentShape('next')
|
|
1484
|
+
* ```
|
|
1485
|
+
*
|
|
1486
|
+
* @public
|
|
1487
|
+
*/
|
|
1478
1488
|
selectAdjacentShape(direction) {
|
|
1479
|
-
const readingOrderShapes = this.getCurrentPageShapesInReadingOrder();
|
|
1480
1489
|
const selectedShapeIds = this.getSelectedShapeIds();
|
|
1490
|
+
const firstParentId = selectedShapeIds[0] ? this.getShape(selectedShapeIds[0])?.parentId : null;
|
|
1491
|
+
const isSelectedWithinContainer = firstParentId && selectedShapeIds.every((shapeId) => this.getShape(shapeId)?.parentId === firstParentId) && !isPageId(firstParentId);
|
|
1492
|
+
const readingOrderShapes = isSelectedWithinContainer ? this._getShapesInReadingOrder(
|
|
1493
|
+
this.getCurrentPageShapes().filter((shape2) => shape2.parentId === firstParentId)
|
|
1494
|
+
) : this.getCurrentPageShapesInReadingOrder();
|
|
1481
1495
|
const currentShapeId = selectedShapeIds.length === 1 ? selectedShapeIds[0] : readingOrderShapes.find((shape2) => selectedShapeIds.includes(shape2.id))?.id;
|
|
1482
1496
|
let adjacentShapeId;
|
|
1483
1497
|
if (direction === "next" || direction === "prev") {
|
|
@@ -1491,18 +1505,15 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
1491
1505
|
}
|
|
1492
1506
|
const shape = this.getShape(adjacentShapeId);
|
|
1493
1507
|
if (!shape) return;
|
|
1494
|
-
this.
|
|
1495
|
-
this.zoomToSelectionIfOffscreen(256, {
|
|
1496
|
-
animation: {
|
|
1497
|
-
duration: this.options.animationMediumMs
|
|
1498
|
-
},
|
|
1499
|
-
inset: 0
|
|
1500
|
-
});
|
|
1508
|
+
this._selectShapesAndZoom([shape.id]);
|
|
1501
1509
|
}
|
|
1502
1510
|
getCurrentPageShapesInReadingOrder() {
|
|
1511
|
+
const shapes = this.getCurrentPageShapes().filter((shape) => isPageId(shape.parentId));
|
|
1512
|
+
return this._getShapesInReadingOrder(shapes);
|
|
1513
|
+
}
|
|
1514
|
+
_getShapesInReadingOrder(shapes) {
|
|
1503
1515
|
const SHALLOW_ANGLE = 20;
|
|
1504
1516
|
const ROW_THRESHOLD = 100;
|
|
1505
|
-
const shapes = this.getCurrentPageShapes();
|
|
1506
1517
|
const tabbableShapes = shapes.filter((shape) => this.getShapeUtil(shape).canTabTo(shape));
|
|
1507
1518
|
if (tabbableShapes.length <= 1) return tabbableShapes;
|
|
1508
1519
|
const shapesWithCenters = tabbableShapes.map((shape) => ({
|
|
@@ -1600,6 +1611,31 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
1600
1611
|
});
|
|
1601
1612
|
return lowestScoringShape.shape.id;
|
|
1602
1613
|
}
|
|
1614
|
+
selectParentShape() {
|
|
1615
|
+
const selectedShape = this.getOnlySelectedShape();
|
|
1616
|
+
if (!selectedShape) return;
|
|
1617
|
+
const parentShape = this.getShape(selectedShape.parentId);
|
|
1618
|
+
if (!parentShape) return;
|
|
1619
|
+
this._selectShapesAndZoom([parentShape.id]);
|
|
1620
|
+
}
|
|
1621
|
+
selectFirstChildShape() {
|
|
1622
|
+
const selectedShapes = this.getSelectedShapes();
|
|
1623
|
+
if (!selectedShapes.length) return;
|
|
1624
|
+
const selectedShape = selectedShapes[0];
|
|
1625
|
+
const children = this.getSortedChildIdsForParent(selectedShape.id).map((id) => this.getShape(id)).filter((i) => i);
|
|
1626
|
+
const sortedChildren = this._getShapesInReadingOrder(children);
|
|
1627
|
+
if (sortedChildren.length === 0) return;
|
|
1628
|
+
this._selectShapesAndZoom([sortedChildren[0].id]);
|
|
1629
|
+
}
|
|
1630
|
+
_selectShapesAndZoom(ids) {
|
|
1631
|
+
this.setSelectedShapes(ids);
|
|
1632
|
+
this.zoomToSelectionIfOffscreen(256, {
|
|
1633
|
+
animation: {
|
|
1634
|
+
duration: this.options.animationMediumMs
|
|
1635
|
+
},
|
|
1636
|
+
inset: 0
|
|
1637
|
+
});
|
|
1638
|
+
}
|
|
1603
1639
|
/**
|
|
1604
1640
|
* Clear the selection.
|
|
1605
1641
|
*
|
|
@@ -1772,13 +1808,21 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
1772
1808
|
setEditingShape(shape) {
|
|
1773
1809
|
const id = typeof shape === "string" ? shape : shape?.id ?? null;
|
|
1774
1810
|
this.setRichTextEditor(null);
|
|
1775
|
-
|
|
1811
|
+
const prevEditingShapeId = this.getEditingShapeId();
|
|
1812
|
+
if (id !== prevEditingShapeId) {
|
|
1776
1813
|
if (id) {
|
|
1777
1814
|
const shape2 = this.getShape(id);
|
|
1778
1815
|
if (shape2 && this.getShapeUtil(shape2).canEdit(shape2)) {
|
|
1779
1816
|
this.run(
|
|
1780
1817
|
() => {
|
|
1781
1818
|
this._updateCurrentPageState({ editingShapeId: id });
|
|
1819
|
+
if (prevEditingShapeId) {
|
|
1820
|
+
const prevEditingShape = this.getShape(prevEditingShapeId);
|
|
1821
|
+
if (prevEditingShape) {
|
|
1822
|
+
this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape);
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1825
|
+
this.getShapeUtil(shape2).onEditStart?.(shape2);
|
|
1782
1826
|
},
|
|
1783
1827
|
{ history: "ignore" }
|
|
1784
1828
|
);
|
|
@@ -1789,6 +1833,12 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
1789
1833
|
() => {
|
|
1790
1834
|
this._updateCurrentPageState({ editingShapeId: null });
|
|
1791
1835
|
this._currentRichTextEditor.set(null);
|
|
1836
|
+
if (prevEditingShapeId) {
|
|
1837
|
+
const prevEditingShape = this.getShape(prevEditingShapeId);
|
|
1838
|
+
if (prevEditingShape) {
|
|
1839
|
+
this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape);
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1792
1842
|
},
|
|
1793
1843
|
{ history: "ignore" }
|
|
1794
1844
|
);
|
|
@@ -1984,12 +2034,22 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
1984
2034
|
}
|
|
1985
2035
|
return baseCamera;
|
|
1986
2036
|
}
|
|
2037
|
+
_getFollowingPresence(targetUserId) {
|
|
2038
|
+
const visited = [this.user.getId()];
|
|
2039
|
+
const collaborators = this.getCollaborators();
|
|
2040
|
+
let leaderPresence = null;
|
|
2041
|
+
while (targetUserId && !visited.includes(targetUserId)) {
|
|
2042
|
+
leaderPresence = collaborators.find((c) => c.userId === targetUserId) ?? null;
|
|
2043
|
+
targetUserId = leaderPresence?.followingUserId ?? null;
|
|
2044
|
+
if (leaderPresence) {
|
|
2045
|
+
visited.push(leaderPresence.userId);
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
2048
|
+
return leaderPresence;
|
|
2049
|
+
}
|
|
1987
2050
|
getViewportPageBoundsForFollowing() {
|
|
1988
|
-
const
|
|
1989
|
-
if (!
|
|
1990
|
-
const leaderPresence = this.getCollaborators().find((c) => c.userId === followingUserId);
|
|
1991
|
-
if (!leaderPresence) return null;
|
|
1992
|
-
if (!leaderPresence.camera || !leaderPresence.screenBounds) return null;
|
|
2051
|
+
const leaderPresence = this._getFollowingPresence(this.getInstanceState().followingUserId);
|
|
2052
|
+
if (!leaderPresence?.camera || !leaderPresence?.screenBounds) return null;
|
|
1993
2053
|
const { w: lw, h: lh } = leaderPresence.screenBounds;
|
|
1994
2054
|
const { x: lx, y: ly, z: lz } = leaderPresence.camera;
|
|
1995
2055
|
const theirViewport = new Box(-lx, -ly, lw / lz, lh / lz);
|
|
@@ -2896,34 +2956,30 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
2896
2956
|
*/
|
|
2897
2957
|
startFollowingUser(userId) {
|
|
2898
2958
|
this.stopFollowingUser();
|
|
2899
|
-
const leaderPresences = this._getCollaboratorsQuery().get().filter((p) => p.userId === userId);
|
|
2900
|
-
if (!leaderPresences.length) {
|
|
2901
|
-
console.warn("User not found");
|
|
2902
|
-
return this;
|
|
2903
|
-
}
|
|
2904
2959
|
const thisUserId = this.user.getId();
|
|
2905
2960
|
if (!thisUserId) {
|
|
2906
2961
|
console.warn("You should set the userId for the current instance before following a user");
|
|
2907
2962
|
}
|
|
2908
|
-
|
|
2963
|
+
const leaderPresence = this._getFollowingPresence(userId);
|
|
2964
|
+
if (!leaderPresence) {
|
|
2909
2965
|
return this;
|
|
2910
2966
|
}
|
|
2911
2967
|
const latestLeaderPresence = computed("latestLeaderPresence", () => {
|
|
2912
|
-
return this.
|
|
2968
|
+
return this._getFollowingPresence(userId);
|
|
2913
2969
|
});
|
|
2914
2970
|
transact(() => {
|
|
2915
2971
|
this.updateInstanceState({ followingUserId: userId }, { history: "ignore" });
|
|
2916
2972
|
const dispose = react("update current page", () => {
|
|
2917
|
-
const
|
|
2918
|
-
if (!
|
|
2973
|
+
const leaderPresence2 = latestLeaderPresence.get();
|
|
2974
|
+
if (!leaderPresence2) {
|
|
2919
2975
|
this.stopFollowingUser();
|
|
2920
2976
|
return;
|
|
2921
2977
|
}
|
|
2922
|
-
if (
|
|
2978
|
+
if (leaderPresence2.currentPageId !== this.getCurrentPageId() && this.getPage(leaderPresence2.currentPageId)) {
|
|
2923
2979
|
this.run(
|
|
2924
2980
|
() => {
|
|
2925
2981
|
this.store.put([
|
|
2926
|
-
{ ...this.getInstanceState(), currentPageId:
|
|
2982
|
+
{ ...this.getInstanceState(), currentPageId: leaderPresence2.currentPageId }
|
|
2927
2983
|
]);
|
|
2928
2984
|
this._isLockedOnFollowingUser.set(true);
|
|
2929
2985
|
},
|
|
@@ -2938,8 +2994,8 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
2938
2994
|
this.off("stop-following", cancel);
|
|
2939
2995
|
};
|
|
2940
2996
|
const moveTowardsUser = () => {
|
|
2941
|
-
const
|
|
2942
|
-
if (!
|
|
2997
|
+
const leaderPresence2 = latestLeaderPresence.get();
|
|
2998
|
+
if (!leaderPresence2) {
|
|
2943
2999
|
this.stopFollowingUser();
|
|
2944
3000
|
return;
|
|
2945
3001
|
}
|
|
@@ -3468,7 +3524,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
3468
3524
|
this.fonts.trackFontsForShape(shape2);
|
|
3469
3525
|
return this.getShapeUtil(shape2).getGeometry(shape2, opts);
|
|
3470
3526
|
},
|
|
3471
|
-
{ areRecordsEqual:
|
|
3527
|
+
{ areRecordsEqual: areShapesContentEqual }
|
|
3472
3528
|
);
|
|
3473
3529
|
}
|
|
3474
3530
|
return this._shapeGeometryCaches[context].get(
|
|
@@ -3511,9 +3567,15 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
3511
3567
|
);
|
|
3512
3568
|
}
|
|
3513
3569
|
_getShapeHandlesCache() {
|
|
3514
|
-
return this.store.createComputedCache(
|
|
3515
|
-
|
|
3516
|
-
|
|
3570
|
+
return this.store.createComputedCache(
|
|
3571
|
+
"handles",
|
|
3572
|
+
(shape) => {
|
|
3573
|
+
return this.getShapeUtil(shape).getHandles?.(shape);
|
|
3574
|
+
},
|
|
3575
|
+
{
|
|
3576
|
+
areRecordsEqual: areShapesContentEqual
|
|
3577
|
+
}
|
|
3578
|
+
);
|
|
3517
3579
|
}
|
|
3518
3580
|
/**
|
|
3519
3581
|
* Get the handles (if any) for a shape.
|
|
@@ -4397,9 +4459,15 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
4397
4459
|
}
|
|
4398
4460
|
_getBindingsIndexCache() {
|
|
4399
4461
|
const index = bindingsIndex(this);
|
|
4400
|
-
return this.store.createComputedCache(
|
|
4401
|
-
|
|
4402
|
-
|
|
4462
|
+
return this.store.createComputedCache(
|
|
4463
|
+
"bindingsIndex",
|
|
4464
|
+
(shape) => {
|
|
4465
|
+
return index.get().get(shape.id);
|
|
4466
|
+
},
|
|
4467
|
+
// we can ignore the shape equality check here because the index is
|
|
4468
|
+
// computed incrementally based on what bindings are in the store
|
|
4469
|
+
{ areRecordsEqual: () => true }
|
|
4470
|
+
);
|
|
4403
4471
|
}
|
|
4404
4472
|
/**
|
|
4405
4473
|
* Get a binding from the store by its ID if it exists.
|
|
@@ -7474,7 +7542,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
7474
7542
|
const { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera());
|
|
7475
7543
|
const { x: dx, y: dy, z: dz = 0 } = info.delta;
|
|
7476
7544
|
let behavior = wheelBehavior;
|
|
7477
|
-
if (
|
|
7545
|
+
if (info.ctrlKey) behavior = wheelBehavior === "pan" ? "zoom" : "pan";
|
|
7478
7546
|
switch (behavior) {
|
|
7479
7547
|
case "zoom": {
|
|
7480
7548
|
const { x, y } = this.inputs.currentScreenPoint;
|
|
@@ -7555,12 +7623,10 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
7555
7623
|
const { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera());
|
|
7556
7624
|
if (this.inputs.isPanning && this.inputs.isPointing) {
|
|
7557
7625
|
const { currentScreenPoint, previousScreenPoint } = this.inputs;
|
|
7558
|
-
const { panSpeed } = cameraOptions;
|
|
7559
7626
|
const offset = Vec.Sub(currentScreenPoint, previousScreenPoint);
|
|
7560
|
-
this.setCamera(
|
|
7561
|
-
|
|
7562
|
-
|
|
7563
|
-
);
|
|
7627
|
+
this.setCamera(new Vec(cx + offset.x / cz, cy + offset.y / cz, cz), {
|
|
7628
|
+
immediate: true
|
|
7629
|
+
});
|
|
7564
7630
|
this.maybeTrackPerformance("Panning");
|
|
7565
7631
|
return;
|
|
7566
7632
|
}
|