@tldraw/editor 3.9.0-internal.7f0e15f4f7d9 → 3.10.0-canary.15f6aaa3d2d3
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/CHANGELOG.md +90 -0
- package/README.md +1 -1
- package/dist-cjs/index.d.ts +43 -7
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawEditor.js +2 -3
- package/dist-cjs/lib/TldrawEditor.js.map +2 -2
- package/dist-cjs/lib/components/LiveCollaborators.js +5 -0
- package/dist-cjs/lib/components/LiveCollaborators.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultBrush.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCursor.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 +2 -2
- package/dist-cjs/lib/components/default-components/DefaultScribble.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +435 -252
- package/dist-cjs/lib/editor/Editor.js.map +3 -3
- package/dist-cjs/lib/editor/managers/FontManager.js +25 -26
- package/dist-cjs/lib/editor/managers/FontManager.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js +7 -2
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/exports/getSvgJsx.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 +43 -7
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawEditor.mjs +2 -3
- package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
- package/dist-esm/lib/components/LiveCollaborators.mjs +5 -0
- package/dist-esm/lib/components/LiveCollaborators.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultBrush.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCursor.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 +2 -2
- package/dist-esm/lib/components/default-components/DefaultScribble.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +431 -248
- package/dist-esm/lib/editor/Editor.mjs.map +3 -3
- package/dist-esm/lib/editor/managers/FontManager.mjs +26 -27
- package/dist-esm/lib/editor/managers/FontManager.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +7 -2
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/package.json +7 -7
- package/src/index.ts +2 -0
- package/src/lib/TldrawEditor.tsx +3 -3
- package/src/lib/components/LiveCollaborators.tsx +5 -0
- package/src/lib/components/default-components/DefaultBrush.tsx +1 -0
- package/src/lib/components/default-components/DefaultCollaboratorHint.tsx +1 -0
- package/src/lib/components/default-components/DefaultCursor.tsx +1 -0
- package/src/lib/components/default-components/DefaultErrorFallback.tsx +5 -3
- package/src/lib/components/default-components/DefaultScribble.tsx +1 -0
- package/src/lib/components/default-components/DefaultShapeIndicator.tsx +1 -0
- package/src/lib/editor/Editor.ts +560 -276
- package/src/lib/editor/managers/FontManager.ts +26 -27
- package/src/lib/editor/shapes/ShapeUtil.ts +32 -5
- package/src/lib/exports/getSvgJsx.tsx +1 -0
- package/src/version.ts +3 -3
|
@@ -46,7 +46,7 @@ var __privateIn = (member, obj) => Object(obj) !== obj ? __typeError('Cannot use
|
|
|
46
46
|
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
47
47
|
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
48
48
|
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
49
|
-
var __setMetaKeyTimeout_dec, __setCtrlKeyTimeout_dec, __setAltKeyTimeout_dec, __setShiftKeyTimeout_dec, _getIsReadonly_dec, _getIsFocused_dec, _getSharedOpacity_dec, _getSharedStyles_dec, __getSelectionSharedStyles_dec, __getBindingsIndexCache_dec, _getCurrentPageRenderingShapesSorted_dec, _getCurrentPageShapesSorted_dec, _getCurrentPageShapes_dec, _getCurrentPageBounds_dec, _getCulledShapes_dec, __notVisibleShapes_dec, __getShapeMaskedPageBoundsCache_dec, __getShapeMaskCache_dec, __getShapeClipPathCache_dec, __getShapePageBoundsCache_dec, __getShapePageTransformCache_dec, __getShapeHandlesCache_dec,
|
|
49
|
+
var __setMetaKeyTimeout_dec, __setCtrlKeyTimeout_dec, __setAltKeyTimeout_dec, __setShiftKeyTimeout_dec, _getIsReadonly_dec, _getIsFocused_dec, _getSharedOpacity_dec, _getSharedStyles_dec, __getSelectionSharedStyles_dec, __getBindingsIndexCache_dec, _getCurrentPageRenderingShapesSorted_dec, _getCurrentPageShapesSorted_dec, _getCurrentPageShapes_dec, _getCurrentPageBounds_dec, _getCulledShapes_dec, __notVisibleShapes_dec, __getShapeMaskedPageBoundsCache_dec, __getShapeMaskCache_dec, __getShapeClipPathCache_dec, __getShapePageBoundsCache_dec, __getShapePageTransformCache_dec, __getShapeHandlesCache_dec, __getAllAssetsQuery_dec, _getCurrentPageShapeIdsSorted_dec, _getCurrentPageId_dec, _getPages_dec, __getAllPagesQuery_dec, _getRenderingShapes_dec, _getCollaboratorsOnCurrentPage_dec, _getCollaborators_dec, __getCollaboratorsQuery_dec, _getViewportPageBounds_dec, _getViewportScreenCenter_dec, _getViewportScreenBounds_dec, _getZoomLevel_dec, _getCameraForFollowing_dec, _getViewportPageBoundsForFollowing_dec, _getCamera_dec, __unsafe_getCameraId_dec, _getErasingShapes_dec, _getErasingShapeIds_dec, _getHintingShape_dec, _getHintingShapeIds_dec, _getHoveredShape_dec, _getHoveredShapeId_dec, _getRichTextEditor_dec, _getEditingShape_dec, _getEditingShapeId_dec, _getFocusedGroup_dec, _getFocusedGroupId_dec, _getSelectionRotatedScreenBounds_dec, _getSelectionRotatedPageBounds_dec, _getSelectionRotation_dec, _getSelectionPageBounds_dec, _getOnlySelectedShape_dec, _getOnlySelectedShapeId_dec, _getSelectedShapes_dec, _getSelectedShapeIds_dec, __getCurrentPageStateId_dec, _getCurrentPageState_dec, __getPageStatesQuery_dec, _getPageStates_dec, _getIsMenuOpen_dec, _getOpenMenus_dec, _getInstanceState_dec, _getDocumentSettings_dec, _getCurrentToolId_dec, _getCurrentTool_dec, _getPath_dec, _getCanRedo_dec, _getCanUndo_dec, _getIsShapeHiddenCache_dec, _a, _init;
|
|
50
50
|
import {
|
|
51
51
|
EMPTY_ARRAY,
|
|
52
52
|
atom,
|
|
@@ -99,6 +99,7 @@ import {
|
|
|
99
99
|
structuredClone,
|
|
100
100
|
uniqueId
|
|
101
101
|
} from "@tldraw/utils";
|
|
102
|
+
import { Number } from "core-js";
|
|
102
103
|
import EventEmitter from "eventemitter3";
|
|
103
104
|
import {
|
|
104
105
|
getSnapshot,
|
|
@@ -129,7 +130,7 @@ import { Vec } from "../primitives/Vec.mjs";
|
|
|
129
130
|
import { EASINGS } from "../primitives/easings.mjs";
|
|
130
131
|
import { Group2d } from "../primitives/geometry/Group2d.mjs";
|
|
131
132
|
import { intersectPolygonPolygon } from "../primitives/intersect.mjs";
|
|
132
|
-
import {
|
|
133
|
+
import { PI, approximately, areAnglesCompatible, clamp, pointInPolygon } from "../primitives/utils.mjs";
|
|
133
134
|
import { SharedStyleMap } from "../utils/SharedStylesMap.mjs";
|
|
134
135
|
import { dataUrlToFile } from "../utils/assets.mjs";
|
|
135
136
|
import { debugFlags } from "../utils/debug-flags.mjs";
|
|
@@ -156,7 +157,7 @@ import { TextManager } from "./managers/TextManager.mjs";
|
|
|
156
157
|
import { TickManager } from "./managers/TickManager.mjs";
|
|
157
158
|
import { UserPreferencesManager } from "./managers/UserPreferencesManager.mjs";
|
|
158
159
|
import { RootState } from "./tools/RootState.mjs";
|
|
159
|
-
class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed], _getCanUndo_dec = [computed], _getCanRedo_dec = [computed], _getPath_dec = [computed], _getCurrentTool_dec = [computed], _getCurrentToolId_dec = [computed], _getDocumentSettings_dec = [computed], _getInstanceState_dec = [computed], _getOpenMenus_dec = [computed], _getIsMenuOpen_dec = [computed], _getPageStates_dec = [computed], __getPageStatesQuery_dec = [computed], _getCurrentPageState_dec = [computed], __getCurrentPageStateId_dec = [computed], _getSelectedShapeIds_dec = [computed], _getSelectedShapes_dec = [computed], _getOnlySelectedShapeId_dec = [computed], _getOnlySelectedShape_dec = [computed], _getSelectionPageBounds_dec = [computed], _getSelectionRotation_dec = [computed], _getSelectionRotatedPageBounds_dec = [computed], _getSelectionRotatedScreenBounds_dec = [computed], _getFocusedGroupId_dec = [computed], _getFocusedGroup_dec = [computed], _getEditingShapeId_dec = [computed], _getEditingShape_dec = [computed], _getRichTextEditor_dec = [computed], _getHoveredShapeId_dec = [computed], _getHoveredShape_dec = [computed], _getHintingShapeIds_dec = [computed], _getHintingShape_dec = [computed], _getErasingShapeIds_dec = [computed], _getErasingShapes_dec = [computed], __unsafe_getCameraId_dec = [computed], _getCamera_dec = [computed], _getViewportPageBoundsForFollowing_dec = [computed], _getCameraForFollowing_dec = [computed], _getZoomLevel_dec = [computed], _getViewportScreenBounds_dec = [computed], _getViewportScreenCenter_dec = [computed], _getViewportPageBounds_dec = [computed], __getCollaboratorsQuery_dec = [computed], _getCollaborators_dec = [computed], _getCollaboratorsOnCurrentPage_dec = [computed], _getRenderingShapes_dec = [computed], __getAllPagesQuery_dec = [computed], _getPages_dec = [computed], _getCurrentPageId_dec = [computed], _getCurrentPageShapeIdsSorted_dec = [computed], __getAllAssetsQuery_dec = [computed],
|
|
160
|
+
class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed], _getCanUndo_dec = [computed], _getCanRedo_dec = [computed], _getPath_dec = [computed], _getCurrentTool_dec = [computed], _getCurrentToolId_dec = [computed], _getDocumentSettings_dec = [computed], _getInstanceState_dec = [computed], _getOpenMenus_dec = [computed], _getIsMenuOpen_dec = [computed], _getPageStates_dec = [computed], __getPageStatesQuery_dec = [computed], _getCurrentPageState_dec = [computed], __getCurrentPageStateId_dec = [computed], _getSelectedShapeIds_dec = [computed], _getSelectedShapes_dec = [computed], _getOnlySelectedShapeId_dec = [computed], _getOnlySelectedShape_dec = [computed], _getSelectionPageBounds_dec = [computed], _getSelectionRotation_dec = [computed], _getSelectionRotatedPageBounds_dec = [computed], _getSelectionRotatedScreenBounds_dec = [computed], _getFocusedGroupId_dec = [computed], _getFocusedGroup_dec = [computed], _getEditingShapeId_dec = [computed], _getEditingShape_dec = [computed], _getRichTextEditor_dec = [computed], _getHoveredShapeId_dec = [computed], _getHoveredShape_dec = [computed], _getHintingShapeIds_dec = [computed], _getHintingShape_dec = [computed], _getErasingShapeIds_dec = [computed], _getErasingShapes_dec = [computed], __unsafe_getCameraId_dec = [computed], _getCamera_dec = [computed], _getViewportPageBoundsForFollowing_dec = [computed], _getCameraForFollowing_dec = [computed], _getZoomLevel_dec = [computed], _getViewportScreenBounds_dec = [computed], _getViewportScreenCenter_dec = [computed], _getViewportPageBounds_dec = [computed], __getCollaboratorsQuery_dec = [computed], _getCollaborators_dec = [computed], _getCollaboratorsOnCurrentPage_dec = [computed], _getRenderingShapes_dec = [computed], __getAllPagesQuery_dec = [computed], _getPages_dec = [computed], _getCurrentPageId_dec = [computed], _getCurrentPageShapeIdsSorted_dec = [computed], __getAllAssetsQuery_dec = [computed], __getShapeHandlesCache_dec = [computed], __getShapePageTransformCache_dec = [computed], __getShapePageBoundsCache_dec = [computed], __getShapeClipPathCache_dec = [computed], __getShapeMaskCache_dec = [computed], __getShapeMaskedPageBoundsCache_dec = [computed], __notVisibleShapes_dec = [computed], _getCulledShapes_dec = [computed], _getCurrentPageBounds_dec = [computed], _getCurrentPageShapes_dec = [computed], _getCurrentPageShapesSorted_dec = [computed], _getCurrentPageRenderingShapesSorted_dec = [computed], __getBindingsIndexCache_dec = [computed], __getSelectionSharedStyles_dec = [computed], _getSharedStyles_dec = [computed({ isEqual: (a, b) => a.equals(b) })], _getSharedOpacity_dec = [computed], _getIsFocused_dec = [computed], _getIsReadonly_dec = [computed], __setShiftKeyTimeout_dec = [bind], __setAltKeyTimeout_dec = [bind], __setCtrlKeyTimeout_dec = [bind], __setMetaKeyTimeout_dec = [bind], _a) {
|
|
160
161
|
constructor({
|
|
161
162
|
store,
|
|
162
163
|
user,
|
|
@@ -175,6 +176,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
175
176
|
}) {
|
|
176
177
|
super();
|
|
177
178
|
__runInitializers(_init, 5, this);
|
|
179
|
+
__publicField(this, "id", uniqueId());
|
|
178
180
|
__publicField(this, "_isShapeHiddenPredicate");
|
|
179
181
|
__publicField(this, "options");
|
|
180
182
|
__publicField(this, "contextId", uniqueId());
|
|
@@ -329,6 +331,8 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
329
331
|
__publicField(this, "_cameraStateTimeoutRemaining", 0);
|
|
330
332
|
/* @internal */
|
|
331
333
|
__publicField(this, "_currentPageShapeIds");
|
|
334
|
+
/* --------------------- Shapes --------------------- */
|
|
335
|
+
__publicField(this, "_shapeGeometryCaches", {});
|
|
332
336
|
// Parents and children
|
|
333
337
|
/**
|
|
334
338
|
* A cache of parents to children.
|
|
@@ -3279,16 +3283,6 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
3279
3283
|
async uploadAsset(asset, file, abortSignal) {
|
|
3280
3284
|
return await this.store.props.assets.upload(asset, file, abortSignal);
|
|
3281
3285
|
}
|
|
3282
|
-
_getShapeGeometryCache() {
|
|
3283
|
-
return this.store.createComputedCache(
|
|
3284
|
-
"bounds",
|
|
3285
|
-
(shape) => {
|
|
3286
|
-
this.fonts.trackFontsForShape(shape);
|
|
3287
|
-
return this.getShapeUtil(shape).getGeometry(shape);
|
|
3288
|
-
},
|
|
3289
|
-
{ areRecordsEqual: (a, b) => a.props === b.props }
|
|
3290
|
-
);
|
|
3291
|
-
}
|
|
3292
3286
|
/**
|
|
3293
3287
|
* Get the geometry of a shape.
|
|
3294
3288
|
*
|
|
@@ -3296,14 +3290,29 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
3296
3290
|
* ```ts
|
|
3297
3291
|
* editor.getShapeGeometry(myShape)
|
|
3298
3292
|
* editor.getShapeGeometry(myShapeId)
|
|
3293
|
+
* editor.getShapeGeometry(myShapeId, { context: "arrow" })
|
|
3299
3294
|
* ```
|
|
3300
3295
|
*
|
|
3301
3296
|
* @param shape - The shape (or shape id) to get the geometry for.
|
|
3297
|
+
* @param opts - Additional options about the request for geometry. Passed to {@link ShapeUtil.getGeometry}.
|
|
3302
3298
|
*
|
|
3303
3299
|
* @public
|
|
3304
3300
|
*/
|
|
3305
|
-
getShapeGeometry(shape) {
|
|
3306
|
-
|
|
3301
|
+
getShapeGeometry(shape, opts) {
|
|
3302
|
+
const context = opts?.context ?? "none";
|
|
3303
|
+
if (!this._shapeGeometryCaches[context]) {
|
|
3304
|
+
this._shapeGeometryCaches[context] = this.store.createComputedCache(
|
|
3305
|
+
"bounds",
|
|
3306
|
+
(shape2) => {
|
|
3307
|
+
this.fonts.trackFontsForShape(shape2);
|
|
3308
|
+
return this.getShapeUtil(shape2).getGeometry(shape2, opts);
|
|
3309
|
+
},
|
|
3310
|
+
{ areRecordsEqual: (a, b) => a.props === b.props }
|
|
3311
|
+
);
|
|
3312
|
+
}
|
|
3313
|
+
return this._shapeGeometryCaches[context].get(
|
|
3314
|
+
typeof shape === "string" ? shape : shape.id
|
|
3315
|
+
);
|
|
3307
3316
|
}
|
|
3308
3317
|
_getShapeHandlesCache() {
|
|
3309
3318
|
return this.store.createComputedCache("handles", (shape) => {
|
|
@@ -4369,27 +4378,28 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
4369
4378
|
});
|
|
4370
4379
|
return this;
|
|
4371
4380
|
}
|
|
4381
|
+
// Gets a shape partial that includes life cycle changes: on translate start, on translate, on translate end
|
|
4372
4382
|
getChangesToTranslateShape(initialShape, newShapeCoords) {
|
|
4373
4383
|
let workingShape = initialShape;
|
|
4374
4384
|
const util = this.getShapeUtil(initialShape);
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4385
|
+
const afterTranslateStart = util.onTranslateStart?.(workingShape);
|
|
4386
|
+
if (afterTranslateStart) {
|
|
4387
|
+
workingShape = applyPartialToRecordWithProps(workingShape, afterTranslateStart);
|
|
4388
|
+
}
|
|
4379
4389
|
workingShape = applyPartialToRecordWithProps(workingShape, {
|
|
4380
4390
|
id: initialShape.id,
|
|
4381
4391
|
type: initialShape.type,
|
|
4382
4392
|
x: newShapeCoords.x,
|
|
4383
4393
|
y: newShapeCoords.y
|
|
4384
4394
|
});
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4395
|
+
const afterTranslate = util.onTranslate?.(initialShape, workingShape);
|
|
4396
|
+
if (afterTranslate) {
|
|
4397
|
+
workingShape = applyPartialToRecordWithProps(workingShape, afterTranslate);
|
|
4398
|
+
}
|
|
4399
|
+
const afterTranslateEnd = util.onTranslateEnd?.(initialShape, workingShape);
|
|
4400
|
+
if (afterTranslateEnd) {
|
|
4401
|
+
workingShape = applyPartialToRecordWithProps(workingShape, afterTranslateEnd);
|
|
4402
|
+
}
|
|
4393
4403
|
return workingShape;
|
|
4394
4404
|
}
|
|
4395
4405
|
/**
|
|
@@ -4696,6 +4706,30 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
4696
4706
|
if (changes) this.updateShapes(changes);
|
|
4697
4707
|
return this;
|
|
4698
4708
|
}
|
|
4709
|
+
/**
|
|
4710
|
+
* @internal
|
|
4711
|
+
*/
|
|
4712
|
+
collectShapesViaArrowBindings(info) {
|
|
4713
|
+
const { initialShapes, resultShapes, resultBounds, bindings, visited } = info;
|
|
4714
|
+
for (const binding of bindings) {
|
|
4715
|
+
for (const id of [binding.fromId, binding.toId]) {
|
|
4716
|
+
if (!visited.has(id)) {
|
|
4717
|
+
const aligningShape = initialShapes.find((s) => s.id === id);
|
|
4718
|
+
if (aligningShape && !visited.has(aligningShape.id)) {
|
|
4719
|
+
visited.add(aligningShape.id);
|
|
4720
|
+
const shapePageBounds = this.getShapePageBounds(aligningShape);
|
|
4721
|
+
if (!shapePageBounds) continue;
|
|
4722
|
+
resultShapes.push(aligningShape);
|
|
4723
|
+
resultBounds.push(shapePageBounds);
|
|
4724
|
+
this.collectShapesViaArrowBindings({
|
|
4725
|
+
...info,
|
|
4726
|
+
bindings: this.getBindingsInvolvingShape(aligningShape, "arrow")
|
|
4727
|
+
});
|
|
4728
|
+
}
|
|
4729
|
+
}
|
|
4730
|
+
}
|
|
4731
|
+
}
|
|
4732
|
+
}
|
|
4699
4733
|
/**
|
|
4700
4734
|
* Flip shape positions.
|
|
4701
4735
|
*
|
|
@@ -4711,35 +4745,52 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
4711
4745
|
* @public
|
|
4712
4746
|
*/
|
|
4713
4747
|
flipShapes(shapes, operation) {
|
|
4714
|
-
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4715
4748
|
if (this.getIsReadonly()) return this;
|
|
4716
|
-
|
|
4749
|
+
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4750
|
+
const shapesToFlipFirstPass = compact(ids.map((id) => this.getShape(id)));
|
|
4751
|
+
for (const shape of shapesToFlipFirstPass) {
|
|
4752
|
+
if (this.isShapeOfType(shape, "group")) {
|
|
4753
|
+
const childrenOfGroups = compact(
|
|
4754
|
+
this.getSortedChildIdsForParent(shape.id).map((id) => this.getShape(id))
|
|
4755
|
+
);
|
|
4756
|
+
shapesToFlipFirstPass.push(...childrenOfGroups);
|
|
4757
|
+
}
|
|
4758
|
+
}
|
|
4759
|
+
const shapesToFlip = [];
|
|
4760
|
+
const allBounds = [];
|
|
4761
|
+
for (const shape of shapesToFlipFirstPass) {
|
|
4762
|
+
const util = this.getShapeUtil(shape);
|
|
4763
|
+
if (!util.canBeLaidOut(shape, {
|
|
4764
|
+
type: "flip",
|
|
4765
|
+
shapes: shapesToFlipFirstPass
|
|
4766
|
+
})) {
|
|
4767
|
+
continue;
|
|
4768
|
+
}
|
|
4769
|
+
const pageBounds = this.getShapePageBounds(shape);
|
|
4770
|
+
const localBounds = this.getShapeGeometry(shape).bounds;
|
|
4771
|
+
const pageTransform = this.getShapePageTransform(shape.id);
|
|
4772
|
+
if (!(pageBounds && localBounds && pageTransform)) continue;
|
|
4773
|
+
shapesToFlip.push({
|
|
4774
|
+
shape,
|
|
4775
|
+
localBounds,
|
|
4776
|
+
pageTransform,
|
|
4777
|
+
isAspectRatioLocked: util.isAspectRatioLocked(shape)
|
|
4778
|
+
});
|
|
4779
|
+
allBounds.push(pageBounds);
|
|
4780
|
+
}
|
|
4717
4781
|
if (!shapesToFlip.length) return this;
|
|
4718
|
-
|
|
4719
|
-
shapesToFlip.map((shape) => {
|
|
4720
|
-
if (this.isShapeOfType(shape, "group")) {
|
|
4721
|
-
return this.getSortedChildIdsForParent(shape.id).map((id) => this.getShape(id));
|
|
4722
|
-
}
|
|
4723
|
-
return shape;
|
|
4724
|
-
}).flat()
|
|
4725
|
-
);
|
|
4726
|
-
const scaleOriginPage = Box.Common(
|
|
4727
|
-
compact(shapesToFlip.map((id) => this.getShapePageBounds(id)))
|
|
4728
|
-
).center;
|
|
4782
|
+
const scaleOriginPage = Box.Common(allBounds).center;
|
|
4729
4783
|
this.run(() => {
|
|
4730
|
-
for (const shape of shapesToFlip) {
|
|
4731
|
-
const bounds = this.getShapeGeometry(shape).bounds;
|
|
4732
|
-
const initialPageTransform = this.getShapePageTransform(shape.id);
|
|
4733
|
-
if (!initialPageTransform) continue;
|
|
4784
|
+
for (const { shape, localBounds, pageTransform, isAspectRatioLocked } of shapesToFlip) {
|
|
4734
4785
|
this.resizeShape(
|
|
4735
4786
|
shape.id,
|
|
4736
4787
|
{ x: operation === "horizontal" ? -1 : 1, y: operation === "vertical" ? -1 : 1 },
|
|
4737
4788
|
{
|
|
4738
|
-
initialBounds:
|
|
4739
|
-
initialPageTransform,
|
|
4789
|
+
initialBounds: localBounds,
|
|
4790
|
+
initialPageTransform: pageTransform,
|
|
4740
4791
|
initialShape: shape,
|
|
4792
|
+
isAspectRatioLocked,
|
|
4741
4793
|
mode: "scale_shape",
|
|
4742
|
-
isAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),
|
|
4743
4794
|
scaleOrigin: scaleOriginPage,
|
|
4744
4795
|
scaleAxisRotation: 0
|
|
4745
4796
|
}
|
|
@@ -4766,15 +4817,40 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
4766
4817
|
stackShapes(shapes, operation, gap) {
|
|
4767
4818
|
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4768
4819
|
if (this.getIsReadonly()) return this;
|
|
4769
|
-
const
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
const
|
|
4820
|
+
const shapesToStackFirstPass = compact(ids.map((id) => this.getShape(id)));
|
|
4821
|
+
const shapeClustersToStack = [];
|
|
4822
|
+
const allBounds = [];
|
|
4823
|
+
const visited = /* @__PURE__ */ new Set();
|
|
4824
|
+
for (const shape of shapesToStackFirstPass) {
|
|
4825
|
+
if (visited.has(shape.id)) continue;
|
|
4826
|
+
visited.add(shape.id);
|
|
4827
|
+
const shapePageBounds = this.getShapePageBounds(shape);
|
|
4828
|
+
if (!shapePageBounds) continue;
|
|
4829
|
+
if (!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
4830
|
+
type: "stack",
|
|
4831
|
+
shapes: shapesToStackFirstPass
|
|
4832
|
+
})) {
|
|
4833
|
+
continue;
|
|
4834
|
+
}
|
|
4835
|
+
const shapesMovingTogether = [shape];
|
|
4836
|
+
const boundsOfShapesMovingTogether = [shapePageBounds];
|
|
4837
|
+
this.collectShapesViaArrowBindings({
|
|
4838
|
+
bindings: this.getBindingsToShape(shape.id, "arrow"),
|
|
4839
|
+
initialShapes: shapesToStackFirstPass,
|
|
4840
|
+
resultShapes: shapesMovingTogether,
|
|
4841
|
+
resultBounds: boundsOfShapesMovingTogether,
|
|
4842
|
+
visited
|
|
4843
|
+
});
|
|
4844
|
+
const commonPageBounds = Box.Common(boundsOfShapesMovingTogether);
|
|
4845
|
+
if (!commonPageBounds) continue;
|
|
4846
|
+
shapeClustersToStack.push({
|
|
4847
|
+
shapes: shapesMovingTogether,
|
|
4848
|
+
pageBounds: commonPageBounds
|
|
4849
|
+
});
|
|
4850
|
+
allBounds.push(commonPageBounds);
|
|
4851
|
+
}
|
|
4852
|
+
const len = shapeClustersToStack.length;
|
|
4774
4853
|
if (gap === 0 && len < 3 || len < 2) return this;
|
|
4775
|
-
const pageBounds = Object.fromEntries(
|
|
4776
|
-
shapesToStack.map((shape) => [shape.id, this.getShapePageBounds(shape)])
|
|
4777
|
-
);
|
|
4778
4854
|
let val;
|
|
4779
4855
|
let min;
|
|
4780
4856
|
let max;
|
|
@@ -4790,57 +4866,55 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
4790
4866
|
max = "maxY";
|
|
4791
4867
|
dim = "height";
|
|
4792
4868
|
}
|
|
4793
|
-
let shapeGap;
|
|
4869
|
+
let shapeGap = 0;
|
|
4794
4870
|
if (gap === 0) {
|
|
4795
|
-
const gaps =
|
|
4796
|
-
|
|
4871
|
+
const gaps = {};
|
|
4872
|
+
shapeClustersToStack.sort((a, b) => a.pageBounds[min] - b.pageBounds[min]);
|
|
4797
4873
|
for (let i = 0; i < len - 1; i++) {
|
|
4798
|
-
const
|
|
4799
|
-
const
|
|
4800
|
-
const
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
const current = gaps.find((g) => g.gap === gap2);
|
|
4804
|
-
if (current) {
|
|
4805
|
-
current.count++;
|
|
4806
|
-
} else {
|
|
4807
|
-
gaps.push({ gap: gap2, count: 1 });
|
|
4874
|
+
const currCluster = shapeClustersToStack[i];
|
|
4875
|
+
const nextCluster = shapeClustersToStack[i + 1];
|
|
4876
|
+
const gap2 = nextCluster.pageBounds[min] - currCluster.pageBounds[max];
|
|
4877
|
+
if (!gaps[gap2]) {
|
|
4878
|
+
gaps[gap2] = 0;
|
|
4808
4879
|
}
|
|
4880
|
+
gaps[gap2]++;
|
|
4809
4881
|
}
|
|
4810
|
-
let maxCount =
|
|
4811
|
-
|
|
4812
|
-
if (
|
|
4813
|
-
maxCount =
|
|
4814
|
-
shapeGap =
|
|
4882
|
+
let maxCount = 1;
|
|
4883
|
+
for (const [gap2, count] of Object.entries(gaps)) {
|
|
4884
|
+
if (count > maxCount) {
|
|
4885
|
+
maxCount = count;
|
|
4886
|
+
shapeGap = parseFloat(gap2);
|
|
4815
4887
|
}
|
|
4816
|
-
}
|
|
4888
|
+
}
|
|
4817
4889
|
if (maxCount === 1) {
|
|
4818
|
-
|
|
4890
|
+
let totalCount = 0;
|
|
4891
|
+
for (const [gap2, count] of Object.entries(gaps)) {
|
|
4892
|
+
shapeGap += parseFloat(gap2) * count;
|
|
4893
|
+
totalCount += count;
|
|
4894
|
+
}
|
|
4895
|
+
shapeGap /= totalCount;
|
|
4819
4896
|
}
|
|
4820
4897
|
} else {
|
|
4821
4898
|
shapeGap = gap;
|
|
4822
4899
|
}
|
|
4823
4900
|
const changes = [];
|
|
4824
|
-
let v =
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
-
const delta =
|
|
4828
|
-
delta[val] = v + shapeGap - pageBounds[
|
|
4829
|
-
const
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
[val]: shape[val] + localDelta[val]
|
|
4836
|
-
} : {
|
|
4837
|
-
id: shape.id,
|
|
4838
|
-
type: shape.type,
|
|
4839
|
-
[val]: shape[val] + localDelta[val]
|
|
4901
|
+
let v = shapeClustersToStack[0].pageBounds[max];
|
|
4902
|
+
for (let i = 1; i < shapeClustersToStack.length; i++) {
|
|
4903
|
+
const { shapes: shapes2, pageBounds } = shapeClustersToStack[i];
|
|
4904
|
+
const delta = new Vec();
|
|
4905
|
+
delta[val] = v + shapeGap - pageBounds[val];
|
|
4906
|
+
for (const shape of shapes2) {
|
|
4907
|
+
const shapeDelta = delta.clone();
|
|
4908
|
+
const parent = this.getShapeParent(shape);
|
|
4909
|
+
if (parent) {
|
|
4910
|
+
const parentTransform = this.getShapePageTransform(parent);
|
|
4911
|
+
if (parentTransform) shapeDelta.rot(-parentTransform.rotation());
|
|
4840
4912
|
}
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
|
|
4913
|
+
shapeDelta.add(shape);
|
|
4914
|
+
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
4915
|
+
}
|
|
4916
|
+
v += pageBounds[dim] + shapeGap;
|
|
4917
|
+
}
|
|
4844
4918
|
this.updateShapes(changes);
|
|
4845
4919
|
return this;
|
|
4846
4920
|
}
|
|
@@ -4858,91 +4932,101 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
4858
4932
|
* @param gap - The padding to apply to the packed shapes. Defaults to 16.
|
|
4859
4933
|
*/
|
|
4860
4934
|
packShapes(shapes, gap) {
|
|
4861
|
-
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4862
4935
|
if (this.getIsReadonly()) return this;
|
|
4863
|
-
|
|
4864
|
-
const
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
|
|
4868
|
-
const
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4936
|
+
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4937
|
+
const shapesToPackFirstPass = compact(ids.map((id) => this.getShape(id)));
|
|
4938
|
+
const shapeClustersToPack = [];
|
|
4939
|
+
const allBounds = [];
|
|
4940
|
+
const visited = /* @__PURE__ */ new Set();
|
|
4941
|
+
for (const shape of shapesToPackFirstPass) {
|
|
4942
|
+
if (visited.has(shape.id)) continue;
|
|
4943
|
+
visited.add(shape.id);
|
|
4944
|
+
const shapePageBounds = this.getShapePageBounds(shape);
|
|
4945
|
+
if (!shapePageBounds) continue;
|
|
4946
|
+
if (!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
4947
|
+
type: "pack",
|
|
4948
|
+
shapes: shapesToPackFirstPass
|
|
4949
|
+
})) {
|
|
4950
|
+
continue;
|
|
4951
|
+
}
|
|
4952
|
+
const shapesMovingTogether = [shape];
|
|
4953
|
+
const boundsOfShapesMovingTogether = [shapePageBounds];
|
|
4954
|
+
this.collectShapesViaArrowBindings({
|
|
4955
|
+
bindings: this.getBindingsToShape(shape.id, "arrow"),
|
|
4956
|
+
initialShapes: shapesToPackFirstPass,
|
|
4957
|
+
resultShapes: shapesMovingTogether,
|
|
4958
|
+
resultBounds: boundsOfShapesMovingTogether,
|
|
4959
|
+
visited
|
|
4960
|
+
});
|
|
4961
|
+
const commonPageBounds = Box.Common(boundsOfShapesMovingTogether);
|
|
4962
|
+
if (!commonPageBounds) continue;
|
|
4963
|
+
shapeClustersToPack.push({
|
|
4964
|
+
shapes: shapesMovingTogether,
|
|
4965
|
+
pageBounds: commonPageBounds,
|
|
4966
|
+
nextPageBounds: commonPageBounds.clone()
|
|
4967
|
+
});
|
|
4968
|
+
allBounds.push(commonPageBounds);
|
|
4969
|
+
}
|
|
4970
|
+
if (shapeClustersToPack.length < 2) return this;
|
|
4971
|
+
let area = 0;
|
|
4972
|
+
for (const { pageBounds } of shapeClustersToPack) {
|
|
4973
|
+
area += pageBounds.width * pageBounds.height;
|
|
4974
|
+
}
|
|
4975
|
+
const commonBounds = Box.Common(allBounds);
|
|
4879
4976
|
const maxWidth = commonBounds.width;
|
|
4880
|
-
|
|
4977
|
+
shapeClustersToPack.sort((a, b) => a.pageBounds.width - b.pageBounds.width).sort((a, b) => a.pageBounds.height - b.pageBounds.height);
|
|
4881
4978
|
const startWidth = Math.max(Math.ceil(Math.sqrt(area / 0.95)), maxWidth);
|
|
4882
4979
|
const spaces = [new Box(commonBounds.x, commonBounds.y, startWidth, Infinity)];
|
|
4883
4980
|
let width = 0;
|
|
4884
4981
|
let height = 0;
|
|
4885
4982
|
let space;
|
|
4886
4983
|
let last2;
|
|
4887
|
-
for (
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
width = Math.max(width, bounds.maxX);
|
|
4897
|
-
if (bounds.width === space.width && bounds.height === space.height) {
|
|
4984
|
+
for (const { nextPageBounds } of shapeClustersToPack) {
|
|
4985
|
+
for (let i = spaces.length - 1; i >= 0; i--) {
|
|
4986
|
+
space = spaces[i];
|
|
4987
|
+
if (nextPageBounds.width > space.width || nextPageBounds.height > space.height) continue;
|
|
4988
|
+
nextPageBounds.x = space.x;
|
|
4989
|
+
nextPageBounds.y = space.y;
|
|
4990
|
+
height = Math.max(height, nextPageBounds.maxY);
|
|
4991
|
+
width = Math.max(width, nextPageBounds.maxX);
|
|
4992
|
+
if (nextPageBounds.width === space.width && nextPageBounds.height === space.height) {
|
|
4898
4993
|
last2 = spaces.pop();
|
|
4899
|
-
if (
|
|
4900
|
-
} else if (
|
|
4901
|
-
space.x +=
|
|
4902
|
-
space.width -=
|
|
4903
|
-
} else if (
|
|
4904
|
-
space.y +=
|
|
4905
|
-
space.height -=
|
|
4994
|
+
if (i < spaces.length) spaces[i] = last2;
|
|
4995
|
+
} else if (nextPageBounds.height === space.height) {
|
|
4996
|
+
space.x += nextPageBounds.width + gap;
|
|
4997
|
+
space.width -= nextPageBounds.width + gap;
|
|
4998
|
+
} else if (nextPageBounds.width === space.width) {
|
|
4999
|
+
space.y += nextPageBounds.height + gap;
|
|
5000
|
+
space.height -= nextPageBounds.height + gap;
|
|
4906
5001
|
} else {
|
|
4907
5002
|
spaces.push(
|
|
4908
5003
|
new Box(
|
|
4909
|
-
space.x + (
|
|
5004
|
+
space.x + (nextPageBounds.width + gap),
|
|
4910
5005
|
space.y,
|
|
4911
|
-
space.width - (
|
|
4912
|
-
|
|
5006
|
+
space.width - (nextPageBounds.width + gap),
|
|
5007
|
+
nextPageBounds.height
|
|
4913
5008
|
)
|
|
4914
5009
|
);
|
|
4915
|
-
space.y +=
|
|
4916
|
-
space.height -=
|
|
5010
|
+
space.y += nextPageBounds.height + gap;
|
|
5011
|
+
space.height -= nextPageBounds.height + gap;
|
|
4917
5012
|
}
|
|
4918
5013
|
break;
|
|
4919
5014
|
}
|
|
4920
5015
|
}
|
|
4921
|
-
const commonAfter = Box.Common(
|
|
5016
|
+
const commonAfter = Box.Common(shapeClustersToPack.map((s) => s.nextPageBounds));
|
|
4922
5017
|
const centerDelta = Vec.Sub(commonBounds.center, commonAfter.center);
|
|
4923
|
-
let nextBounds;
|
|
4924
5018
|
const changes = [];
|
|
4925
|
-
for (
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
|
|
4935
|
-
|
|
4936
|
-
y: shape.y + delta.y
|
|
4937
|
-
};
|
|
4938
|
-
const translateStartChange = this.getShapeUtil(shape).onTranslateStart?.({
|
|
4939
|
-
...shape,
|
|
4940
|
-
...change
|
|
4941
|
-
});
|
|
4942
|
-
if (translateStartChange) {
|
|
4943
|
-
changes.push({ ...change, ...translateStartChange });
|
|
4944
|
-
} else {
|
|
4945
|
-
changes.push(change);
|
|
5019
|
+
for (const { shapes: shapes2, pageBounds, nextPageBounds } of shapeClustersToPack) {
|
|
5020
|
+
const delta = Vec.Sub(nextPageBounds.point, pageBounds.point).add(centerDelta);
|
|
5021
|
+
for (const shape of shapes2) {
|
|
5022
|
+
const shapeDelta = delta.clone();
|
|
5023
|
+
const parent = this.getShapeParent(shape);
|
|
5024
|
+
if (parent) {
|
|
5025
|
+
const parentTransform = this.getShapeParentTransform(shape);
|
|
5026
|
+
if (parentTransform) shapeDelta.rot(-parentTransform.rotation());
|
|
5027
|
+
}
|
|
5028
|
+
shapeDelta.add(shape);
|
|
5029
|
+
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
4946
5030
|
}
|
|
4947
5031
|
}
|
|
4948
5032
|
if (changes.length) {
|
|
@@ -4965,19 +5049,45 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
4965
5049
|
* @public
|
|
4966
5050
|
*/
|
|
4967
5051
|
alignShapes(shapes, operation) {
|
|
4968
|
-
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4969
5052
|
if (this.getIsReadonly()) return this;
|
|
4970
|
-
|
|
4971
|
-
const
|
|
4972
|
-
const
|
|
4973
|
-
|
|
4974
|
-
);
|
|
4975
|
-
const
|
|
5053
|
+
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
5054
|
+
const shapesToAlignFirstPass = compact(ids.map((id) => this.getShape(id)));
|
|
5055
|
+
const shapeClustersToAlign = [];
|
|
5056
|
+
const allBounds = [];
|
|
5057
|
+
const visited = /* @__PURE__ */ new Set();
|
|
5058
|
+
for (const shape of shapesToAlignFirstPass) {
|
|
5059
|
+
if (visited.has(shape.id)) continue;
|
|
5060
|
+
visited.add(shape.id);
|
|
5061
|
+
const shapePageBounds = this.getShapePageBounds(shape);
|
|
5062
|
+
if (!shapePageBounds) continue;
|
|
5063
|
+
if (!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
5064
|
+
type: "align",
|
|
5065
|
+
shapes: shapesToAlignFirstPass
|
|
5066
|
+
})) {
|
|
5067
|
+
continue;
|
|
5068
|
+
}
|
|
5069
|
+
const shapesMovingTogether = [shape];
|
|
5070
|
+
const boundsOfShapesMovingTogether = [shapePageBounds];
|
|
5071
|
+
this.collectShapesViaArrowBindings({
|
|
5072
|
+
bindings: this.getBindingsToShape(shape.id, "arrow"),
|
|
5073
|
+
initialShapes: shapesToAlignFirstPass,
|
|
5074
|
+
resultShapes: shapesMovingTogether,
|
|
5075
|
+
resultBounds: boundsOfShapesMovingTogether,
|
|
5076
|
+
visited
|
|
5077
|
+
});
|
|
5078
|
+
const commonPageBounds = Box.Common(boundsOfShapesMovingTogether);
|
|
5079
|
+
if (!commonPageBounds) continue;
|
|
5080
|
+
shapeClustersToAlign.push({
|
|
5081
|
+
shapes: shapesMovingTogether,
|
|
5082
|
+
pageBounds: commonPageBounds
|
|
5083
|
+
});
|
|
5084
|
+
allBounds.push(commonPageBounds);
|
|
5085
|
+
}
|
|
5086
|
+
if (shapeClustersToAlign.length < 2) return this;
|
|
5087
|
+
const commonBounds = Box.Common(allBounds);
|
|
4976
5088
|
const changes = [];
|
|
4977
|
-
|
|
4978
|
-
const
|
|
4979
|
-
if (!pageBounds) return;
|
|
4980
|
-
const delta = { x: 0, y: 0 };
|
|
5089
|
+
shapeClustersToAlign.forEach(({ shapes: shapes2, pageBounds }) => {
|
|
5090
|
+
const delta = new Vec();
|
|
4981
5091
|
switch (operation) {
|
|
4982
5092
|
case "top": {
|
|
4983
5093
|
delta.y = commonBounds.minY - pageBounds.minY;
|
|
@@ -5004,9 +5114,16 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
5004
5114
|
break;
|
|
5005
5115
|
}
|
|
5006
5116
|
}
|
|
5007
|
-
const
|
|
5008
|
-
|
|
5009
|
-
|
|
5117
|
+
for (const shape of shapes2) {
|
|
5118
|
+
const shapeDelta = delta.clone();
|
|
5119
|
+
const parent = this.getShapeParent(shape);
|
|
5120
|
+
if (parent) {
|
|
5121
|
+
const parentTransform = this.getShapePageTransform(parent);
|
|
5122
|
+
if (parentTransform) shapeDelta.rot(-parentTransform.rotation());
|
|
5123
|
+
}
|
|
5124
|
+
shapeDelta.add(shape);
|
|
5125
|
+
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
5126
|
+
}
|
|
5010
5127
|
});
|
|
5011
5128
|
this.updateShapes(changes);
|
|
5012
5129
|
return this;
|
|
@@ -5026,47 +5143,95 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
5026
5143
|
* @public
|
|
5027
5144
|
*/
|
|
5028
5145
|
distributeShapes(shapes, operation) {
|
|
5029
|
-
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
5030
5146
|
if (this.getIsReadonly()) return this;
|
|
5031
|
-
|
|
5032
|
-
const
|
|
5033
|
-
const
|
|
5034
|
-
const
|
|
5035
|
-
|
|
5036
|
-
)
|
|
5147
|
+
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
5148
|
+
const shapesToDistributeFirstPass = compact(ids.map((id) => this.getShape(id)));
|
|
5149
|
+
const shapeClustersToDistribute = [];
|
|
5150
|
+
const allBounds = [];
|
|
5151
|
+
const visited = /* @__PURE__ */ new Set();
|
|
5152
|
+
for (const shape of shapesToDistributeFirstPass) {
|
|
5153
|
+
if (visited.has(shape.id)) continue;
|
|
5154
|
+
visited.add(shape.id);
|
|
5155
|
+
const shapePageBounds = this.getShapePageBounds(shape);
|
|
5156
|
+
if (!shapePageBounds) continue;
|
|
5157
|
+
if (!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
5158
|
+
type: "distribute",
|
|
5159
|
+
shapes: shapesToDistributeFirstPass
|
|
5160
|
+
})) {
|
|
5161
|
+
continue;
|
|
5162
|
+
}
|
|
5163
|
+
const shapesMovingTogether = [shape];
|
|
5164
|
+
const boundsOfShapesMovingTogether = [shapePageBounds];
|
|
5165
|
+
this.collectShapesViaArrowBindings({
|
|
5166
|
+
bindings: this.getBindingsToShape(shape.id, "arrow"),
|
|
5167
|
+
initialShapes: shapesToDistributeFirstPass,
|
|
5168
|
+
resultShapes: shapesMovingTogether,
|
|
5169
|
+
resultBounds: boundsOfShapesMovingTogether,
|
|
5170
|
+
visited
|
|
5171
|
+
});
|
|
5172
|
+
const commonPageBounds = Box.Common(boundsOfShapesMovingTogether);
|
|
5173
|
+
if (!commonPageBounds) continue;
|
|
5174
|
+
shapeClustersToDistribute.push({
|
|
5175
|
+
shapes: shapesMovingTogether,
|
|
5176
|
+
pageBounds: commonPageBounds
|
|
5177
|
+
});
|
|
5178
|
+
allBounds.push(commonPageBounds);
|
|
5179
|
+
}
|
|
5180
|
+
if (shapeClustersToDistribute.length < 3) return this;
|
|
5037
5181
|
let val;
|
|
5038
5182
|
let min;
|
|
5039
5183
|
let max;
|
|
5040
|
-
let mid;
|
|
5041
5184
|
let dim;
|
|
5042
5185
|
if (operation === "horizontal") {
|
|
5043
5186
|
val = "x";
|
|
5044
5187
|
min = "minX";
|
|
5045
5188
|
max = "maxX";
|
|
5046
|
-
mid = "midX";
|
|
5047
5189
|
dim = "width";
|
|
5048
5190
|
} else {
|
|
5049
5191
|
val = "y";
|
|
5050
5192
|
min = "minY";
|
|
5051
5193
|
max = "maxY";
|
|
5052
|
-
mid = "midY";
|
|
5053
5194
|
dim = "height";
|
|
5054
5195
|
}
|
|
5055
5196
|
const changes = [];
|
|
5056
|
-
const first =
|
|
5057
|
-
|
|
5058
|
-
)
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5197
|
+
const first = shapeClustersToDistribute.sort((a, b) => a.pageBounds[min] - b.pageBounds[min])[0];
|
|
5198
|
+
const last2 = shapeClustersToDistribute.sort((a, b) => b.pageBounds[max] - a.pageBounds[max])[0];
|
|
5199
|
+
if (first === last2) {
|
|
5200
|
+
const excludedShapeIds = new Set(first.shapes.map((s) => s.id));
|
|
5201
|
+
return this.distributeShapes(
|
|
5202
|
+
ids.filter((id) => !excludedShapeIds.has(id)),
|
|
5203
|
+
operation
|
|
5204
|
+
);
|
|
5205
|
+
}
|
|
5206
|
+
const shapeClustersToMove = shapeClustersToDistribute.filter((shape) => shape !== first && shape !== last2).sort((a, b) => {
|
|
5207
|
+
if (a.pageBounds[min] === b.pageBounds[min]) {
|
|
5208
|
+
return a.shapes[0].id < b.shapes[0].id ? -1 : 1;
|
|
5209
|
+
}
|
|
5210
|
+
return a.pageBounds[min] - b.pageBounds[min];
|
|
5069
5211
|
});
|
|
5212
|
+
const maxFirst = first.pageBounds[max];
|
|
5213
|
+
const range = last2.pageBounds[min] - maxFirst;
|
|
5214
|
+
const summedShapeDimensions = shapeClustersToMove.reduce((acc, s) => acc + s.pageBounds[dim], 0);
|
|
5215
|
+
const gap = (range - summedShapeDimensions) / (shapeClustersToMove.length + 1);
|
|
5216
|
+
for (let v = maxFirst + gap, i = 0; i < shapeClustersToMove.length; i++) {
|
|
5217
|
+
const { shapes: shapes2, pageBounds } = shapeClustersToMove[i];
|
|
5218
|
+
const delta = new Vec();
|
|
5219
|
+
delta[val] = v - pageBounds[val];
|
|
5220
|
+
if (v + pageBounds[dim] > last2.pageBounds[max] - 1) {
|
|
5221
|
+
delta[val] = last2.pageBounds[max] - pageBounds[max] - 1;
|
|
5222
|
+
}
|
|
5223
|
+
for (const shape of shapes2) {
|
|
5224
|
+
const shapeDelta = delta.clone();
|
|
5225
|
+
const parent = this.getShapeParent(shape);
|
|
5226
|
+
if (parent) {
|
|
5227
|
+
const parentTransform = this.getShapePageTransform(parent);
|
|
5228
|
+
if (parentTransform) shapeDelta.rot(-parentTransform.rotation());
|
|
5229
|
+
}
|
|
5230
|
+
shapeDelta.add(shape);
|
|
5231
|
+
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
5232
|
+
}
|
|
5233
|
+
v += pageBounds[dim] + gap;
|
|
5234
|
+
}
|
|
5070
5235
|
this.updateShapes(changes);
|
|
5071
5236
|
return this;
|
|
5072
5237
|
}
|
|
@@ -5087,59 +5252,78 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
5087
5252
|
stretchShapes(shapes, operation) {
|
|
5088
5253
|
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
5089
5254
|
if (this.getIsReadonly()) return this;
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
const
|
|
5094
|
-
const
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
const scale = new Vec(1, commonBounds.height / pageBounds.height);
|
|
5109
|
-
this.resizeShape(shape.id, scale, {
|
|
5110
|
-
initialBounds: bounds,
|
|
5111
|
-
scaleOrigin: new Vec(pageBounds.center.x, commonBounds.minY),
|
|
5112
|
-
isAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),
|
|
5113
|
-
scaleAxisRotation: 0
|
|
5114
|
-
});
|
|
5115
|
-
}
|
|
5116
|
-
});
|
|
5117
|
-
break;
|
|
5118
|
-
}
|
|
5119
|
-
case "horizontal": {
|
|
5120
|
-
this.run(() => {
|
|
5121
|
-
for (const shape of shapesToStretch) {
|
|
5122
|
-
const bounds = shapeBounds[shape.id];
|
|
5123
|
-
const pageBounds = shapePageBounds[shape.id];
|
|
5124
|
-
const pageRotation = this.getShapePageTransform(shape).rotation();
|
|
5125
|
-
if (pageRotation % PI2) continue;
|
|
5126
|
-
const localOffset = new Vec(commonBounds.minX - pageBounds.minX, 0);
|
|
5127
|
-
const parentTransform = this.getShapeParentTransform(shape);
|
|
5128
|
-
if (parentTransform) localOffset.rot(-parentTransform.rotation());
|
|
5129
|
-
const { x, y } = Vec.Add(localOffset, shape);
|
|
5130
|
-
this.updateShapes([{ id: shape.id, type: shape.type, x, y }]);
|
|
5131
|
-
const scale = new Vec(commonBounds.width / pageBounds.width, 1);
|
|
5132
|
-
this.resizeShape(shape.id, scale, {
|
|
5133
|
-
initialBounds: bounds,
|
|
5134
|
-
scaleOrigin: new Vec(commonBounds.minX, pageBounds.center.y),
|
|
5135
|
-
isAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),
|
|
5136
|
-
scaleAxisRotation: 0
|
|
5137
|
-
});
|
|
5138
|
-
}
|
|
5139
|
-
});
|
|
5140
|
-
break;
|
|
5255
|
+
const shapesToStretchFirstPass = compact(ids.map((id) => this.getShape(id))).filter(
|
|
5256
|
+
(s) => this.getShapePageTransform(s)?.rotation() % (PI / 2) === 0
|
|
5257
|
+
);
|
|
5258
|
+
const shapeClustersToStretch = [];
|
|
5259
|
+
const allBounds = [];
|
|
5260
|
+
const visited = /* @__PURE__ */ new Set();
|
|
5261
|
+
for (const shape of shapesToStretchFirstPass) {
|
|
5262
|
+
if (visited.has(shape.id)) continue;
|
|
5263
|
+
visited.add(shape.id);
|
|
5264
|
+
const shapePageBounds = this.getShapePageBounds(shape);
|
|
5265
|
+
if (!shapePageBounds) continue;
|
|
5266
|
+
const shapesMovingTogether = [shape];
|
|
5267
|
+
const boundsOfShapesMovingTogether = [shapePageBounds];
|
|
5268
|
+
if (!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
5269
|
+
type: "stretch",
|
|
5270
|
+
shapes: shapesToStretchFirstPass
|
|
5271
|
+
})) {
|
|
5272
|
+
continue;
|
|
5141
5273
|
}
|
|
5274
|
+
this.collectShapesViaArrowBindings({
|
|
5275
|
+
bindings: this.getBindingsToShape(shape.id, "arrow"),
|
|
5276
|
+
initialShapes: shapesToStretchFirstPass,
|
|
5277
|
+
resultShapes: shapesMovingTogether,
|
|
5278
|
+
resultBounds: boundsOfShapesMovingTogether,
|
|
5279
|
+
visited
|
|
5280
|
+
});
|
|
5281
|
+
const commonPageBounds = Box.Common(boundsOfShapesMovingTogether);
|
|
5282
|
+
if (!commonPageBounds) continue;
|
|
5283
|
+
shapeClustersToStretch.push({
|
|
5284
|
+
shapes: shapesMovingTogether,
|
|
5285
|
+
pageBounds: commonPageBounds
|
|
5286
|
+
});
|
|
5287
|
+
allBounds.push(commonPageBounds);
|
|
5288
|
+
}
|
|
5289
|
+
if (shapeClustersToStretch.length < 2) return this;
|
|
5290
|
+
const commonBounds = Box.Common(allBounds);
|
|
5291
|
+
let val;
|
|
5292
|
+
let min;
|
|
5293
|
+
let dim;
|
|
5294
|
+
if (operation === "horizontal") {
|
|
5295
|
+
val = "x";
|
|
5296
|
+
min = "minX";
|
|
5297
|
+
dim = "width";
|
|
5298
|
+
} else {
|
|
5299
|
+
val = "y";
|
|
5300
|
+
min = "minY";
|
|
5301
|
+
dim = "height";
|
|
5142
5302
|
}
|
|
5303
|
+
this.run(() => {
|
|
5304
|
+
shapeClustersToStretch.forEach(({ shapes: shapes2, pageBounds }) => {
|
|
5305
|
+
const localOffset = new Vec();
|
|
5306
|
+
localOffset[val] = commonBounds[min] - pageBounds[min];
|
|
5307
|
+
const scaleOrigin = pageBounds.center.clone();
|
|
5308
|
+
scaleOrigin[val] = commonBounds[min];
|
|
5309
|
+
const scale = new Vec(1, 1);
|
|
5310
|
+
scale[val] = commonBounds[dim] / pageBounds[dim];
|
|
5311
|
+
for (const shape of shapes2) {
|
|
5312
|
+
const shapeLocalOffset = localOffset.clone();
|
|
5313
|
+
const parentTransform = this.getShapeParentTransform(shape);
|
|
5314
|
+
if (parentTransform) localOffset.rot(-parentTransform.rotation());
|
|
5315
|
+
shapeLocalOffset.add(shape);
|
|
5316
|
+
const changes = this.getChangesToTranslateShape(shape, shapeLocalOffset);
|
|
5317
|
+
this.updateShape(changes);
|
|
5318
|
+
this.resizeShape(shape.id, scale, {
|
|
5319
|
+
initialBounds: this.getShapeGeometry(shape).bounds,
|
|
5320
|
+
scaleOrigin,
|
|
5321
|
+
isAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),
|
|
5322
|
+
scaleAxisRotation: 0
|
|
5323
|
+
});
|
|
5324
|
+
}
|
|
5325
|
+
});
|
|
5326
|
+
});
|
|
5143
5327
|
return this;
|
|
5144
5328
|
}
|
|
5145
5329
|
/**
|
|
@@ -7389,7 +7573,6 @@ __decorateElement(_init, 1, "getPages", _getPages_dec, Editor);
|
|
|
7389
7573
|
__decorateElement(_init, 1, "getCurrentPageId", _getCurrentPageId_dec, Editor);
|
|
7390
7574
|
__decorateElement(_init, 1, "getCurrentPageShapeIdsSorted", _getCurrentPageShapeIdsSorted_dec, Editor);
|
|
7391
7575
|
__decorateElement(_init, 1, "_getAllAssetsQuery", __getAllAssetsQuery_dec, Editor);
|
|
7392
|
-
__decorateElement(_init, 1, "_getShapeGeometryCache", __getShapeGeometryCache_dec, Editor);
|
|
7393
7576
|
__decorateElement(_init, 1, "_getShapeHandlesCache", __getShapeHandlesCache_dec, Editor);
|
|
7394
7577
|
__decorateElement(_init, 1, "_getShapePageTransformCache", __getShapePageTransformCache_dec, Editor);
|
|
7395
7578
|
__decorateElement(_init, 1, "_getShapePageBoundsCache", __getShapePageBoundsCache_dec, Editor);
|
|
@@ -7479,7 +7662,7 @@ function withIsolatedShapes(editor, shapeIds, callback) {
|
|
|
7479
7662
|
result = Result.err(error);
|
|
7480
7663
|
}
|
|
7481
7664
|
});
|
|
7482
|
-
editor.store.applyDiff(reverseRecordsDiff(changes));
|
|
7665
|
+
editor.store.applyDiff(reverseRecordsDiff(changes), { runCallbacks: false });
|
|
7483
7666
|
},
|
|
7484
7667
|
{ history: "ignore" }
|
|
7485
7668
|
);
|