@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
|
@@ -80,6 +80,7 @@ var import_state = require("@tldraw/state");
|
|
|
80
80
|
var import_store = require("@tldraw/store");
|
|
81
81
|
var import_tlschema = require("@tldraw/tlschema");
|
|
82
82
|
var import_utils = require("@tldraw/utils");
|
|
83
|
+
var import_core_js = require("core-js");
|
|
83
84
|
var import_eventemitter3 = __toESM(require("eventemitter3"));
|
|
84
85
|
var import_TLEditorSnapshot = require("../config/TLEditorSnapshot");
|
|
85
86
|
var import_createTLUser = require("../config/createTLUser");
|
|
@@ -122,8 +123,8 @@ var import_TextManager = require("./managers/TextManager");
|
|
|
122
123
|
var import_TickManager = require("./managers/TickManager");
|
|
123
124
|
var import_UserPreferencesManager = require("./managers/UserPreferencesManager");
|
|
124
125
|
var import_RootState = require("./tools/RootState");
|
|
125
|
-
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,
|
|
126
|
-
class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_dec = [import_state.computed], _getCanUndo_dec = [import_state.computed], _getCanRedo_dec = [import_state.computed], _getPath_dec = [import_state.computed], _getCurrentTool_dec = [import_state.computed], _getCurrentToolId_dec = [import_state.computed], _getDocumentSettings_dec = [import_state.computed], _getInstanceState_dec = [import_state.computed], _getOpenMenus_dec = [import_state.computed], _getIsMenuOpen_dec = [import_state.computed], _getPageStates_dec = [import_state.computed], __getPageStatesQuery_dec = [import_state.computed], _getCurrentPageState_dec = [import_state.computed], __getCurrentPageStateId_dec = [import_state.computed], _getSelectedShapeIds_dec = [import_state.computed], _getSelectedShapes_dec = [import_state.computed], _getOnlySelectedShapeId_dec = [import_state.computed], _getOnlySelectedShape_dec = [import_state.computed], _getSelectionPageBounds_dec = [import_state.computed], _getSelectionRotation_dec = [import_state.computed], _getSelectionRotatedPageBounds_dec = [import_state.computed], _getSelectionRotatedScreenBounds_dec = [import_state.computed], _getFocusedGroupId_dec = [import_state.computed], _getFocusedGroup_dec = [import_state.computed], _getEditingShapeId_dec = [import_state.computed], _getEditingShape_dec = [import_state.computed], _getRichTextEditor_dec = [import_state.computed], _getHoveredShapeId_dec = [import_state.computed], _getHoveredShape_dec = [import_state.computed], _getHintingShapeIds_dec = [import_state.computed], _getHintingShape_dec = [import_state.computed], _getErasingShapeIds_dec = [import_state.computed], _getErasingShapes_dec = [import_state.computed], __unsafe_getCameraId_dec = [import_state.computed], _getCamera_dec = [import_state.computed], _getViewportPageBoundsForFollowing_dec = [import_state.computed], _getCameraForFollowing_dec = [import_state.computed], _getZoomLevel_dec = [import_state.computed], _getViewportScreenBounds_dec = [import_state.computed], _getViewportScreenCenter_dec = [import_state.computed], _getViewportPageBounds_dec = [import_state.computed], __getCollaboratorsQuery_dec = [import_state.computed], _getCollaborators_dec = [import_state.computed], _getCollaboratorsOnCurrentPage_dec = [import_state.computed], _getRenderingShapes_dec = [import_state.computed], __getAllPagesQuery_dec = [import_state.computed], _getPages_dec = [import_state.computed], _getCurrentPageId_dec = [import_state.computed], _getCurrentPageShapeIdsSorted_dec = [import_state.computed], __getAllAssetsQuery_dec = [import_state.computed],
|
|
126
|
+
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;
|
|
127
|
+
class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_dec = [import_state.computed], _getCanUndo_dec = [import_state.computed], _getCanRedo_dec = [import_state.computed], _getPath_dec = [import_state.computed], _getCurrentTool_dec = [import_state.computed], _getCurrentToolId_dec = [import_state.computed], _getDocumentSettings_dec = [import_state.computed], _getInstanceState_dec = [import_state.computed], _getOpenMenus_dec = [import_state.computed], _getIsMenuOpen_dec = [import_state.computed], _getPageStates_dec = [import_state.computed], __getPageStatesQuery_dec = [import_state.computed], _getCurrentPageState_dec = [import_state.computed], __getCurrentPageStateId_dec = [import_state.computed], _getSelectedShapeIds_dec = [import_state.computed], _getSelectedShapes_dec = [import_state.computed], _getOnlySelectedShapeId_dec = [import_state.computed], _getOnlySelectedShape_dec = [import_state.computed], _getSelectionPageBounds_dec = [import_state.computed], _getSelectionRotation_dec = [import_state.computed], _getSelectionRotatedPageBounds_dec = [import_state.computed], _getSelectionRotatedScreenBounds_dec = [import_state.computed], _getFocusedGroupId_dec = [import_state.computed], _getFocusedGroup_dec = [import_state.computed], _getEditingShapeId_dec = [import_state.computed], _getEditingShape_dec = [import_state.computed], _getRichTextEditor_dec = [import_state.computed], _getHoveredShapeId_dec = [import_state.computed], _getHoveredShape_dec = [import_state.computed], _getHintingShapeIds_dec = [import_state.computed], _getHintingShape_dec = [import_state.computed], _getErasingShapeIds_dec = [import_state.computed], _getErasingShapes_dec = [import_state.computed], __unsafe_getCameraId_dec = [import_state.computed], _getCamera_dec = [import_state.computed], _getViewportPageBoundsForFollowing_dec = [import_state.computed], _getCameraForFollowing_dec = [import_state.computed], _getZoomLevel_dec = [import_state.computed], _getViewportScreenBounds_dec = [import_state.computed], _getViewportScreenCenter_dec = [import_state.computed], _getViewportPageBounds_dec = [import_state.computed], __getCollaboratorsQuery_dec = [import_state.computed], _getCollaborators_dec = [import_state.computed], _getCollaboratorsOnCurrentPage_dec = [import_state.computed], _getRenderingShapes_dec = [import_state.computed], __getAllPagesQuery_dec = [import_state.computed], _getPages_dec = [import_state.computed], _getCurrentPageId_dec = [import_state.computed], _getCurrentPageShapeIdsSorted_dec = [import_state.computed], __getAllAssetsQuery_dec = [import_state.computed], __getShapeHandlesCache_dec = [import_state.computed], __getShapePageTransformCache_dec = [import_state.computed], __getShapePageBoundsCache_dec = [import_state.computed], __getShapeClipPathCache_dec = [import_state.computed], __getShapeMaskCache_dec = [import_state.computed], __getShapeMaskedPageBoundsCache_dec = [import_state.computed], __notVisibleShapes_dec = [import_state.computed], _getCulledShapes_dec = [import_state.computed], _getCurrentPageBounds_dec = [import_state.computed], _getCurrentPageShapes_dec = [import_state.computed], _getCurrentPageShapesSorted_dec = [import_state.computed], _getCurrentPageRenderingShapesSorted_dec = [import_state.computed], __getBindingsIndexCache_dec = [import_state.computed], __getSelectionSharedStyles_dec = [import_state.computed], _getSharedStyles_dec = [(0, import_state.computed)({ isEqual: (a, b) => a.equals(b) })], _getSharedOpacity_dec = [import_state.computed], _getIsFocused_dec = [import_state.computed], _getIsReadonly_dec = [import_state.computed], __setShiftKeyTimeout_dec = [import_utils.bind], __setAltKeyTimeout_dec = [import_utils.bind], __setCtrlKeyTimeout_dec = [import_utils.bind], __setMetaKeyTimeout_dec = [import_utils.bind], _a) {
|
|
127
128
|
constructor({
|
|
128
129
|
store,
|
|
129
130
|
user,
|
|
@@ -142,6 +143,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
142
143
|
}) {
|
|
143
144
|
super();
|
|
144
145
|
__runInitializers(_init, 5, this);
|
|
146
|
+
__publicField(this, "id", (0, import_utils.uniqueId)());
|
|
145
147
|
__publicField(this, "_isShapeHiddenPredicate");
|
|
146
148
|
__publicField(this, "options");
|
|
147
149
|
__publicField(this, "contextId", (0, import_utils.uniqueId)());
|
|
@@ -296,6 +298,8 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
296
298
|
__publicField(this, "_cameraStateTimeoutRemaining", 0);
|
|
297
299
|
/* @internal */
|
|
298
300
|
__publicField(this, "_currentPageShapeIds");
|
|
301
|
+
/* --------------------- Shapes --------------------- */
|
|
302
|
+
__publicField(this, "_shapeGeometryCaches", {});
|
|
299
303
|
// Parents and children
|
|
300
304
|
/**
|
|
301
305
|
* A cache of parents to children.
|
|
@@ -2143,9 +2147,9 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
2143
2147
|
this.stopFollowingUser();
|
|
2144
2148
|
}
|
|
2145
2149
|
const _point = import_Vec.Vec.Cast(point);
|
|
2146
|
-
if (!Number.isFinite(_point.x)) _point.x = 0;
|
|
2147
|
-
if (!Number.isFinite(_point.y)) _point.y = 0;
|
|
2148
|
-
if (_point.z === void 0 || !Number.isFinite(_point.z)) point.z = this.getZoomLevel();
|
|
2150
|
+
if (!import_core_js.Number.isFinite(_point.x)) _point.x = 0;
|
|
2151
|
+
if (!import_core_js.Number.isFinite(_point.y)) _point.y = 0;
|
|
2152
|
+
if (_point.z === void 0 || !import_core_js.Number.isFinite(_point.z)) point.z = this.getZoomLevel();
|
|
2149
2153
|
const camera = this.getConstrainedCamera(_point, opts);
|
|
2150
2154
|
if (opts?.animation) {
|
|
2151
2155
|
const { width, height } = this.getViewportScreenBounds();
|
|
@@ -3246,16 +3250,6 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
3246
3250
|
async uploadAsset(asset, file, abortSignal) {
|
|
3247
3251
|
return await this.store.props.assets.upload(asset, file, abortSignal);
|
|
3248
3252
|
}
|
|
3249
|
-
_getShapeGeometryCache() {
|
|
3250
|
-
return this.store.createComputedCache(
|
|
3251
|
-
"bounds",
|
|
3252
|
-
(shape) => {
|
|
3253
|
-
this.fonts.trackFontsForShape(shape);
|
|
3254
|
-
return this.getShapeUtil(shape).getGeometry(shape);
|
|
3255
|
-
},
|
|
3256
|
-
{ areRecordsEqual: (a, b) => a.props === b.props }
|
|
3257
|
-
);
|
|
3258
|
-
}
|
|
3259
3253
|
/**
|
|
3260
3254
|
* Get the geometry of a shape.
|
|
3261
3255
|
*
|
|
@@ -3263,14 +3257,29 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
3263
3257
|
* ```ts
|
|
3264
3258
|
* editor.getShapeGeometry(myShape)
|
|
3265
3259
|
* editor.getShapeGeometry(myShapeId)
|
|
3260
|
+
* editor.getShapeGeometry(myShapeId, { context: "arrow" })
|
|
3266
3261
|
* ```
|
|
3267
3262
|
*
|
|
3268
3263
|
* @param shape - The shape (or shape id) to get the geometry for.
|
|
3264
|
+
* @param opts - Additional options about the request for geometry. Passed to {@link ShapeUtil.getGeometry}.
|
|
3269
3265
|
*
|
|
3270
3266
|
* @public
|
|
3271
3267
|
*/
|
|
3272
|
-
getShapeGeometry(shape) {
|
|
3273
|
-
|
|
3268
|
+
getShapeGeometry(shape, opts) {
|
|
3269
|
+
const context = opts?.context ?? "none";
|
|
3270
|
+
if (!this._shapeGeometryCaches[context]) {
|
|
3271
|
+
this._shapeGeometryCaches[context] = this.store.createComputedCache(
|
|
3272
|
+
"bounds",
|
|
3273
|
+
(shape2) => {
|
|
3274
|
+
this.fonts.trackFontsForShape(shape2);
|
|
3275
|
+
return this.getShapeUtil(shape2).getGeometry(shape2, opts);
|
|
3276
|
+
},
|
|
3277
|
+
{ areRecordsEqual: (a, b) => a.props === b.props }
|
|
3278
|
+
);
|
|
3279
|
+
}
|
|
3280
|
+
return this._shapeGeometryCaches[context].get(
|
|
3281
|
+
typeof shape === "string" ? shape : shape.id
|
|
3282
|
+
);
|
|
3274
3283
|
}
|
|
3275
3284
|
_getShapeHandlesCache() {
|
|
3276
3285
|
return this.store.createComputedCache("handles", (shape) => {
|
|
@@ -4336,27 +4345,28 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
4336
4345
|
});
|
|
4337
4346
|
return this;
|
|
4338
4347
|
}
|
|
4348
|
+
// Gets a shape partial that includes life cycle changes: on translate start, on translate, on translate end
|
|
4339
4349
|
getChangesToTranslateShape(initialShape, newShapeCoords) {
|
|
4340
4350
|
let workingShape = initialShape;
|
|
4341
4351
|
const util = this.getShapeUtil(initialShape);
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4352
|
+
const afterTranslateStart = util.onTranslateStart?.(workingShape);
|
|
4353
|
+
if (afterTranslateStart) {
|
|
4354
|
+
workingShape = applyPartialToRecordWithProps(workingShape, afterTranslateStart);
|
|
4355
|
+
}
|
|
4346
4356
|
workingShape = applyPartialToRecordWithProps(workingShape, {
|
|
4347
4357
|
id: initialShape.id,
|
|
4348
4358
|
type: initialShape.type,
|
|
4349
4359
|
x: newShapeCoords.x,
|
|
4350
4360
|
y: newShapeCoords.y
|
|
4351
4361
|
});
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4362
|
+
const afterTranslate = util.onTranslate?.(initialShape, workingShape);
|
|
4363
|
+
if (afterTranslate) {
|
|
4364
|
+
workingShape = applyPartialToRecordWithProps(workingShape, afterTranslate);
|
|
4365
|
+
}
|
|
4366
|
+
const afterTranslateEnd = util.onTranslateEnd?.(initialShape, workingShape);
|
|
4367
|
+
if (afterTranslateEnd) {
|
|
4368
|
+
workingShape = applyPartialToRecordWithProps(workingShape, afterTranslateEnd);
|
|
4369
|
+
}
|
|
4360
4370
|
return workingShape;
|
|
4361
4371
|
}
|
|
4362
4372
|
/**
|
|
@@ -4663,6 +4673,30 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
4663
4673
|
if (changes) this.updateShapes(changes);
|
|
4664
4674
|
return this;
|
|
4665
4675
|
}
|
|
4676
|
+
/**
|
|
4677
|
+
* @internal
|
|
4678
|
+
*/
|
|
4679
|
+
collectShapesViaArrowBindings(info) {
|
|
4680
|
+
const { initialShapes, resultShapes, resultBounds, bindings, visited } = info;
|
|
4681
|
+
for (const binding of bindings) {
|
|
4682
|
+
for (const id of [binding.fromId, binding.toId]) {
|
|
4683
|
+
if (!visited.has(id)) {
|
|
4684
|
+
const aligningShape = initialShapes.find((s) => s.id === id);
|
|
4685
|
+
if (aligningShape && !visited.has(aligningShape.id)) {
|
|
4686
|
+
visited.add(aligningShape.id);
|
|
4687
|
+
const shapePageBounds = this.getShapePageBounds(aligningShape);
|
|
4688
|
+
if (!shapePageBounds) continue;
|
|
4689
|
+
resultShapes.push(aligningShape);
|
|
4690
|
+
resultBounds.push(shapePageBounds);
|
|
4691
|
+
this.collectShapesViaArrowBindings({
|
|
4692
|
+
...info,
|
|
4693
|
+
bindings: this.getBindingsInvolvingShape(aligningShape, "arrow")
|
|
4694
|
+
});
|
|
4695
|
+
}
|
|
4696
|
+
}
|
|
4697
|
+
}
|
|
4698
|
+
}
|
|
4699
|
+
}
|
|
4666
4700
|
/**
|
|
4667
4701
|
* Flip shape positions.
|
|
4668
4702
|
*
|
|
@@ -4678,35 +4712,52 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
4678
4712
|
* @public
|
|
4679
4713
|
*/
|
|
4680
4714
|
flipShapes(shapes, operation) {
|
|
4681
|
-
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4682
4715
|
if (this.getIsReadonly()) return this;
|
|
4683
|
-
|
|
4716
|
+
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4717
|
+
const shapesToFlipFirstPass = (0, import_utils.compact)(ids.map((id) => this.getShape(id)));
|
|
4718
|
+
for (const shape of shapesToFlipFirstPass) {
|
|
4719
|
+
if (this.isShapeOfType(shape, "group")) {
|
|
4720
|
+
const childrenOfGroups = (0, import_utils.compact)(
|
|
4721
|
+
this.getSortedChildIdsForParent(shape.id).map((id) => this.getShape(id))
|
|
4722
|
+
);
|
|
4723
|
+
shapesToFlipFirstPass.push(...childrenOfGroups);
|
|
4724
|
+
}
|
|
4725
|
+
}
|
|
4726
|
+
const shapesToFlip = [];
|
|
4727
|
+
const allBounds = [];
|
|
4728
|
+
for (const shape of shapesToFlipFirstPass) {
|
|
4729
|
+
const util = this.getShapeUtil(shape);
|
|
4730
|
+
if (!util.canBeLaidOut(shape, {
|
|
4731
|
+
type: "flip",
|
|
4732
|
+
shapes: shapesToFlipFirstPass
|
|
4733
|
+
})) {
|
|
4734
|
+
continue;
|
|
4735
|
+
}
|
|
4736
|
+
const pageBounds = this.getShapePageBounds(shape);
|
|
4737
|
+
const localBounds = this.getShapeGeometry(shape).bounds;
|
|
4738
|
+
const pageTransform = this.getShapePageTransform(shape.id);
|
|
4739
|
+
if (!(pageBounds && localBounds && pageTransform)) continue;
|
|
4740
|
+
shapesToFlip.push({
|
|
4741
|
+
shape,
|
|
4742
|
+
localBounds,
|
|
4743
|
+
pageTransform,
|
|
4744
|
+
isAspectRatioLocked: util.isAspectRatioLocked(shape)
|
|
4745
|
+
});
|
|
4746
|
+
allBounds.push(pageBounds);
|
|
4747
|
+
}
|
|
4684
4748
|
if (!shapesToFlip.length) return this;
|
|
4685
|
-
|
|
4686
|
-
shapesToFlip.map((shape) => {
|
|
4687
|
-
if (this.isShapeOfType(shape, "group")) {
|
|
4688
|
-
return this.getSortedChildIdsForParent(shape.id).map((id) => this.getShape(id));
|
|
4689
|
-
}
|
|
4690
|
-
return shape;
|
|
4691
|
-
}).flat()
|
|
4692
|
-
);
|
|
4693
|
-
const scaleOriginPage = import_Box.Box.Common(
|
|
4694
|
-
(0, import_utils.compact)(shapesToFlip.map((id) => this.getShapePageBounds(id)))
|
|
4695
|
-
).center;
|
|
4749
|
+
const scaleOriginPage = import_Box.Box.Common(allBounds).center;
|
|
4696
4750
|
this.run(() => {
|
|
4697
|
-
for (const shape of shapesToFlip) {
|
|
4698
|
-
const bounds = this.getShapeGeometry(shape).bounds;
|
|
4699
|
-
const initialPageTransform = this.getShapePageTransform(shape.id);
|
|
4700
|
-
if (!initialPageTransform) continue;
|
|
4751
|
+
for (const { shape, localBounds, pageTransform, isAspectRatioLocked } of shapesToFlip) {
|
|
4701
4752
|
this.resizeShape(
|
|
4702
4753
|
shape.id,
|
|
4703
4754
|
{ x: operation === "horizontal" ? -1 : 1, y: operation === "vertical" ? -1 : 1 },
|
|
4704
4755
|
{
|
|
4705
|
-
initialBounds:
|
|
4706
|
-
initialPageTransform,
|
|
4756
|
+
initialBounds: localBounds,
|
|
4757
|
+
initialPageTransform: pageTransform,
|
|
4707
4758
|
initialShape: shape,
|
|
4759
|
+
isAspectRatioLocked,
|
|
4708
4760
|
mode: "scale_shape",
|
|
4709
|
-
isAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),
|
|
4710
4761
|
scaleOrigin: scaleOriginPage,
|
|
4711
4762
|
scaleAxisRotation: 0
|
|
4712
4763
|
}
|
|
@@ -4733,15 +4784,40 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
4733
4784
|
stackShapes(shapes, operation, gap) {
|
|
4734
4785
|
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4735
4786
|
if (this.getIsReadonly()) return this;
|
|
4736
|
-
const
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
const
|
|
4787
|
+
const shapesToStackFirstPass = (0, import_utils.compact)(ids.map((id) => this.getShape(id)));
|
|
4788
|
+
const shapeClustersToStack = [];
|
|
4789
|
+
const allBounds = [];
|
|
4790
|
+
const visited = /* @__PURE__ */ new Set();
|
|
4791
|
+
for (const shape of shapesToStackFirstPass) {
|
|
4792
|
+
if (visited.has(shape.id)) continue;
|
|
4793
|
+
visited.add(shape.id);
|
|
4794
|
+
const shapePageBounds = this.getShapePageBounds(shape);
|
|
4795
|
+
if (!shapePageBounds) continue;
|
|
4796
|
+
if (!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
4797
|
+
type: "stack",
|
|
4798
|
+
shapes: shapesToStackFirstPass
|
|
4799
|
+
})) {
|
|
4800
|
+
continue;
|
|
4801
|
+
}
|
|
4802
|
+
const shapesMovingTogether = [shape];
|
|
4803
|
+
const boundsOfShapesMovingTogether = [shapePageBounds];
|
|
4804
|
+
this.collectShapesViaArrowBindings({
|
|
4805
|
+
bindings: this.getBindingsToShape(shape.id, "arrow"),
|
|
4806
|
+
initialShapes: shapesToStackFirstPass,
|
|
4807
|
+
resultShapes: shapesMovingTogether,
|
|
4808
|
+
resultBounds: boundsOfShapesMovingTogether,
|
|
4809
|
+
visited
|
|
4810
|
+
});
|
|
4811
|
+
const commonPageBounds = import_Box.Box.Common(boundsOfShapesMovingTogether);
|
|
4812
|
+
if (!commonPageBounds) continue;
|
|
4813
|
+
shapeClustersToStack.push({
|
|
4814
|
+
shapes: shapesMovingTogether,
|
|
4815
|
+
pageBounds: commonPageBounds
|
|
4816
|
+
});
|
|
4817
|
+
allBounds.push(commonPageBounds);
|
|
4818
|
+
}
|
|
4819
|
+
const len = shapeClustersToStack.length;
|
|
4741
4820
|
if (gap === 0 && len < 3 || len < 2) return this;
|
|
4742
|
-
const pageBounds = Object.fromEntries(
|
|
4743
|
-
shapesToStack.map((shape) => [shape.id, this.getShapePageBounds(shape)])
|
|
4744
|
-
);
|
|
4745
4821
|
let val;
|
|
4746
4822
|
let min;
|
|
4747
4823
|
let max;
|
|
@@ -4757,57 +4833,55 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
4757
4833
|
max = "maxY";
|
|
4758
4834
|
dim = "height";
|
|
4759
4835
|
}
|
|
4760
|
-
let shapeGap;
|
|
4836
|
+
let shapeGap = 0;
|
|
4761
4837
|
if (gap === 0) {
|
|
4762
|
-
const gaps =
|
|
4763
|
-
|
|
4838
|
+
const gaps = {};
|
|
4839
|
+
shapeClustersToStack.sort((a, b) => a.pageBounds[min] - b.pageBounds[min]);
|
|
4764
4840
|
for (let i = 0; i < len - 1; i++) {
|
|
4765
|
-
const
|
|
4766
|
-
const
|
|
4767
|
-
const
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
const current = gaps.find((g) => g.gap === gap2);
|
|
4771
|
-
if (current) {
|
|
4772
|
-
current.count++;
|
|
4773
|
-
} else {
|
|
4774
|
-
gaps.push({ gap: gap2, count: 1 });
|
|
4841
|
+
const currCluster = shapeClustersToStack[i];
|
|
4842
|
+
const nextCluster = shapeClustersToStack[i + 1];
|
|
4843
|
+
const gap2 = nextCluster.pageBounds[min] - currCluster.pageBounds[max];
|
|
4844
|
+
if (!gaps[gap2]) {
|
|
4845
|
+
gaps[gap2] = 0;
|
|
4775
4846
|
}
|
|
4847
|
+
gaps[gap2]++;
|
|
4776
4848
|
}
|
|
4777
|
-
let maxCount =
|
|
4778
|
-
|
|
4779
|
-
if (
|
|
4780
|
-
maxCount =
|
|
4781
|
-
shapeGap =
|
|
4849
|
+
let maxCount = 1;
|
|
4850
|
+
for (const [gap2, count] of Object.entries(gaps)) {
|
|
4851
|
+
if (count > maxCount) {
|
|
4852
|
+
maxCount = count;
|
|
4853
|
+
shapeGap = parseFloat(gap2);
|
|
4782
4854
|
}
|
|
4783
|
-
}
|
|
4855
|
+
}
|
|
4784
4856
|
if (maxCount === 1) {
|
|
4785
|
-
|
|
4857
|
+
let totalCount = 0;
|
|
4858
|
+
for (const [gap2, count] of Object.entries(gaps)) {
|
|
4859
|
+
shapeGap += parseFloat(gap2) * count;
|
|
4860
|
+
totalCount += count;
|
|
4861
|
+
}
|
|
4862
|
+
shapeGap /= totalCount;
|
|
4786
4863
|
}
|
|
4787
4864
|
} else {
|
|
4788
4865
|
shapeGap = gap;
|
|
4789
4866
|
}
|
|
4790
4867
|
const changes = [];
|
|
4791
|
-
let v =
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
const delta =
|
|
4795
|
-
delta[val] = v + shapeGap - pageBounds[
|
|
4796
|
-
const
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
[val]: shape[val] + localDelta[val]
|
|
4803
|
-
} : {
|
|
4804
|
-
id: shape.id,
|
|
4805
|
-
type: shape.type,
|
|
4806
|
-
[val]: shape[val] + localDelta[val]
|
|
4868
|
+
let v = shapeClustersToStack[0].pageBounds[max];
|
|
4869
|
+
for (let i = 1; i < shapeClustersToStack.length; i++) {
|
|
4870
|
+
const { shapes: shapes2, pageBounds } = shapeClustersToStack[i];
|
|
4871
|
+
const delta = new import_Vec.Vec();
|
|
4872
|
+
delta[val] = v + shapeGap - pageBounds[val];
|
|
4873
|
+
for (const shape of shapes2) {
|
|
4874
|
+
const shapeDelta = delta.clone();
|
|
4875
|
+
const parent = this.getShapeParent(shape);
|
|
4876
|
+
if (parent) {
|
|
4877
|
+
const parentTransform = this.getShapePageTransform(parent);
|
|
4878
|
+
if (parentTransform) shapeDelta.rot(-parentTransform.rotation());
|
|
4807
4879
|
}
|
|
4808
|
-
|
|
4809
|
-
|
|
4810
|
-
|
|
4880
|
+
shapeDelta.add(shape);
|
|
4881
|
+
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
4882
|
+
}
|
|
4883
|
+
v += pageBounds[dim] + shapeGap;
|
|
4884
|
+
}
|
|
4811
4885
|
this.updateShapes(changes);
|
|
4812
4886
|
return this;
|
|
4813
4887
|
}
|
|
@@ -4825,91 +4899,101 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
4825
4899
|
* @param gap - The padding to apply to the packed shapes. Defaults to 16.
|
|
4826
4900
|
*/
|
|
4827
4901
|
packShapes(shapes, gap) {
|
|
4828
|
-
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4829
4902
|
if (this.getIsReadonly()) return this;
|
|
4830
|
-
|
|
4831
|
-
const
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
const
|
|
4836
|
-
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
|
|
4844
|
-
|
|
4845
|
-
|
|
4903
|
+
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4904
|
+
const shapesToPackFirstPass = (0, import_utils.compact)(ids.map((id) => this.getShape(id)));
|
|
4905
|
+
const shapeClustersToPack = [];
|
|
4906
|
+
const allBounds = [];
|
|
4907
|
+
const visited = /* @__PURE__ */ new Set();
|
|
4908
|
+
for (const shape of shapesToPackFirstPass) {
|
|
4909
|
+
if (visited.has(shape.id)) continue;
|
|
4910
|
+
visited.add(shape.id);
|
|
4911
|
+
const shapePageBounds = this.getShapePageBounds(shape);
|
|
4912
|
+
if (!shapePageBounds) continue;
|
|
4913
|
+
if (!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
4914
|
+
type: "pack",
|
|
4915
|
+
shapes: shapesToPackFirstPass
|
|
4916
|
+
})) {
|
|
4917
|
+
continue;
|
|
4918
|
+
}
|
|
4919
|
+
const shapesMovingTogether = [shape];
|
|
4920
|
+
const boundsOfShapesMovingTogether = [shapePageBounds];
|
|
4921
|
+
this.collectShapesViaArrowBindings({
|
|
4922
|
+
bindings: this.getBindingsToShape(shape.id, "arrow"),
|
|
4923
|
+
initialShapes: shapesToPackFirstPass,
|
|
4924
|
+
resultShapes: shapesMovingTogether,
|
|
4925
|
+
resultBounds: boundsOfShapesMovingTogether,
|
|
4926
|
+
visited
|
|
4927
|
+
});
|
|
4928
|
+
const commonPageBounds = import_Box.Box.Common(boundsOfShapesMovingTogether);
|
|
4929
|
+
if (!commonPageBounds) continue;
|
|
4930
|
+
shapeClustersToPack.push({
|
|
4931
|
+
shapes: shapesMovingTogether,
|
|
4932
|
+
pageBounds: commonPageBounds,
|
|
4933
|
+
nextPageBounds: commonPageBounds.clone()
|
|
4934
|
+
});
|
|
4935
|
+
allBounds.push(commonPageBounds);
|
|
4936
|
+
}
|
|
4937
|
+
if (shapeClustersToPack.length < 2) return this;
|
|
4938
|
+
let area = 0;
|
|
4939
|
+
for (const { pageBounds } of shapeClustersToPack) {
|
|
4940
|
+
area += pageBounds.width * pageBounds.height;
|
|
4941
|
+
}
|
|
4942
|
+
const commonBounds = import_Box.Box.Common(allBounds);
|
|
4846
4943
|
const maxWidth = commonBounds.width;
|
|
4847
|
-
|
|
4944
|
+
shapeClustersToPack.sort((a, b) => a.pageBounds.width - b.pageBounds.width).sort((a, b) => a.pageBounds.height - b.pageBounds.height);
|
|
4848
4945
|
const startWidth = Math.max(Math.ceil(Math.sqrt(area / 0.95)), maxWidth);
|
|
4849
4946
|
const spaces = [new import_Box.Box(commonBounds.x, commonBounds.y, startWidth, Infinity)];
|
|
4850
4947
|
let width = 0;
|
|
4851
4948
|
let height = 0;
|
|
4852
4949
|
let space;
|
|
4853
4950
|
let last2;
|
|
4854
|
-
for (
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
width = Math.max(width, bounds.maxX);
|
|
4864
|
-
if (bounds.width === space.width && bounds.height === space.height) {
|
|
4951
|
+
for (const { nextPageBounds } of shapeClustersToPack) {
|
|
4952
|
+
for (let i = spaces.length - 1; i >= 0; i--) {
|
|
4953
|
+
space = spaces[i];
|
|
4954
|
+
if (nextPageBounds.width > space.width || nextPageBounds.height > space.height) continue;
|
|
4955
|
+
nextPageBounds.x = space.x;
|
|
4956
|
+
nextPageBounds.y = space.y;
|
|
4957
|
+
height = Math.max(height, nextPageBounds.maxY);
|
|
4958
|
+
width = Math.max(width, nextPageBounds.maxX);
|
|
4959
|
+
if (nextPageBounds.width === space.width && nextPageBounds.height === space.height) {
|
|
4865
4960
|
last2 = spaces.pop();
|
|
4866
|
-
if (
|
|
4867
|
-
} else if (
|
|
4868
|
-
space.x +=
|
|
4869
|
-
space.width -=
|
|
4870
|
-
} else if (
|
|
4871
|
-
space.y +=
|
|
4872
|
-
space.height -=
|
|
4961
|
+
if (i < spaces.length) spaces[i] = last2;
|
|
4962
|
+
} else if (nextPageBounds.height === space.height) {
|
|
4963
|
+
space.x += nextPageBounds.width + gap;
|
|
4964
|
+
space.width -= nextPageBounds.width + gap;
|
|
4965
|
+
} else if (nextPageBounds.width === space.width) {
|
|
4966
|
+
space.y += nextPageBounds.height + gap;
|
|
4967
|
+
space.height -= nextPageBounds.height + gap;
|
|
4873
4968
|
} else {
|
|
4874
4969
|
spaces.push(
|
|
4875
4970
|
new import_Box.Box(
|
|
4876
|
-
space.x + (
|
|
4971
|
+
space.x + (nextPageBounds.width + gap),
|
|
4877
4972
|
space.y,
|
|
4878
|
-
space.width - (
|
|
4879
|
-
|
|
4973
|
+
space.width - (nextPageBounds.width + gap),
|
|
4974
|
+
nextPageBounds.height
|
|
4880
4975
|
)
|
|
4881
4976
|
);
|
|
4882
|
-
space.y +=
|
|
4883
|
-
space.height -=
|
|
4977
|
+
space.y += nextPageBounds.height + gap;
|
|
4978
|
+
space.height -= nextPageBounds.height + gap;
|
|
4884
4979
|
}
|
|
4885
4980
|
break;
|
|
4886
4981
|
}
|
|
4887
4982
|
}
|
|
4888
|
-
const commonAfter = import_Box.Box.Common(
|
|
4983
|
+
const commonAfter = import_Box.Box.Common(shapeClustersToPack.map((s) => s.nextPageBounds));
|
|
4889
4984
|
const centerDelta = import_Vec.Vec.Sub(commonBounds.center, commonAfter.center);
|
|
4890
|
-
let nextBounds;
|
|
4891
4985
|
const changes = [];
|
|
4892
|
-
for (
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
y: shape.y + delta.y
|
|
4904
|
-
};
|
|
4905
|
-
const translateStartChange = this.getShapeUtil(shape).onTranslateStart?.({
|
|
4906
|
-
...shape,
|
|
4907
|
-
...change
|
|
4908
|
-
});
|
|
4909
|
-
if (translateStartChange) {
|
|
4910
|
-
changes.push({ ...change, ...translateStartChange });
|
|
4911
|
-
} else {
|
|
4912
|
-
changes.push(change);
|
|
4986
|
+
for (const { shapes: shapes2, pageBounds, nextPageBounds } of shapeClustersToPack) {
|
|
4987
|
+
const delta = import_Vec.Vec.Sub(nextPageBounds.point, pageBounds.point).add(centerDelta);
|
|
4988
|
+
for (const shape of shapes2) {
|
|
4989
|
+
const shapeDelta = delta.clone();
|
|
4990
|
+
const parent = this.getShapeParent(shape);
|
|
4991
|
+
if (parent) {
|
|
4992
|
+
const parentTransform = this.getShapeParentTransform(shape);
|
|
4993
|
+
if (parentTransform) shapeDelta.rot(-parentTransform.rotation());
|
|
4994
|
+
}
|
|
4995
|
+
shapeDelta.add(shape);
|
|
4996
|
+
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
4913
4997
|
}
|
|
4914
4998
|
}
|
|
4915
4999
|
if (changes.length) {
|
|
@@ -4932,19 +5016,45 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
4932
5016
|
* @public
|
|
4933
5017
|
*/
|
|
4934
5018
|
alignShapes(shapes, operation) {
|
|
4935
|
-
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4936
5019
|
if (this.getIsReadonly()) return this;
|
|
4937
|
-
|
|
4938
|
-
const
|
|
4939
|
-
const
|
|
4940
|
-
|
|
4941
|
-
);
|
|
4942
|
-
const
|
|
5020
|
+
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
5021
|
+
const shapesToAlignFirstPass = (0, import_utils.compact)(ids.map((id) => this.getShape(id)));
|
|
5022
|
+
const shapeClustersToAlign = [];
|
|
5023
|
+
const allBounds = [];
|
|
5024
|
+
const visited = /* @__PURE__ */ new Set();
|
|
5025
|
+
for (const shape of shapesToAlignFirstPass) {
|
|
5026
|
+
if (visited.has(shape.id)) continue;
|
|
5027
|
+
visited.add(shape.id);
|
|
5028
|
+
const shapePageBounds = this.getShapePageBounds(shape);
|
|
5029
|
+
if (!shapePageBounds) continue;
|
|
5030
|
+
if (!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
5031
|
+
type: "align",
|
|
5032
|
+
shapes: shapesToAlignFirstPass
|
|
5033
|
+
})) {
|
|
5034
|
+
continue;
|
|
5035
|
+
}
|
|
5036
|
+
const shapesMovingTogether = [shape];
|
|
5037
|
+
const boundsOfShapesMovingTogether = [shapePageBounds];
|
|
5038
|
+
this.collectShapesViaArrowBindings({
|
|
5039
|
+
bindings: this.getBindingsToShape(shape.id, "arrow"),
|
|
5040
|
+
initialShapes: shapesToAlignFirstPass,
|
|
5041
|
+
resultShapes: shapesMovingTogether,
|
|
5042
|
+
resultBounds: boundsOfShapesMovingTogether,
|
|
5043
|
+
visited
|
|
5044
|
+
});
|
|
5045
|
+
const commonPageBounds = import_Box.Box.Common(boundsOfShapesMovingTogether);
|
|
5046
|
+
if (!commonPageBounds) continue;
|
|
5047
|
+
shapeClustersToAlign.push({
|
|
5048
|
+
shapes: shapesMovingTogether,
|
|
5049
|
+
pageBounds: commonPageBounds
|
|
5050
|
+
});
|
|
5051
|
+
allBounds.push(commonPageBounds);
|
|
5052
|
+
}
|
|
5053
|
+
if (shapeClustersToAlign.length < 2) return this;
|
|
5054
|
+
const commonBounds = import_Box.Box.Common(allBounds);
|
|
4943
5055
|
const changes = [];
|
|
4944
|
-
|
|
4945
|
-
const
|
|
4946
|
-
if (!pageBounds) return;
|
|
4947
|
-
const delta = { x: 0, y: 0 };
|
|
5056
|
+
shapeClustersToAlign.forEach(({ shapes: shapes2, pageBounds }) => {
|
|
5057
|
+
const delta = new import_Vec.Vec();
|
|
4948
5058
|
switch (operation) {
|
|
4949
5059
|
case "top": {
|
|
4950
5060
|
delta.y = commonBounds.minY - pageBounds.minY;
|
|
@@ -4971,9 +5081,16 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
4971
5081
|
break;
|
|
4972
5082
|
}
|
|
4973
5083
|
}
|
|
4974
|
-
const
|
|
4975
|
-
|
|
4976
|
-
|
|
5084
|
+
for (const shape of shapes2) {
|
|
5085
|
+
const shapeDelta = delta.clone();
|
|
5086
|
+
const parent = this.getShapeParent(shape);
|
|
5087
|
+
if (parent) {
|
|
5088
|
+
const parentTransform = this.getShapePageTransform(parent);
|
|
5089
|
+
if (parentTransform) shapeDelta.rot(-parentTransform.rotation());
|
|
5090
|
+
}
|
|
5091
|
+
shapeDelta.add(shape);
|
|
5092
|
+
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
5093
|
+
}
|
|
4977
5094
|
});
|
|
4978
5095
|
this.updateShapes(changes);
|
|
4979
5096
|
return this;
|
|
@@ -4993,47 +5110,95 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
4993
5110
|
* @public
|
|
4994
5111
|
*/
|
|
4995
5112
|
distributeShapes(shapes, operation) {
|
|
4996
|
-
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4997
5113
|
if (this.getIsReadonly()) return this;
|
|
4998
|
-
|
|
4999
|
-
const
|
|
5000
|
-
const
|
|
5001
|
-
const
|
|
5002
|
-
|
|
5003
|
-
)
|
|
5114
|
+
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
5115
|
+
const shapesToDistributeFirstPass = (0, import_utils.compact)(ids.map((id) => this.getShape(id)));
|
|
5116
|
+
const shapeClustersToDistribute = [];
|
|
5117
|
+
const allBounds = [];
|
|
5118
|
+
const visited = /* @__PURE__ */ new Set();
|
|
5119
|
+
for (const shape of shapesToDistributeFirstPass) {
|
|
5120
|
+
if (visited.has(shape.id)) continue;
|
|
5121
|
+
visited.add(shape.id);
|
|
5122
|
+
const shapePageBounds = this.getShapePageBounds(shape);
|
|
5123
|
+
if (!shapePageBounds) continue;
|
|
5124
|
+
if (!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
5125
|
+
type: "distribute",
|
|
5126
|
+
shapes: shapesToDistributeFirstPass
|
|
5127
|
+
})) {
|
|
5128
|
+
continue;
|
|
5129
|
+
}
|
|
5130
|
+
const shapesMovingTogether = [shape];
|
|
5131
|
+
const boundsOfShapesMovingTogether = [shapePageBounds];
|
|
5132
|
+
this.collectShapesViaArrowBindings({
|
|
5133
|
+
bindings: this.getBindingsToShape(shape.id, "arrow"),
|
|
5134
|
+
initialShapes: shapesToDistributeFirstPass,
|
|
5135
|
+
resultShapes: shapesMovingTogether,
|
|
5136
|
+
resultBounds: boundsOfShapesMovingTogether,
|
|
5137
|
+
visited
|
|
5138
|
+
});
|
|
5139
|
+
const commonPageBounds = import_Box.Box.Common(boundsOfShapesMovingTogether);
|
|
5140
|
+
if (!commonPageBounds) continue;
|
|
5141
|
+
shapeClustersToDistribute.push({
|
|
5142
|
+
shapes: shapesMovingTogether,
|
|
5143
|
+
pageBounds: commonPageBounds
|
|
5144
|
+
});
|
|
5145
|
+
allBounds.push(commonPageBounds);
|
|
5146
|
+
}
|
|
5147
|
+
if (shapeClustersToDistribute.length < 3) return this;
|
|
5004
5148
|
let val;
|
|
5005
5149
|
let min;
|
|
5006
5150
|
let max;
|
|
5007
|
-
let mid;
|
|
5008
5151
|
let dim;
|
|
5009
5152
|
if (operation === "horizontal") {
|
|
5010
5153
|
val = "x";
|
|
5011
5154
|
min = "minX";
|
|
5012
5155
|
max = "maxX";
|
|
5013
|
-
mid = "midX";
|
|
5014
5156
|
dim = "width";
|
|
5015
5157
|
} else {
|
|
5016
5158
|
val = "y";
|
|
5017
5159
|
min = "minY";
|
|
5018
5160
|
max = "maxY";
|
|
5019
|
-
mid = "midY";
|
|
5020
5161
|
dim = "height";
|
|
5021
5162
|
}
|
|
5022
5163
|
const changes = [];
|
|
5023
|
-
const first =
|
|
5024
|
-
|
|
5025
|
-
)
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5164
|
+
const first = shapeClustersToDistribute.sort((a, b) => a.pageBounds[min] - b.pageBounds[min])[0];
|
|
5165
|
+
const last2 = shapeClustersToDistribute.sort((a, b) => b.pageBounds[max] - a.pageBounds[max])[0];
|
|
5166
|
+
if (first === last2) {
|
|
5167
|
+
const excludedShapeIds = new Set(first.shapes.map((s) => s.id));
|
|
5168
|
+
return this.distributeShapes(
|
|
5169
|
+
ids.filter((id) => !excludedShapeIds.has(id)),
|
|
5170
|
+
operation
|
|
5171
|
+
);
|
|
5172
|
+
}
|
|
5173
|
+
const shapeClustersToMove = shapeClustersToDistribute.filter((shape) => shape !== first && shape !== last2).sort((a, b) => {
|
|
5174
|
+
if (a.pageBounds[min] === b.pageBounds[min]) {
|
|
5175
|
+
return a.shapes[0].id < b.shapes[0].id ? -1 : 1;
|
|
5176
|
+
}
|
|
5177
|
+
return a.pageBounds[min] - b.pageBounds[min];
|
|
5036
5178
|
});
|
|
5179
|
+
const maxFirst = first.pageBounds[max];
|
|
5180
|
+
const range = last2.pageBounds[min] - maxFirst;
|
|
5181
|
+
const summedShapeDimensions = shapeClustersToMove.reduce((acc, s) => acc + s.pageBounds[dim], 0);
|
|
5182
|
+
const gap = (range - summedShapeDimensions) / (shapeClustersToMove.length + 1);
|
|
5183
|
+
for (let v = maxFirst + gap, i = 0; i < shapeClustersToMove.length; i++) {
|
|
5184
|
+
const { shapes: shapes2, pageBounds } = shapeClustersToMove[i];
|
|
5185
|
+
const delta = new import_Vec.Vec();
|
|
5186
|
+
delta[val] = v - pageBounds[val];
|
|
5187
|
+
if (v + pageBounds[dim] > last2.pageBounds[max] - 1) {
|
|
5188
|
+
delta[val] = last2.pageBounds[max] - pageBounds[max] - 1;
|
|
5189
|
+
}
|
|
5190
|
+
for (const shape of shapes2) {
|
|
5191
|
+
const shapeDelta = delta.clone();
|
|
5192
|
+
const parent = this.getShapeParent(shape);
|
|
5193
|
+
if (parent) {
|
|
5194
|
+
const parentTransform = this.getShapePageTransform(parent);
|
|
5195
|
+
if (parentTransform) shapeDelta.rot(-parentTransform.rotation());
|
|
5196
|
+
}
|
|
5197
|
+
shapeDelta.add(shape);
|
|
5198
|
+
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
5199
|
+
}
|
|
5200
|
+
v += pageBounds[dim] + gap;
|
|
5201
|
+
}
|
|
5037
5202
|
this.updateShapes(changes);
|
|
5038
5203
|
return this;
|
|
5039
5204
|
}
|
|
@@ -5054,59 +5219,78 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
5054
5219
|
stretchShapes(shapes, operation) {
|
|
5055
5220
|
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
5056
5221
|
if (this.getIsReadonly()) return this;
|
|
5057
|
-
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
const
|
|
5061
|
-
const
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
const scale = new import_Vec.Vec(1, commonBounds.height / pageBounds.height);
|
|
5076
|
-
this.resizeShape(shape.id, scale, {
|
|
5077
|
-
initialBounds: bounds,
|
|
5078
|
-
scaleOrigin: new import_Vec.Vec(pageBounds.center.x, commonBounds.minY),
|
|
5079
|
-
isAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),
|
|
5080
|
-
scaleAxisRotation: 0
|
|
5081
|
-
});
|
|
5082
|
-
}
|
|
5083
|
-
});
|
|
5084
|
-
break;
|
|
5085
|
-
}
|
|
5086
|
-
case "horizontal": {
|
|
5087
|
-
this.run(() => {
|
|
5088
|
-
for (const shape of shapesToStretch) {
|
|
5089
|
-
const bounds = shapeBounds[shape.id];
|
|
5090
|
-
const pageBounds = shapePageBounds[shape.id];
|
|
5091
|
-
const pageRotation = this.getShapePageTransform(shape).rotation();
|
|
5092
|
-
if (pageRotation % import_utils2.PI2) continue;
|
|
5093
|
-
const localOffset = new import_Vec.Vec(commonBounds.minX - pageBounds.minX, 0);
|
|
5094
|
-
const parentTransform = this.getShapeParentTransform(shape);
|
|
5095
|
-
if (parentTransform) localOffset.rot(-parentTransform.rotation());
|
|
5096
|
-
const { x, y } = import_Vec.Vec.Add(localOffset, shape);
|
|
5097
|
-
this.updateShapes([{ id: shape.id, type: shape.type, x, y }]);
|
|
5098
|
-
const scale = new import_Vec.Vec(commonBounds.width / pageBounds.width, 1);
|
|
5099
|
-
this.resizeShape(shape.id, scale, {
|
|
5100
|
-
initialBounds: bounds,
|
|
5101
|
-
scaleOrigin: new import_Vec.Vec(commonBounds.minX, pageBounds.center.y),
|
|
5102
|
-
isAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),
|
|
5103
|
-
scaleAxisRotation: 0
|
|
5104
|
-
});
|
|
5105
|
-
}
|
|
5106
|
-
});
|
|
5107
|
-
break;
|
|
5222
|
+
const shapesToStretchFirstPass = (0, import_utils.compact)(ids.map((id) => this.getShape(id))).filter(
|
|
5223
|
+
(s) => this.getShapePageTransform(s)?.rotation() % (import_utils2.PI / 2) === 0
|
|
5224
|
+
);
|
|
5225
|
+
const shapeClustersToStretch = [];
|
|
5226
|
+
const allBounds = [];
|
|
5227
|
+
const visited = /* @__PURE__ */ new Set();
|
|
5228
|
+
for (const shape of shapesToStretchFirstPass) {
|
|
5229
|
+
if (visited.has(shape.id)) continue;
|
|
5230
|
+
visited.add(shape.id);
|
|
5231
|
+
const shapePageBounds = this.getShapePageBounds(shape);
|
|
5232
|
+
if (!shapePageBounds) continue;
|
|
5233
|
+
const shapesMovingTogether = [shape];
|
|
5234
|
+
const boundsOfShapesMovingTogether = [shapePageBounds];
|
|
5235
|
+
if (!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
5236
|
+
type: "stretch",
|
|
5237
|
+
shapes: shapesToStretchFirstPass
|
|
5238
|
+
})) {
|
|
5239
|
+
continue;
|
|
5108
5240
|
}
|
|
5241
|
+
this.collectShapesViaArrowBindings({
|
|
5242
|
+
bindings: this.getBindingsToShape(shape.id, "arrow"),
|
|
5243
|
+
initialShapes: shapesToStretchFirstPass,
|
|
5244
|
+
resultShapes: shapesMovingTogether,
|
|
5245
|
+
resultBounds: boundsOfShapesMovingTogether,
|
|
5246
|
+
visited
|
|
5247
|
+
});
|
|
5248
|
+
const commonPageBounds = import_Box.Box.Common(boundsOfShapesMovingTogether);
|
|
5249
|
+
if (!commonPageBounds) continue;
|
|
5250
|
+
shapeClustersToStretch.push({
|
|
5251
|
+
shapes: shapesMovingTogether,
|
|
5252
|
+
pageBounds: commonPageBounds
|
|
5253
|
+
});
|
|
5254
|
+
allBounds.push(commonPageBounds);
|
|
5255
|
+
}
|
|
5256
|
+
if (shapeClustersToStretch.length < 2) return this;
|
|
5257
|
+
const commonBounds = import_Box.Box.Common(allBounds);
|
|
5258
|
+
let val;
|
|
5259
|
+
let min;
|
|
5260
|
+
let dim;
|
|
5261
|
+
if (operation === "horizontal") {
|
|
5262
|
+
val = "x";
|
|
5263
|
+
min = "minX";
|
|
5264
|
+
dim = "width";
|
|
5265
|
+
} else {
|
|
5266
|
+
val = "y";
|
|
5267
|
+
min = "minY";
|
|
5268
|
+
dim = "height";
|
|
5109
5269
|
}
|
|
5270
|
+
this.run(() => {
|
|
5271
|
+
shapeClustersToStretch.forEach(({ shapes: shapes2, pageBounds }) => {
|
|
5272
|
+
const localOffset = new import_Vec.Vec();
|
|
5273
|
+
localOffset[val] = commonBounds[min] - pageBounds[min];
|
|
5274
|
+
const scaleOrigin = pageBounds.center.clone();
|
|
5275
|
+
scaleOrigin[val] = commonBounds[min];
|
|
5276
|
+
const scale = new import_Vec.Vec(1, 1);
|
|
5277
|
+
scale[val] = commonBounds[dim] / pageBounds[dim];
|
|
5278
|
+
for (const shape of shapes2) {
|
|
5279
|
+
const shapeLocalOffset = localOffset.clone();
|
|
5280
|
+
const parentTransform = this.getShapeParentTransform(shape);
|
|
5281
|
+
if (parentTransform) localOffset.rot(-parentTransform.rotation());
|
|
5282
|
+
shapeLocalOffset.add(shape);
|
|
5283
|
+
const changes = this.getChangesToTranslateShape(shape, shapeLocalOffset);
|
|
5284
|
+
this.updateShape(changes);
|
|
5285
|
+
this.resizeShape(shape.id, scale, {
|
|
5286
|
+
initialBounds: this.getShapeGeometry(shape).bounds,
|
|
5287
|
+
scaleOrigin,
|
|
5288
|
+
isAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),
|
|
5289
|
+
scaleAxisRotation: 0
|
|
5290
|
+
});
|
|
5291
|
+
}
|
|
5292
|
+
});
|
|
5293
|
+
});
|
|
5110
5294
|
return this;
|
|
5111
5295
|
}
|
|
5112
5296
|
/**
|
|
@@ -5121,8 +5305,8 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
5121
5305
|
resizeShape(shape, scale, opts = {}) {
|
|
5122
5306
|
const id = typeof shape === "string" ? shape : shape.id;
|
|
5123
5307
|
if (this.getIsReadonly()) return this;
|
|
5124
|
-
if (!Number.isFinite(scale.x)) scale = new import_Vec.Vec(1, scale.y);
|
|
5125
|
-
if (!Number.isFinite(scale.y)) scale = new import_Vec.Vec(scale.x, 1);
|
|
5308
|
+
if (!import_core_js.Number.isFinite(scale.x)) scale = new import_Vec.Vec(1, scale.y);
|
|
5309
|
+
if (!import_core_js.Number.isFinite(scale.y)) scale = new import_Vec.Vec(scale.x, 1);
|
|
5126
5310
|
const initialShape = opts.initialShape ?? this.getShape(id);
|
|
5127
5311
|
if (!initialShape) return this;
|
|
5128
5312
|
const scaleOrigin = opts.scaleOrigin ?? this.getShapePageBounds(id)?.center;
|
|
@@ -7356,7 +7540,6 @@ __decorateElement(_init, 1, "getPages", _getPages_dec, Editor);
|
|
|
7356
7540
|
__decorateElement(_init, 1, "getCurrentPageId", _getCurrentPageId_dec, Editor);
|
|
7357
7541
|
__decorateElement(_init, 1, "getCurrentPageShapeIdsSorted", _getCurrentPageShapeIdsSorted_dec, Editor);
|
|
7358
7542
|
__decorateElement(_init, 1, "_getAllAssetsQuery", __getAllAssetsQuery_dec, Editor);
|
|
7359
|
-
__decorateElement(_init, 1, "_getShapeGeometryCache", __getShapeGeometryCache_dec, Editor);
|
|
7360
7543
|
__decorateElement(_init, 1, "_getShapeHandlesCache", __getShapeHandlesCache_dec, Editor);
|
|
7361
7544
|
__decorateElement(_init, 1, "_getShapePageTransformCache", __getShapePageTransformCache_dec, Editor);
|
|
7362
7545
|
__decorateElement(_init, 1, "_getShapePageBoundsCache", __getShapePageBoundsCache_dec, Editor);
|
|
@@ -7446,7 +7629,7 @@ function withIsolatedShapes(editor, shapeIds, callback) {
|
|
|
7446
7629
|
result = import_utils.Result.err(error);
|
|
7447
7630
|
}
|
|
7448
7631
|
});
|
|
7449
|
-
editor.store.applyDiff((0, import_store.reverseRecordsDiff)(changes));
|
|
7632
|
+
editor.store.applyDiff((0, import_store.reverseRecordsDiff)(changes), { runCallbacks: false });
|
|
7450
7633
|
},
|
|
7451
7634
|
{ history: "ignore" }
|
|
7452
7635
|
);
|