@tldraw/editor 3.9.0-canary.88e8ddb29f5d → 3.9.0-canary.952d02721a3e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.d.ts +39 -7
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +431 -249
- package/dist-cjs/lib/editor/Editor.js.map +3 -3
- 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/getSvgAsImage.js +1 -1
- package/dist-cjs/lib/exports/getSvgAsImage.js.map +2 -2
- package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
- package/dist-cjs/lib/globals/environment.js +3 -1
- package/dist-cjs/lib/globals/environment.js.map +2 -2
- package/dist-cjs/lib/license/LicenseManager.js +1 -1
- package/dist-cjs/lib/license/LicenseManager.js.map +2 -2
- package/dist-cjs/lib/utils/browserCanvasMaxSize.js +104 -28
- package/dist-cjs/lib/utils/browserCanvasMaxSize.js.map +3 -3
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +39 -7
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +427 -245
- package/dist-esm/lib/editor/Editor.mjs.map +3 -3
- 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/getSvgAsImage.mjs +1 -1
- package/dist-esm/lib/exports/getSvgAsImage.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
- package/dist-esm/lib/globals/environment.mjs +3 -1
- package/dist-esm/lib/globals/environment.mjs.map +2 -2
- package/dist-esm/lib/license/LicenseManager.mjs +1 -1
- package/dist-esm/lib/license/LicenseManager.mjs.map +2 -2
- package/dist-esm/lib/utils/browserCanvasMaxSize.mjs +104 -18
- package/dist-esm/lib/utils/browserCanvasMaxSize.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/package.json +7 -9
- package/src/index.ts +2 -0
- package/src/lib/editor/Editor.ts +556 -273
- package/src/lib/editor/shapes/ShapeUtil.ts +32 -5
- package/src/lib/exports/getSvgAsImage.ts +1 -1
- package/src/lib/exports/getSvgJsx.tsx +1 -0
- package/src/lib/globals/environment.ts +3 -0
- package/src/lib/license/LicenseManager.test.ts +16 -13
- package/src/lib/license/LicenseManager.ts +2 -2
- package/src/lib/utils/browserCanvasMaxSize.ts +121 -21
- 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");
|
|
@@ -121,8 +122,8 @@ var import_TextManager = require("./managers/TextManager");
|
|
|
121
122
|
var import_TickManager = require("./managers/TickManager");
|
|
122
123
|
var import_UserPreferencesManager = require("./managers/UserPreferencesManager");
|
|
123
124
|
var import_RootState = require("./tools/RootState");
|
|
124
|
-
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,
|
|
125
|
-
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], _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],
|
|
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, __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, _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;
|
|
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], _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) {
|
|
126
127
|
constructor({
|
|
127
128
|
store,
|
|
128
129
|
user,
|
|
@@ -284,6 +285,8 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
284
285
|
__publicField(this, "_cameraStateTimeoutRemaining", 0);
|
|
285
286
|
/* @internal */
|
|
286
287
|
__publicField(this, "_currentPageShapeIds");
|
|
288
|
+
/* --------------------- Shapes --------------------- */
|
|
289
|
+
__publicField(this, "_shapeGeometryCaches", {});
|
|
287
290
|
// Parents and children
|
|
288
291
|
/**
|
|
289
292
|
* A cache of parents to children.
|
|
@@ -2092,9 +2095,9 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
2092
2095
|
this.stopFollowingUser();
|
|
2093
2096
|
}
|
|
2094
2097
|
const _point = import_Vec.Vec.Cast(point);
|
|
2095
|
-
if (!Number.isFinite(_point.x)) _point.x = 0;
|
|
2096
|
-
if (!Number.isFinite(_point.y)) _point.y = 0;
|
|
2097
|
-
if (_point.z === void 0 || !Number.isFinite(_point.z)) point.z = this.getZoomLevel();
|
|
2098
|
+
if (!import_core_js.Number.isFinite(_point.x)) _point.x = 0;
|
|
2099
|
+
if (!import_core_js.Number.isFinite(_point.y)) _point.y = 0;
|
|
2100
|
+
if (_point.z === void 0 || !import_core_js.Number.isFinite(_point.z)) point.z = this.getZoomLevel();
|
|
2098
2101
|
const camera = this.getConstrainedCamera(_point, opts);
|
|
2099
2102
|
if (opts?.animation) {
|
|
2100
2103
|
const { width, height } = this.getViewportScreenBounds();
|
|
@@ -3195,13 +3198,6 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
3195
3198
|
async uploadAsset(asset, file, abortSignal) {
|
|
3196
3199
|
return await this.store.props.assets.upload(asset, file, abortSignal);
|
|
3197
3200
|
}
|
|
3198
|
-
_getShapeGeometryCache() {
|
|
3199
|
-
return this.store.createComputedCache(
|
|
3200
|
-
"bounds",
|
|
3201
|
-
(shape) => this.getShapeUtil(shape).getGeometry(shape),
|
|
3202
|
-
(a, b) => a.props === b.props
|
|
3203
|
-
);
|
|
3204
|
-
}
|
|
3205
3201
|
/**
|
|
3206
3202
|
* Get the geometry of a shape.
|
|
3207
3203
|
*
|
|
@@ -3209,14 +3205,26 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
3209
3205
|
* ```ts
|
|
3210
3206
|
* editor.getShapeGeometry(myShape)
|
|
3211
3207
|
* editor.getShapeGeometry(myShapeId)
|
|
3208
|
+
* editor.getShapeGeometry(myShapeId, { context: "arrow" })
|
|
3212
3209
|
* ```
|
|
3213
3210
|
*
|
|
3214
3211
|
* @param shape - The shape (or shape id) to get the geometry for.
|
|
3212
|
+
* @param opts - Additional options about the request for geometry. Passed to {@link ShapeUtil.getGeometry}.
|
|
3215
3213
|
*
|
|
3216
3214
|
* @public
|
|
3217
3215
|
*/
|
|
3218
|
-
getShapeGeometry(shape) {
|
|
3219
|
-
|
|
3216
|
+
getShapeGeometry(shape, opts) {
|
|
3217
|
+
const context = opts?.context ?? "none";
|
|
3218
|
+
if (!this._shapeGeometryCaches[context]) {
|
|
3219
|
+
this._shapeGeometryCaches[context] = this.store.createComputedCache(
|
|
3220
|
+
"bounds",
|
|
3221
|
+
(shape2) => this.getShapeUtil(shape2).getGeometry(shape2, opts),
|
|
3222
|
+
(a, b) => a.props === b.props
|
|
3223
|
+
);
|
|
3224
|
+
}
|
|
3225
|
+
return this._shapeGeometryCaches[context].get(
|
|
3226
|
+
typeof shape === "string" ? shape : shape.id
|
|
3227
|
+
);
|
|
3220
3228
|
}
|
|
3221
3229
|
_getShapeHandlesCache() {
|
|
3222
3230
|
return this.store.createComputedCache("handles", (shape) => {
|
|
@@ -4282,27 +4290,28 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
4282
4290
|
});
|
|
4283
4291
|
return this;
|
|
4284
4292
|
}
|
|
4293
|
+
// Gets a shape partial that includes life cycle changes: on translate start, on translate, on translate end
|
|
4285
4294
|
getChangesToTranslateShape(initialShape, newShapeCoords) {
|
|
4286
4295
|
let workingShape = initialShape;
|
|
4287
4296
|
const util = this.getShapeUtil(initialShape);
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4297
|
+
const afterTranslateStart = util.onTranslateStart?.(workingShape);
|
|
4298
|
+
if (afterTranslateStart) {
|
|
4299
|
+
workingShape = applyPartialToRecordWithProps(workingShape, afterTranslateStart);
|
|
4300
|
+
}
|
|
4292
4301
|
workingShape = applyPartialToRecordWithProps(workingShape, {
|
|
4293
4302
|
id: initialShape.id,
|
|
4294
4303
|
type: initialShape.type,
|
|
4295
4304
|
x: newShapeCoords.x,
|
|
4296
4305
|
y: newShapeCoords.y
|
|
4297
4306
|
});
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4307
|
+
const afterTranslate = util.onTranslate?.(initialShape, workingShape);
|
|
4308
|
+
if (afterTranslate) {
|
|
4309
|
+
workingShape = applyPartialToRecordWithProps(workingShape, afterTranslate);
|
|
4310
|
+
}
|
|
4311
|
+
const afterTranslateEnd = util.onTranslateEnd?.(initialShape, workingShape);
|
|
4312
|
+
if (afterTranslateEnd) {
|
|
4313
|
+
workingShape = applyPartialToRecordWithProps(workingShape, afterTranslateEnd);
|
|
4314
|
+
}
|
|
4306
4315
|
return workingShape;
|
|
4307
4316
|
}
|
|
4308
4317
|
/**
|
|
@@ -4609,6 +4618,30 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
4609
4618
|
if (changes) this.updateShapes(changes);
|
|
4610
4619
|
return this;
|
|
4611
4620
|
}
|
|
4621
|
+
/**
|
|
4622
|
+
* @internal
|
|
4623
|
+
*/
|
|
4624
|
+
collectShapesViaArrowBindings(info) {
|
|
4625
|
+
const { initialShapes, resultShapes, resultBounds, bindings, visited } = info;
|
|
4626
|
+
for (const binding of bindings) {
|
|
4627
|
+
for (const id of [binding.fromId, binding.toId]) {
|
|
4628
|
+
if (!visited.has(id)) {
|
|
4629
|
+
const aligningShape = initialShapes.find((s) => s.id === id);
|
|
4630
|
+
if (aligningShape && !visited.has(aligningShape.id)) {
|
|
4631
|
+
visited.add(aligningShape.id);
|
|
4632
|
+
const shapePageBounds = this.getShapePageBounds(aligningShape);
|
|
4633
|
+
if (!shapePageBounds) continue;
|
|
4634
|
+
resultShapes.push(aligningShape);
|
|
4635
|
+
resultBounds.push(shapePageBounds);
|
|
4636
|
+
this.collectShapesViaArrowBindings({
|
|
4637
|
+
...info,
|
|
4638
|
+
bindings: this.getBindingsInvolvingShape(aligningShape, "arrow")
|
|
4639
|
+
});
|
|
4640
|
+
}
|
|
4641
|
+
}
|
|
4642
|
+
}
|
|
4643
|
+
}
|
|
4644
|
+
}
|
|
4612
4645
|
/**
|
|
4613
4646
|
* Flip shape positions.
|
|
4614
4647
|
*
|
|
@@ -4624,35 +4657,52 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
4624
4657
|
* @public
|
|
4625
4658
|
*/
|
|
4626
4659
|
flipShapes(shapes, operation) {
|
|
4627
|
-
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4628
4660
|
if (this.getIsReadonly()) return this;
|
|
4629
|
-
|
|
4661
|
+
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4662
|
+
const shapesToFlipFirstPass = (0, import_utils.compact)(ids.map((id) => this.getShape(id)));
|
|
4663
|
+
for (const shape of shapesToFlipFirstPass) {
|
|
4664
|
+
if (this.isShapeOfType(shape, "group")) {
|
|
4665
|
+
const childrenOfGroups = (0, import_utils.compact)(
|
|
4666
|
+
this.getSortedChildIdsForParent(shape.id).map((id) => this.getShape(id))
|
|
4667
|
+
);
|
|
4668
|
+
shapesToFlipFirstPass.push(...childrenOfGroups);
|
|
4669
|
+
}
|
|
4670
|
+
}
|
|
4671
|
+
const shapesToFlip = [];
|
|
4672
|
+
const allBounds = [];
|
|
4673
|
+
for (const shape of shapesToFlipFirstPass) {
|
|
4674
|
+
const util = this.getShapeUtil(shape);
|
|
4675
|
+
if (!util.canBeLaidOut(shape, {
|
|
4676
|
+
type: "flip",
|
|
4677
|
+
shapes: shapesToFlipFirstPass
|
|
4678
|
+
})) {
|
|
4679
|
+
continue;
|
|
4680
|
+
}
|
|
4681
|
+
const pageBounds = this.getShapePageBounds(shape);
|
|
4682
|
+
const localBounds = this.getShapeGeometry(shape).bounds;
|
|
4683
|
+
const pageTransform = this.getShapePageTransform(shape.id);
|
|
4684
|
+
if (!(pageBounds && localBounds && pageTransform)) continue;
|
|
4685
|
+
shapesToFlip.push({
|
|
4686
|
+
shape,
|
|
4687
|
+
localBounds,
|
|
4688
|
+
pageTransform,
|
|
4689
|
+
isAspectRatioLocked: util.isAspectRatioLocked(shape)
|
|
4690
|
+
});
|
|
4691
|
+
allBounds.push(pageBounds);
|
|
4692
|
+
}
|
|
4630
4693
|
if (!shapesToFlip.length) return this;
|
|
4631
|
-
|
|
4632
|
-
shapesToFlip.map((shape) => {
|
|
4633
|
-
if (this.isShapeOfType(shape, "group")) {
|
|
4634
|
-
return this.getSortedChildIdsForParent(shape.id).map((id) => this.getShape(id));
|
|
4635
|
-
}
|
|
4636
|
-
return shape;
|
|
4637
|
-
}).flat()
|
|
4638
|
-
);
|
|
4639
|
-
const scaleOriginPage = import_Box.Box.Common(
|
|
4640
|
-
(0, import_utils.compact)(shapesToFlip.map((id) => this.getShapePageBounds(id)))
|
|
4641
|
-
).center;
|
|
4694
|
+
const scaleOriginPage = import_Box.Box.Common(allBounds).center;
|
|
4642
4695
|
this.run(() => {
|
|
4643
|
-
for (const shape of shapesToFlip) {
|
|
4644
|
-
const bounds = this.getShapeGeometry(shape).bounds;
|
|
4645
|
-
const initialPageTransform = this.getShapePageTransform(shape.id);
|
|
4646
|
-
if (!initialPageTransform) continue;
|
|
4696
|
+
for (const { shape, localBounds, pageTransform, isAspectRatioLocked } of shapesToFlip) {
|
|
4647
4697
|
this.resizeShape(
|
|
4648
4698
|
shape.id,
|
|
4649
4699
|
{ x: operation === "horizontal" ? -1 : 1, y: operation === "vertical" ? -1 : 1 },
|
|
4650
4700
|
{
|
|
4651
|
-
initialBounds:
|
|
4652
|
-
initialPageTransform,
|
|
4701
|
+
initialBounds: localBounds,
|
|
4702
|
+
initialPageTransform: pageTransform,
|
|
4653
4703
|
initialShape: shape,
|
|
4704
|
+
isAspectRatioLocked,
|
|
4654
4705
|
mode: "scale_shape",
|
|
4655
|
-
isAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),
|
|
4656
4706
|
scaleOrigin: scaleOriginPage,
|
|
4657
4707
|
scaleAxisRotation: 0
|
|
4658
4708
|
}
|
|
@@ -4679,15 +4729,40 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
4679
4729
|
stackShapes(shapes, operation, gap) {
|
|
4680
4730
|
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4681
4731
|
if (this.getIsReadonly()) return this;
|
|
4682
|
-
const
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
const
|
|
4732
|
+
const shapesToStackFirstPass = (0, import_utils.compact)(ids.map((id) => this.getShape(id)));
|
|
4733
|
+
const shapeClustersToStack = [];
|
|
4734
|
+
const allBounds = [];
|
|
4735
|
+
const visited = /* @__PURE__ */ new Set();
|
|
4736
|
+
for (const shape of shapesToStackFirstPass) {
|
|
4737
|
+
if (visited.has(shape.id)) continue;
|
|
4738
|
+
visited.add(shape.id);
|
|
4739
|
+
const shapePageBounds = this.getShapePageBounds(shape);
|
|
4740
|
+
if (!shapePageBounds) continue;
|
|
4741
|
+
if (!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
4742
|
+
type: "stack",
|
|
4743
|
+
shapes: shapesToStackFirstPass
|
|
4744
|
+
})) {
|
|
4745
|
+
continue;
|
|
4746
|
+
}
|
|
4747
|
+
const shapesMovingTogether = [shape];
|
|
4748
|
+
const boundsOfShapesMovingTogether = [shapePageBounds];
|
|
4749
|
+
this.collectShapesViaArrowBindings({
|
|
4750
|
+
bindings: this.getBindingsToShape(shape.id, "arrow"),
|
|
4751
|
+
initialShapes: shapesToStackFirstPass,
|
|
4752
|
+
resultShapes: shapesMovingTogether,
|
|
4753
|
+
resultBounds: boundsOfShapesMovingTogether,
|
|
4754
|
+
visited
|
|
4755
|
+
});
|
|
4756
|
+
const commonPageBounds = import_Box.Box.Common(boundsOfShapesMovingTogether);
|
|
4757
|
+
if (!commonPageBounds) continue;
|
|
4758
|
+
shapeClustersToStack.push({
|
|
4759
|
+
shapes: shapesMovingTogether,
|
|
4760
|
+
pageBounds: commonPageBounds
|
|
4761
|
+
});
|
|
4762
|
+
allBounds.push(commonPageBounds);
|
|
4763
|
+
}
|
|
4764
|
+
const len = shapeClustersToStack.length;
|
|
4687
4765
|
if (gap === 0 && len < 3 || len < 2) return this;
|
|
4688
|
-
const pageBounds = Object.fromEntries(
|
|
4689
|
-
shapesToStack.map((shape) => [shape.id, this.getShapePageBounds(shape)])
|
|
4690
|
-
);
|
|
4691
4766
|
let val;
|
|
4692
4767
|
let min;
|
|
4693
4768
|
let max;
|
|
@@ -4703,57 +4778,55 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
4703
4778
|
max = "maxY";
|
|
4704
4779
|
dim = "height";
|
|
4705
4780
|
}
|
|
4706
|
-
let shapeGap;
|
|
4781
|
+
let shapeGap = 0;
|
|
4707
4782
|
if (gap === 0) {
|
|
4708
|
-
const gaps =
|
|
4709
|
-
|
|
4783
|
+
const gaps = {};
|
|
4784
|
+
shapeClustersToStack.sort((a, b) => a.pageBounds[min] - b.pageBounds[min]);
|
|
4710
4785
|
for (let i = 0; i < len - 1; i++) {
|
|
4711
|
-
const
|
|
4712
|
-
const
|
|
4713
|
-
const
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
const current = gaps.find((g) => g.gap === gap2);
|
|
4717
|
-
if (current) {
|
|
4718
|
-
current.count++;
|
|
4719
|
-
} else {
|
|
4720
|
-
gaps.push({ gap: gap2, count: 1 });
|
|
4786
|
+
const currCluster = shapeClustersToStack[i];
|
|
4787
|
+
const nextCluster = shapeClustersToStack[i + 1];
|
|
4788
|
+
const gap2 = nextCluster.pageBounds[min] - currCluster.pageBounds[max];
|
|
4789
|
+
if (!gaps[gap2]) {
|
|
4790
|
+
gaps[gap2] = 0;
|
|
4721
4791
|
}
|
|
4792
|
+
gaps[gap2]++;
|
|
4722
4793
|
}
|
|
4723
|
-
let maxCount =
|
|
4724
|
-
|
|
4725
|
-
if (
|
|
4726
|
-
maxCount =
|
|
4727
|
-
shapeGap =
|
|
4794
|
+
let maxCount = 1;
|
|
4795
|
+
for (const [gap2, count] of Object.entries(gaps)) {
|
|
4796
|
+
if (count > maxCount) {
|
|
4797
|
+
maxCount = count;
|
|
4798
|
+
shapeGap = parseFloat(gap2);
|
|
4728
4799
|
}
|
|
4729
|
-
}
|
|
4800
|
+
}
|
|
4730
4801
|
if (maxCount === 1) {
|
|
4731
|
-
|
|
4802
|
+
let totalCount = 0;
|
|
4803
|
+
for (const [gap2, count] of Object.entries(gaps)) {
|
|
4804
|
+
shapeGap += parseFloat(gap2) * count;
|
|
4805
|
+
totalCount += count;
|
|
4806
|
+
}
|
|
4807
|
+
shapeGap /= totalCount;
|
|
4732
4808
|
}
|
|
4733
4809
|
} else {
|
|
4734
4810
|
shapeGap = gap;
|
|
4735
4811
|
}
|
|
4736
4812
|
const changes = [];
|
|
4737
|
-
let v =
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
const delta =
|
|
4741
|
-
delta[val] = v + shapeGap - pageBounds[
|
|
4742
|
-
const
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
[val]: shape[val] + localDelta[val]
|
|
4749
|
-
} : {
|
|
4750
|
-
id: shape.id,
|
|
4751
|
-
type: shape.type,
|
|
4752
|
-
[val]: shape[val] + localDelta[val]
|
|
4813
|
+
let v = shapeClustersToStack[0].pageBounds[max];
|
|
4814
|
+
for (let i = 1; i < shapeClustersToStack.length; i++) {
|
|
4815
|
+
const { shapes: shapes2, pageBounds } = shapeClustersToStack[i];
|
|
4816
|
+
const delta = new import_Vec.Vec();
|
|
4817
|
+
delta[val] = v + shapeGap - pageBounds[val];
|
|
4818
|
+
for (const shape of shapes2) {
|
|
4819
|
+
const shapeDelta = delta.clone();
|
|
4820
|
+
const parent = this.getShapeParent(shape);
|
|
4821
|
+
if (parent) {
|
|
4822
|
+
const parentTransform = this.getShapePageTransform(parent);
|
|
4823
|
+
if (parentTransform) shapeDelta.rot(-parentTransform.rotation());
|
|
4753
4824
|
}
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4825
|
+
shapeDelta.add(shape);
|
|
4826
|
+
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
4827
|
+
}
|
|
4828
|
+
v += pageBounds[dim] + shapeGap;
|
|
4829
|
+
}
|
|
4757
4830
|
this.updateShapes(changes);
|
|
4758
4831
|
return this;
|
|
4759
4832
|
}
|
|
@@ -4771,91 +4844,101 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
4771
4844
|
* @param gap - The padding to apply to the packed shapes. Defaults to 16.
|
|
4772
4845
|
*/
|
|
4773
4846
|
packShapes(shapes, gap) {
|
|
4774
|
-
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4775
4847
|
if (this.getIsReadonly()) return this;
|
|
4776
|
-
|
|
4777
|
-
const
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
const
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4848
|
+
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4849
|
+
const shapesToPackFirstPass = (0, import_utils.compact)(ids.map((id) => this.getShape(id)));
|
|
4850
|
+
const shapeClustersToPack = [];
|
|
4851
|
+
const allBounds = [];
|
|
4852
|
+
const visited = /* @__PURE__ */ new Set();
|
|
4853
|
+
for (const shape of shapesToPackFirstPass) {
|
|
4854
|
+
if (visited.has(shape.id)) continue;
|
|
4855
|
+
visited.add(shape.id);
|
|
4856
|
+
const shapePageBounds = this.getShapePageBounds(shape);
|
|
4857
|
+
if (!shapePageBounds) continue;
|
|
4858
|
+
if (!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
4859
|
+
type: "pack",
|
|
4860
|
+
shapes: shapesToPackFirstPass
|
|
4861
|
+
})) {
|
|
4862
|
+
continue;
|
|
4863
|
+
}
|
|
4864
|
+
const shapesMovingTogether = [shape];
|
|
4865
|
+
const boundsOfShapesMovingTogether = [shapePageBounds];
|
|
4866
|
+
this.collectShapesViaArrowBindings({
|
|
4867
|
+
bindings: this.getBindingsToShape(shape.id, "arrow"),
|
|
4868
|
+
initialShapes: shapesToPackFirstPass,
|
|
4869
|
+
resultShapes: shapesMovingTogether,
|
|
4870
|
+
resultBounds: boundsOfShapesMovingTogether,
|
|
4871
|
+
visited
|
|
4872
|
+
});
|
|
4873
|
+
const commonPageBounds = import_Box.Box.Common(boundsOfShapesMovingTogether);
|
|
4874
|
+
if (!commonPageBounds) continue;
|
|
4875
|
+
shapeClustersToPack.push({
|
|
4876
|
+
shapes: shapesMovingTogether,
|
|
4877
|
+
pageBounds: commonPageBounds,
|
|
4878
|
+
nextPageBounds: commonPageBounds.clone()
|
|
4879
|
+
});
|
|
4880
|
+
allBounds.push(commonPageBounds);
|
|
4881
|
+
}
|
|
4882
|
+
if (shapeClustersToPack.length < 2) return this;
|
|
4883
|
+
let area = 0;
|
|
4884
|
+
for (const { pageBounds } of shapeClustersToPack) {
|
|
4885
|
+
area += pageBounds.width * pageBounds.height;
|
|
4886
|
+
}
|
|
4887
|
+
const commonBounds = import_Box.Box.Common(allBounds);
|
|
4792
4888
|
const maxWidth = commonBounds.width;
|
|
4793
|
-
|
|
4889
|
+
shapeClustersToPack.sort((a, b) => a.pageBounds.width - b.pageBounds.width).sort((a, b) => a.pageBounds.height - b.pageBounds.height);
|
|
4794
4890
|
const startWidth = Math.max(Math.ceil(Math.sqrt(area / 0.95)), maxWidth);
|
|
4795
4891
|
const spaces = [new import_Box.Box(commonBounds.x, commonBounds.y, startWidth, Infinity)];
|
|
4796
4892
|
let width = 0;
|
|
4797
4893
|
let height = 0;
|
|
4798
4894
|
let space;
|
|
4799
4895
|
let last2;
|
|
4800
|
-
for (
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
|
|
4808
|
-
|
|
4809
|
-
width = Math.max(width, bounds.maxX);
|
|
4810
|
-
if (bounds.width === space.width && bounds.height === space.height) {
|
|
4896
|
+
for (const { nextPageBounds } of shapeClustersToPack) {
|
|
4897
|
+
for (let i = spaces.length - 1; i >= 0; i--) {
|
|
4898
|
+
space = spaces[i];
|
|
4899
|
+
if (nextPageBounds.width > space.width || nextPageBounds.height > space.height) continue;
|
|
4900
|
+
nextPageBounds.x = space.x;
|
|
4901
|
+
nextPageBounds.y = space.y;
|
|
4902
|
+
height = Math.max(height, nextPageBounds.maxY);
|
|
4903
|
+
width = Math.max(width, nextPageBounds.maxX);
|
|
4904
|
+
if (nextPageBounds.width === space.width && nextPageBounds.height === space.height) {
|
|
4811
4905
|
last2 = spaces.pop();
|
|
4812
|
-
if (
|
|
4813
|
-
} else if (
|
|
4814
|
-
space.x +=
|
|
4815
|
-
space.width -=
|
|
4816
|
-
} else if (
|
|
4817
|
-
space.y +=
|
|
4818
|
-
space.height -=
|
|
4906
|
+
if (i < spaces.length) spaces[i] = last2;
|
|
4907
|
+
} else if (nextPageBounds.height === space.height) {
|
|
4908
|
+
space.x += nextPageBounds.width + gap;
|
|
4909
|
+
space.width -= nextPageBounds.width + gap;
|
|
4910
|
+
} else if (nextPageBounds.width === space.width) {
|
|
4911
|
+
space.y += nextPageBounds.height + gap;
|
|
4912
|
+
space.height -= nextPageBounds.height + gap;
|
|
4819
4913
|
} else {
|
|
4820
4914
|
spaces.push(
|
|
4821
4915
|
new import_Box.Box(
|
|
4822
|
-
space.x + (
|
|
4916
|
+
space.x + (nextPageBounds.width + gap),
|
|
4823
4917
|
space.y,
|
|
4824
|
-
space.width - (
|
|
4825
|
-
|
|
4918
|
+
space.width - (nextPageBounds.width + gap),
|
|
4919
|
+
nextPageBounds.height
|
|
4826
4920
|
)
|
|
4827
4921
|
);
|
|
4828
|
-
space.y +=
|
|
4829
|
-
space.height -=
|
|
4922
|
+
space.y += nextPageBounds.height + gap;
|
|
4923
|
+
space.height -= nextPageBounds.height + gap;
|
|
4830
4924
|
}
|
|
4831
4925
|
break;
|
|
4832
4926
|
}
|
|
4833
4927
|
}
|
|
4834
|
-
const commonAfter = import_Box.Box.Common(
|
|
4928
|
+
const commonAfter = import_Box.Box.Common(shapeClustersToPack.map((s) => s.nextPageBounds));
|
|
4835
4929
|
const centerDelta = import_Vec.Vec.Sub(commonBounds.center, commonAfter.center);
|
|
4836
|
-
let nextBounds;
|
|
4837
4930
|
const changes = [];
|
|
4838
|
-
for (
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
|
|
4848
|
-
|
|
4849
|
-
y: shape.y + delta.y
|
|
4850
|
-
};
|
|
4851
|
-
const translateStartChange = this.getShapeUtil(shape).onTranslateStart?.({
|
|
4852
|
-
...shape,
|
|
4853
|
-
...change
|
|
4854
|
-
});
|
|
4855
|
-
if (translateStartChange) {
|
|
4856
|
-
changes.push({ ...change, ...translateStartChange });
|
|
4857
|
-
} else {
|
|
4858
|
-
changes.push(change);
|
|
4931
|
+
for (const { shapes: shapes2, pageBounds, nextPageBounds } of shapeClustersToPack) {
|
|
4932
|
+
const delta = import_Vec.Vec.Sub(nextPageBounds.point, pageBounds.point).add(centerDelta);
|
|
4933
|
+
for (const shape of shapes2) {
|
|
4934
|
+
const shapeDelta = delta.clone();
|
|
4935
|
+
const parent = this.getShapeParent(shape);
|
|
4936
|
+
if (parent) {
|
|
4937
|
+
const parentTransform = this.getShapeParentTransform(shape);
|
|
4938
|
+
if (parentTransform) shapeDelta.rot(-parentTransform.rotation());
|
|
4939
|
+
}
|
|
4940
|
+
shapeDelta.add(shape);
|
|
4941
|
+
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
4859
4942
|
}
|
|
4860
4943
|
}
|
|
4861
4944
|
if (changes.length) {
|
|
@@ -4878,19 +4961,45 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
4878
4961
|
* @public
|
|
4879
4962
|
*/
|
|
4880
4963
|
alignShapes(shapes, operation) {
|
|
4881
|
-
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4882
4964
|
if (this.getIsReadonly()) return this;
|
|
4883
|
-
|
|
4884
|
-
const
|
|
4885
|
-
const
|
|
4886
|
-
|
|
4887
|
-
);
|
|
4888
|
-
const
|
|
4965
|
+
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4966
|
+
const shapesToAlignFirstPass = (0, import_utils.compact)(ids.map((id) => this.getShape(id)));
|
|
4967
|
+
const shapeClustersToAlign = [];
|
|
4968
|
+
const allBounds = [];
|
|
4969
|
+
const visited = /* @__PURE__ */ new Set();
|
|
4970
|
+
for (const shape of shapesToAlignFirstPass) {
|
|
4971
|
+
if (visited.has(shape.id)) continue;
|
|
4972
|
+
visited.add(shape.id);
|
|
4973
|
+
const shapePageBounds = this.getShapePageBounds(shape);
|
|
4974
|
+
if (!shapePageBounds) continue;
|
|
4975
|
+
if (!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
4976
|
+
type: "align",
|
|
4977
|
+
shapes: shapesToAlignFirstPass
|
|
4978
|
+
})) {
|
|
4979
|
+
continue;
|
|
4980
|
+
}
|
|
4981
|
+
const shapesMovingTogether = [shape];
|
|
4982
|
+
const boundsOfShapesMovingTogether = [shapePageBounds];
|
|
4983
|
+
this.collectShapesViaArrowBindings({
|
|
4984
|
+
bindings: this.getBindingsToShape(shape.id, "arrow"),
|
|
4985
|
+
initialShapes: shapesToAlignFirstPass,
|
|
4986
|
+
resultShapes: shapesMovingTogether,
|
|
4987
|
+
resultBounds: boundsOfShapesMovingTogether,
|
|
4988
|
+
visited
|
|
4989
|
+
});
|
|
4990
|
+
const commonPageBounds = import_Box.Box.Common(boundsOfShapesMovingTogether);
|
|
4991
|
+
if (!commonPageBounds) continue;
|
|
4992
|
+
shapeClustersToAlign.push({
|
|
4993
|
+
shapes: shapesMovingTogether,
|
|
4994
|
+
pageBounds: commonPageBounds
|
|
4995
|
+
});
|
|
4996
|
+
allBounds.push(commonPageBounds);
|
|
4997
|
+
}
|
|
4998
|
+
if (shapeClustersToAlign.length < 2) return this;
|
|
4999
|
+
const commonBounds = import_Box.Box.Common(allBounds);
|
|
4889
5000
|
const changes = [];
|
|
4890
|
-
|
|
4891
|
-
const
|
|
4892
|
-
if (!pageBounds) return;
|
|
4893
|
-
const delta = { x: 0, y: 0 };
|
|
5001
|
+
shapeClustersToAlign.forEach(({ shapes: shapes2, pageBounds }) => {
|
|
5002
|
+
const delta = new import_Vec.Vec();
|
|
4894
5003
|
switch (operation) {
|
|
4895
5004
|
case "top": {
|
|
4896
5005
|
delta.y = commonBounds.minY - pageBounds.minY;
|
|
@@ -4917,9 +5026,16 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
4917
5026
|
break;
|
|
4918
5027
|
}
|
|
4919
5028
|
}
|
|
4920
|
-
const
|
|
4921
|
-
|
|
4922
|
-
|
|
5029
|
+
for (const shape of shapes2) {
|
|
5030
|
+
const shapeDelta = delta.clone();
|
|
5031
|
+
const parent = this.getShapeParent(shape);
|
|
5032
|
+
if (parent) {
|
|
5033
|
+
const parentTransform = this.getShapePageTransform(parent);
|
|
5034
|
+
if (parentTransform) shapeDelta.rot(-parentTransform.rotation());
|
|
5035
|
+
}
|
|
5036
|
+
shapeDelta.add(shape);
|
|
5037
|
+
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
5038
|
+
}
|
|
4923
5039
|
});
|
|
4924
5040
|
this.updateShapes(changes);
|
|
4925
5041
|
return this;
|
|
@@ -4939,47 +5055,95 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
4939
5055
|
* @public
|
|
4940
5056
|
*/
|
|
4941
5057
|
distributeShapes(shapes, operation) {
|
|
4942
|
-
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4943
5058
|
if (this.getIsReadonly()) return this;
|
|
4944
|
-
|
|
4945
|
-
const
|
|
4946
|
-
const
|
|
4947
|
-
const
|
|
4948
|
-
|
|
4949
|
-
)
|
|
5059
|
+
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
5060
|
+
const shapesToDistributeFirstPass = (0, import_utils.compact)(ids.map((id) => this.getShape(id)));
|
|
5061
|
+
const shapeClustersToDistribute = [];
|
|
5062
|
+
const allBounds = [];
|
|
5063
|
+
const visited = /* @__PURE__ */ new Set();
|
|
5064
|
+
for (const shape of shapesToDistributeFirstPass) {
|
|
5065
|
+
if (visited.has(shape.id)) continue;
|
|
5066
|
+
visited.add(shape.id);
|
|
5067
|
+
const shapePageBounds = this.getShapePageBounds(shape);
|
|
5068
|
+
if (!shapePageBounds) continue;
|
|
5069
|
+
if (!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
5070
|
+
type: "distribute",
|
|
5071
|
+
shapes: shapesToDistributeFirstPass
|
|
5072
|
+
})) {
|
|
5073
|
+
continue;
|
|
5074
|
+
}
|
|
5075
|
+
const shapesMovingTogether = [shape];
|
|
5076
|
+
const boundsOfShapesMovingTogether = [shapePageBounds];
|
|
5077
|
+
this.collectShapesViaArrowBindings({
|
|
5078
|
+
bindings: this.getBindingsToShape(shape.id, "arrow"),
|
|
5079
|
+
initialShapes: shapesToDistributeFirstPass,
|
|
5080
|
+
resultShapes: shapesMovingTogether,
|
|
5081
|
+
resultBounds: boundsOfShapesMovingTogether,
|
|
5082
|
+
visited
|
|
5083
|
+
});
|
|
5084
|
+
const commonPageBounds = import_Box.Box.Common(boundsOfShapesMovingTogether);
|
|
5085
|
+
if (!commonPageBounds) continue;
|
|
5086
|
+
shapeClustersToDistribute.push({
|
|
5087
|
+
shapes: shapesMovingTogether,
|
|
5088
|
+
pageBounds: commonPageBounds
|
|
5089
|
+
});
|
|
5090
|
+
allBounds.push(commonPageBounds);
|
|
5091
|
+
}
|
|
5092
|
+
if (shapeClustersToDistribute.length < 3) return this;
|
|
4950
5093
|
let val;
|
|
4951
5094
|
let min;
|
|
4952
5095
|
let max;
|
|
4953
|
-
let mid;
|
|
4954
5096
|
let dim;
|
|
4955
5097
|
if (operation === "horizontal") {
|
|
4956
5098
|
val = "x";
|
|
4957
5099
|
min = "minX";
|
|
4958
5100
|
max = "maxX";
|
|
4959
|
-
mid = "midX";
|
|
4960
5101
|
dim = "width";
|
|
4961
5102
|
} else {
|
|
4962
5103
|
val = "y";
|
|
4963
5104
|
min = "minY";
|
|
4964
5105
|
max = "maxY";
|
|
4965
|
-
mid = "midY";
|
|
4966
5106
|
dim = "height";
|
|
4967
5107
|
}
|
|
4968
5108
|
const changes = [];
|
|
4969
|
-
const first =
|
|
4970
|
-
|
|
4971
|
-
)
|
|
4972
|
-
|
|
4973
|
-
|
|
4974
|
-
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
5109
|
+
const first = shapeClustersToDistribute.sort((a, b) => a.pageBounds[min] - b.pageBounds[min])[0];
|
|
5110
|
+
const last2 = shapeClustersToDistribute.sort((a, b) => b.pageBounds[max] - a.pageBounds[max])[0];
|
|
5111
|
+
if (first === last2) {
|
|
5112
|
+
const excludedShapeIds = new Set(first.shapes.map((s) => s.id));
|
|
5113
|
+
return this.distributeShapes(
|
|
5114
|
+
ids.filter((id) => !excludedShapeIds.has(id)),
|
|
5115
|
+
operation
|
|
5116
|
+
);
|
|
5117
|
+
}
|
|
5118
|
+
const shapeClustersToMove = shapeClustersToDistribute.filter((shape) => shape !== first && shape !== last2).sort((a, b) => {
|
|
5119
|
+
if (a.pageBounds[min] === b.pageBounds[min]) {
|
|
5120
|
+
return a.shapes[0].id < b.shapes[0].id ? -1 : 1;
|
|
5121
|
+
}
|
|
5122
|
+
return a.pageBounds[min] - b.pageBounds[min];
|
|
4982
5123
|
});
|
|
5124
|
+
const maxFirst = first.pageBounds[max];
|
|
5125
|
+
const range = last2.pageBounds[min] - maxFirst;
|
|
5126
|
+
const summedShapeDimensions = shapeClustersToMove.reduce((acc, s) => acc + s.pageBounds[dim], 0);
|
|
5127
|
+
const gap = (range - summedShapeDimensions) / (shapeClustersToMove.length + 1);
|
|
5128
|
+
for (let v = maxFirst + gap, i = 0; i < shapeClustersToMove.length; i++) {
|
|
5129
|
+
const { shapes: shapes2, pageBounds } = shapeClustersToMove[i];
|
|
5130
|
+
const delta = new import_Vec.Vec();
|
|
5131
|
+
delta[val] = v - pageBounds[val];
|
|
5132
|
+
if (v + pageBounds[dim] > last2.pageBounds[max] - 1) {
|
|
5133
|
+
delta[val] = last2.pageBounds[max] - pageBounds[max] - 1;
|
|
5134
|
+
}
|
|
5135
|
+
for (const shape of shapes2) {
|
|
5136
|
+
const shapeDelta = delta.clone();
|
|
5137
|
+
const parent = this.getShapeParent(shape);
|
|
5138
|
+
if (parent) {
|
|
5139
|
+
const parentTransform = this.getShapePageTransform(parent);
|
|
5140
|
+
if (parentTransform) shapeDelta.rot(-parentTransform.rotation());
|
|
5141
|
+
}
|
|
5142
|
+
shapeDelta.add(shape);
|
|
5143
|
+
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
5144
|
+
}
|
|
5145
|
+
v += pageBounds[dim] + gap;
|
|
5146
|
+
}
|
|
4983
5147
|
this.updateShapes(changes);
|
|
4984
5148
|
return this;
|
|
4985
5149
|
}
|
|
@@ -5000,59 +5164,78 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
5000
5164
|
stretchShapes(shapes, operation) {
|
|
5001
5165
|
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
5002
5166
|
if (this.getIsReadonly()) return this;
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
const
|
|
5007
|
-
const
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
const scale = new import_Vec.Vec(1, commonBounds.height / pageBounds.height);
|
|
5022
|
-
this.resizeShape(shape.id, scale, {
|
|
5023
|
-
initialBounds: bounds,
|
|
5024
|
-
scaleOrigin: new import_Vec.Vec(pageBounds.center.x, commonBounds.minY),
|
|
5025
|
-
isAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),
|
|
5026
|
-
scaleAxisRotation: 0
|
|
5027
|
-
});
|
|
5028
|
-
}
|
|
5029
|
-
});
|
|
5030
|
-
break;
|
|
5031
|
-
}
|
|
5032
|
-
case "horizontal": {
|
|
5033
|
-
this.run(() => {
|
|
5034
|
-
for (const shape of shapesToStretch) {
|
|
5035
|
-
const bounds = shapeBounds[shape.id];
|
|
5036
|
-
const pageBounds = shapePageBounds[shape.id];
|
|
5037
|
-
const pageRotation = this.getShapePageTransform(shape).rotation();
|
|
5038
|
-
if (pageRotation % import_utils2.PI2) continue;
|
|
5039
|
-
const localOffset = new import_Vec.Vec(commonBounds.minX - pageBounds.minX, 0);
|
|
5040
|
-
const parentTransform = this.getShapeParentTransform(shape);
|
|
5041
|
-
if (parentTransform) localOffset.rot(-parentTransform.rotation());
|
|
5042
|
-
const { x, y } = import_Vec.Vec.Add(localOffset, shape);
|
|
5043
|
-
this.updateShapes([{ id: shape.id, type: shape.type, x, y }]);
|
|
5044
|
-
const scale = new import_Vec.Vec(commonBounds.width / pageBounds.width, 1);
|
|
5045
|
-
this.resizeShape(shape.id, scale, {
|
|
5046
|
-
initialBounds: bounds,
|
|
5047
|
-
scaleOrigin: new import_Vec.Vec(commonBounds.minX, pageBounds.center.y),
|
|
5048
|
-
isAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),
|
|
5049
|
-
scaleAxisRotation: 0
|
|
5050
|
-
});
|
|
5051
|
-
}
|
|
5052
|
-
});
|
|
5053
|
-
break;
|
|
5167
|
+
const shapesToStretchFirstPass = (0, import_utils.compact)(ids.map((id) => this.getShape(id))).filter(
|
|
5168
|
+
(s) => this.getShapePageTransform(s)?.rotation() % (import_utils2.PI / 2) === 0
|
|
5169
|
+
);
|
|
5170
|
+
const shapeClustersToStretch = [];
|
|
5171
|
+
const allBounds = [];
|
|
5172
|
+
const visited = /* @__PURE__ */ new Set();
|
|
5173
|
+
for (const shape of shapesToStretchFirstPass) {
|
|
5174
|
+
if (visited.has(shape.id)) continue;
|
|
5175
|
+
visited.add(shape.id);
|
|
5176
|
+
const shapePageBounds = this.getShapePageBounds(shape);
|
|
5177
|
+
if (!shapePageBounds) continue;
|
|
5178
|
+
const shapesMovingTogether = [shape];
|
|
5179
|
+
const boundsOfShapesMovingTogether = [shapePageBounds];
|
|
5180
|
+
if (!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
5181
|
+
type: "stretch",
|
|
5182
|
+
shapes: shapesToStretchFirstPass
|
|
5183
|
+
})) {
|
|
5184
|
+
continue;
|
|
5054
5185
|
}
|
|
5186
|
+
this.collectShapesViaArrowBindings({
|
|
5187
|
+
bindings: this.getBindingsToShape(shape.id, "arrow"),
|
|
5188
|
+
initialShapes: shapesToStretchFirstPass,
|
|
5189
|
+
resultShapes: shapesMovingTogether,
|
|
5190
|
+
resultBounds: boundsOfShapesMovingTogether,
|
|
5191
|
+
visited
|
|
5192
|
+
});
|
|
5193
|
+
const commonPageBounds = import_Box.Box.Common(boundsOfShapesMovingTogether);
|
|
5194
|
+
if (!commonPageBounds) continue;
|
|
5195
|
+
shapeClustersToStretch.push({
|
|
5196
|
+
shapes: shapesMovingTogether,
|
|
5197
|
+
pageBounds: commonPageBounds
|
|
5198
|
+
});
|
|
5199
|
+
allBounds.push(commonPageBounds);
|
|
5200
|
+
}
|
|
5201
|
+
if (shapeClustersToStretch.length < 2) return this;
|
|
5202
|
+
const commonBounds = import_Box.Box.Common(allBounds);
|
|
5203
|
+
let val;
|
|
5204
|
+
let min;
|
|
5205
|
+
let dim;
|
|
5206
|
+
if (operation === "horizontal") {
|
|
5207
|
+
val = "x";
|
|
5208
|
+
min = "minX";
|
|
5209
|
+
dim = "width";
|
|
5210
|
+
} else {
|
|
5211
|
+
val = "y";
|
|
5212
|
+
min = "minY";
|
|
5213
|
+
dim = "height";
|
|
5055
5214
|
}
|
|
5215
|
+
this.run(() => {
|
|
5216
|
+
shapeClustersToStretch.forEach(({ shapes: shapes2, pageBounds }) => {
|
|
5217
|
+
const localOffset = new import_Vec.Vec();
|
|
5218
|
+
localOffset[val] = commonBounds[min] - pageBounds[min];
|
|
5219
|
+
const scaleOrigin = pageBounds.center.clone();
|
|
5220
|
+
scaleOrigin[val] = commonBounds[min];
|
|
5221
|
+
const scale = new import_Vec.Vec(1, 1);
|
|
5222
|
+
scale[val] = commonBounds[dim] / pageBounds[dim];
|
|
5223
|
+
for (const shape of shapes2) {
|
|
5224
|
+
const shapeLocalOffset = localOffset.clone();
|
|
5225
|
+
const parentTransform = this.getShapeParentTransform(shape);
|
|
5226
|
+
if (parentTransform) localOffset.rot(-parentTransform.rotation());
|
|
5227
|
+
shapeLocalOffset.add(shape);
|
|
5228
|
+
const changes = this.getChangesToTranslateShape(shape, shapeLocalOffset);
|
|
5229
|
+
this.updateShape(changes);
|
|
5230
|
+
this.resizeShape(shape.id, scale, {
|
|
5231
|
+
initialBounds: this.getShapeGeometry(shape).bounds,
|
|
5232
|
+
scaleOrigin,
|
|
5233
|
+
isAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),
|
|
5234
|
+
scaleAxisRotation: 0
|
|
5235
|
+
});
|
|
5236
|
+
}
|
|
5237
|
+
});
|
|
5238
|
+
});
|
|
5056
5239
|
return this;
|
|
5057
5240
|
}
|
|
5058
5241
|
/**
|
|
@@ -5067,8 +5250,8 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
5067
5250
|
resizeShape(shape, scale, opts = {}) {
|
|
5068
5251
|
const id = typeof shape === "string" ? shape : shape.id;
|
|
5069
5252
|
if (this.getIsReadonly()) return this;
|
|
5070
|
-
if (!Number.isFinite(scale.x)) scale = new import_Vec.Vec(1, scale.y);
|
|
5071
|
-
if (!Number.isFinite(scale.y)) scale = new import_Vec.Vec(scale.x, 1);
|
|
5253
|
+
if (!import_core_js.Number.isFinite(scale.x)) scale = new import_Vec.Vec(1, scale.y);
|
|
5254
|
+
if (!import_core_js.Number.isFinite(scale.y)) scale = new import_Vec.Vec(scale.x, 1);
|
|
5072
5255
|
const initialShape = opts.initialShape ?? this.getShape(id);
|
|
5073
5256
|
if (!initialShape) return this;
|
|
5074
5257
|
const scaleOrigin = opts.scaleOrigin ?? this.getShapePageBounds(id)?.center;
|
|
@@ -6354,7 +6537,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_
|
|
|
6354
6537
|
switch (withDefaults.format) {
|
|
6355
6538
|
case "svg":
|
|
6356
6539
|
return {
|
|
6357
|
-
blob: new Blob([result.svg], { type: "
|
|
6540
|
+
blob: new Blob([result.svg], { type: "image/svg+xml" }),
|
|
6358
6541
|
width: result.width,
|
|
6359
6542
|
height: result.height
|
|
6360
6543
|
};
|
|
@@ -7301,7 +7484,6 @@ __decorateElement(_init, 1, "getPages", _getPages_dec, Editor);
|
|
|
7301
7484
|
__decorateElement(_init, 1, "getCurrentPageId", _getCurrentPageId_dec, Editor);
|
|
7302
7485
|
__decorateElement(_init, 1, "getCurrentPageShapeIdsSorted", _getCurrentPageShapeIdsSorted_dec, Editor);
|
|
7303
7486
|
__decorateElement(_init, 1, "_getAllAssetsQuery", __getAllAssetsQuery_dec, Editor);
|
|
7304
|
-
__decorateElement(_init, 1, "_getShapeGeometryCache", __getShapeGeometryCache_dec, Editor);
|
|
7305
7487
|
__decorateElement(_init, 1, "_getShapeHandlesCache", __getShapeHandlesCache_dec, Editor);
|
|
7306
7488
|
__decorateElement(_init, 1, "_getShapePageTransformCache", __getShapePageTransformCache_dec, Editor);
|
|
7307
7489
|
__decorateElement(_init, 1, "_getShapePageBoundsCache", __getShapePageBoundsCache_dec, Editor);
|