@tldraw/editor 3.9.0-canary.c8a14268052e → 3.9.0-canary.ce9ba0ae55c6
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 +430 -248
- 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 +426 -244
- 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 +555 -272
- 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
|
@@ -46,7 +46,7 @@ var __privateIn = (member, obj) => Object(obj) !== obj ? __typeError('Cannot use
|
|
|
46
46
|
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
47
47
|
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
48
48
|
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
49
|
-
var __setMetaKeyTimeout_dec, __setCtrlKeyTimeout_dec, __setAltKeyTimeout_dec, __setShiftKeyTimeout_dec, _getIsReadonly_dec, _getIsFocused_dec, _getSharedOpacity_dec, _getSharedStyles_dec, __getSelectionSharedStyles_dec, __getBindingsIndexCache_dec, _getCurrentPageRenderingShapesSorted_dec, _getCurrentPageShapesSorted_dec, _getCurrentPageShapes_dec, _getCurrentPageBounds_dec, _getCulledShapes_dec, __notVisibleShapes_dec, __getShapeMaskedPageBoundsCache_dec, __getShapeMaskCache_dec, __getShapeClipPathCache_dec, __getShapePageBoundsCache_dec, __getShapePageTransformCache_dec, __getShapeHandlesCache_dec,
|
|
49
|
+
var __setMetaKeyTimeout_dec, __setCtrlKeyTimeout_dec, __setAltKeyTimeout_dec, __setShiftKeyTimeout_dec, _getIsReadonly_dec, _getIsFocused_dec, _getSharedOpacity_dec, _getSharedStyles_dec, __getSelectionSharedStyles_dec, __getBindingsIndexCache_dec, _getCurrentPageRenderingShapesSorted_dec, _getCurrentPageShapesSorted_dec, _getCurrentPageShapes_dec, _getCurrentPageBounds_dec, _getCulledShapes_dec, __notVisibleShapes_dec, __getShapeMaskedPageBoundsCache_dec, __getShapeMaskCache_dec, __getShapeClipPathCache_dec, __getShapePageBoundsCache_dec, __getShapePageTransformCache_dec, __getShapeHandlesCache_dec, __getAllAssetsQuery_dec, _getCurrentPageShapeIdsSorted_dec, _getCurrentPageId_dec, _getPages_dec, __getAllPagesQuery_dec, _getRenderingShapes_dec, _getCollaboratorsOnCurrentPage_dec, _getCollaborators_dec, __getCollaboratorsQuery_dec, _getViewportPageBounds_dec, _getViewportScreenCenter_dec, _getViewportScreenBounds_dec, _getZoomLevel_dec, _getCameraForFollowing_dec, _getViewportPageBoundsForFollowing_dec, _getCamera_dec, __unsafe_getCameraId_dec, _getErasingShapes_dec, _getErasingShapeIds_dec, _getHintingShape_dec, _getHintingShapeIds_dec, _getHoveredShape_dec, _getHoveredShapeId_dec, _getEditingShape_dec, _getEditingShapeId_dec, _getFocusedGroup_dec, _getFocusedGroupId_dec, _getSelectionRotatedScreenBounds_dec, _getSelectionRotatedPageBounds_dec, _getSelectionRotation_dec, _getSelectionPageBounds_dec, _getOnlySelectedShape_dec, _getOnlySelectedShapeId_dec, _getSelectedShapes_dec, _getSelectedShapeIds_dec, __getCurrentPageStateId_dec, _getCurrentPageState_dec, __getPageStatesQuery_dec, _getPageStates_dec, _getIsMenuOpen_dec, _getOpenMenus_dec, _getInstanceState_dec, _getDocumentSettings_dec, _getCurrentToolId_dec, _getCurrentTool_dec, _getPath_dec, _getCanRedo_dec, _getCanUndo_dec, _getIsShapeHiddenCache_dec, _a, _init;
|
|
50
50
|
import { EMPTY_ARRAY, atom, computed, react, transact, unsafe__withoutCapture } from "@tldraw/state";
|
|
51
51
|
import {
|
|
52
52
|
reverseRecordsDiff
|
|
@@ -92,6 +92,7 @@ import {
|
|
|
92
92
|
structuredClone,
|
|
93
93
|
uniqueId
|
|
94
94
|
} from "@tldraw/utils";
|
|
95
|
+
import { Number } from "core-js";
|
|
95
96
|
import EventEmitter from "eventemitter3";
|
|
96
97
|
import {
|
|
97
98
|
getSnapshot,
|
|
@@ -122,7 +123,7 @@ import { Vec } from "../primitives/Vec.mjs";
|
|
|
122
123
|
import { EASINGS } from "../primitives/easings.mjs";
|
|
123
124
|
import { Group2d } from "../primitives/geometry/Group2d.mjs";
|
|
124
125
|
import { intersectPolygonPolygon } from "../primitives/intersect.mjs";
|
|
125
|
-
import {
|
|
126
|
+
import { PI, approximately, areAnglesCompatible, clamp, pointInPolygon } from "../primitives/utils.mjs";
|
|
126
127
|
import { SharedStyleMap } from "../utils/SharedStylesMap.mjs";
|
|
127
128
|
import { dataUrlToFile } from "../utils/assets.mjs";
|
|
128
129
|
import { debugFlags } from "../utils/debug-flags.mjs";
|
|
@@ -148,7 +149,7 @@ import { TextManager } from "./managers/TextManager.mjs";
|
|
|
148
149
|
import { TickManager } from "./managers/TickManager.mjs";
|
|
149
150
|
import { UserPreferencesManager } from "./managers/UserPreferencesManager.mjs";
|
|
150
151
|
import { RootState } from "./tools/RootState.mjs";
|
|
151
|
-
class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed], _getCanUndo_dec = [computed], _getCanRedo_dec = [computed], _getPath_dec = [computed], _getCurrentTool_dec = [computed], _getCurrentToolId_dec = [computed], _getDocumentSettings_dec = [computed], _getInstanceState_dec = [computed], _getOpenMenus_dec = [computed], _getIsMenuOpen_dec = [computed], _getPageStates_dec = [computed], __getPageStatesQuery_dec = [computed], _getCurrentPageState_dec = [computed], __getCurrentPageStateId_dec = [computed], _getSelectedShapeIds_dec = [computed], _getSelectedShapes_dec = [computed], _getOnlySelectedShapeId_dec = [computed], _getOnlySelectedShape_dec = [computed], _getSelectionPageBounds_dec = [computed], _getSelectionRotation_dec = [computed], _getSelectionRotatedPageBounds_dec = [computed], _getSelectionRotatedScreenBounds_dec = [computed], _getFocusedGroupId_dec = [computed], _getFocusedGroup_dec = [computed], _getEditingShapeId_dec = [computed], _getEditingShape_dec = [computed], _getHoveredShapeId_dec = [computed], _getHoveredShape_dec = [computed], _getHintingShapeIds_dec = [computed], _getHintingShape_dec = [computed], _getErasingShapeIds_dec = [computed], _getErasingShapes_dec = [computed], __unsafe_getCameraId_dec = [computed], _getCamera_dec = [computed], _getViewportPageBoundsForFollowing_dec = [computed], _getCameraForFollowing_dec = [computed], _getZoomLevel_dec = [computed], _getViewportScreenBounds_dec = [computed], _getViewportScreenCenter_dec = [computed], _getViewportPageBounds_dec = [computed], __getCollaboratorsQuery_dec = [computed], _getCollaborators_dec = [computed], _getCollaboratorsOnCurrentPage_dec = [computed], _getRenderingShapes_dec = [computed], __getAllPagesQuery_dec = [computed], _getPages_dec = [computed], _getCurrentPageId_dec = [computed], _getCurrentPageShapeIdsSorted_dec = [computed], __getAllAssetsQuery_dec = [computed],
|
|
152
|
+
class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed], _getCanUndo_dec = [computed], _getCanRedo_dec = [computed], _getPath_dec = [computed], _getCurrentTool_dec = [computed], _getCurrentToolId_dec = [computed], _getDocumentSettings_dec = [computed], _getInstanceState_dec = [computed], _getOpenMenus_dec = [computed], _getIsMenuOpen_dec = [computed], _getPageStates_dec = [computed], __getPageStatesQuery_dec = [computed], _getCurrentPageState_dec = [computed], __getCurrentPageStateId_dec = [computed], _getSelectedShapeIds_dec = [computed], _getSelectedShapes_dec = [computed], _getOnlySelectedShapeId_dec = [computed], _getOnlySelectedShape_dec = [computed], _getSelectionPageBounds_dec = [computed], _getSelectionRotation_dec = [computed], _getSelectionRotatedPageBounds_dec = [computed], _getSelectionRotatedScreenBounds_dec = [computed], _getFocusedGroupId_dec = [computed], _getFocusedGroup_dec = [computed], _getEditingShapeId_dec = [computed], _getEditingShape_dec = [computed], _getHoveredShapeId_dec = [computed], _getHoveredShape_dec = [computed], _getHintingShapeIds_dec = [computed], _getHintingShape_dec = [computed], _getErasingShapeIds_dec = [computed], _getErasingShapes_dec = [computed], __unsafe_getCameraId_dec = [computed], _getCamera_dec = [computed], _getViewportPageBoundsForFollowing_dec = [computed], _getCameraForFollowing_dec = [computed], _getZoomLevel_dec = [computed], _getViewportScreenBounds_dec = [computed], _getViewportScreenCenter_dec = [computed], _getViewportPageBounds_dec = [computed], __getCollaboratorsQuery_dec = [computed], _getCollaborators_dec = [computed], _getCollaboratorsOnCurrentPage_dec = [computed], _getRenderingShapes_dec = [computed], __getAllPagesQuery_dec = [computed], _getPages_dec = [computed], _getCurrentPageId_dec = [computed], _getCurrentPageShapeIdsSorted_dec = [computed], __getAllAssetsQuery_dec = [computed], __getShapeHandlesCache_dec = [computed], __getShapePageTransformCache_dec = [computed], __getShapePageBoundsCache_dec = [computed], __getShapeClipPathCache_dec = [computed], __getShapeMaskCache_dec = [computed], __getShapeMaskedPageBoundsCache_dec = [computed], __notVisibleShapes_dec = [computed], _getCulledShapes_dec = [computed], _getCurrentPageBounds_dec = [computed], _getCurrentPageShapes_dec = [computed], _getCurrentPageShapesSorted_dec = [computed], _getCurrentPageRenderingShapesSorted_dec = [computed], __getBindingsIndexCache_dec = [computed], __getSelectionSharedStyles_dec = [computed], _getSharedStyles_dec = [computed({ isEqual: (a, b) => a.equals(b) })], _getSharedOpacity_dec = [computed], _getIsFocused_dec = [computed], _getIsReadonly_dec = [computed], __setShiftKeyTimeout_dec = [bind], __setAltKeyTimeout_dec = [bind], __setCtrlKeyTimeout_dec = [bind], __setMetaKeyTimeout_dec = [bind], _a) {
|
|
152
153
|
constructor({
|
|
153
154
|
store,
|
|
154
155
|
user,
|
|
@@ -310,6 +311,8 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
310
311
|
__publicField(this, "_cameraStateTimeoutRemaining", 0);
|
|
311
312
|
/* @internal */
|
|
312
313
|
__publicField(this, "_currentPageShapeIds");
|
|
314
|
+
/* --------------------- Shapes --------------------- */
|
|
315
|
+
__publicField(this, "_shapeGeometryCaches", {});
|
|
313
316
|
// Parents and children
|
|
314
317
|
/**
|
|
315
318
|
* A cache of parents to children.
|
|
@@ -3221,13 +3224,6 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
3221
3224
|
async uploadAsset(asset, file, abortSignal) {
|
|
3222
3225
|
return await this.store.props.assets.upload(asset, file, abortSignal);
|
|
3223
3226
|
}
|
|
3224
|
-
_getShapeGeometryCache() {
|
|
3225
|
-
return this.store.createComputedCache(
|
|
3226
|
-
"bounds",
|
|
3227
|
-
(shape) => this.getShapeUtil(shape).getGeometry(shape),
|
|
3228
|
-
(a, b) => a.props === b.props
|
|
3229
|
-
);
|
|
3230
|
-
}
|
|
3231
3227
|
/**
|
|
3232
3228
|
* Get the geometry of a shape.
|
|
3233
3229
|
*
|
|
@@ -3235,14 +3231,26 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
3235
3231
|
* ```ts
|
|
3236
3232
|
* editor.getShapeGeometry(myShape)
|
|
3237
3233
|
* editor.getShapeGeometry(myShapeId)
|
|
3234
|
+
* editor.getShapeGeometry(myShapeId, { context: "arrow" })
|
|
3238
3235
|
* ```
|
|
3239
3236
|
*
|
|
3240
3237
|
* @param shape - The shape (or shape id) to get the geometry for.
|
|
3238
|
+
* @param opts - Additional options about the request for geometry. Passed to {@link ShapeUtil.getGeometry}.
|
|
3241
3239
|
*
|
|
3242
3240
|
* @public
|
|
3243
3241
|
*/
|
|
3244
|
-
getShapeGeometry(shape) {
|
|
3245
|
-
|
|
3242
|
+
getShapeGeometry(shape, opts) {
|
|
3243
|
+
const context = opts?.context ?? "none";
|
|
3244
|
+
if (!this._shapeGeometryCaches[context]) {
|
|
3245
|
+
this._shapeGeometryCaches[context] = this.store.createComputedCache(
|
|
3246
|
+
"bounds",
|
|
3247
|
+
(shape2) => this.getShapeUtil(shape2).getGeometry(shape2, opts),
|
|
3248
|
+
(a, b) => a.props === b.props
|
|
3249
|
+
);
|
|
3250
|
+
}
|
|
3251
|
+
return this._shapeGeometryCaches[context].get(
|
|
3252
|
+
typeof shape === "string" ? shape : shape.id
|
|
3253
|
+
);
|
|
3246
3254
|
}
|
|
3247
3255
|
_getShapeHandlesCache() {
|
|
3248
3256
|
return this.store.createComputedCache("handles", (shape) => {
|
|
@@ -4308,27 +4316,28 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
4308
4316
|
});
|
|
4309
4317
|
return this;
|
|
4310
4318
|
}
|
|
4319
|
+
// Gets a shape partial that includes life cycle changes: on translate start, on translate, on translate end
|
|
4311
4320
|
getChangesToTranslateShape(initialShape, newShapeCoords) {
|
|
4312
4321
|
let workingShape = initialShape;
|
|
4313
4322
|
const util = this.getShapeUtil(initialShape);
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
|
|
4323
|
+
const afterTranslateStart = util.onTranslateStart?.(workingShape);
|
|
4324
|
+
if (afterTranslateStart) {
|
|
4325
|
+
workingShape = applyPartialToRecordWithProps(workingShape, afterTranslateStart);
|
|
4326
|
+
}
|
|
4318
4327
|
workingShape = applyPartialToRecordWithProps(workingShape, {
|
|
4319
4328
|
id: initialShape.id,
|
|
4320
4329
|
type: initialShape.type,
|
|
4321
4330
|
x: newShapeCoords.x,
|
|
4322
4331
|
y: newShapeCoords.y
|
|
4323
4332
|
});
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4333
|
+
const afterTranslate = util.onTranslate?.(initialShape, workingShape);
|
|
4334
|
+
if (afterTranslate) {
|
|
4335
|
+
workingShape = applyPartialToRecordWithProps(workingShape, afterTranslate);
|
|
4336
|
+
}
|
|
4337
|
+
const afterTranslateEnd = util.onTranslateEnd?.(initialShape, workingShape);
|
|
4338
|
+
if (afterTranslateEnd) {
|
|
4339
|
+
workingShape = applyPartialToRecordWithProps(workingShape, afterTranslateEnd);
|
|
4340
|
+
}
|
|
4332
4341
|
return workingShape;
|
|
4333
4342
|
}
|
|
4334
4343
|
/**
|
|
@@ -4635,6 +4644,30 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
4635
4644
|
if (changes) this.updateShapes(changes);
|
|
4636
4645
|
return this;
|
|
4637
4646
|
}
|
|
4647
|
+
/**
|
|
4648
|
+
* @internal
|
|
4649
|
+
*/
|
|
4650
|
+
collectShapesViaArrowBindings(info) {
|
|
4651
|
+
const { initialShapes, resultShapes, resultBounds, bindings, visited } = info;
|
|
4652
|
+
for (const binding of bindings) {
|
|
4653
|
+
for (const id of [binding.fromId, binding.toId]) {
|
|
4654
|
+
if (!visited.has(id)) {
|
|
4655
|
+
const aligningShape = initialShapes.find((s) => s.id === id);
|
|
4656
|
+
if (aligningShape && !visited.has(aligningShape.id)) {
|
|
4657
|
+
visited.add(aligningShape.id);
|
|
4658
|
+
const shapePageBounds = this.getShapePageBounds(aligningShape);
|
|
4659
|
+
if (!shapePageBounds) continue;
|
|
4660
|
+
resultShapes.push(aligningShape);
|
|
4661
|
+
resultBounds.push(shapePageBounds);
|
|
4662
|
+
this.collectShapesViaArrowBindings({
|
|
4663
|
+
...info,
|
|
4664
|
+
bindings: this.getBindingsInvolvingShape(aligningShape, "arrow")
|
|
4665
|
+
});
|
|
4666
|
+
}
|
|
4667
|
+
}
|
|
4668
|
+
}
|
|
4669
|
+
}
|
|
4670
|
+
}
|
|
4638
4671
|
/**
|
|
4639
4672
|
* Flip shape positions.
|
|
4640
4673
|
*
|
|
@@ -4650,35 +4683,52 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
4650
4683
|
* @public
|
|
4651
4684
|
*/
|
|
4652
4685
|
flipShapes(shapes, operation) {
|
|
4653
|
-
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4654
4686
|
if (this.getIsReadonly()) return this;
|
|
4655
|
-
|
|
4687
|
+
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4688
|
+
const shapesToFlipFirstPass = compact(ids.map((id) => this.getShape(id)));
|
|
4689
|
+
for (const shape of shapesToFlipFirstPass) {
|
|
4690
|
+
if (this.isShapeOfType(shape, "group")) {
|
|
4691
|
+
const childrenOfGroups = compact(
|
|
4692
|
+
this.getSortedChildIdsForParent(shape.id).map((id) => this.getShape(id))
|
|
4693
|
+
);
|
|
4694
|
+
shapesToFlipFirstPass.push(...childrenOfGroups);
|
|
4695
|
+
}
|
|
4696
|
+
}
|
|
4697
|
+
const shapesToFlip = [];
|
|
4698
|
+
const allBounds = [];
|
|
4699
|
+
for (const shape of shapesToFlipFirstPass) {
|
|
4700
|
+
const util = this.getShapeUtil(shape);
|
|
4701
|
+
if (!util.canBeLaidOut(shape, {
|
|
4702
|
+
type: "flip",
|
|
4703
|
+
shapes: shapesToFlipFirstPass
|
|
4704
|
+
})) {
|
|
4705
|
+
continue;
|
|
4706
|
+
}
|
|
4707
|
+
const pageBounds = this.getShapePageBounds(shape);
|
|
4708
|
+
const localBounds = this.getShapeGeometry(shape).bounds;
|
|
4709
|
+
const pageTransform = this.getShapePageTransform(shape.id);
|
|
4710
|
+
if (!(pageBounds && localBounds && pageTransform)) continue;
|
|
4711
|
+
shapesToFlip.push({
|
|
4712
|
+
shape,
|
|
4713
|
+
localBounds,
|
|
4714
|
+
pageTransform,
|
|
4715
|
+
isAspectRatioLocked: util.isAspectRatioLocked(shape)
|
|
4716
|
+
});
|
|
4717
|
+
allBounds.push(pageBounds);
|
|
4718
|
+
}
|
|
4656
4719
|
if (!shapesToFlip.length) return this;
|
|
4657
|
-
|
|
4658
|
-
shapesToFlip.map((shape) => {
|
|
4659
|
-
if (this.isShapeOfType(shape, "group")) {
|
|
4660
|
-
return this.getSortedChildIdsForParent(shape.id).map((id) => this.getShape(id));
|
|
4661
|
-
}
|
|
4662
|
-
return shape;
|
|
4663
|
-
}).flat()
|
|
4664
|
-
);
|
|
4665
|
-
const scaleOriginPage = Box.Common(
|
|
4666
|
-
compact(shapesToFlip.map((id) => this.getShapePageBounds(id)))
|
|
4667
|
-
).center;
|
|
4720
|
+
const scaleOriginPage = Box.Common(allBounds).center;
|
|
4668
4721
|
this.run(() => {
|
|
4669
|
-
for (const shape of shapesToFlip) {
|
|
4670
|
-
const bounds = this.getShapeGeometry(shape).bounds;
|
|
4671
|
-
const initialPageTransform = this.getShapePageTransform(shape.id);
|
|
4672
|
-
if (!initialPageTransform) continue;
|
|
4722
|
+
for (const { shape, localBounds, pageTransform, isAspectRatioLocked } of shapesToFlip) {
|
|
4673
4723
|
this.resizeShape(
|
|
4674
4724
|
shape.id,
|
|
4675
4725
|
{ x: operation === "horizontal" ? -1 : 1, y: operation === "vertical" ? -1 : 1 },
|
|
4676
4726
|
{
|
|
4677
|
-
initialBounds:
|
|
4678
|
-
initialPageTransform,
|
|
4727
|
+
initialBounds: localBounds,
|
|
4728
|
+
initialPageTransform: pageTransform,
|
|
4679
4729
|
initialShape: shape,
|
|
4730
|
+
isAspectRatioLocked,
|
|
4680
4731
|
mode: "scale_shape",
|
|
4681
|
-
isAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),
|
|
4682
4732
|
scaleOrigin: scaleOriginPage,
|
|
4683
4733
|
scaleAxisRotation: 0
|
|
4684
4734
|
}
|
|
@@ -4705,15 +4755,40 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
4705
4755
|
stackShapes(shapes, operation, gap) {
|
|
4706
4756
|
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4707
4757
|
if (this.getIsReadonly()) return this;
|
|
4708
|
-
const
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
const
|
|
4758
|
+
const shapesToStackFirstPass = compact(ids.map((id) => this.getShape(id)));
|
|
4759
|
+
const shapeClustersToStack = [];
|
|
4760
|
+
const allBounds = [];
|
|
4761
|
+
const visited = /* @__PURE__ */ new Set();
|
|
4762
|
+
for (const shape of shapesToStackFirstPass) {
|
|
4763
|
+
if (visited.has(shape.id)) continue;
|
|
4764
|
+
visited.add(shape.id);
|
|
4765
|
+
const shapePageBounds = this.getShapePageBounds(shape);
|
|
4766
|
+
if (!shapePageBounds) continue;
|
|
4767
|
+
if (!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
4768
|
+
type: "stack",
|
|
4769
|
+
shapes: shapesToStackFirstPass
|
|
4770
|
+
})) {
|
|
4771
|
+
continue;
|
|
4772
|
+
}
|
|
4773
|
+
const shapesMovingTogether = [shape];
|
|
4774
|
+
const boundsOfShapesMovingTogether = [shapePageBounds];
|
|
4775
|
+
this.collectShapesViaArrowBindings({
|
|
4776
|
+
bindings: this.getBindingsToShape(shape.id, "arrow"),
|
|
4777
|
+
initialShapes: shapesToStackFirstPass,
|
|
4778
|
+
resultShapes: shapesMovingTogether,
|
|
4779
|
+
resultBounds: boundsOfShapesMovingTogether,
|
|
4780
|
+
visited
|
|
4781
|
+
});
|
|
4782
|
+
const commonPageBounds = Box.Common(boundsOfShapesMovingTogether);
|
|
4783
|
+
if (!commonPageBounds) continue;
|
|
4784
|
+
shapeClustersToStack.push({
|
|
4785
|
+
shapes: shapesMovingTogether,
|
|
4786
|
+
pageBounds: commonPageBounds
|
|
4787
|
+
});
|
|
4788
|
+
allBounds.push(commonPageBounds);
|
|
4789
|
+
}
|
|
4790
|
+
const len = shapeClustersToStack.length;
|
|
4713
4791
|
if (gap === 0 && len < 3 || len < 2) return this;
|
|
4714
|
-
const pageBounds = Object.fromEntries(
|
|
4715
|
-
shapesToStack.map((shape) => [shape.id, this.getShapePageBounds(shape)])
|
|
4716
|
-
);
|
|
4717
4792
|
let val;
|
|
4718
4793
|
let min;
|
|
4719
4794
|
let max;
|
|
@@ -4729,57 +4804,55 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
4729
4804
|
max = "maxY";
|
|
4730
4805
|
dim = "height";
|
|
4731
4806
|
}
|
|
4732
|
-
let shapeGap;
|
|
4807
|
+
let shapeGap = 0;
|
|
4733
4808
|
if (gap === 0) {
|
|
4734
|
-
const gaps =
|
|
4735
|
-
|
|
4809
|
+
const gaps = {};
|
|
4810
|
+
shapeClustersToStack.sort((a, b) => a.pageBounds[min] - b.pageBounds[min]);
|
|
4736
4811
|
for (let i = 0; i < len - 1; i++) {
|
|
4737
|
-
const
|
|
4738
|
-
const
|
|
4739
|
-
const
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
const current = gaps.find((g) => g.gap === gap2);
|
|
4743
|
-
if (current) {
|
|
4744
|
-
current.count++;
|
|
4745
|
-
} else {
|
|
4746
|
-
gaps.push({ gap: gap2, count: 1 });
|
|
4812
|
+
const currCluster = shapeClustersToStack[i];
|
|
4813
|
+
const nextCluster = shapeClustersToStack[i + 1];
|
|
4814
|
+
const gap2 = nextCluster.pageBounds[min] - currCluster.pageBounds[max];
|
|
4815
|
+
if (!gaps[gap2]) {
|
|
4816
|
+
gaps[gap2] = 0;
|
|
4747
4817
|
}
|
|
4818
|
+
gaps[gap2]++;
|
|
4748
4819
|
}
|
|
4749
|
-
let maxCount =
|
|
4750
|
-
|
|
4751
|
-
if (
|
|
4752
|
-
maxCount =
|
|
4753
|
-
shapeGap =
|
|
4820
|
+
let maxCount = 1;
|
|
4821
|
+
for (const [gap2, count] of Object.entries(gaps)) {
|
|
4822
|
+
if (count > maxCount) {
|
|
4823
|
+
maxCount = count;
|
|
4824
|
+
shapeGap = parseFloat(gap2);
|
|
4754
4825
|
}
|
|
4755
|
-
}
|
|
4826
|
+
}
|
|
4756
4827
|
if (maxCount === 1) {
|
|
4757
|
-
|
|
4828
|
+
let totalCount = 0;
|
|
4829
|
+
for (const [gap2, count] of Object.entries(gaps)) {
|
|
4830
|
+
shapeGap += parseFloat(gap2) * count;
|
|
4831
|
+
totalCount += count;
|
|
4832
|
+
}
|
|
4833
|
+
shapeGap /= totalCount;
|
|
4758
4834
|
}
|
|
4759
4835
|
} else {
|
|
4760
4836
|
shapeGap = gap;
|
|
4761
4837
|
}
|
|
4762
4838
|
const changes = [];
|
|
4763
|
-
let v =
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
const delta =
|
|
4767
|
-
delta[val] = v + shapeGap - pageBounds[
|
|
4768
|
-
const
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
[val]: shape[val] + localDelta[val]
|
|
4775
|
-
} : {
|
|
4776
|
-
id: shape.id,
|
|
4777
|
-
type: shape.type,
|
|
4778
|
-
[val]: shape[val] + localDelta[val]
|
|
4839
|
+
let v = shapeClustersToStack[0].pageBounds[max];
|
|
4840
|
+
for (let i = 1; i < shapeClustersToStack.length; i++) {
|
|
4841
|
+
const { shapes: shapes2, pageBounds } = shapeClustersToStack[i];
|
|
4842
|
+
const delta = new Vec();
|
|
4843
|
+
delta[val] = v + shapeGap - pageBounds[val];
|
|
4844
|
+
for (const shape of shapes2) {
|
|
4845
|
+
const shapeDelta = delta.clone();
|
|
4846
|
+
const parent = this.getShapeParent(shape);
|
|
4847
|
+
if (parent) {
|
|
4848
|
+
const parentTransform = this.getShapePageTransform(parent);
|
|
4849
|
+
if (parentTransform) shapeDelta.rot(-parentTransform.rotation());
|
|
4779
4850
|
}
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4851
|
+
shapeDelta.add(shape);
|
|
4852
|
+
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
4853
|
+
}
|
|
4854
|
+
v += pageBounds[dim] + shapeGap;
|
|
4855
|
+
}
|
|
4783
4856
|
this.updateShapes(changes);
|
|
4784
4857
|
return this;
|
|
4785
4858
|
}
|
|
@@ -4797,91 +4870,101 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
4797
4870
|
* @param gap - The padding to apply to the packed shapes. Defaults to 16.
|
|
4798
4871
|
*/
|
|
4799
4872
|
packShapes(shapes, gap) {
|
|
4800
|
-
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4801
4873
|
if (this.getIsReadonly()) return this;
|
|
4802
|
-
|
|
4803
|
-
const
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
const
|
|
4808
|
-
|
|
4809
|
-
|
|
4810
|
-
|
|
4811
|
-
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
|
|
4874
|
+
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4875
|
+
const shapesToPackFirstPass = compact(ids.map((id) => this.getShape(id)));
|
|
4876
|
+
const shapeClustersToPack = [];
|
|
4877
|
+
const allBounds = [];
|
|
4878
|
+
const visited = /* @__PURE__ */ new Set();
|
|
4879
|
+
for (const shape of shapesToPackFirstPass) {
|
|
4880
|
+
if (visited.has(shape.id)) continue;
|
|
4881
|
+
visited.add(shape.id);
|
|
4882
|
+
const shapePageBounds = this.getShapePageBounds(shape);
|
|
4883
|
+
if (!shapePageBounds) continue;
|
|
4884
|
+
if (!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
4885
|
+
type: "pack",
|
|
4886
|
+
shapes: shapesToPackFirstPass
|
|
4887
|
+
})) {
|
|
4888
|
+
continue;
|
|
4889
|
+
}
|
|
4890
|
+
const shapesMovingTogether = [shape];
|
|
4891
|
+
const boundsOfShapesMovingTogether = [shapePageBounds];
|
|
4892
|
+
this.collectShapesViaArrowBindings({
|
|
4893
|
+
bindings: this.getBindingsToShape(shape.id, "arrow"),
|
|
4894
|
+
initialShapes: shapesToPackFirstPass,
|
|
4895
|
+
resultShapes: shapesMovingTogether,
|
|
4896
|
+
resultBounds: boundsOfShapesMovingTogether,
|
|
4897
|
+
visited
|
|
4898
|
+
});
|
|
4899
|
+
const commonPageBounds = Box.Common(boundsOfShapesMovingTogether);
|
|
4900
|
+
if (!commonPageBounds) continue;
|
|
4901
|
+
shapeClustersToPack.push({
|
|
4902
|
+
shapes: shapesMovingTogether,
|
|
4903
|
+
pageBounds: commonPageBounds,
|
|
4904
|
+
nextPageBounds: commonPageBounds.clone()
|
|
4905
|
+
});
|
|
4906
|
+
allBounds.push(commonPageBounds);
|
|
4907
|
+
}
|
|
4908
|
+
if (shapeClustersToPack.length < 2) return this;
|
|
4909
|
+
let area = 0;
|
|
4910
|
+
for (const { pageBounds } of shapeClustersToPack) {
|
|
4911
|
+
area += pageBounds.width * pageBounds.height;
|
|
4912
|
+
}
|
|
4913
|
+
const commonBounds = Box.Common(allBounds);
|
|
4818
4914
|
const maxWidth = commonBounds.width;
|
|
4819
|
-
|
|
4915
|
+
shapeClustersToPack.sort((a, b) => a.pageBounds.width - b.pageBounds.width).sort((a, b) => a.pageBounds.height - b.pageBounds.height);
|
|
4820
4916
|
const startWidth = Math.max(Math.ceil(Math.sqrt(area / 0.95)), maxWidth);
|
|
4821
4917
|
const spaces = [new Box(commonBounds.x, commonBounds.y, startWidth, Infinity)];
|
|
4822
4918
|
let width = 0;
|
|
4823
4919
|
let height = 0;
|
|
4824
4920
|
let space;
|
|
4825
4921
|
let last2;
|
|
4826
|
-
for (
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
width = Math.max(width, bounds.maxX);
|
|
4836
|
-
if (bounds.width === space.width && bounds.height === space.height) {
|
|
4922
|
+
for (const { nextPageBounds } of shapeClustersToPack) {
|
|
4923
|
+
for (let i = spaces.length - 1; i >= 0; i--) {
|
|
4924
|
+
space = spaces[i];
|
|
4925
|
+
if (nextPageBounds.width > space.width || nextPageBounds.height > space.height) continue;
|
|
4926
|
+
nextPageBounds.x = space.x;
|
|
4927
|
+
nextPageBounds.y = space.y;
|
|
4928
|
+
height = Math.max(height, nextPageBounds.maxY);
|
|
4929
|
+
width = Math.max(width, nextPageBounds.maxX);
|
|
4930
|
+
if (nextPageBounds.width === space.width && nextPageBounds.height === space.height) {
|
|
4837
4931
|
last2 = spaces.pop();
|
|
4838
|
-
if (
|
|
4839
|
-
} else if (
|
|
4840
|
-
space.x +=
|
|
4841
|
-
space.width -=
|
|
4842
|
-
} else if (
|
|
4843
|
-
space.y +=
|
|
4844
|
-
space.height -=
|
|
4932
|
+
if (i < spaces.length) spaces[i] = last2;
|
|
4933
|
+
} else if (nextPageBounds.height === space.height) {
|
|
4934
|
+
space.x += nextPageBounds.width + gap;
|
|
4935
|
+
space.width -= nextPageBounds.width + gap;
|
|
4936
|
+
} else if (nextPageBounds.width === space.width) {
|
|
4937
|
+
space.y += nextPageBounds.height + gap;
|
|
4938
|
+
space.height -= nextPageBounds.height + gap;
|
|
4845
4939
|
} else {
|
|
4846
4940
|
spaces.push(
|
|
4847
4941
|
new Box(
|
|
4848
|
-
space.x + (
|
|
4942
|
+
space.x + (nextPageBounds.width + gap),
|
|
4849
4943
|
space.y,
|
|
4850
|
-
space.width - (
|
|
4851
|
-
|
|
4944
|
+
space.width - (nextPageBounds.width + gap),
|
|
4945
|
+
nextPageBounds.height
|
|
4852
4946
|
)
|
|
4853
4947
|
);
|
|
4854
|
-
space.y +=
|
|
4855
|
-
space.height -=
|
|
4948
|
+
space.y += nextPageBounds.height + gap;
|
|
4949
|
+
space.height -= nextPageBounds.height + gap;
|
|
4856
4950
|
}
|
|
4857
4951
|
break;
|
|
4858
4952
|
}
|
|
4859
4953
|
}
|
|
4860
|
-
const commonAfter = Box.Common(
|
|
4954
|
+
const commonAfter = Box.Common(shapeClustersToPack.map((s) => s.nextPageBounds));
|
|
4861
4955
|
const centerDelta = Vec.Sub(commonBounds.center, commonAfter.center);
|
|
4862
|
-
let nextBounds;
|
|
4863
4956
|
const changes = [];
|
|
4864
|
-
for (
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
y: shape.y + delta.y
|
|
4876
|
-
};
|
|
4877
|
-
const translateStartChange = this.getShapeUtil(shape).onTranslateStart?.({
|
|
4878
|
-
...shape,
|
|
4879
|
-
...change
|
|
4880
|
-
});
|
|
4881
|
-
if (translateStartChange) {
|
|
4882
|
-
changes.push({ ...change, ...translateStartChange });
|
|
4883
|
-
} else {
|
|
4884
|
-
changes.push(change);
|
|
4957
|
+
for (const { shapes: shapes2, pageBounds, nextPageBounds } of shapeClustersToPack) {
|
|
4958
|
+
const delta = Vec.Sub(nextPageBounds.point, pageBounds.point).add(centerDelta);
|
|
4959
|
+
for (const shape of shapes2) {
|
|
4960
|
+
const shapeDelta = delta.clone();
|
|
4961
|
+
const parent = this.getShapeParent(shape);
|
|
4962
|
+
if (parent) {
|
|
4963
|
+
const parentTransform = this.getShapeParentTransform(shape);
|
|
4964
|
+
if (parentTransform) shapeDelta.rot(-parentTransform.rotation());
|
|
4965
|
+
}
|
|
4966
|
+
shapeDelta.add(shape);
|
|
4967
|
+
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
4885
4968
|
}
|
|
4886
4969
|
}
|
|
4887
4970
|
if (changes.length) {
|
|
@@ -4904,19 +4987,45 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
4904
4987
|
* @public
|
|
4905
4988
|
*/
|
|
4906
4989
|
alignShapes(shapes, operation) {
|
|
4907
|
-
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4908
4990
|
if (this.getIsReadonly()) return this;
|
|
4909
|
-
|
|
4910
|
-
const
|
|
4911
|
-
const
|
|
4912
|
-
|
|
4913
|
-
);
|
|
4914
|
-
const
|
|
4991
|
+
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4992
|
+
const shapesToAlignFirstPass = compact(ids.map((id) => this.getShape(id)));
|
|
4993
|
+
const shapeClustersToAlign = [];
|
|
4994
|
+
const allBounds = [];
|
|
4995
|
+
const visited = /* @__PURE__ */ new Set();
|
|
4996
|
+
for (const shape of shapesToAlignFirstPass) {
|
|
4997
|
+
if (visited.has(shape.id)) continue;
|
|
4998
|
+
visited.add(shape.id);
|
|
4999
|
+
const shapePageBounds = this.getShapePageBounds(shape);
|
|
5000
|
+
if (!shapePageBounds) continue;
|
|
5001
|
+
if (!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
5002
|
+
type: "align",
|
|
5003
|
+
shapes: shapesToAlignFirstPass
|
|
5004
|
+
})) {
|
|
5005
|
+
continue;
|
|
5006
|
+
}
|
|
5007
|
+
const shapesMovingTogether = [shape];
|
|
5008
|
+
const boundsOfShapesMovingTogether = [shapePageBounds];
|
|
5009
|
+
this.collectShapesViaArrowBindings({
|
|
5010
|
+
bindings: this.getBindingsToShape(shape.id, "arrow"),
|
|
5011
|
+
initialShapes: shapesToAlignFirstPass,
|
|
5012
|
+
resultShapes: shapesMovingTogether,
|
|
5013
|
+
resultBounds: boundsOfShapesMovingTogether,
|
|
5014
|
+
visited
|
|
5015
|
+
});
|
|
5016
|
+
const commonPageBounds = Box.Common(boundsOfShapesMovingTogether);
|
|
5017
|
+
if (!commonPageBounds) continue;
|
|
5018
|
+
shapeClustersToAlign.push({
|
|
5019
|
+
shapes: shapesMovingTogether,
|
|
5020
|
+
pageBounds: commonPageBounds
|
|
5021
|
+
});
|
|
5022
|
+
allBounds.push(commonPageBounds);
|
|
5023
|
+
}
|
|
5024
|
+
if (shapeClustersToAlign.length < 2) return this;
|
|
5025
|
+
const commonBounds = Box.Common(allBounds);
|
|
4915
5026
|
const changes = [];
|
|
4916
|
-
|
|
4917
|
-
const
|
|
4918
|
-
if (!pageBounds) return;
|
|
4919
|
-
const delta = { x: 0, y: 0 };
|
|
5027
|
+
shapeClustersToAlign.forEach(({ shapes: shapes2, pageBounds }) => {
|
|
5028
|
+
const delta = new Vec();
|
|
4920
5029
|
switch (operation) {
|
|
4921
5030
|
case "top": {
|
|
4922
5031
|
delta.y = commonBounds.minY - pageBounds.minY;
|
|
@@ -4943,9 +5052,16 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
4943
5052
|
break;
|
|
4944
5053
|
}
|
|
4945
5054
|
}
|
|
4946
|
-
const
|
|
4947
|
-
|
|
4948
|
-
|
|
5055
|
+
for (const shape of shapes2) {
|
|
5056
|
+
const shapeDelta = delta.clone();
|
|
5057
|
+
const parent = this.getShapeParent(shape);
|
|
5058
|
+
if (parent) {
|
|
5059
|
+
const parentTransform = this.getShapePageTransform(parent);
|
|
5060
|
+
if (parentTransform) shapeDelta.rot(-parentTransform.rotation());
|
|
5061
|
+
}
|
|
5062
|
+
shapeDelta.add(shape);
|
|
5063
|
+
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
5064
|
+
}
|
|
4949
5065
|
});
|
|
4950
5066
|
this.updateShapes(changes);
|
|
4951
5067
|
return this;
|
|
@@ -4965,47 +5081,95 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
4965
5081
|
* @public
|
|
4966
5082
|
*/
|
|
4967
5083
|
distributeShapes(shapes, operation) {
|
|
4968
|
-
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
4969
5084
|
if (this.getIsReadonly()) return this;
|
|
4970
|
-
|
|
4971
|
-
const
|
|
4972
|
-
const
|
|
4973
|
-
const
|
|
4974
|
-
|
|
4975
|
-
)
|
|
5085
|
+
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
5086
|
+
const shapesToDistributeFirstPass = compact(ids.map((id) => this.getShape(id)));
|
|
5087
|
+
const shapeClustersToDistribute = [];
|
|
5088
|
+
const allBounds = [];
|
|
5089
|
+
const visited = /* @__PURE__ */ new Set();
|
|
5090
|
+
for (const shape of shapesToDistributeFirstPass) {
|
|
5091
|
+
if (visited.has(shape.id)) continue;
|
|
5092
|
+
visited.add(shape.id);
|
|
5093
|
+
const shapePageBounds = this.getShapePageBounds(shape);
|
|
5094
|
+
if (!shapePageBounds) continue;
|
|
5095
|
+
if (!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
5096
|
+
type: "distribute",
|
|
5097
|
+
shapes: shapesToDistributeFirstPass
|
|
5098
|
+
})) {
|
|
5099
|
+
continue;
|
|
5100
|
+
}
|
|
5101
|
+
const shapesMovingTogether = [shape];
|
|
5102
|
+
const boundsOfShapesMovingTogether = [shapePageBounds];
|
|
5103
|
+
this.collectShapesViaArrowBindings({
|
|
5104
|
+
bindings: this.getBindingsToShape(shape.id, "arrow"),
|
|
5105
|
+
initialShapes: shapesToDistributeFirstPass,
|
|
5106
|
+
resultShapes: shapesMovingTogether,
|
|
5107
|
+
resultBounds: boundsOfShapesMovingTogether,
|
|
5108
|
+
visited
|
|
5109
|
+
});
|
|
5110
|
+
const commonPageBounds = Box.Common(boundsOfShapesMovingTogether);
|
|
5111
|
+
if (!commonPageBounds) continue;
|
|
5112
|
+
shapeClustersToDistribute.push({
|
|
5113
|
+
shapes: shapesMovingTogether,
|
|
5114
|
+
pageBounds: commonPageBounds
|
|
5115
|
+
});
|
|
5116
|
+
allBounds.push(commonPageBounds);
|
|
5117
|
+
}
|
|
5118
|
+
if (shapeClustersToDistribute.length < 3) return this;
|
|
4976
5119
|
let val;
|
|
4977
5120
|
let min;
|
|
4978
5121
|
let max;
|
|
4979
|
-
let mid;
|
|
4980
5122
|
let dim;
|
|
4981
5123
|
if (operation === "horizontal") {
|
|
4982
5124
|
val = "x";
|
|
4983
5125
|
min = "minX";
|
|
4984
5126
|
max = "maxX";
|
|
4985
|
-
mid = "midX";
|
|
4986
5127
|
dim = "width";
|
|
4987
5128
|
} else {
|
|
4988
5129
|
val = "y";
|
|
4989
5130
|
min = "minY";
|
|
4990
5131
|
max = "maxY";
|
|
4991
|
-
mid = "midY";
|
|
4992
5132
|
dim = "height";
|
|
4993
5133
|
}
|
|
4994
5134
|
const changes = [];
|
|
4995
|
-
const first =
|
|
4996
|
-
|
|
4997
|
-
)
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5135
|
+
const first = shapeClustersToDistribute.sort((a, b) => a.pageBounds[min] - b.pageBounds[min])[0];
|
|
5136
|
+
const last2 = shapeClustersToDistribute.sort((a, b) => b.pageBounds[max] - a.pageBounds[max])[0];
|
|
5137
|
+
if (first === last2) {
|
|
5138
|
+
const excludedShapeIds = new Set(first.shapes.map((s) => s.id));
|
|
5139
|
+
return this.distributeShapes(
|
|
5140
|
+
ids.filter((id) => !excludedShapeIds.has(id)),
|
|
5141
|
+
operation
|
|
5142
|
+
);
|
|
5143
|
+
}
|
|
5144
|
+
const shapeClustersToMove = shapeClustersToDistribute.filter((shape) => shape !== first && shape !== last2).sort((a, b) => {
|
|
5145
|
+
if (a.pageBounds[min] === b.pageBounds[min]) {
|
|
5146
|
+
return a.shapes[0].id < b.shapes[0].id ? -1 : 1;
|
|
5147
|
+
}
|
|
5148
|
+
return a.pageBounds[min] - b.pageBounds[min];
|
|
5008
5149
|
});
|
|
5150
|
+
const maxFirst = first.pageBounds[max];
|
|
5151
|
+
const range = last2.pageBounds[min] - maxFirst;
|
|
5152
|
+
const summedShapeDimensions = shapeClustersToMove.reduce((acc, s) => acc + s.pageBounds[dim], 0);
|
|
5153
|
+
const gap = (range - summedShapeDimensions) / (shapeClustersToMove.length + 1);
|
|
5154
|
+
for (let v = maxFirst + gap, i = 0; i < shapeClustersToMove.length; i++) {
|
|
5155
|
+
const { shapes: shapes2, pageBounds } = shapeClustersToMove[i];
|
|
5156
|
+
const delta = new Vec();
|
|
5157
|
+
delta[val] = v - pageBounds[val];
|
|
5158
|
+
if (v + pageBounds[dim] > last2.pageBounds[max] - 1) {
|
|
5159
|
+
delta[val] = last2.pageBounds[max] - pageBounds[max] - 1;
|
|
5160
|
+
}
|
|
5161
|
+
for (const shape of shapes2) {
|
|
5162
|
+
const shapeDelta = delta.clone();
|
|
5163
|
+
const parent = this.getShapeParent(shape);
|
|
5164
|
+
if (parent) {
|
|
5165
|
+
const parentTransform = this.getShapePageTransform(parent);
|
|
5166
|
+
if (parentTransform) shapeDelta.rot(-parentTransform.rotation());
|
|
5167
|
+
}
|
|
5168
|
+
shapeDelta.add(shape);
|
|
5169
|
+
changes.push(this.getChangesToTranslateShape(shape, shapeDelta));
|
|
5170
|
+
}
|
|
5171
|
+
v += pageBounds[dim] + gap;
|
|
5172
|
+
}
|
|
5009
5173
|
this.updateShapes(changes);
|
|
5010
5174
|
return this;
|
|
5011
5175
|
}
|
|
@@ -5026,59 +5190,78 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
|
|
|
5026
5190
|
stretchShapes(shapes, operation) {
|
|
5027
5191
|
const ids = typeof shapes[0] === "string" ? shapes : shapes.map((s) => s.id);
|
|
5028
5192
|
if (this.getIsReadonly()) return this;
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
|
|
5032
|
-
const
|
|
5033
|
-
const
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
const scale = new Vec(1, commonBounds.height / pageBounds.height);
|
|
5048
|
-
this.resizeShape(shape.id, scale, {
|
|
5049
|
-
initialBounds: bounds,
|
|
5050
|
-
scaleOrigin: new Vec(pageBounds.center.x, commonBounds.minY),
|
|
5051
|
-
isAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),
|
|
5052
|
-
scaleAxisRotation: 0
|
|
5053
|
-
});
|
|
5054
|
-
}
|
|
5055
|
-
});
|
|
5056
|
-
break;
|
|
5057
|
-
}
|
|
5058
|
-
case "horizontal": {
|
|
5059
|
-
this.run(() => {
|
|
5060
|
-
for (const shape of shapesToStretch) {
|
|
5061
|
-
const bounds = shapeBounds[shape.id];
|
|
5062
|
-
const pageBounds = shapePageBounds[shape.id];
|
|
5063
|
-
const pageRotation = this.getShapePageTransform(shape).rotation();
|
|
5064
|
-
if (pageRotation % PI2) continue;
|
|
5065
|
-
const localOffset = new Vec(commonBounds.minX - pageBounds.minX, 0);
|
|
5066
|
-
const parentTransform = this.getShapeParentTransform(shape);
|
|
5067
|
-
if (parentTransform) localOffset.rot(-parentTransform.rotation());
|
|
5068
|
-
const { x, y } = Vec.Add(localOffset, shape);
|
|
5069
|
-
this.updateShapes([{ id: shape.id, type: shape.type, x, y }]);
|
|
5070
|
-
const scale = new Vec(commonBounds.width / pageBounds.width, 1);
|
|
5071
|
-
this.resizeShape(shape.id, scale, {
|
|
5072
|
-
initialBounds: bounds,
|
|
5073
|
-
scaleOrigin: new Vec(commonBounds.minX, pageBounds.center.y),
|
|
5074
|
-
isAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),
|
|
5075
|
-
scaleAxisRotation: 0
|
|
5076
|
-
});
|
|
5077
|
-
}
|
|
5078
|
-
});
|
|
5079
|
-
break;
|
|
5193
|
+
const shapesToStretchFirstPass = compact(ids.map((id) => this.getShape(id))).filter(
|
|
5194
|
+
(s) => this.getShapePageTransform(s)?.rotation() % (PI / 2) === 0
|
|
5195
|
+
);
|
|
5196
|
+
const shapeClustersToStretch = [];
|
|
5197
|
+
const allBounds = [];
|
|
5198
|
+
const visited = /* @__PURE__ */ new Set();
|
|
5199
|
+
for (const shape of shapesToStretchFirstPass) {
|
|
5200
|
+
if (visited.has(shape.id)) continue;
|
|
5201
|
+
visited.add(shape.id);
|
|
5202
|
+
const shapePageBounds = this.getShapePageBounds(shape);
|
|
5203
|
+
if (!shapePageBounds) continue;
|
|
5204
|
+
const shapesMovingTogether = [shape];
|
|
5205
|
+
const boundsOfShapesMovingTogether = [shapePageBounds];
|
|
5206
|
+
if (!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
5207
|
+
type: "stretch",
|
|
5208
|
+
shapes: shapesToStretchFirstPass
|
|
5209
|
+
})) {
|
|
5210
|
+
continue;
|
|
5080
5211
|
}
|
|
5212
|
+
this.collectShapesViaArrowBindings({
|
|
5213
|
+
bindings: this.getBindingsToShape(shape.id, "arrow"),
|
|
5214
|
+
initialShapes: shapesToStretchFirstPass,
|
|
5215
|
+
resultShapes: shapesMovingTogether,
|
|
5216
|
+
resultBounds: boundsOfShapesMovingTogether,
|
|
5217
|
+
visited
|
|
5218
|
+
});
|
|
5219
|
+
const commonPageBounds = Box.Common(boundsOfShapesMovingTogether);
|
|
5220
|
+
if (!commonPageBounds) continue;
|
|
5221
|
+
shapeClustersToStretch.push({
|
|
5222
|
+
shapes: shapesMovingTogether,
|
|
5223
|
+
pageBounds: commonPageBounds
|
|
5224
|
+
});
|
|
5225
|
+
allBounds.push(commonPageBounds);
|
|
5226
|
+
}
|
|
5227
|
+
if (shapeClustersToStretch.length < 2) return this;
|
|
5228
|
+
const commonBounds = Box.Common(allBounds);
|
|
5229
|
+
let val;
|
|
5230
|
+
let min;
|
|
5231
|
+
let dim;
|
|
5232
|
+
if (operation === "horizontal") {
|
|
5233
|
+
val = "x";
|
|
5234
|
+
min = "minX";
|
|
5235
|
+
dim = "width";
|
|
5236
|
+
} else {
|
|
5237
|
+
val = "y";
|
|
5238
|
+
min = "minY";
|
|
5239
|
+
dim = "height";
|
|
5081
5240
|
}
|
|
5241
|
+
this.run(() => {
|
|
5242
|
+
shapeClustersToStretch.forEach(({ shapes: shapes2, pageBounds }) => {
|
|
5243
|
+
const localOffset = new Vec();
|
|
5244
|
+
localOffset[val] = commonBounds[min] - pageBounds[min];
|
|
5245
|
+
const scaleOrigin = pageBounds.center.clone();
|
|
5246
|
+
scaleOrigin[val] = commonBounds[min];
|
|
5247
|
+
const scale = new Vec(1, 1);
|
|
5248
|
+
scale[val] = commonBounds[dim] / pageBounds[dim];
|
|
5249
|
+
for (const shape of shapes2) {
|
|
5250
|
+
const shapeLocalOffset = localOffset.clone();
|
|
5251
|
+
const parentTransform = this.getShapeParentTransform(shape);
|
|
5252
|
+
if (parentTransform) localOffset.rot(-parentTransform.rotation());
|
|
5253
|
+
shapeLocalOffset.add(shape);
|
|
5254
|
+
const changes = this.getChangesToTranslateShape(shape, shapeLocalOffset);
|
|
5255
|
+
this.updateShape(changes);
|
|
5256
|
+
this.resizeShape(shape.id, scale, {
|
|
5257
|
+
initialBounds: this.getShapeGeometry(shape).bounds,
|
|
5258
|
+
scaleOrigin,
|
|
5259
|
+
isAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),
|
|
5260
|
+
scaleAxisRotation: 0
|
|
5261
|
+
});
|
|
5262
|
+
}
|
|
5263
|
+
});
|
|
5264
|
+
});
|
|
5082
5265
|
return this;
|
|
5083
5266
|
}
|
|
5084
5267
|
/**
|
|
@@ -7327,7 +7510,6 @@ __decorateElement(_init, 1, "getPages", _getPages_dec, Editor);
|
|
|
7327
7510
|
__decorateElement(_init, 1, "getCurrentPageId", _getCurrentPageId_dec, Editor);
|
|
7328
7511
|
__decorateElement(_init, 1, "getCurrentPageShapeIdsSorted", _getCurrentPageShapeIdsSorted_dec, Editor);
|
|
7329
7512
|
__decorateElement(_init, 1, "_getAllAssetsQuery", __getAllAssetsQuery_dec, Editor);
|
|
7330
|
-
__decorateElement(_init, 1, "_getShapeGeometryCache", __getShapeGeometryCache_dec, Editor);
|
|
7331
7513
|
__decorateElement(_init, 1, "_getShapeHandlesCache", __getShapeHandlesCache_dec, Editor);
|
|
7332
7514
|
__decorateElement(_init, 1, "_getShapePageTransformCache", __getShapePageTransformCache_dec, Editor);
|
|
7333
7515
|
__decorateElement(_init, 1, "_getShapePageBoundsCache", __getShapePageBoundsCache_dec, Editor);
|