@excalidraw/element 0.18.0-60b2758 → 0.18.0-699826
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/dev/index.js +1599 -1365
- package/dist/dev/index.js.map +4 -4
- package/dist/prod/index.js +15 -14
- package/dist/types/common/src/appEventBus.d.ts +27 -0
- package/dist/types/common/src/colors.d.ts +1 -1
- package/dist/types/common/src/constants.d.ts +1 -2
- package/dist/types/common/src/index.d.ts +2 -0
- package/dist/types/common/src/utils.d.ts +1 -3
- package/dist/types/common/src/versionedSnapshotStore.d.ts +17 -0
- package/dist/types/element/src/Scene.d.ts +7 -3
- package/dist/types/element/src/arrowheads.d.ts +3 -0
- package/dist/types/element/src/binding.d.ts +3 -4
- package/dist/types/element/src/bounds.d.ts +22 -3
- package/dist/types/element/src/duplicate.d.ts +1 -0
- package/dist/types/element/src/elbowArrow.d.ts +2 -0
- package/dist/types/element/src/frame.d.ts +7 -6
- package/dist/types/element/src/index.d.ts +1 -0
- package/dist/types/element/src/linearElementEditor.d.ts +5 -2
- package/dist/types/element/src/mutateElement.d.ts +2 -0
- package/dist/types/element/src/selection.d.ts +7 -3
- package/dist/types/element/src/shape.d.ts +1 -1
- package/dist/types/element/src/textElement.d.ts +1 -1
- package/dist/types/element/src/textWrapping.d.ts +26 -0
- package/dist/types/element/src/typeChecks.d.ts +1 -0
- package/dist/types/element/src/types.d.ts +4 -1
- package/dist/types/element/src/utils.d.ts +2 -2
- package/dist/types/element/src/visualdebug.d.ts +1 -2
- package/dist/types/excalidraw/actions/actionAddToLibrary.d.ts +17 -11
- package/dist/types/excalidraw/actions/actionBoundText.d.ts +13 -9
- package/dist/types/excalidraw/actions/actionCanvas.d.ts +72 -48
- package/dist/types/excalidraw/actions/actionClipboard.d.ts +12 -8
- package/dist/types/excalidraw/actions/actionCropEditor.d.ts +6 -4
- package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +18 -12
- package/dist/types/excalidraw/actions/actionDeselect.d.ts +159 -0
- package/dist/types/excalidraw/actions/actionElementLink.d.ts +6 -4
- package/dist/types/excalidraw/actions/actionElementLock.d.ts +12 -8
- package/dist/types/excalidraw/actions/actionEmbeddable.d.ts +6 -4
- package/dist/types/excalidraw/actions/actionExport.d.ts +55 -319
- package/dist/types/excalidraw/actions/actionFrame.d.ts +24 -16
- package/dist/types/excalidraw/actions/actionGroup.d.ts +13 -9
- package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +6 -4
- package/dist/types/excalidraw/actions/actionLink.d.ts +6 -4
- package/dist/types/excalidraw/actions/actionMenu.d.ts +6 -4
- package/dist/types/excalidraw/actions/actionProperties.d.ts +14 -10
- package/dist/types/excalidraw/actions/actionSelectAll.d.ts +6 -4
- package/dist/types/excalidraw/actions/actionStyles.d.ts +6 -3
- package/dist/types/excalidraw/actions/actionTextAutoResize.d.ts +3 -3
- package/dist/types/excalidraw/actions/actionToggleArrowBinding.d.ts +172 -0
- package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +6 -4
- package/dist/types/excalidraw/actions/actionToggleMidpointSnapping.d.ts +172 -0
- package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +6 -4
- package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +6 -4
- package/dist/types/excalidraw/actions/actionToggleStats.d.ts +6 -4
- package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +6 -4
- package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +6 -4
- package/dist/types/excalidraw/actions/index.d.ts +3 -0
- package/dist/types/excalidraw/actions/types.d.ts +1 -1
- package/dist/types/excalidraw/{animated-trail.d.ts → animatedTrail.d.ts} +4 -3
- package/dist/types/excalidraw/appState.d.ts +4 -0
- package/dist/types/excalidraw/clipboard.d.ts +2 -3
- package/dist/types/excalidraw/components/App.d.ts +53 -14
- package/dist/types/excalidraw/components/AppStateObserver.d.ts +37 -0
- package/dist/types/excalidraw/components/CommandPalette/defaultCommandPaletteItems.d.ts +1 -2
- package/dist/types/excalidraw/components/IconPicker.d.ts +14 -9
- package/dist/types/excalidraw/components/Range.d.ts +10 -4
- package/dist/types/excalidraw/components/SVGLayer.d.ts +1 -1
- package/dist/types/excalidraw/components/TTDDialog/CodeMirrorEditor.d.ts +11 -0
- package/dist/types/excalidraw/components/TTDDialog/TTDDialogInput.d.ts +3 -3
- package/dist/types/excalidraw/components/TTDDialog/TTDDialogOutput.d.ts +4 -1
- package/dist/types/excalidraw/components/TTDDialog/mermaid-lang-lite.d.ts +2 -0
- package/dist/types/excalidraw/components/TTDDialog/utils/mermaidAutoFix.d.ts +1 -0
- package/dist/types/excalidraw/components/TTDDialog/utils/mermaidError.d.ts +10 -0
- package/dist/types/excalidraw/components/Toast.d.ts +8 -4
- package/dist/types/excalidraw/components/canvases/InteractiveCanvas.d.ts +2 -1
- package/dist/types/excalidraw/components/canvases/NewElementCanvas.d.ts +1 -0
- package/dist/types/excalidraw/components/canvases/StaticCanvas.d.ts +1 -1
- package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuItemContentRadio.d.ts +2 -1
- package/dist/types/excalidraw/components/icons.d.ts +17 -8
- package/dist/types/excalidraw/components/main-menu/DefaultItems.d.ts +9 -3
- package/dist/types/excalidraw/components/shapes.d.ts +7 -0
- package/dist/types/excalidraw/data/blob.d.ts +19 -16
- package/dist/types/excalidraw/data/filesystem.d.ts +3 -5
- package/dist/types/excalidraw/data/index.d.ts +2 -3
- package/dist/types/excalidraw/data/json.d.ts +24 -14
- package/dist/types/excalidraw/data/resave.d.ts +7 -2
- package/dist/types/excalidraw/eraser/index.d.ts +2 -3
- package/dist/types/excalidraw/{laser-trails.d.ts → laserTrails.d.ts} +5 -7
- package/dist/types/excalidraw/lasso/index.d.ts +2 -3
- package/dist/types/excalidraw/renderer/animation.d.ts +4 -1
- package/dist/types/excalidraw/scene/Renderer.d.ts +425 -19
- package/dist/types/excalidraw/textAutoResizeHandle.d.ts +15 -0
- package/dist/types/excalidraw/types.d.ts +103 -8
- package/dist/types/excalidraw/wysiwyg/textWysiwyg.d.ts +5 -1
- package/dist/types/fractional-indexing/src/index.d.ts +29 -0
- package/dist/types/math/src/constants.d.ts +0 -1
- package/dist/types/math/src/curve.d.ts +4 -1
- package/dist/types/math/src/point.d.ts +2 -1
- package/dist/types/utils/src/index.d.ts +1 -2
- package/package.json +4 -3
- package/dist/types/excalidraw/animation-frame-handler.d.ts +0 -16
- package/dist/types/excalidraw/components/DiagramToCodePlugin/DiagramToCodePlugin.d.ts +0 -4
- package/dist/types/excalidraw/components/ExcalidrawLogo.d.ts +0 -15
- package/dist/types/excalidraw/components/InitializeApp.d.ts +0 -10
- package/dist/types/excalidraw/components/TTDDialog/TTDDialogTrigger.d.ts +0 -8
- package/dist/types/excalidraw/components/TTDDialog/utils/TTDStreamFetch.d.ts +0 -24
- package/dist/types/excalidraw/components/footer/FooterCenter.d.ts +0 -8
- package/dist/types/excalidraw/components/live-collaboration/LiveCollaborationTrigger.d.ts +0 -11
- package/dist/types/excalidraw/components/welcome-screen/WelcomeScreen.Center.d.ts +0 -58
- package/dist/types/excalidraw/components/welcome-screen/WelcomeScreen.Hints.d.ts +0 -19
- package/dist/types/excalidraw/components/welcome-screen/WelcomeScreen.d.ts +0 -84
- package/dist/types/excalidraw/data/reconcile.d.ts +0 -7
- package/dist/types/excalidraw/index.d.ts +0 -48
- package/dist/types/excalidraw/polyfill.d.ts +0 -2
- package/dist/types/utils/src/bbox.d.ts +0 -9
- package/dist/types/utils/src/withinBounds.d.ts +0 -19
package/dist/dev/index.js
CHANGED
|
@@ -2269,9 +2269,9 @@ import {
|
|
|
2269
2269
|
degreesToRadians,
|
|
2270
2270
|
lineSegment as lineSegment6,
|
|
2271
2271
|
pointDistance as pointDistance7,
|
|
2272
|
-
pointFrom as
|
|
2272
|
+
pointFrom as pointFrom13,
|
|
2273
2273
|
pointFromArray as pointFromArray3,
|
|
2274
|
-
pointRotateRads as
|
|
2274
|
+
pointRotateRads as pointRotateRads12
|
|
2275
2275
|
} from "@excalidraw/math";
|
|
2276
2276
|
|
|
2277
2277
|
// ../utils/src/shape.ts
|
|
@@ -2613,9 +2613,9 @@ function ae(e, t = {}) {
|
|
|
2613
2613
|
|
|
2614
2614
|
// src/shape.ts
|
|
2615
2615
|
import {
|
|
2616
|
-
pointFrom as
|
|
2616
|
+
pointFrom as pointFrom12,
|
|
2617
2617
|
pointDistance as pointDistance6,
|
|
2618
|
-
pointRotateRads as
|
|
2618
|
+
pointRotateRads as pointRotateRads11
|
|
2619
2619
|
} from "@excalidraw/math";
|
|
2620
2620
|
import {
|
|
2621
2621
|
ROUGHNESS,
|
|
@@ -2632,8 +2632,8 @@ init_define_import_meta_env();
|
|
|
2632
2632
|
import {
|
|
2633
2633
|
isRightAngleRads,
|
|
2634
2634
|
lineSegment as lineSegment5,
|
|
2635
|
-
pointFrom as
|
|
2636
|
-
pointRotateRads as
|
|
2635
|
+
pointFrom as pointFrom11,
|
|
2636
|
+
pointRotateRads as pointRotateRads10
|
|
2637
2637
|
} from "@excalidraw/math";
|
|
2638
2638
|
import {
|
|
2639
2639
|
BOUND_TEXT_PADDING as BOUND_TEXT_PADDING3,
|
|
@@ -3124,7 +3124,7 @@ import {
|
|
|
3124
3124
|
} from "@excalidraw/math";
|
|
3125
3125
|
import {
|
|
3126
3126
|
DRAGGING_THRESHOLD,
|
|
3127
|
-
KEYS
|
|
3127
|
+
KEYS,
|
|
3128
3128
|
shouldRotateWithDiscreteAngle,
|
|
3129
3129
|
getGridPoint,
|
|
3130
3130
|
invariant as invariant8,
|
|
@@ -3142,7 +3142,6 @@ import {
|
|
|
3142
3142
|
// src/binding.ts
|
|
3143
3143
|
init_define_import_meta_env();
|
|
3144
3144
|
import {
|
|
3145
|
-
KEYS,
|
|
3146
3145
|
arrayToMap as arrayToMap2,
|
|
3147
3146
|
getFeatureFlag,
|
|
3148
3147
|
invariant as invariant7,
|
|
@@ -3375,6 +3374,25 @@ var canBecomePolygon = (points) => {
|
|
|
3375
3374
|
return points.length > 3 || // 3-point polygons can't have all points in a single line
|
|
3376
3375
|
points.length === 3 && !pointsEqual(points[0], points[points.length - 1]);
|
|
3377
3376
|
};
|
|
3377
|
+
var isEligibleFrameChildType = (type) => {
|
|
3378
|
+
switch (type) {
|
|
3379
|
+
case "rectangle":
|
|
3380
|
+
case "diamond":
|
|
3381
|
+
case "ellipse":
|
|
3382
|
+
case "arrow":
|
|
3383
|
+
case "line":
|
|
3384
|
+
case "freedraw":
|
|
3385
|
+
case "text":
|
|
3386
|
+
case "image":
|
|
3387
|
+
case "frame":
|
|
3388
|
+
case "embeddable": {
|
|
3389
|
+
return true;
|
|
3390
|
+
}
|
|
3391
|
+
default: {
|
|
3392
|
+
return false;
|
|
3393
|
+
}
|
|
3394
|
+
}
|
|
3395
|
+
};
|
|
3378
3396
|
|
|
3379
3397
|
// src/utils.ts
|
|
3380
3398
|
var ElementShapesCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -3409,12 +3427,12 @@ var setElementShapesCacheEntry = (element, shape, offset) => {
|
|
|
3409
3427
|
}
|
|
3410
3428
|
shapes.set(offset, shape);
|
|
3411
3429
|
};
|
|
3412
|
-
function deconstructLinearOrFreeDrawElement(element) {
|
|
3430
|
+
function deconstructLinearOrFreeDrawElement(element, elementsMap) {
|
|
3413
3431
|
const cachedShape = getElementShapesCacheEntry(element, 0);
|
|
3414
3432
|
if (cachedShape) {
|
|
3415
3433
|
return cachedShape;
|
|
3416
3434
|
}
|
|
3417
|
-
const ops = generateLinearCollisionShape(element);
|
|
3435
|
+
const ops = generateLinearCollisionShape(element, elementsMap);
|
|
3418
3436
|
const lines = [];
|
|
3419
3437
|
const curves = [];
|
|
3420
3438
|
for (let idx = 0; idx < ops.length; idx += 1) {
|
|
@@ -3821,7 +3839,7 @@ var getSnapOutlineMidPoint = (point, element, elementsMap, zoom) => {
|
|
|
3821
3839
|
)
|
|
3822
3840
|
];
|
|
3823
3841
|
const candidate = sideMidpoints.find(
|
|
3824
|
-
(
|
|
3842
|
+
(midpoint) => pointDistance2(point, midpoint) <= maxBindingDistance_simple(zoom) + element.strokeWidth / 2 && !hitElementItself({
|
|
3825
3843
|
point,
|
|
3826
3844
|
element,
|
|
3827
3845
|
threshold: 0,
|
|
@@ -3831,19 +3849,21 @@ var getSnapOutlineMidPoint = (point, element, elementsMap, zoom) => {
|
|
|
3831
3849
|
);
|
|
3832
3850
|
return candidate;
|
|
3833
3851
|
};
|
|
3834
|
-
var projectFixedPointOntoDiagonal = (arrow, point, element, startOrEnd, elementsMap, zoom) => {
|
|
3852
|
+
var projectFixedPointOntoDiagonal = (arrow, point, element, startOrEnd, elementsMap, zoom, isMidpointSnappingEnabled = true) => {
|
|
3835
3853
|
invariant2(arrow.points.length >= 2, "Arrow must have at least two points");
|
|
3836
3854
|
if (arrow.width < 3 && arrow.height < 3) {
|
|
3837
3855
|
return null;
|
|
3838
3856
|
}
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3857
|
+
if (isMidpointSnappingEnabled) {
|
|
3858
|
+
const sideMidPoint = getSnapOutlineMidPoint(
|
|
3859
|
+
point,
|
|
3860
|
+
element,
|
|
3861
|
+
elementsMap,
|
|
3862
|
+
zoom
|
|
3863
|
+
);
|
|
3864
|
+
if (sideMidPoint) {
|
|
3865
|
+
return sideMidPoint;
|
|
3866
|
+
}
|
|
3847
3867
|
}
|
|
3848
3868
|
const [diagonalOne, diagonalTwo] = getDiagonalsForBindableElement(
|
|
3849
3869
|
element,
|
|
@@ -4315,91 +4335,168 @@ var parseTokens = (line2) => {
|
|
|
4315
4335
|
return line2.normalize("NFC").split(breakLineRegex).filter(Boolean);
|
|
4316
4336
|
};
|
|
4317
4337
|
var wrapText = (text, font, maxWidth) => {
|
|
4338
|
+
return getWrappedTextLines(text, font, maxWidth).map((line2) => line2.text).join("\n");
|
|
4339
|
+
};
|
|
4340
|
+
var getHardLineBreaks = (text) => {
|
|
4341
|
+
let offset = 0;
|
|
4342
|
+
return text.split("\n").map((line2) => {
|
|
4343
|
+
const start = offset;
|
|
4344
|
+
const end = start + line2.length;
|
|
4345
|
+
offset = end + 1;
|
|
4346
|
+
return {
|
|
4347
|
+
text: line2,
|
|
4348
|
+
start,
|
|
4349
|
+
end
|
|
4350
|
+
};
|
|
4351
|
+
});
|
|
4352
|
+
};
|
|
4353
|
+
var getWrappedTextLines = (text, font, maxWidth) => {
|
|
4318
4354
|
if (!Number.isFinite(maxWidth) || maxWidth < 0) {
|
|
4319
|
-
return text;
|
|
4355
|
+
return getHardLineBreaks(text);
|
|
4320
4356
|
}
|
|
4321
4357
|
const lines = [];
|
|
4322
|
-
|
|
4323
|
-
for (const originalLine of
|
|
4324
|
-
const
|
|
4325
|
-
if (
|
|
4326
|
-
lines.push(
|
|
4327
|
-
|
|
4358
|
+
let offset = 0;
|
|
4359
|
+
for (const originalLine of text.split("\n")) {
|
|
4360
|
+
const originalLineWidth = getLineWidth(originalLine, font);
|
|
4361
|
+
if (originalLineWidth <= maxWidth) {
|
|
4362
|
+
lines.push({
|
|
4363
|
+
text: originalLine,
|
|
4364
|
+
start: offset,
|
|
4365
|
+
end: offset + originalLine.length
|
|
4366
|
+
});
|
|
4367
|
+
} else {
|
|
4368
|
+
lines.push(...wrapLine(originalLine, font, maxWidth, offset));
|
|
4328
4369
|
}
|
|
4329
|
-
|
|
4330
|
-
lines.push(...wrappedLine);
|
|
4370
|
+
offset += originalLine.length + 1;
|
|
4331
4371
|
}
|
|
4332
|
-
return lines
|
|
4372
|
+
return lines;
|
|
4333
4373
|
};
|
|
4334
|
-
var wrapLine = (line2, font, maxWidth) => {
|
|
4374
|
+
var wrapLine = (line2, font, maxWidth, lineStart) => {
|
|
4335
4375
|
const lines = [];
|
|
4336
4376
|
const tokens = parseTokens(line2);
|
|
4337
|
-
const tokenIterator = tokens[Symbol.iterator]();
|
|
4338
4377
|
let currentLine = "";
|
|
4378
|
+
let currentLineStart = lineStart;
|
|
4379
|
+
let currentLineEnd = lineStart;
|
|
4339
4380
|
let currentLineWidth = 0;
|
|
4340
|
-
let
|
|
4341
|
-
|
|
4342
|
-
|
|
4381
|
+
let tokenOffset = lineStart;
|
|
4382
|
+
let tokenIndex = 0;
|
|
4383
|
+
while (tokenIndex < tokens.length) {
|
|
4384
|
+
const token = tokens[tokenIndex];
|
|
4385
|
+
const tokenStart = tokenOffset;
|
|
4386
|
+
const tokenEnd = tokenStart + token.length;
|
|
4343
4387
|
const testLine = currentLine + token;
|
|
4344
4388
|
const testLineWidth = isSingleCharacter(token) ? currentLineWidth + charWidth.calculate(token, font) : getLineWidth(testLine, font);
|
|
4345
4389
|
if (/\s/.test(token) || testLineWidth <= maxWidth) {
|
|
4390
|
+
if (!currentLine) {
|
|
4391
|
+
currentLineStart = tokenStart;
|
|
4392
|
+
}
|
|
4346
4393
|
currentLine = testLine;
|
|
4394
|
+
currentLineEnd = tokenEnd;
|
|
4347
4395
|
currentLineWidth = testLineWidth;
|
|
4348
|
-
|
|
4396
|
+
tokenOffset = tokenEnd;
|
|
4397
|
+
tokenIndex++;
|
|
4349
4398
|
continue;
|
|
4350
4399
|
}
|
|
4351
4400
|
if (!currentLine) {
|
|
4352
|
-
const wrappedWord = wrapWord(token, font, maxWidth);
|
|
4353
|
-
const trailingLine = wrappedWord[wrappedWord.length - 1] ??
|
|
4401
|
+
const wrappedWord = wrapWord(token, font, maxWidth, tokenStart);
|
|
4402
|
+
const trailingLine = wrappedWord[wrappedWord.length - 1] ?? {
|
|
4403
|
+
text: "",
|
|
4404
|
+
start: tokenStart,
|
|
4405
|
+
end: tokenStart
|
|
4406
|
+
};
|
|
4354
4407
|
const precedingLines = wrappedWord.slice(0, -1);
|
|
4355
4408
|
lines.push(...precedingLines);
|
|
4356
|
-
currentLine = trailingLine;
|
|
4357
|
-
|
|
4358
|
-
|
|
4409
|
+
currentLine = trailingLine.text;
|
|
4410
|
+
currentLineStart = trailingLine.start;
|
|
4411
|
+
currentLineEnd = trailingLine.end;
|
|
4412
|
+
currentLineWidth = getLineWidth(trailingLine.text, font);
|
|
4413
|
+
tokenOffset = tokenEnd;
|
|
4414
|
+
tokenIndex++;
|
|
4359
4415
|
} else {
|
|
4360
|
-
lines.push(
|
|
4416
|
+
lines.push(
|
|
4417
|
+
trimLineEndAtSoftBreak(currentLine, currentLineStart, currentLineEnd)
|
|
4418
|
+
);
|
|
4361
4419
|
currentLine = "";
|
|
4420
|
+
currentLineStart = tokenStart;
|
|
4421
|
+
currentLineEnd = tokenStart;
|
|
4362
4422
|
currentLineWidth = 0;
|
|
4363
4423
|
}
|
|
4364
4424
|
}
|
|
4365
4425
|
if (currentLine) {
|
|
4366
|
-
const trailingLine = trimLine(
|
|
4426
|
+
const trailingLine = trimLine(
|
|
4427
|
+
currentLine,
|
|
4428
|
+
currentLineStart,
|
|
4429
|
+
currentLineEnd,
|
|
4430
|
+
font,
|
|
4431
|
+
maxWidth
|
|
4432
|
+
);
|
|
4367
4433
|
lines.push(trailingLine);
|
|
4368
4434
|
}
|
|
4369
4435
|
return lines;
|
|
4370
4436
|
};
|
|
4371
|
-
var wrapWord = (word, font, maxWidth) => {
|
|
4437
|
+
var wrapWord = (word, font, maxWidth, wordStart) => {
|
|
4372
4438
|
if (getEmojiRegex().test(word)) {
|
|
4373
|
-
return [
|
|
4439
|
+
return [
|
|
4440
|
+
{
|
|
4441
|
+
text: word,
|
|
4442
|
+
start: wordStart,
|
|
4443
|
+
end: wordStart + word.length
|
|
4444
|
+
}
|
|
4445
|
+
];
|
|
4374
4446
|
}
|
|
4375
4447
|
satisfiesWordInvariant(word);
|
|
4376
4448
|
const lines = [];
|
|
4377
4449
|
const chars = Array.from(word);
|
|
4378
4450
|
let currentLine = "";
|
|
4451
|
+
let currentLineStart = wordStart;
|
|
4452
|
+
let currentLineEnd = wordStart;
|
|
4379
4453
|
let currentLineWidth = 0;
|
|
4454
|
+
let offset = wordStart;
|
|
4380
4455
|
for (const char of chars) {
|
|
4456
|
+
const charStart = offset;
|
|
4457
|
+
const charEnd = charStart + char.length;
|
|
4381
4458
|
const _charWidth = charWidth.calculate(char, font);
|
|
4382
4459
|
const testLineWidth = currentLineWidth + _charWidth;
|
|
4383
4460
|
if (testLineWidth <= maxWidth) {
|
|
4461
|
+
if (!currentLine) {
|
|
4462
|
+
currentLineStart = charStart;
|
|
4463
|
+
}
|
|
4384
4464
|
currentLine = currentLine + char;
|
|
4465
|
+
currentLineEnd = charEnd;
|
|
4385
4466
|
currentLineWidth = testLineWidth;
|
|
4467
|
+
offset = charEnd;
|
|
4386
4468
|
continue;
|
|
4387
4469
|
}
|
|
4388
4470
|
if (currentLine) {
|
|
4389
|
-
lines.push(
|
|
4471
|
+
lines.push({
|
|
4472
|
+
text: currentLine,
|
|
4473
|
+
start: currentLineStart,
|
|
4474
|
+
end: currentLineEnd
|
|
4475
|
+
});
|
|
4390
4476
|
}
|
|
4391
4477
|
currentLine = char;
|
|
4478
|
+
currentLineStart = charStart;
|
|
4479
|
+
currentLineEnd = charEnd;
|
|
4392
4480
|
currentLineWidth = _charWidth;
|
|
4481
|
+
offset = charEnd;
|
|
4393
4482
|
}
|
|
4394
4483
|
if (currentLine) {
|
|
4395
|
-
lines.push(
|
|
4484
|
+
lines.push({
|
|
4485
|
+
text: currentLine,
|
|
4486
|
+
start: currentLineStart,
|
|
4487
|
+
end: currentLineEnd
|
|
4488
|
+
});
|
|
4396
4489
|
}
|
|
4397
4490
|
return lines;
|
|
4398
4491
|
};
|
|
4399
|
-
var trimLine = (line2, font, maxWidth) => {
|
|
4492
|
+
var trimLine = (line2, start, end, font, maxWidth) => {
|
|
4400
4493
|
const shouldTrimWhitespaces = getLineWidth(line2, font) > maxWidth;
|
|
4401
4494
|
if (!shouldTrimWhitespaces) {
|
|
4402
|
-
return
|
|
4495
|
+
return {
|
|
4496
|
+
text: line2,
|
|
4497
|
+
start,
|
|
4498
|
+
end
|
|
4499
|
+
};
|
|
4403
4500
|
}
|
|
4404
4501
|
let [, trimmedLine, whitespaces] = line2.match(/^(.+?)(\s+)$/) ?? [
|
|
4405
4502
|
line2,
|
|
@@ -4416,7 +4513,19 @@ var trimLine = (line2, font, maxWidth) => {
|
|
|
4416
4513
|
trimmedLine = trimmedLine + whitespace;
|
|
4417
4514
|
trimmedLineWidth = testLineWidth;
|
|
4418
4515
|
}
|
|
4419
|
-
return
|
|
4516
|
+
return {
|
|
4517
|
+
text: trimmedLine,
|
|
4518
|
+
start,
|
|
4519
|
+
end: end - (line2.length - trimmedLine.length)
|
|
4520
|
+
};
|
|
4521
|
+
};
|
|
4522
|
+
var trimLineEndAtSoftBreak = (line2, start, end) => {
|
|
4523
|
+
const trimmedLine = line2.trimEnd();
|
|
4524
|
+
return {
|
|
4525
|
+
text: trimmedLine,
|
|
4526
|
+
start,
|
|
4527
|
+
end: end - (line2.length - trimmedLine.length)
|
|
4528
|
+
};
|
|
4420
4529
|
};
|
|
4421
4530
|
var isSingleCharacter = (maybeSingleCharacter) => {
|
|
4422
4531
|
return maybeSingleCharacter.codePointAt(0) !== void 0 && maybeSingleCharacter.codePointAt(1) === void 0;
|
|
@@ -4655,7 +4764,8 @@ var getContainerCenter = (container, appState, elementsMap) => {
|
|
|
4655
4764
|
if (!midSegmentMidpoint) {
|
|
4656
4765
|
midSegmentMidpoint = LinearElementEditor.getSegmentMidPoint(
|
|
4657
4766
|
container,
|
|
4658
|
-
index + 1
|
|
4767
|
+
index + 1,
|
|
4768
|
+
elementsMap
|
|
4659
4769
|
);
|
|
4660
4770
|
}
|
|
4661
4771
|
return { x: midSegmentMidpoint[0], y: midSegmentMidpoint[1] };
|
|
@@ -4806,7 +4916,7 @@ var distanceToElement = (element, elementsMap, p) => {
|
|
|
4806
4916
|
case "line":
|
|
4807
4917
|
case "arrow":
|
|
4808
4918
|
case "freedraw":
|
|
4809
|
-
return distanceToLinearOrFreeDraElement(element, p);
|
|
4919
|
+
return distanceToLinearOrFreeDraElement(element, elementsMap, p);
|
|
4810
4920
|
}
|
|
4811
4921
|
};
|
|
4812
4922
|
var distanceToRectanguloidElement = (element, elementsMap, p) => {
|
|
@@ -4835,20 +4945,33 @@ var distanceToEllipseElement = (element, elementsMap, p) => {
|
|
|
4835
4945
|
ellipse2(center, element.width / 2, element.height / 2)
|
|
4836
4946
|
);
|
|
4837
4947
|
};
|
|
4838
|
-
var distanceToLinearOrFreeDraElement = (element, p) => {
|
|
4839
|
-
const [lines, curves] = deconstructLinearOrFreeDrawElement(
|
|
4948
|
+
var distanceToLinearOrFreeDraElement = (element, elementsMap, p) => {
|
|
4949
|
+
const [lines, curves] = deconstructLinearOrFreeDrawElement(
|
|
4950
|
+
element,
|
|
4951
|
+
elementsMap
|
|
4952
|
+
);
|
|
4840
4953
|
return Math.min(
|
|
4841
4954
|
...lines.map((s) => distanceToLineSegment(p, s)),
|
|
4842
4955
|
...curves.map((a2) => curvePointDistance(a2, p))
|
|
4843
4956
|
);
|
|
4844
4957
|
};
|
|
4845
4958
|
|
|
4959
|
+
// src/comparisons.ts
|
|
4960
|
+
init_define_import_meta_env();
|
|
4961
|
+
var hasBackground = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "line" || type === "freedraw";
|
|
4962
|
+
var hasStrokeColor = (type) => type === "rectangle" || type === "ellipse" || type === "diamond" || type === "freedraw" || type === "arrow" || type === "line" || type === "text" || type === "embeddable";
|
|
4963
|
+
var hasStrokeWidth = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "freedraw" || type === "arrow" || type === "line";
|
|
4964
|
+
var hasStrokeStyle = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "arrow" || type === "line";
|
|
4965
|
+
var canChangeRoundness = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "line" || type === "diamond" || type === "image";
|
|
4966
|
+
var toolIsArrow = (type) => type === "arrow";
|
|
4967
|
+
var canHaveArrowheads = (type) => type === "arrow";
|
|
4968
|
+
|
|
4846
4969
|
// src/collision.ts
|
|
4847
4970
|
var shouldTestInside = (element) => {
|
|
4848
4971
|
if (element.type === "arrow") {
|
|
4849
4972
|
return false;
|
|
4850
4973
|
}
|
|
4851
|
-
const isDraggableFromInside = !isTransparent(element.backgroundColor) || hasBoundTextElement(element) || isIframeLikeElement(element) || isTextElement(element);
|
|
4974
|
+
const isDraggableFromInside = hasBackground(element.type) && !isTransparent(element.backgroundColor) || hasBoundTextElement(element) || isIframeLikeElement(element) || isTextElement(element);
|
|
4852
4975
|
if (element.type === "line") {
|
|
4853
4976
|
return isDraggableFromInside && isPathALoop(element.points);
|
|
4854
4977
|
}
|
|
@@ -4885,14 +5008,11 @@ var hitElementItself = ({
|
|
|
4885
5008
|
)
|
|
4886
5009
|
) : false;
|
|
4887
5010
|
const bounds = getElementBounds(element, elementsMap, true);
|
|
4888
|
-
const hitBounds =
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
-element.angle
|
|
4894
|
-
),
|
|
4895
|
-
pointFrom5(bounds[2] + threshold, bounds[3] + threshold)
|
|
5011
|
+
const hitBounds = isPointInRotatedBounds(
|
|
5012
|
+
point,
|
|
5013
|
+
bounds,
|
|
5014
|
+
element.angle,
|
|
5015
|
+
threshold
|
|
4896
5016
|
);
|
|
4897
5017
|
if (!hitBounds && !hitFrameName) {
|
|
4898
5018
|
return false;
|
|
@@ -4910,13 +5030,17 @@ var hitElementItself = ({
|
|
|
4910
5030
|
cachedHit = result;
|
|
4911
5031
|
return result;
|
|
4912
5032
|
};
|
|
5033
|
+
var isPointInRotatedBounds = (point, bounds, angle, tolerance = 0) => {
|
|
5034
|
+
const adjustedPoint = angle === 0 ? point : pointRotateRads6(point, getCenterForBounds(bounds), -angle);
|
|
5035
|
+
return isPointWithinBounds(
|
|
5036
|
+
pointFrom5(bounds[0] - tolerance, bounds[1] - tolerance),
|
|
5037
|
+
adjustedPoint,
|
|
5038
|
+
pointFrom5(bounds[2] + tolerance, bounds[3] + tolerance)
|
|
5039
|
+
);
|
|
5040
|
+
};
|
|
4913
5041
|
var hitElementBoundingBox = (point, element, elementsMap, tolerance = 0) => {
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
y1 -= tolerance;
|
|
4917
|
-
x2 += tolerance;
|
|
4918
|
-
y2 += tolerance;
|
|
4919
|
-
return isPointWithinBounds(pointFrom5(x1, y1), point, pointFrom5(x2, y2));
|
|
5042
|
+
const bounds = getElementBounds(element, elementsMap, true);
|
|
5043
|
+
return isPointInRotatedBounds(point, bounds, element.angle, tolerance);
|
|
4920
5044
|
};
|
|
4921
5045
|
var hitElementBoundingBoxOnly = (hitArgs, elementsMap) => !hitElementItself(hitArgs) && // bound text is considered part of the element (even if it's outside the bounding box)
|
|
4922
5046
|
!hitElementBoundText(hitArgs.point, hitArgs.element, elementsMap) && hitElementBoundingBox(hitArgs.point, hitArgs.element, elementsMap);
|
|
@@ -4980,7 +5104,7 @@ var getAllHoveredElementAtPoint = (point, elements, elementsMap, tolerance) => {
|
|
|
4980
5104
|
);
|
|
4981
5105
|
if (isBindableElement(element, false) && bindingBorderTest(element, point, elementsMap, tolerance)) {
|
|
4982
5106
|
candidateElements.push(element);
|
|
4983
|
-
if (!isTransparent(element.backgroundColor)) {
|
|
5107
|
+
if (hasBackground(element.type) && !isTransparent(element.backgroundColor)) {
|
|
4984
5108
|
break;
|
|
4985
5109
|
}
|
|
4986
5110
|
}
|
|
@@ -5075,7 +5199,12 @@ var intersectElementWithLineSegment = (element, elementsMap, line2, offset = 0,
|
|
|
5075
5199
|
case "line":
|
|
5076
5200
|
case "freedraw":
|
|
5077
5201
|
case "arrow":
|
|
5078
|
-
return intersectLinearOrFreeDrawWithLineSegment(
|
|
5202
|
+
return intersectLinearOrFreeDrawWithLineSegment(
|
|
5203
|
+
element,
|
|
5204
|
+
line2,
|
|
5205
|
+
elementsMap,
|
|
5206
|
+
onlyFirst
|
|
5207
|
+
);
|
|
5079
5208
|
}
|
|
5080
5209
|
};
|
|
5081
5210
|
var curveIntersections = (curves, segment, intersections, center, angle, onlyFirst = false) => {
|
|
@@ -5114,8 +5243,11 @@ var lineIntersections = (lines, segment, intersections, center, angle, onlyFirst
|
|
|
5114
5243
|
}
|
|
5115
5244
|
return intersections;
|
|
5116
5245
|
};
|
|
5117
|
-
var intersectLinearOrFreeDrawWithLineSegment = (element, segment, onlyFirst = false) => {
|
|
5118
|
-
const [lines, curves] = deconstructLinearOrFreeDrawElement(
|
|
5246
|
+
var intersectLinearOrFreeDrawWithLineSegment = (element, segment, elementsMap, onlyFirst = false) => {
|
|
5247
|
+
const [lines, curves] = deconstructLinearOrFreeDrawElement(
|
|
5248
|
+
element,
|
|
5249
|
+
elementsMap
|
|
5250
|
+
);
|
|
5119
5251
|
const intersections = [];
|
|
5120
5252
|
for (const l2 of lines) {
|
|
5121
5253
|
const intersection = lineSegmentIntersectionPoints2(l2, segment);
|
|
@@ -5137,7 +5269,9 @@ var intersectLinearOrFreeDrawWithLineSegment = (element, segment, onlyFirst = fa
|
|
|
5137
5269
|
if (!doBoundsIntersect(b1, b2)) {
|
|
5138
5270
|
continue;
|
|
5139
5271
|
}
|
|
5140
|
-
const hits = curveIntersectLineSegment(c, segment
|
|
5272
|
+
const hits = curveIntersectLineSegment(c, segment, {
|
|
5273
|
+
iterLimit: 10
|
|
5274
|
+
});
|
|
5141
5275
|
if (hits.length > 0) {
|
|
5142
5276
|
intersections.push(...hits);
|
|
5143
5277
|
if (onlyFirst) {
|
|
@@ -6242,7 +6376,7 @@ var getElbowArrowData = (arrow, elementsMap, nextPoints, options) => {
|
|
|
6242
6376
|
const origEndGlobalPoint = pointTranslate2(nextPoints[nextPoints.length - 1], vector2(arrow.x, arrow.y));
|
|
6243
6377
|
let hoveredStartElement = null;
|
|
6244
6378
|
let hoveredEndElement = null;
|
|
6245
|
-
if (options?.isDragging) {
|
|
6379
|
+
if (options?.isDragging && options?.isBindingEnabled !== false) {
|
|
6246
6380
|
const elements = Array.from(elementsMap.values());
|
|
6247
6381
|
hoveredStartElement = getHoveredElement(
|
|
6248
6382
|
origStartGlobalPoint,
|
|
@@ -6273,7 +6407,9 @@ var getElbowArrowData = (arrow, elementsMap, nextPoints, options) => {
|
|
|
6273
6407
|
origStartGlobalPoint,
|
|
6274
6408
|
hoveredStartElement,
|
|
6275
6409
|
elementsMap,
|
|
6276
|
-
options?.isDragging
|
|
6410
|
+
options?.isDragging,
|
|
6411
|
+
options?.isBindingEnabled,
|
|
6412
|
+
options?.isMidpointSnappingEnabled
|
|
6277
6413
|
);
|
|
6278
6414
|
const endGlobalPoint = getGlobalPoint(
|
|
6279
6415
|
{
|
|
@@ -6288,7 +6424,9 @@ var getElbowArrowData = (arrow, elementsMap, nextPoints, options) => {
|
|
|
6288
6424
|
origEndGlobalPoint,
|
|
6289
6425
|
hoveredEndElement,
|
|
6290
6426
|
elementsMap,
|
|
6291
|
-
options?.isDragging
|
|
6427
|
+
options?.isDragging,
|
|
6428
|
+
options?.isBindingEnabled,
|
|
6429
|
+
options?.isMidpointSnappingEnabled
|
|
6292
6430
|
);
|
|
6293
6431
|
const startHeading = getBindPointHeading(
|
|
6294
6432
|
startGlobalPoint,
|
|
@@ -6844,7 +6982,7 @@ var normalizeArrowElementUpdate = (global2, nextFixedSegments, startIsSpecial, e
|
|
|
6844
6982
|
vectorScale6(vectorFromPoint6(global2[0]), -1)
|
|
6845
6983
|
)
|
|
6846
6984
|
);
|
|
6847
|
-
if (offsetX < -MAX_POS || offsetX > MAX_POS || offsetY < -MAX_POS || offsetY > MAX_POS || offsetX + points[points.length - 1][0] < -MAX_POS ||
|
|
6985
|
+
if (offsetX < -MAX_POS || offsetX > MAX_POS || offsetY < -MAX_POS || offsetY > MAX_POS || offsetX + points[points.length - 1][0] < -MAX_POS || offsetX + points[points.length - 1][0] > MAX_POS || offsetY + points[points.length - 1][1] < -MAX_POS || offsetY + points[points.length - 1][1] > MAX_POS) {
|
|
6848
6986
|
console.error(
|
|
6849
6987
|
"Elbow arrow normalization is outside reasonable bounds (> 1e6)",
|
|
6850
6988
|
{
|
|
@@ -6911,14 +7049,16 @@ var neighborIndexToHeading = (idx) => {
|
|
|
6911
7049
|
}
|
|
6912
7050
|
return HEADING_LEFT;
|
|
6913
7051
|
};
|
|
6914
|
-
var getGlobalPoint = (arrow, startOrEnd, fixedPointRatio, initialPoint, element, elementsMap, isDragging) => {
|
|
7052
|
+
var getGlobalPoint = (arrow, startOrEnd, fixedPointRatio, initialPoint, element, elementsMap, isDragging, isBindingEnabled2 = true, isMidpointSnappingEnabled = true) => {
|
|
6915
7053
|
if (isDragging) {
|
|
6916
|
-
if (element && elementsMap) {
|
|
7054
|
+
if (isBindingEnabled2 && element && elementsMap) {
|
|
6917
7055
|
return bindPointToSnapToElementOutline(
|
|
6918
7056
|
arrow,
|
|
6919
7057
|
element,
|
|
6920
7058
|
startOrEnd,
|
|
6921
|
-
elementsMap
|
|
7059
|
+
elementsMap,
|
|
7060
|
+
void 0,
|
|
7061
|
+
isMidpointSnappingEnabled
|
|
6922
7062
|
);
|
|
6923
7063
|
}
|
|
6924
7064
|
return initialPoint;
|
|
@@ -7079,9 +7219,6 @@ var maxBindingDistance_simple = (zoom) => {
|
|
|
7079
7219
|
BASE_BINDING_DISTANCE * 2
|
|
7080
7220
|
);
|
|
7081
7221
|
};
|
|
7082
|
-
var shouldEnableBindingForPointerEvent = (event) => {
|
|
7083
|
-
return !event[KEYS.CTRL_OR_CMD];
|
|
7084
|
-
};
|
|
7085
7222
|
var isBindingEnabled = (appState) => {
|
|
7086
7223
|
return appState.isBindingEnabled;
|
|
7087
7224
|
};
|
|
@@ -7099,8 +7236,20 @@ var bindOrUnbindBindingElement = (arrow, draggingPoints, scenePointerX, scenePoi
|
|
|
7099
7236
|
finalize: true
|
|
7100
7237
|
}
|
|
7101
7238
|
);
|
|
7102
|
-
bindOrUnbindBindingElementEdge(
|
|
7103
|
-
|
|
7239
|
+
bindOrUnbindBindingElementEdge(
|
|
7240
|
+
arrow,
|
|
7241
|
+
start,
|
|
7242
|
+
"start",
|
|
7243
|
+
scene,
|
|
7244
|
+
appState.isBindingEnabled
|
|
7245
|
+
);
|
|
7246
|
+
bindOrUnbindBindingElementEdge(
|
|
7247
|
+
arrow,
|
|
7248
|
+
end,
|
|
7249
|
+
"end",
|
|
7250
|
+
scene,
|
|
7251
|
+
appState.isBindingEnabled
|
|
7252
|
+
);
|
|
7104
7253
|
if (start.focusPoint || end.focusPoint) {
|
|
7105
7254
|
const updates = /* @__PURE__ */ new Map();
|
|
7106
7255
|
if (start.focusPoint) {
|
|
@@ -7129,11 +7278,19 @@ var bindOrUnbindBindingElement = (arrow, draggingPoints, scenePointerX, scenePoi
|
|
|
7129
7278
|
}
|
|
7130
7279
|
return { start, end };
|
|
7131
7280
|
};
|
|
7132
|
-
var bindOrUnbindBindingElementEdge = (arrow, { mode, element, focusPoint }, startOrEnd, scene) => {
|
|
7281
|
+
var bindOrUnbindBindingElementEdge = (arrow, { mode, element, focusPoint }, startOrEnd, scene, shouldSnapToOutline = true) => {
|
|
7133
7282
|
if (mode === null) {
|
|
7134
7283
|
unbindBindingElement(arrow, startOrEnd, scene);
|
|
7135
7284
|
} else if (mode !== void 0) {
|
|
7136
|
-
bindBindingElement(
|
|
7285
|
+
bindBindingElement(
|
|
7286
|
+
arrow,
|
|
7287
|
+
element,
|
|
7288
|
+
mode,
|
|
7289
|
+
startOrEnd,
|
|
7290
|
+
scene,
|
|
7291
|
+
focusPoint,
|
|
7292
|
+
shouldSnapToOutline
|
|
7293
|
+
);
|
|
7137
7294
|
}
|
|
7138
7295
|
};
|
|
7139
7296
|
var bindingStrategyForElbowArrowEndpointDragging = (arrow, draggingPoints, elementsMap, elements, zoom) => {
|
|
@@ -7429,11 +7586,7 @@ var getBindingStrategyForDraggingBindingElementEndpoints_simple = (arrow, draggi
|
|
|
7429
7586
|
threshold: 0,
|
|
7430
7587
|
overrideShouldTestInside: true
|
|
7431
7588
|
});
|
|
7432
|
-
if (otherBinding && otherBinding.elementId === hit?.id) {
|
|
7433
|
-
invariant7(
|
|
7434
|
-
!opts?.newArrow || appState.selectedLinearElement?.initialState.origin,
|
|
7435
|
-
"appState.selectedLinearElement.initialState.origin must be defined for new arrows"
|
|
7436
|
-
);
|
|
7589
|
+
if (otherBinding && otherBinding.elementId === hit?.id && (!opts?.newArrow || appState.selectedLinearElement?.initialState.origin)) {
|
|
7437
7590
|
return {
|
|
7438
7591
|
start: {
|
|
7439
7592
|
mode: "inside",
|
|
@@ -7487,7 +7640,8 @@ var getBindingStrategyForDraggingBindingElementEndpoints_simple = (arrow, draggi
|
|
|
7487
7640
|
hit,
|
|
7488
7641
|
startDragged ? "start" : "end",
|
|
7489
7642
|
elementsMap,
|
|
7490
|
-
appState.zoom
|
|
7643
|
+
appState.zoom,
|
|
7644
|
+
appState.isMidpointSnappingEnabled
|
|
7491
7645
|
) || globalPoint
|
|
7492
7646
|
} : { mode: null };
|
|
7493
7647
|
const otherEndpoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
|
@@ -7516,7 +7670,8 @@ var getBindingStrategyForDraggingBindingElementEndpoints_simple = (arrow, draggi
|
|
|
7516
7670
|
otherBindableElement,
|
|
7517
7671
|
startDragged ? "end" : "start",
|
|
7518
7672
|
elementsMap,
|
|
7519
|
-
appState.zoom
|
|
7673
|
+
appState.zoom,
|
|
7674
|
+
appState.isMidpointSnappingEnabled
|
|
7520
7675
|
) || otherEndpoint
|
|
7521
7676
|
} : { mode: void 0 } : { mode: void 0 };
|
|
7522
7677
|
return {
|
|
@@ -7626,7 +7781,7 @@ var bindOrUnbindBindingElements = (selectedArrows, scene, appState) => {
|
|
|
7626
7781
|
);
|
|
7627
7782
|
});
|
|
7628
7783
|
};
|
|
7629
|
-
var bindBindingElement = (arrow, hoveredElement, mode, startOrEnd, scene, focusPoint) => {
|
|
7784
|
+
var bindBindingElement = (arrow, hoveredElement, mode, startOrEnd, scene, focusPoint, shouldSnapToOutline = true) => {
|
|
7630
7785
|
const elementsMap = scene.getNonDeletedElementsMap();
|
|
7631
7786
|
let binding;
|
|
7632
7787
|
if (isElbowArrow(arrow)) {
|
|
@@ -7637,7 +7792,8 @@ var bindBindingElement = (arrow, hoveredElement, mode, startOrEnd, scene, focusP
|
|
|
7637
7792
|
arrow,
|
|
7638
7793
|
hoveredElement,
|
|
7639
7794
|
startOrEnd,
|
|
7640
|
-
elementsMap
|
|
7795
|
+
elementsMap,
|
|
7796
|
+
shouldSnapToOutline
|
|
7641
7797
|
)
|
|
7642
7798
|
};
|
|
7643
7799
|
} else {
|
|
@@ -7849,7 +8005,7 @@ var getDistanceForBinding = (point, bindableElement, elementsMap, zoom) => {
|
|
|
7849
8005
|
const bindDistance = maxBindingDistance_simple(zoom);
|
|
7850
8006
|
return distance3 > bindDistance ? null : distance3;
|
|
7851
8007
|
};
|
|
7852
|
-
var bindPointToSnapToElementOutline = (arrowElement, bindableElement, startOrEnd, elementsMap, customIntersector) => {
|
|
8008
|
+
var bindPointToSnapToElementOutline = (arrowElement, bindableElement, startOrEnd, elementsMap, customIntersector, isMidpointSnappingEnabled = true) => {
|
|
7853
8009
|
const elbowed = isElbowArrow(arrowElement);
|
|
7854
8010
|
const point = LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
|
7855
8011
|
arrowElement,
|
|
@@ -7878,13 +8034,7 @@ var bindPointToSnapToElementOutline = (arrowElement, bindableElement, startOrEnd
|
|
|
7878
8034
|
const isHorizontal = headingIsHorizontal(
|
|
7879
8035
|
headingForPointFromElement(bindableElement, aabb, point)
|
|
7880
8036
|
);
|
|
7881
|
-
const snapPoint = snapToMid(
|
|
7882
|
-
bindableElement,
|
|
7883
|
-
elementsMap,
|
|
7884
|
-
edgePoint,
|
|
7885
|
-
0.05,
|
|
7886
|
-
arrowElement
|
|
7887
|
-
);
|
|
8037
|
+
const snapPoint = isMidpointSnappingEnabled ? snapToMid(bindableElement, elementsMap, edgePoint, 0.05, arrowElement) : void 0;
|
|
7888
8038
|
const resolved = snapPoint || point;
|
|
7889
8039
|
const otherPoint = pointFrom8(
|
|
7890
8040
|
isHorizontal ? bindableCenter[0] : resolved[0],
|
|
@@ -8216,17 +8366,23 @@ var updateBoundPoint = (arrow, startOrEnd, binding, bindableElement, elementsMap
|
|
|
8216
8366
|
null
|
|
8217
8367
|
);
|
|
8218
8368
|
};
|
|
8219
|
-
var calculateFixedPointForElbowArrowBinding = (linearElement, hoveredElement, startOrEnd, elementsMap) => {
|
|
8369
|
+
var calculateFixedPointForElbowArrowBinding = (linearElement, hoveredElement, startOrEnd, elementsMap, shouldSnapToOutline = true, isMidpointSnappingEnabled = true) => {
|
|
8220
8370
|
const bounds = [
|
|
8221
8371
|
hoveredElement.x,
|
|
8222
8372
|
hoveredElement.y,
|
|
8223
8373
|
hoveredElement.x + hoveredElement.width,
|
|
8224
8374
|
hoveredElement.y + hoveredElement.height
|
|
8225
8375
|
];
|
|
8226
|
-
const snappedPoint = bindPointToSnapToElementOutline(
|
|
8376
|
+
const snappedPoint = shouldSnapToOutline ? bindPointToSnapToElementOutline(
|
|
8227
8377
|
linearElement,
|
|
8228
8378
|
hoveredElement,
|
|
8229
8379
|
startOrEnd,
|
|
8380
|
+
elementsMap,
|
|
8381
|
+
void 0,
|
|
8382
|
+
isMidpointSnappingEnabled
|
|
8383
|
+
) : LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
|
8384
|
+
linearElement,
|
|
8385
|
+
startOrEnd === "start" ? 0 : -1,
|
|
8230
8386
|
elementsMap
|
|
8231
8387
|
);
|
|
8232
8388
|
const globalMidPoint = pointFrom8(
|
|
@@ -8240,8 +8396,8 @@ var calculateFixedPointForElbowArrowBinding = (linearElement, hoveredElement, st
|
|
|
8240
8396
|
);
|
|
8241
8397
|
return {
|
|
8242
8398
|
fixedPoint: normalizeFixedPoint([
|
|
8243
|
-
(nonRotatedSnappedGlobalPoint[0] - hoveredElement.x) / hoveredElement.width,
|
|
8244
|
-
(nonRotatedSnappedGlobalPoint[1] - hoveredElement.y) / hoveredElement.height
|
|
8399
|
+
(nonRotatedSnappedGlobalPoint[0] - hoveredElement.x) / Math.max(hoveredElement.width, PRECISION2),
|
|
8400
|
+
(nonRotatedSnappedGlobalPoint[1] - hoveredElement.y) / Math.max(hoveredElement.height, PRECISION2)
|
|
8245
8401
|
])
|
|
8246
8402
|
};
|
|
8247
8403
|
};
|
|
@@ -8257,8 +8413,8 @@ var calculateFixedPointForNonElbowArrowBinding = (linearElement, hoveredElement,
|
|
|
8257
8413
|
elementCenter,
|
|
8258
8414
|
-hoveredElement.angle
|
|
8259
8415
|
);
|
|
8260
|
-
const fixedPointX = (nonRotatedPoint[0] - hoveredElement.x) / hoveredElement.width;
|
|
8261
|
-
const fixedPointY = (nonRotatedPoint[1] - hoveredElement.y) / hoveredElement.height;
|
|
8416
|
+
const fixedPointX = (nonRotatedPoint[0] - hoveredElement.x) / Math.max(hoveredElement.width, PRECISION2);
|
|
8417
|
+
const fixedPointY = (nonRotatedPoint[1] - hoveredElement.y) / Math.max(hoveredElement.height, PRECISION2);
|
|
8262
8418
|
return {
|
|
8263
8419
|
fixedPoint: normalizeFixedPoint([fixedPointX, fixedPointY])
|
|
8264
8420
|
};
|
|
@@ -8587,10 +8743,10 @@ var normalizeFixedPoint = (fixedPoint) => {
|
|
|
8587
8743
|
if (!isFixedPoint(fixedPoint)) {
|
|
8588
8744
|
return [0.5001, 0.5001];
|
|
8589
8745
|
}
|
|
8590
|
-
const
|
|
8591
|
-
if (Math.abs(fixedPoint[0] - 0.5) <
|
|
8746
|
+
const EPSILON = 1e-4;
|
|
8747
|
+
if (Math.abs(fixedPoint[0] - 0.5) < EPSILON || Math.abs(fixedPoint[1] - 0.5) < EPSILON) {
|
|
8592
8748
|
return fixedPoint.map(
|
|
8593
|
-
(ratio) => Math.abs(ratio - 0.5) <
|
|
8749
|
+
(ratio) => Math.abs(ratio - 0.5) < EPSILON ? 0.5001 : ratio
|
|
8594
8750
|
);
|
|
8595
8751
|
}
|
|
8596
8752
|
return fixedPoint;
|
|
@@ -9083,7 +9239,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
9083
9239
|
elementsMap,
|
|
9084
9240
|
pivotPoint,
|
|
9085
9241
|
pointFrom9(scenePointerX, scenePointerY),
|
|
9086
|
-
event[
|
|
9242
|
+
event[KEYS.CTRL_OR_CMD] ? null : app.getEffectiveGridSize(),
|
|
9087
9243
|
customLineAngle
|
|
9088
9244
|
);
|
|
9089
9245
|
const target = pointFrom9(
|
|
@@ -9098,7 +9254,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
9098
9254
|
elementsMap,
|
|
9099
9255
|
scenePointerX - linearElementEditor.pointerOffset.x,
|
|
9100
9256
|
scenePointerY - linearElementEditor.pointerOffset.y,
|
|
9101
|
-
event[
|
|
9257
|
+
event[KEYS.CTRL_OR_CMD] ? null : app.getEffectiveGridSize()
|
|
9102
9258
|
);
|
|
9103
9259
|
deltaX = newDraggingPointPosition[0] - point[0];
|
|
9104
9260
|
deltaY = newDraggingPointPosition[1] - point[1];
|
|
@@ -9118,11 +9274,20 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
9118
9274
|
event.altKey,
|
|
9119
9275
|
linearElementEditor
|
|
9120
9276
|
);
|
|
9121
|
-
_LinearElementEditor.movePoints(
|
|
9122
|
-
|
|
9123
|
-
|
|
9124
|
-
|
|
9125
|
-
|
|
9277
|
+
_LinearElementEditor.movePoints(
|
|
9278
|
+
element,
|
|
9279
|
+
app.scene,
|
|
9280
|
+
positions,
|
|
9281
|
+
{
|
|
9282
|
+
startBinding: updates?.startBinding,
|
|
9283
|
+
endBinding: updates?.endBinding,
|
|
9284
|
+
moveMidPointsWithElement: updates?.moveMidPointsWithElement
|
|
9285
|
+
},
|
|
9286
|
+
{
|
|
9287
|
+
isBindingEnabled: app.state.isBindingEnabled,
|
|
9288
|
+
isMidpointSnappingEnabled: app.state.isMidpointSnappingEnabled
|
|
9289
|
+
}
|
|
9290
|
+
);
|
|
9126
9291
|
if (isBindingElement(element, false)) {
|
|
9127
9292
|
if (isBindingEnabled(app.state)) {
|
|
9128
9293
|
suggestedBinding = updates?.suggestedBinding ?? null;
|
|
@@ -9158,7 +9323,8 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
9158
9323
|
startBindingElement,
|
|
9159
9324
|
"start",
|
|
9160
9325
|
elementsMap,
|
|
9161
|
-
app.state.zoom
|
|
9326
|
+
app.state.zoom,
|
|
9327
|
+
app.state.isMidpointSnappingEnabled
|
|
9162
9328
|
) : linearElementEditor.initialState.altFocusPoint
|
|
9163
9329
|
}
|
|
9164
9330
|
};
|
|
@@ -9192,12 +9358,14 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
9192
9358
|
return false;
|
|
9193
9359
|
});
|
|
9194
9360
|
}
|
|
9195
|
-
|
|
9196
|
-
|
|
9197
|
-
|
|
9198
|
-
|
|
9199
|
-
|
|
9200
|
-
|
|
9361
|
+
if (lastClickedPoint < 0 || !selectedPointsIndices.includes(lastClickedPoint) || !element.points[lastClickedPoint]) {
|
|
9362
|
+
console.error(
|
|
9363
|
+
`There must be a valid lastClickedPoint in order to drag it. selectedPointsIndices(${JSON.stringify(
|
|
9364
|
+
selectedPointsIndices
|
|
9365
|
+
)}) points(0..${element.points.length - 1}) lastClickedPoint(${lastClickedPoint}) isElbowArrow: ${elbowed}`
|
|
9366
|
+
);
|
|
9367
|
+
lastClickedPoint = element.points.length - 1;
|
|
9368
|
+
}
|
|
9201
9369
|
const draggingPoint = element.points[lastClickedPoint];
|
|
9202
9370
|
const pivotPoint = element.points[lastClickedPoint === 0 ? 1 : lastClickedPoint - 1];
|
|
9203
9371
|
const singlePointDragged = selectedPointsIndices.length === 1;
|
|
@@ -9214,7 +9382,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
9214
9382
|
elementsMap,
|
|
9215
9383
|
pivotPoint,
|
|
9216
9384
|
pointFrom9(scenePointerX, scenePointerY),
|
|
9217
|
-
event[
|
|
9385
|
+
event[KEYS.CTRL_OR_CMD] ? null : app.getEffectiveGridSize(),
|
|
9218
9386
|
customLineAngle
|
|
9219
9387
|
);
|
|
9220
9388
|
const target = pointFrom9(
|
|
@@ -9229,7 +9397,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
9229
9397
|
elementsMap,
|
|
9230
9398
|
scenePointerX - linearElementEditor.pointerOffset.x,
|
|
9231
9399
|
scenePointerY - linearElementEditor.pointerOffset.y,
|
|
9232
|
-
event[
|
|
9400
|
+
event[KEYS.CTRL_OR_CMD] ? null : app.getEffectiveGridSize()
|
|
9233
9401
|
);
|
|
9234
9402
|
deltaX = newDraggingPointPosition[0] - draggingPoint[0];
|
|
9235
9403
|
deltaY = newDraggingPointPosition[1] - draggingPoint[1];
|
|
@@ -9249,11 +9417,20 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
9249
9417
|
event.altKey,
|
|
9250
9418
|
linearElementEditor
|
|
9251
9419
|
);
|
|
9252
|
-
_LinearElementEditor.movePoints(
|
|
9253
|
-
|
|
9254
|
-
|
|
9255
|
-
|
|
9256
|
-
|
|
9420
|
+
_LinearElementEditor.movePoints(
|
|
9421
|
+
element,
|
|
9422
|
+
app.scene,
|
|
9423
|
+
positions,
|
|
9424
|
+
{
|
|
9425
|
+
startBinding: updates?.startBinding,
|
|
9426
|
+
endBinding: updates?.endBinding,
|
|
9427
|
+
moveMidPointsWithElement: updates?.moveMidPointsWithElement
|
|
9428
|
+
},
|
|
9429
|
+
{
|
|
9430
|
+
isBindingEnabled: app.state.isBindingEnabled,
|
|
9431
|
+
isMidpointSnappingEnabled: app.state.isMidpointSnappingEnabled
|
|
9432
|
+
}
|
|
9433
|
+
);
|
|
9257
9434
|
if (isBindingElement(element, false)) {
|
|
9258
9435
|
if (isBindingEnabled(app.state) && (startIsSelected || endIsSelected)) {
|
|
9259
9436
|
suggestedBinding = updates?.suggestedBinding ?? null;
|
|
@@ -9306,7 +9483,8 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
9306
9483
|
altFocusPointBindableElement,
|
|
9307
9484
|
"start",
|
|
9308
9485
|
elementsMap,
|
|
9309
|
-
app.state.zoom
|
|
9486
|
+
app.state.zoom,
|
|
9487
|
+
app.state.isMidpointSnappingEnabled
|
|
9310
9488
|
) : linearElementEditor.initialState.altFocusPoint
|
|
9311
9489
|
},
|
|
9312
9490
|
segmentMidPointHoveredCoords: newSelectedMidPointHoveredCoords,
|
|
@@ -9401,7 +9579,8 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
9401
9579
|
element.points[index],
|
|
9402
9580
|
element.points[index + 1],
|
|
9403
9581
|
index,
|
|
9404
|
-
appState.zoom
|
|
9582
|
+
appState.zoom,
|
|
9583
|
+
elementsMap
|
|
9405
9584
|
)) {
|
|
9406
9585
|
midpoints.push(null);
|
|
9407
9586
|
index++;
|
|
@@ -9409,7 +9588,8 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
9409
9588
|
}
|
|
9410
9589
|
const segmentMidPoint = _LinearElementEditor.getSegmentMidPoint(
|
|
9411
9590
|
element,
|
|
9412
|
-
index + 1
|
|
9591
|
+
index + 1,
|
|
9592
|
+
elementsMap
|
|
9413
9593
|
);
|
|
9414
9594
|
midpoints.push(segmentMidPoint);
|
|
9415
9595
|
index++;
|
|
@@ -9473,7 +9653,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
9473
9653
|
}
|
|
9474
9654
|
return null;
|
|
9475
9655
|
};
|
|
9476
|
-
static isSegmentTooShort(element, startPoint, endPoint, index, zoom) {
|
|
9656
|
+
static isSegmentTooShort(element, startPoint, endPoint, index, zoom, elementsMap) {
|
|
9477
9657
|
if (isElbowArrow(element)) {
|
|
9478
9658
|
if (index >= 0 && index < element.points.length) {
|
|
9479
9659
|
return pointDistance5(startPoint, endPoint) * zoom.value < _LinearElementEditor.POINT_HANDLE_SIZE / 2;
|
|
@@ -9482,7 +9662,10 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
9482
9662
|
}
|
|
9483
9663
|
let distance3 = pointDistance5(startPoint, endPoint);
|
|
9484
9664
|
if (element.points.length > 2 && element.roundness) {
|
|
9485
|
-
const [lines, curves] = deconstructLinearOrFreeDrawElement2(
|
|
9665
|
+
const [lines, curves] = deconstructLinearOrFreeDrawElement2(
|
|
9666
|
+
element,
|
|
9667
|
+
elementsMap
|
|
9668
|
+
);
|
|
9486
9669
|
invariant8(
|
|
9487
9670
|
lines.length === 0 && curves.length > 0,
|
|
9488
9671
|
"Only linears built out of curves are supported"
|
|
@@ -9495,7 +9678,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
9495
9678
|
}
|
|
9496
9679
|
return distance3 * zoom.value < _LinearElementEditor.POINT_HANDLE_SIZE * 4;
|
|
9497
9680
|
}
|
|
9498
|
-
static getSegmentMidPoint(element, index) {
|
|
9681
|
+
static getSegmentMidPoint(element, index, elementsMap) {
|
|
9499
9682
|
if (isElbowArrow(element)) {
|
|
9500
9683
|
invariant8(
|
|
9501
9684
|
element.points.length >= index,
|
|
@@ -9504,7 +9687,10 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
9504
9687
|
const p = pointCenter2(element.points[index - 1], element.points[index]);
|
|
9505
9688
|
return pointFrom9(element.x + p[0], element.y + p[1]);
|
|
9506
9689
|
}
|
|
9507
|
-
const [lines, curves] = deconstructLinearOrFreeDrawElement2(
|
|
9690
|
+
const [lines, curves] = deconstructLinearOrFreeDrawElement2(
|
|
9691
|
+
element,
|
|
9692
|
+
elementsMap
|
|
9693
|
+
);
|
|
9508
9694
|
invariant8(
|
|
9509
9695
|
lines.length === 0 && curves.length > 0 || lines.length > 0 && curves.length === 0,
|
|
9510
9696
|
"Only linears built out of either segments or curves are supported"
|
|
@@ -9586,7 +9772,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
9586
9772
|
elementsMap,
|
|
9587
9773
|
scenePointer.x,
|
|
9588
9774
|
scenePointer.y,
|
|
9589
|
-
event[
|
|
9775
|
+
event[KEYS.CTRL_OR_CMD] ? null : app.getEffectiveGridSize()
|
|
9590
9776
|
)
|
|
9591
9777
|
]
|
|
9592
9778
|
});
|
|
@@ -9699,7 +9885,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
9699
9885
|
elementsMap,
|
|
9700
9886
|
anchor,
|
|
9701
9887
|
pointFrom9(scenePointerX, scenePointerY),
|
|
9702
|
-
event[
|
|
9888
|
+
event[KEYS.CTRL_OR_CMD] ? null : app.getEffectiveGridSize()
|
|
9703
9889
|
);
|
|
9704
9890
|
newPoint = pointFrom9(width + anchor[0], height + anchor[1]);
|
|
9705
9891
|
} else {
|
|
@@ -9708,7 +9894,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
9708
9894
|
elementsMap,
|
|
9709
9895
|
scenePointerX - appState.selectedLinearElement.pointerOffset.x,
|
|
9710
9896
|
scenePointerY - appState.selectedLinearElement.pointerOffset.y,
|
|
9711
|
-
event[
|
|
9897
|
+
event[KEYS.CTRL_OR_CMD] || isElbowArrow(element) ? null : app.getEffectiveGridSize()
|
|
9712
9898
|
);
|
|
9713
9899
|
}
|
|
9714
9900
|
if (lastPoint === lastUncommittedPoint) {
|
|
@@ -9936,7 +10122,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
9936
10122
|
offsetY
|
|
9937
10123
|
);
|
|
9938
10124
|
}
|
|
9939
|
-
static movePoints(element, scene, pointUpdates, otherUpdates) {
|
|
10125
|
+
static movePoints(element, scene, pointUpdates, otherUpdates, options) {
|
|
9940
10126
|
const { points } = element;
|
|
9941
10127
|
if (isLineElement(element) && element.polygon) {
|
|
9942
10128
|
const firstPointUpdate = pointUpdates.get(0);
|
|
@@ -9979,7 +10165,9 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
9979
10165
|
offsetY,
|
|
9980
10166
|
otherUpdates,
|
|
9981
10167
|
{
|
|
9982
|
-
isDragging: Array.from(pointUpdates.values()).some((t) => t.isDragging)
|
|
10168
|
+
isDragging: Array.from(pointUpdates.values()).some((t) => t.isDragging),
|
|
10169
|
+
isBindingEnabled: options?.isBindingEnabled,
|
|
10170
|
+
isMidpointSnappingEnabled: options?.isMidpointSnappingEnabled
|
|
9983
10171
|
}
|
|
9984
10172
|
);
|
|
9985
10173
|
}
|
|
@@ -10022,7 +10210,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
10022
10210
|
pointerDownState: linearElementEditor.initialState,
|
|
10023
10211
|
selectedPointsIndices: linearElementEditor.selectedPointsIndices
|
|
10024
10212
|
};
|
|
10025
|
-
const
|
|
10213
|
+
const midpoint = _LinearElementEditor.createPointAt(
|
|
10026
10214
|
element,
|
|
10027
10215
|
elementsMap,
|
|
10028
10216
|
pointerCoords.x,
|
|
@@ -10031,7 +10219,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
10031
10219
|
);
|
|
10032
10220
|
const points = [
|
|
10033
10221
|
...element.points.slice(0, segmentMidpoint.index),
|
|
10034
|
-
|
|
10222
|
+
midpoint,
|
|
10035
10223
|
...element.points.slice(segmentMidpoint.index)
|
|
10036
10224
|
];
|
|
10037
10225
|
scene.mutateElement(element, { points });
|
|
@@ -10058,7 +10246,9 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
10058
10246
|
updates.points = Array.from(nextPoints);
|
|
10059
10247
|
scene.mutateElement(element, updates, {
|
|
10060
10248
|
informMutation: true,
|
|
10061
|
-
isDragging: options?.isDragging ?? false
|
|
10249
|
+
isDragging: options?.isDragging ?? false,
|
|
10250
|
+
isBindingEnabled: options?.isBindingEnabled,
|
|
10251
|
+
isMidpointSnappingEnabled: options?.isMidpointSnappingEnabled
|
|
10062
10252
|
});
|
|
10063
10253
|
} else {
|
|
10064
10254
|
const nextCoords = getElementPointsCoords(element, nextPoints);
|
|
@@ -10135,7 +10325,8 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
10135
10325
|
const index = element.points.length / 2 - 1;
|
|
10136
10326
|
const midSegmentMidpoint = _LinearElementEditor.getSegmentMidPoint(
|
|
10137
10327
|
element,
|
|
10138
|
-
index + 1
|
|
10328
|
+
index + 1,
|
|
10329
|
+
elementsMap
|
|
10139
10330
|
);
|
|
10140
10331
|
x = midSegmentMidpoint[0] - boundTextElement.width / 2;
|
|
10141
10332
|
y = midSegmentMidpoint[1] - boundTextElement.height / 2;
|
|
@@ -10323,13 +10514,11 @@ var normalizeSelectedPoints = (points) => {
|
|
|
10323
10514
|
var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, scenePointerX, scenePointerY, elementsMap, element, elements, app, angleLocked, altKey, linearElementEditor) => {
|
|
10324
10515
|
const naiveDraggingPoints = new Map(
|
|
10325
10516
|
selectedPointsIndices.map((pointIndex) => {
|
|
10517
|
+
const point = element.points[pointIndex] ?? element.points.at(-1);
|
|
10326
10518
|
return [
|
|
10327
10519
|
pointIndex,
|
|
10328
10520
|
{
|
|
10329
|
-
point: pointFrom9(
|
|
10330
|
-
element.points[pointIndex][0] + deltaX,
|
|
10331
|
-
element.points[pointIndex][1] + deltaY
|
|
10332
|
-
),
|
|
10521
|
+
point: pointFrom9(point[0] + deltaX, point[1] + deltaY),
|
|
10333
10522
|
isDragging: true
|
|
10334
10523
|
}
|
|
10335
10524
|
];
|
|
@@ -10365,14 +10554,14 @@ var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, scenePointerX
|
|
|
10365
10554
|
updates: {
|
|
10366
10555
|
suggestedBinding: suggestedBindingElement ? {
|
|
10367
10556
|
element: suggestedBindingElement,
|
|
10368
|
-
midPoint: snapToMid(
|
|
10557
|
+
midPoint: app.state.isMidpointSnappingEnabled ? snapToMid(
|
|
10369
10558
|
suggestedBindingElement,
|
|
10370
10559
|
elementsMap,
|
|
10371
10560
|
pointFrom9(
|
|
10372
10561
|
scenePointerX - linearElementEditor.pointerOffset.x,
|
|
10373
10562
|
scenePointerY - linearElementEditor.pointerOffset.y
|
|
10374
10563
|
)
|
|
10375
|
-
)
|
|
10564
|
+
) : void 0
|
|
10376
10565
|
} : null
|
|
10377
10566
|
}
|
|
10378
10567
|
};
|
|
@@ -10516,7 +10705,7 @@ var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, scenePointerX
|
|
|
10516
10705
|
nextArrow.endBinding.elementId
|
|
10517
10706
|
) : null;
|
|
10518
10707
|
const endLocalPoint = startIsDraggingOverEndElement ? nextArrow.points[nextArrow.points.length - 1] : endIsDraggingOverStartElement && app.state.bindMode !== "inside" && getFeatureFlag2("COMPLEX_BINDINGS") ? nextArrow.points[0] : endBindable ? updateBoundPoint(
|
|
10519
|
-
|
|
10708
|
+
nextArrow,
|
|
10520
10709
|
"endBinding",
|
|
10521
10710
|
nextArrow.endBinding,
|
|
10522
10711
|
endBindable,
|
|
@@ -10528,7 +10717,7 @@ var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, scenePointerX
|
|
|
10528
10717
|
nextArrow.startBinding.elementId
|
|
10529
10718
|
) : null;
|
|
10530
10719
|
const startLocalPoint = endIsDraggingOverStartElement && getFeatureFlag2("COMPLEX_BINDINGS") ? nextArrow.points[0] : startIsDraggingOverEndElement && app.state.bindMode !== "inside" && getFeatureFlag2("COMPLEX_BINDINGS") ? endLocalPoint : startBindable ? updateBoundPoint(
|
|
10531
|
-
|
|
10720
|
+
nextArrow,
|
|
10532
10721
|
"startBinding",
|
|
10533
10722
|
nextArrow.startBinding,
|
|
10534
10723
|
startBindable,
|
|
@@ -10568,188 +10757,15 @@ var determineCustomLinearAngle = (pivotPoint, draggedPoint) => Math.atan2(dragge
|
|
|
10568
10757
|
// src/frame.ts
|
|
10569
10758
|
init_define_import_meta_env();
|
|
10570
10759
|
import { arrayToMap as arrayToMap5 } from "@excalidraw/common";
|
|
10571
|
-
import { isPointWithinBounds as isPointWithinBounds2, pointFrom as pointFrom11 } from "@excalidraw/math";
|
|
10572
|
-
|
|
10573
|
-
// ../utils/src/bbox.ts
|
|
10574
|
-
init_define_import_meta_env();
|
|
10575
|
-
import {
|
|
10576
|
-
vectorCross as vectorCross3,
|
|
10577
|
-
vectorFromPoint as vectorFromPoint9
|
|
10578
|
-
} from "@excalidraw/math";
|
|
10579
|
-
function getBBox(line2) {
|
|
10580
|
-
return [
|
|
10581
|
-
Math.min(line2[0][0], line2[1][0]),
|
|
10582
|
-
Math.min(line2[0][1], line2[1][1]),
|
|
10583
|
-
Math.max(line2[0][0], line2[1][0]),
|
|
10584
|
-
Math.max(line2[0][1], line2[1][1])
|
|
10585
|
-
];
|
|
10586
|
-
}
|
|
10587
|
-
function doBBoxesIntersect(a2, b2) {
|
|
10588
|
-
return a2[0] <= b2[2] && a2[2] >= b2[0] && a2[1] <= b2[3] && a2[3] >= b2[1];
|
|
10589
|
-
}
|
|
10590
|
-
var EPSILON = 1e-6;
|
|
10591
|
-
function isPointOnLine(l2, p) {
|
|
10592
|
-
const p1 = vectorFromPoint9(l2[1], l2[0]);
|
|
10593
|
-
const p2 = vectorFromPoint9(p, l2[0]);
|
|
10594
|
-
const r = vectorCross3(p1, p2);
|
|
10595
|
-
return Math.abs(r) < EPSILON;
|
|
10596
|
-
}
|
|
10597
|
-
function isPointRightOfLine(l2, p) {
|
|
10598
|
-
const p1 = vectorFromPoint9(l2[1], l2[0]);
|
|
10599
|
-
const p2 = vectorFromPoint9(p, l2[0]);
|
|
10600
|
-
return vectorCross3(p1, p2) < 0;
|
|
10601
|
-
}
|
|
10602
|
-
function isLineSegmentTouchingOrCrossingLine(a2, b2) {
|
|
10603
|
-
return isPointOnLine(a2, b2[0]) || isPointOnLine(a2, b2[1]) || (isPointRightOfLine(a2, b2[0]) ? !isPointRightOfLine(a2, b2[1]) : isPointRightOfLine(a2, b2[1]));
|
|
10604
|
-
}
|
|
10605
|
-
function doLineSegmentsIntersect(a2, b2) {
|
|
10606
|
-
return doBBoxesIntersect(getBBox(a2), getBBox(b2)) && isLineSegmentTouchingOrCrossingLine(a2, b2) && isLineSegmentTouchingOrCrossingLine(b2, a2);
|
|
10607
|
-
}
|
|
10608
|
-
|
|
10609
|
-
// ../utils/src/withinBounds.ts
|
|
10610
|
-
init_define_import_meta_env();
|
|
10611
|
-
import { arrayToMap as arrayToMap3 } from "@excalidraw/common";
|
|
10612
|
-
import { getElementBounds as getElementBounds2 } from "@excalidraw/element";
|
|
10613
|
-
import {
|
|
10614
|
-
isArrowElement as isArrowElement2,
|
|
10615
|
-
isExcalidrawElement as isExcalidrawElement2,
|
|
10616
|
-
isFreeDrawElement as isFreeDrawElement2,
|
|
10617
|
-
isLinearElement as isLinearElement2,
|
|
10618
|
-
isTextElement as isTextElement2
|
|
10619
|
-
} from "@excalidraw/element";
|
|
10620
10760
|
import {
|
|
10621
|
-
|
|
10761
|
+
isPointWithinBounds as isPointWithinBounds2,
|
|
10622
10762
|
pointFrom as pointFrom10,
|
|
10623
|
-
|
|
10624
|
-
rangeInclusive
|
|
10763
|
+
segmentsIntersectAt as segmentsIntersectAt2
|
|
10625
10764
|
} from "@excalidraw/math";
|
|
10626
|
-
var getNonLinearElementRelativePoints = (element) => {
|
|
10627
|
-
if (element.type === "diamond") {
|
|
10628
|
-
return [
|
|
10629
|
-
pointFrom10(element.width / 2, 0),
|
|
10630
|
-
pointFrom10(element.width, element.height / 2),
|
|
10631
|
-
pointFrom10(element.width / 2, element.height),
|
|
10632
|
-
pointFrom10(0, element.height / 2)
|
|
10633
|
-
];
|
|
10634
|
-
}
|
|
10635
|
-
return [
|
|
10636
|
-
pointFrom10(0, 0),
|
|
10637
|
-
pointFrom10(0 + element.width, 0),
|
|
10638
|
-
pointFrom10(0 + element.width, element.height),
|
|
10639
|
-
pointFrom10(0, element.height)
|
|
10640
|
-
];
|
|
10641
|
-
};
|
|
10642
|
-
var getElementRelativePoints = (element) => {
|
|
10643
|
-
if (isLinearElement2(element) || isFreeDrawElement2(element)) {
|
|
10644
|
-
return element.points;
|
|
10645
|
-
}
|
|
10646
|
-
return getNonLinearElementRelativePoints(element);
|
|
10647
|
-
};
|
|
10648
|
-
var getMinMaxPoints = (points) => {
|
|
10649
|
-
const ret = points.reduce(
|
|
10650
|
-
(limits, [x, y]) => {
|
|
10651
|
-
limits.minY = Math.min(limits.minY, y);
|
|
10652
|
-
limits.minX = Math.min(limits.minX, x);
|
|
10653
|
-
limits.maxX = Math.max(limits.maxX, x);
|
|
10654
|
-
limits.maxY = Math.max(limits.maxY, y);
|
|
10655
|
-
return limits;
|
|
10656
|
-
},
|
|
10657
|
-
{
|
|
10658
|
-
minX: Infinity,
|
|
10659
|
-
minY: Infinity,
|
|
10660
|
-
maxX: -Infinity,
|
|
10661
|
-
maxY: -Infinity,
|
|
10662
|
-
cx: 0,
|
|
10663
|
-
cy: 0
|
|
10664
|
-
}
|
|
10665
|
-
);
|
|
10666
|
-
ret.cx = (ret.maxX + ret.minX) / 2;
|
|
10667
|
-
ret.cy = (ret.maxY + ret.minY) / 2;
|
|
10668
|
-
return ret;
|
|
10669
|
-
};
|
|
10670
|
-
var getRotatedBBox = (element) => {
|
|
10671
|
-
const points = getElementRelativePoints(element);
|
|
10672
|
-
const { cx, cy } = getMinMaxPoints(points);
|
|
10673
|
-
const centerPoint = pointFrom10(cx, cy);
|
|
10674
|
-
const rotatedPoints = points.map(
|
|
10675
|
-
(p) => pointRotateRads10(p, centerPoint, element.angle)
|
|
10676
|
-
);
|
|
10677
|
-
const { minX, minY, maxX, maxY } = getMinMaxPoints(rotatedPoints);
|
|
10678
|
-
return [
|
|
10679
|
-
minX + element.x,
|
|
10680
|
-
minY + element.y,
|
|
10681
|
-
maxX + element.x,
|
|
10682
|
-
maxY + element.y
|
|
10683
|
-
];
|
|
10684
|
-
};
|
|
10685
|
-
var isElementInsideBBox = (element, bbox, eitherDirection = false) => {
|
|
10686
|
-
const elementBBox = getRotatedBBox(element);
|
|
10687
|
-
const elementInsideBbox = bbox[0] <= elementBBox[0] && bbox[2] >= elementBBox[2] && bbox[1] <= elementBBox[1] && bbox[3] >= elementBBox[3];
|
|
10688
|
-
if (!eitherDirection) {
|
|
10689
|
-
return elementInsideBbox;
|
|
10690
|
-
}
|
|
10691
|
-
if (elementInsideBbox) {
|
|
10692
|
-
return true;
|
|
10693
|
-
}
|
|
10694
|
-
return elementBBox[0] <= bbox[0] && elementBBox[2] >= bbox[2] && elementBBox[1] <= bbox[1] && elementBBox[3] >= bbox[3];
|
|
10695
|
-
};
|
|
10696
|
-
var elementPartiallyOverlapsWithOrContainsBBox = (element, bbox) => {
|
|
10697
|
-
const elementBBox = getRotatedBBox(element);
|
|
10698
|
-
return (rangeIncludesValue(elementBBox[0], rangeInclusive(bbox[0], bbox[2])) || rangeIncludesValue(
|
|
10699
|
-
bbox[0],
|
|
10700
|
-
rangeInclusive(elementBBox[0], elementBBox[2])
|
|
10701
|
-
)) && (rangeIncludesValue(elementBBox[1], rangeInclusive(bbox[1], bbox[3])) || rangeIncludesValue(
|
|
10702
|
-
bbox[1],
|
|
10703
|
-
rangeInclusive(elementBBox[1], elementBBox[3])
|
|
10704
|
-
));
|
|
10705
|
-
};
|
|
10706
|
-
var elementsOverlappingBBox = ({
|
|
10707
|
-
elements,
|
|
10708
|
-
bounds,
|
|
10709
|
-
type,
|
|
10710
|
-
errorMargin = 0
|
|
10711
|
-
}) => {
|
|
10712
|
-
if (isExcalidrawElement2(bounds)) {
|
|
10713
|
-
bounds = getElementBounds2(bounds, arrayToMap3(elements));
|
|
10714
|
-
}
|
|
10715
|
-
const adjustedBBox = [
|
|
10716
|
-
bounds[0] - errorMargin,
|
|
10717
|
-
bounds[1] - errorMargin,
|
|
10718
|
-
bounds[2] + errorMargin,
|
|
10719
|
-
bounds[3] + errorMargin
|
|
10720
|
-
];
|
|
10721
|
-
const includedElementSet = /* @__PURE__ */ new Set();
|
|
10722
|
-
for (const element of elements) {
|
|
10723
|
-
if (includedElementSet.has(element.id)) {
|
|
10724
|
-
continue;
|
|
10725
|
-
}
|
|
10726
|
-
const isOverlaping = type === "overlap" ? elementPartiallyOverlapsWithOrContainsBBox(element, adjustedBBox) : type === "inside" ? isElementInsideBBox(element, adjustedBBox) : isElementInsideBBox(element, adjustedBBox, true);
|
|
10727
|
-
if (isOverlaping) {
|
|
10728
|
-
includedElementSet.add(element.id);
|
|
10729
|
-
if (element.boundElements) {
|
|
10730
|
-
for (const boundElement of element.boundElements) {
|
|
10731
|
-
includedElementSet.add(boundElement.id);
|
|
10732
|
-
}
|
|
10733
|
-
}
|
|
10734
|
-
if (isTextElement2(element) && element.containerId) {
|
|
10735
|
-
includedElementSet.add(element.containerId);
|
|
10736
|
-
}
|
|
10737
|
-
if (isArrowElement2(element)) {
|
|
10738
|
-
if (element.startBinding) {
|
|
10739
|
-
includedElementSet.add(element.startBinding.elementId);
|
|
10740
|
-
}
|
|
10741
|
-
if (element.endBinding) {
|
|
10742
|
-
includedElementSet.add(element.endBinding?.elementId);
|
|
10743
|
-
}
|
|
10744
|
-
}
|
|
10745
|
-
}
|
|
10746
|
-
}
|
|
10747
|
-
return elements.filter((element) => includedElementSet.has(element.id));
|
|
10748
|
-
};
|
|
10749
10765
|
|
|
10750
10766
|
// src/selection.ts
|
|
10751
10767
|
init_define_import_meta_env();
|
|
10752
|
-
import { arrayToMap as
|
|
10768
|
+
import { arrayToMap as arrayToMap3, isShallowEqual as isShallowEqual2 } from "@excalidraw/common";
|
|
10753
10769
|
|
|
10754
10770
|
// src/groups.ts
|
|
10755
10771
|
init_define_import_meta_env();
|
|
@@ -11025,13 +11041,8 @@ var getSelectedElementsByGroup = (selectedElements, elementsMap, appState) => {
|
|
|
11025
11041
|
};
|
|
11026
11042
|
|
|
11027
11043
|
// src/selection.ts
|
|
11028
|
-
var
|
|
11029
|
-
|
|
11030
|
-
selectedElements.forEach((element) => {
|
|
11031
|
-
if (isFrameLikeElement(element)) {
|
|
11032
|
-
framesInSelection.add(element.id);
|
|
11033
|
-
}
|
|
11034
|
-
});
|
|
11044
|
+
var shouldIgnoreElementFromSelection = (element) => element.locked || isBoundToContainer(element);
|
|
11045
|
+
var excludeElementsFromFrames = (selectedElements, framesInSelection) => {
|
|
11035
11046
|
return selectedElements.filter((element) => {
|
|
11036
11047
|
if (element.frameId && framesInSelection.has(element.frameId)) {
|
|
11037
11048
|
return false;
|
|
@@ -11039,35 +11050,35 @@ var excludeElementsInFramesFromSelection = (selectedElements) => {
|
|
|
11039
11050
|
return true;
|
|
11040
11051
|
});
|
|
11041
11052
|
};
|
|
11042
|
-
var
|
|
11043
|
-
const
|
|
11044
|
-
|
|
11045
|
-
|
|
11046
|
-
element
|
|
11047
|
-
elementsMap
|
|
11048
|
-
);
|
|
11049
|
-
const containingFrame = getContainingFrame(element, elementsMap);
|
|
11050
|
-
if (containingFrame) {
|
|
11051
|
-
const [fx1, fy1, fx2, fy2] = getElementBounds(
|
|
11052
|
-
containingFrame,
|
|
11053
|
-
elementsMap
|
|
11054
|
-
);
|
|
11055
|
-
elementX1 = Math.max(fx1, elementX1);
|
|
11056
|
-
elementY1 = Math.max(fy1, elementY1);
|
|
11057
|
-
elementX2 = Math.min(fx2, elementX2);
|
|
11058
|
-
elementY2 = Math.min(fy2, elementY2);
|
|
11053
|
+
var excludeElementsInFramesFromSelection = (selectedElements) => {
|
|
11054
|
+
const framesInSelection = /* @__PURE__ */ new Set();
|
|
11055
|
+
selectedElements.forEach((element) => {
|
|
11056
|
+
if (isFrameLikeElement(element)) {
|
|
11057
|
+
framesInSelection.add(element.id);
|
|
11059
11058
|
}
|
|
11060
|
-
return element.locked === false && element.type !== "selection" && !isBoundToContainer(element) && selectionX1 <= elementX1 && selectionY1 <= elementY1 && selectionX2 >= elementX2 && selectionY2 >= elementY2;
|
|
11061
11059
|
});
|
|
11062
|
-
|
|
11063
|
-
|
|
11064
|
-
|
|
11065
|
-
|
|
11066
|
-
|
|
11067
|
-
|
|
11068
|
-
|
|
11060
|
+
return excludeElementsFromFrames(selectedElements, framesInSelection);
|
|
11061
|
+
};
|
|
11062
|
+
var getElementsWithinSelection = (elements, selection, elementsMap, excludeElementsInFrames = true, boxSelectionMode = "contain") => {
|
|
11063
|
+
const [selectionStartX, selectionStartY, selectionEndX, selectionEndY] = getElementAbsoluteCoords2(selection, elementsMap);
|
|
11064
|
+
const selectionX1 = Math.min(selectionStartX, selectionEndX);
|
|
11065
|
+
const selectionY1 = Math.min(selectionStartY, selectionEndY);
|
|
11066
|
+
const selectionX2 = Math.max(selectionStartX, selectionEndX);
|
|
11067
|
+
const selectionY2 = Math.max(selectionStartY, selectionEndY);
|
|
11068
|
+
const selectionBounds = [
|
|
11069
|
+
selectionX1,
|
|
11070
|
+
selectionY1,
|
|
11071
|
+
selectionX2,
|
|
11072
|
+
selectionY2
|
|
11073
|
+
];
|
|
11074
|
+
return elementsOverlappingBBox({
|
|
11075
|
+
elements,
|
|
11076
|
+
bounds: selectionBounds,
|
|
11077
|
+
elementsMap,
|
|
11078
|
+
type: boxSelectionMode,
|
|
11079
|
+
shouldIgnoreElementFromSelection,
|
|
11080
|
+
excludeElementsInFrames
|
|
11069
11081
|
});
|
|
11070
|
-
return elementsInSelection;
|
|
11071
11082
|
};
|
|
11072
11083
|
var getVisibleAndNonSelectedElements = (elements, selectedElements, appState, elementsMap) => {
|
|
11073
11084
|
const selectedElementsSet = new Set(
|
|
@@ -11153,7 +11164,7 @@ var _getLinearElementEditor = (targetElements, allElements) => {
|
|
|
11153
11164
|
(el) => el.id === linear.id || boundElements.includes(el.id)
|
|
11154
11165
|
);
|
|
11155
11166
|
if (onlySingleLinearSelected) {
|
|
11156
|
-
return new LinearElementEditor(linear,
|
|
11167
|
+
return new LinearElementEditor(linear, arrayToMap3(allElements));
|
|
11157
11168
|
}
|
|
11158
11169
|
}
|
|
11159
11170
|
return null;
|
|
@@ -11179,9 +11190,263 @@ var getSelectionStateForElements = (targetElements, allElements, appState) => {
|
|
|
11179
11190
|
)
|
|
11180
11191
|
};
|
|
11181
11192
|
};
|
|
11193
|
+
var getActiveTextElement = (selectedElements, appState) => {
|
|
11194
|
+
const activeTextElement = appState.editingTextElement || selectedElements.length === 1 && isTextElement(selectedElements[0]) && selectedElements[0];
|
|
11195
|
+
return activeTextElement || null;
|
|
11196
|
+
};
|
|
11182
11197
|
|
|
11183
|
-
// src/
|
|
11184
|
-
|
|
11198
|
+
// src/fractionalIndex.ts
|
|
11199
|
+
init_define_import_meta_env();
|
|
11200
|
+
import { arrayToMap as arrayToMap4 } from "@excalidraw/common";
|
|
11201
|
+
import {
|
|
11202
|
+
validateOrderKey,
|
|
11203
|
+
generateNKeysBetween
|
|
11204
|
+
} from "@excalidraw/fractional-indexing";
|
|
11205
|
+
var InvalidFractionalIndexError = class extends Error {
|
|
11206
|
+
code = "ELEMENT_HAS_INVALID_INDEX";
|
|
11207
|
+
};
|
|
11208
|
+
var validateFractionalIndices = (elements, {
|
|
11209
|
+
shouldThrow = false,
|
|
11210
|
+
includeBoundTextValidation = false,
|
|
11211
|
+
ignoreLogs,
|
|
11212
|
+
reconciliationContext
|
|
11213
|
+
}) => {
|
|
11214
|
+
const errorMessages = [];
|
|
11215
|
+
const stringifyElement = (element) => `${element?.index}:${element?.id}:${element?.type}:${element?.isDeleted}:${element?.version}:${element?.versionNonce}`;
|
|
11216
|
+
const indices = elements.map((x) => x.index);
|
|
11217
|
+
for (const [i, index] of indices.entries()) {
|
|
11218
|
+
const predecessorIndex = indices[i - 1];
|
|
11219
|
+
const successorIndex = indices[i + 1];
|
|
11220
|
+
if (!isValidFractionalIndex(index, predecessorIndex, successorIndex)) {
|
|
11221
|
+
errorMessages.push(
|
|
11222
|
+
`Fractional indices invariant has been compromised: "${stringifyElement(
|
|
11223
|
+
elements[i - 1]
|
|
11224
|
+
)}", "${stringifyElement(elements[i])}", "${stringifyElement(
|
|
11225
|
+
elements[i + 1]
|
|
11226
|
+
)}"`
|
|
11227
|
+
);
|
|
11228
|
+
}
|
|
11229
|
+
if (includeBoundTextValidation && hasBoundTextElement(elements[i])) {
|
|
11230
|
+
const container = elements[i];
|
|
11231
|
+
const text = getBoundTextElement(container, arrayToMap4(elements));
|
|
11232
|
+
if (text && text.index <= container.index) {
|
|
11233
|
+
errorMessages.push(
|
|
11234
|
+
`Fractional indices invariant for bound elements has been compromised: "${stringifyElement(
|
|
11235
|
+
text
|
|
11236
|
+
)}", "${stringifyElement(container)}"`
|
|
11237
|
+
);
|
|
11238
|
+
}
|
|
11239
|
+
}
|
|
11240
|
+
}
|
|
11241
|
+
if (errorMessages.length) {
|
|
11242
|
+
const error = new InvalidFractionalIndexError();
|
|
11243
|
+
const additionalContext = [];
|
|
11244
|
+
if (reconciliationContext) {
|
|
11245
|
+
additionalContext.push("Additional reconciliation context:");
|
|
11246
|
+
additionalContext.push(
|
|
11247
|
+
reconciliationContext.localElements.map((x) => stringifyElement(x))
|
|
11248
|
+
);
|
|
11249
|
+
additionalContext.push(
|
|
11250
|
+
reconciliationContext.remoteElements.map((x) => stringifyElement(x))
|
|
11251
|
+
);
|
|
11252
|
+
}
|
|
11253
|
+
if (!ignoreLogs) {
|
|
11254
|
+
console.error(
|
|
11255
|
+
errorMessages.join("\n\n"),
|
|
11256
|
+
error.stack,
|
|
11257
|
+
elements.map((x) => stringifyElement(x)),
|
|
11258
|
+
...additionalContext
|
|
11259
|
+
);
|
|
11260
|
+
}
|
|
11261
|
+
if (shouldThrow) {
|
|
11262
|
+
throw error;
|
|
11263
|
+
}
|
|
11264
|
+
}
|
|
11265
|
+
};
|
|
11266
|
+
var orderByFractionalIndex = (elements) => {
|
|
11267
|
+
return elements.sort((a2, b2) => {
|
|
11268
|
+
if (isOrderedElement(a2) && isOrderedElement(b2)) {
|
|
11269
|
+
if (a2.index < b2.index) {
|
|
11270
|
+
return -1;
|
|
11271
|
+
} else if (a2.index > b2.index) {
|
|
11272
|
+
return 1;
|
|
11273
|
+
}
|
|
11274
|
+
return a2.id < b2.id ? -1 : 1;
|
|
11275
|
+
}
|
|
11276
|
+
return 1;
|
|
11277
|
+
});
|
|
11278
|
+
};
|
|
11279
|
+
var syncMovedIndices = (elements, movedElements) => {
|
|
11280
|
+
try {
|
|
11281
|
+
const elementsMap = arrayToMap4(elements);
|
|
11282
|
+
const indicesGroups = getMovedIndicesGroups(elements, movedElements);
|
|
11283
|
+
const elementsUpdates = generateIndices(elements, indicesGroups);
|
|
11284
|
+
const elementsCandidates = elements.map((x) => {
|
|
11285
|
+
const elementUpdates = elementsUpdates.get(x);
|
|
11286
|
+
if (elementUpdates) {
|
|
11287
|
+
return { ...x, index: elementUpdates.index };
|
|
11288
|
+
}
|
|
11289
|
+
return x;
|
|
11290
|
+
});
|
|
11291
|
+
validateFractionalIndices(
|
|
11292
|
+
elementsCandidates,
|
|
11293
|
+
// we don't autofix invalid bound text indices, hence don't include it in the validation
|
|
11294
|
+
{
|
|
11295
|
+
includeBoundTextValidation: false,
|
|
11296
|
+
shouldThrow: true,
|
|
11297
|
+
ignoreLogs: true
|
|
11298
|
+
}
|
|
11299
|
+
);
|
|
11300
|
+
for (const [element, { index }] of elementsUpdates) {
|
|
11301
|
+
mutateElement(element, elementsMap, { index });
|
|
11302
|
+
}
|
|
11303
|
+
} catch (e) {
|
|
11304
|
+
syncInvalidIndices(elements);
|
|
11305
|
+
}
|
|
11306
|
+
return elements;
|
|
11307
|
+
};
|
|
11308
|
+
var syncInvalidIndices = (elements) => {
|
|
11309
|
+
const elementsMap = arrayToMap4(elements);
|
|
11310
|
+
const indicesGroups = getInvalidIndicesGroups(elements);
|
|
11311
|
+
const elementsUpdates = generateIndices(elements, indicesGroups);
|
|
11312
|
+
for (const [element, { index }] of elementsUpdates) {
|
|
11313
|
+
mutateElement(element, elementsMap, { index });
|
|
11314
|
+
}
|
|
11315
|
+
return elements;
|
|
11316
|
+
};
|
|
11317
|
+
var syncInvalidIndicesImmutable = (elements) => {
|
|
11318
|
+
const syncedElements = arrayToMap4(elements);
|
|
11319
|
+
const indicesGroups = getInvalidIndicesGroups(elements);
|
|
11320
|
+
const elementsUpdates = generateIndices(elements, indicesGroups);
|
|
11321
|
+
for (const [element, { index }] of elementsUpdates) {
|
|
11322
|
+
syncedElements.set(element.id, newElementWith(element, { index }));
|
|
11323
|
+
}
|
|
11324
|
+
return syncedElements;
|
|
11325
|
+
};
|
|
11326
|
+
var getMovedIndicesGroups = (elements, movedElements) => {
|
|
11327
|
+
const indicesGroups = [];
|
|
11328
|
+
let i = 0;
|
|
11329
|
+
while (i < elements.length) {
|
|
11330
|
+
if (movedElements.has(elements[i].id)) {
|
|
11331
|
+
const indicesGroup = [i - 1, i];
|
|
11332
|
+
while (++i < elements.length) {
|
|
11333
|
+
if (!movedElements.has(elements[i].id)) {
|
|
11334
|
+
break;
|
|
11335
|
+
}
|
|
11336
|
+
indicesGroup.push(i);
|
|
11337
|
+
}
|
|
11338
|
+
indicesGroup.push(i);
|
|
11339
|
+
indicesGroups.push(indicesGroup);
|
|
11340
|
+
} else {
|
|
11341
|
+
i++;
|
|
11342
|
+
}
|
|
11343
|
+
}
|
|
11344
|
+
return indicesGroups;
|
|
11345
|
+
};
|
|
11346
|
+
var getInvalidIndicesGroups = (elements) => {
|
|
11347
|
+
const indicesGroups = [];
|
|
11348
|
+
let lowerBound = void 0;
|
|
11349
|
+
let upperBound = void 0;
|
|
11350
|
+
let lowerBoundIndex = -1;
|
|
11351
|
+
let upperBoundIndex = 0;
|
|
11352
|
+
const getLowerBound = (index) => {
|
|
11353
|
+
const lowerBound2 = elements[lowerBoundIndex] ? elements[lowerBoundIndex].index : void 0;
|
|
11354
|
+
const candidate = elements[index - 1]?.index;
|
|
11355
|
+
if (!lowerBound2 && candidate || // first lowerBound
|
|
11356
|
+
lowerBound2 && candidate && candidate > lowerBound2) {
|
|
11357
|
+
return [candidate, index - 1];
|
|
11358
|
+
}
|
|
11359
|
+
return [lowerBound2, lowerBoundIndex];
|
|
11360
|
+
};
|
|
11361
|
+
const getUpperBound = (index) => {
|
|
11362
|
+
const upperBound2 = elements[upperBoundIndex] ? elements[upperBoundIndex].index : void 0;
|
|
11363
|
+
if (upperBound2 && index < upperBoundIndex) {
|
|
11364
|
+
return [upperBound2, upperBoundIndex];
|
|
11365
|
+
}
|
|
11366
|
+
let i2 = upperBoundIndex;
|
|
11367
|
+
while (++i2 < elements.length) {
|
|
11368
|
+
const candidate = elements[i2]?.index;
|
|
11369
|
+
if (!upperBound2 && candidate || // first upperBound
|
|
11370
|
+
upperBound2 && candidate && candidate > upperBound2) {
|
|
11371
|
+
return [candidate, i2];
|
|
11372
|
+
}
|
|
11373
|
+
}
|
|
11374
|
+
return [void 0, i2];
|
|
11375
|
+
};
|
|
11376
|
+
let i = 0;
|
|
11377
|
+
while (i < elements.length) {
|
|
11378
|
+
const current = elements[i].index;
|
|
11379
|
+
[lowerBound, lowerBoundIndex] = getLowerBound(i);
|
|
11380
|
+
[upperBound, upperBoundIndex] = getUpperBound(i);
|
|
11381
|
+
if (!isValidFractionalIndex(current, lowerBound, upperBound)) {
|
|
11382
|
+
const indicesGroup = [lowerBoundIndex, i];
|
|
11383
|
+
while (++i < elements.length) {
|
|
11384
|
+
const current2 = elements[i].index;
|
|
11385
|
+
const [nextLowerBound, nextLowerBoundIndex] = getLowerBound(i);
|
|
11386
|
+
const [nextUpperBound, nextUpperBoundIndex] = getUpperBound(i);
|
|
11387
|
+
if (isValidFractionalIndex(current2, nextLowerBound, nextUpperBound)) {
|
|
11388
|
+
break;
|
|
11389
|
+
}
|
|
11390
|
+
[lowerBound, lowerBoundIndex] = [nextLowerBound, nextLowerBoundIndex];
|
|
11391
|
+
[upperBound, upperBoundIndex] = [nextUpperBound, nextUpperBoundIndex];
|
|
11392
|
+
indicesGroup.push(i);
|
|
11393
|
+
}
|
|
11394
|
+
indicesGroup.push(upperBoundIndex);
|
|
11395
|
+
indicesGroups.push(indicesGroup);
|
|
11396
|
+
} else {
|
|
11397
|
+
i++;
|
|
11398
|
+
}
|
|
11399
|
+
}
|
|
11400
|
+
return indicesGroups;
|
|
11401
|
+
};
|
|
11402
|
+
var isValidFractionalIndex = (index, predecessor, successor) => {
|
|
11403
|
+
if (!index) {
|
|
11404
|
+
return false;
|
|
11405
|
+
}
|
|
11406
|
+
try {
|
|
11407
|
+
validateOrderKey(index);
|
|
11408
|
+
} catch {
|
|
11409
|
+
return false;
|
|
11410
|
+
}
|
|
11411
|
+
if (predecessor && successor) {
|
|
11412
|
+
return predecessor < index && index < successor;
|
|
11413
|
+
}
|
|
11414
|
+
if (!predecessor && successor) {
|
|
11415
|
+
return index < successor;
|
|
11416
|
+
}
|
|
11417
|
+
if (predecessor && !successor) {
|
|
11418
|
+
return predecessor < index;
|
|
11419
|
+
}
|
|
11420
|
+
return !!index;
|
|
11421
|
+
};
|
|
11422
|
+
var generateIndices = (elements, indicesGroups) => {
|
|
11423
|
+
const elementsUpdates = /* @__PURE__ */ new Map();
|
|
11424
|
+
for (const indices of indicesGroups) {
|
|
11425
|
+
const lowerBoundIndex = indices.shift();
|
|
11426
|
+
const upperBoundIndex = indices.pop();
|
|
11427
|
+
const fractionalIndices = generateNKeysBetween(
|
|
11428
|
+
elements[lowerBoundIndex]?.index,
|
|
11429
|
+
elements[upperBoundIndex]?.index,
|
|
11430
|
+
indices.length
|
|
11431
|
+
);
|
|
11432
|
+
for (let i = 0; i < indices.length; i++) {
|
|
11433
|
+
const element = elements[indices[i]];
|
|
11434
|
+
elementsUpdates.set(element, {
|
|
11435
|
+
index: fractionalIndices[i]
|
|
11436
|
+
});
|
|
11437
|
+
}
|
|
11438
|
+
}
|
|
11439
|
+
return elementsUpdates;
|
|
11440
|
+
};
|
|
11441
|
+
var isOrderedElement = (element) => {
|
|
11442
|
+
if (element.index) {
|
|
11443
|
+
return true;
|
|
11444
|
+
}
|
|
11445
|
+
return false;
|
|
11446
|
+
};
|
|
11447
|
+
|
|
11448
|
+
// src/frame.ts
|
|
11449
|
+
var bindElementsToFramesAfterDuplication = (nextElements, origElements, origIdToDuplicateId) => {
|
|
11185
11450
|
const nextElementMap = arrayToMap5(nextElements);
|
|
11186
11451
|
for (const element of origElements) {
|
|
11187
11452
|
if (element.frameId) {
|
|
@@ -11201,7 +11466,7 @@ function isElementIntersectingFrame(element, frame, elementsMap) {
|
|
|
11201
11466
|
const elementLineSegments = getElementLineSegments(element, elementsMap);
|
|
11202
11467
|
const intersecting = frameLineSegments.some(
|
|
11203
11468
|
(frameLineSegment) => elementLineSegments.some(
|
|
11204
|
-
(elementLineSegment) =>
|
|
11469
|
+
(elementLineSegment) => segmentsIntersectAt2(frameLineSegment, elementLineSegment)
|
|
11205
11470
|
)
|
|
11206
11471
|
);
|
|
11207
11472
|
return intersecting;
|
|
@@ -11212,8 +11477,9 @@ var getElementsCompletelyInFrame = (elements, frame, elementsMap) => omitGroupsC
|
|
|
11212
11477
|
(element) => !isFrameLikeElement(element) && !element.frameId || element.frameId === frame.id
|
|
11213
11478
|
);
|
|
11214
11479
|
var isElementContainingFrame = (element, frame, elementsMap) => {
|
|
11215
|
-
return
|
|
11216
|
-
(
|
|
11480
|
+
return boundsContainBounds(
|
|
11481
|
+
getElementBounds(element, elementsMap),
|
|
11482
|
+
getElementBounds(frame, elementsMap)
|
|
11217
11483
|
);
|
|
11218
11484
|
};
|
|
11219
11485
|
var getElementsIntersectingFrame = (elements, frame) => {
|
|
@@ -11236,9 +11502,9 @@ var elementOverlapsWithFrame = (element, frame, elementsMap) => {
|
|
|
11236
11502
|
var isCursorInFrame = (cursorCoords, frame, elementsMap) => {
|
|
11237
11503
|
const [fx1, fy1, fx2, fy2] = getElementAbsoluteCoords2(frame, elementsMap);
|
|
11238
11504
|
return isPointWithinBounds2(
|
|
11239
|
-
|
|
11240
|
-
|
|
11241
|
-
|
|
11505
|
+
pointFrom10(fx1, fy1),
|
|
11506
|
+
pointFrom10(cursorCoords.x, cursorCoords.y),
|
|
11507
|
+
pointFrom10(fx2, fy2)
|
|
11242
11508
|
);
|
|
11243
11509
|
};
|
|
11244
11510
|
var groupsAreAtLeastIntersectingTheFrame = (elements, groupIds, frame) => {
|
|
@@ -11446,16 +11712,35 @@ var filterElementsEligibleAsFrameChildren = (elements, frame) => {
|
|
|
11446
11712
|
}
|
|
11447
11713
|
return eligibleElements;
|
|
11448
11714
|
};
|
|
11449
|
-
var
|
|
11450
|
-
|
|
11451
|
-
const
|
|
11452
|
-
|
|
11453
|
-
|
|
11454
|
-
|
|
11715
|
+
var getCommonFrameId = (elements) => {
|
|
11716
|
+
let commonFrameId;
|
|
11717
|
+
for (const element of elements) {
|
|
11718
|
+
if (isFrameLikeElement(element) || !element.frameId) {
|
|
11719
|
+
return null;
|
|
11720
|
+
}
|
|
11721
|
+
if (commonFrameId === void 0) {
|
|
11722
|
+
commonFrameId = element.frameId;
|
|
11723
|
+
} else if (commonFrameId !== element.frameId) {
|
|
11724
|
+
return null;
|
|
11725
|
+
}
|
|
11726
|
+
}
|
|
11727
|
+
return commonFrameId ?? null;
|
|
11728
|
+
};
|
|
11729
|
+
var getFrameChildrenInsertionIndex = (elements, frameId) => {
|
|
11730
|
+
for (let index = elements.length - 1; index >= 0; index--) {
|
|
11731
|
+
const element = elements[index];
|
|
11732
|
+
if (element.id === frameId) {
|
|
11733
|
+
return index;
|
|
11734
|
+
} else if (element.frameId === frameId) {
|
|
11735
|
+
return index + 1;
|
|
11455
11736
|
}
|
|
11456
11737
|
}
|
|
11457
|
-
|
|
11458
|
-
|
|
11738
|
+
return null;
|
|
11739
|
+
};
|
|
11740
|
+
var addElementsToFrame = (allElements, elementsToAdd, frame) => {
|
|
11741
|
+
const elementsMap = arrayToMap5(allElements);
|
|
11742
|
+
const commonFrameId = getCommonFrameId(elementsToAdd);
|
|
11743
|
+
const finalElementsToAdd = /* @__PURE__ */ new Set();
|
|
11459
11744
|
const otherFrames = /* @__PURE__ */ new Set();
|
|
11460
11745
|
for (const element of elementsToAdd) {
|
|
11461
11746
|
if (isFrameLikeElement(element) && element.id !== frame.id) {
|
|
@@ -11469,23 +11754,41 @@ var addElementsToFrame = (allElements, elementsToAdd, frame, appState) => {
|
|
|
11469
11754
|
if (isFrameLikeElement(element) || element.frameId && otherFrames.has(element.frameId)) {
|
|
11470
11755
|
continue;
|
|
11471
11756
|
}
|
|
11472
|
-
|
|
11473
|
-
continue;
|
|
11474
|
-
}
|
|
11475
|
-
if (!currTargetFrameChildrenMap.has(element.id)) {
|
|
11476
|
-
finalElementsToAdd.push(element);
|
|
11477
|
-
}
|
|
11757
|
+
finalElementsToAdd.add(element);
|
|
11478
11758
|
const boundTextElement = getBoundTextElement(element, elementsMap);
|
|
11479
|
-
if (boundTextElement && !
|
|
11480
|
-
finalElementsToAdd.
|
|
11759
|
+
if (boundTextElement && !finalElementsToAdd.has(boundTextElement)) {
|
|
11760
|
+
finalElementsToAdd.add(boundTextElement);
|
|
11481
11761
|
}
|
|
11482
11762
|
}
|
|
11483
11763
|
for (const element of finalElementsToAdd) {
|
|
11484
|
-
|
|
11485
|
-
|
|
11486
|
-
|
|
11764
|
+
if (element.frameId !== frame.id) {
|
|
11765
|
+
mutateElement(element, elementsMap, {
|
|
11766
|
+
frameId: frame.id
|
|
11767
|
+
});
|
|
11768
|
+
}
|
|
11487
11769
|
}
|
|
11488
|
-
|
|
11770
|
+
if (!finalElementsToAdd.size || // if all elements to add already belong to the frame, then we don't want to
|
|
11771
|
+
// reorder (case: we're dragging element children within the frame)
|
|
11772
|
+
commonFrameId === frame.id) {
|
|
11773
|
+
return allElements;
|
|
11774
|
+
}
|
|
11775
|
+
const otherElements = Array.from(allElements.values()).filter(
|
|
11776
|
+
(element) => !finalElementsToAdd.has(element)
|
|
11777
|
+
);
|
|
11778
|
+
const insertionIndex = getFrameChildrenInsertionIndex(
|
|
11779
|
+
otherElements,
|
|
11780
|
+
frame.id
|
|
11781
|
+
);
|
|
11782
|
+
if (insertionIndex === null) {
|
|
11783
|
+
return allElements;
|
|
11784
|
+
}
|
|
11785
|
+
const reorderedElements = [
|
|
11786
|
+
...otherElements.slice(0, insertionIndex),
|
|
11787
|
+
...finalElementsToAdd,
|
|
11788
|
+
...otherElements.slice(insertionIndex)
|
|
11789
|
+
];
|
|
11790
|
+
syncMovedIndices(reorderedElements, arrayToMap5([...finalElementsToAdd]));
|
|
11791
|
+
return Array.isArray(allElements) ? reorderedElements : new Map(reorderedElements.map((element) => [element.id, element]));
|
|
11489
11792
|
};
|
|
11490
11793
|
var removeElementsFromFrame = (elementsToRemove, elementsMap) => {
|
|
11491
11794
|
const _elementsToRemove = /* @__PURE__ */ new Map();
|
|
@@ -11514,12 +11817,11 @@ var removeAllElementsFromFrame = (allElements, frame) => {
|
|
|
11514
11817
|
removeElementsFromFrame(elementsInFrame, arrayToMap5(allElements));
|
|
11515
11818
|
return allElements;
|
|
11516
11819
|
};
|
|
11517
|
-
var replaceAllElementsInFrame = (allElements, nextElementsInFrame, frame
|
|
11820
|
+
var replaceAllElementsInFrame = (allElements, nextElementsInFrame, frame) => {
|
|
11518
11821
|
return addElementsToFrame(
|
|
11519
11822
|
removeAllElementsFromFrame(allElements, frame),
|
|
11520
11823
|
nextElementsInFrame,
|
|
11521
|
-
frame
|
|
11522
|
-
app.state
|
|
11824
|
+
frame
|
|
11523
11825
|
).slice();
|
|
11524
11826
|
};
|
|
11525
11827
|
var updateFrameMembershipOfSelectedElements = (allElements, appState, app) => {
|
|
@@ -11684,12 +11986,17 @@ var getDefaultFrameName = (element) => {
|
|
|
11684
11986
|
var getFrameLikeTitle = (element) => {
|
|
11685
11987
|
return element.name === null ? getDefaultFrameName(element) : element.name;
|
|
11686
11988
|
};
|
|
11687
|
-
var getElementsOverlappingFrame = (elements, frame) => {
|
|
11688
|
-
return
|
|
11689
|
-
|
|
11690
|
-
|
|
11691
|
-
|
|
11692
|
-
|
|
11989
|
+
var getElementsOverlappingFrame = (elements, frame, elementsMap) => {
|
|
11990
|
+
return elements.filter(
|
|
11991
|
+
(el) => (
|
|
11992
|
+
// exclude elements which are overlapping, but are in a different frame,
|
|
11993
|
+
// and thus invisible in target frame
|
|
11994
|
+
(!el.frameId || el.frameId === frame.id) && doBoundsIntersect(
|
|
11995
|
+
getElementBounds(el, elementsMap),
|
|
11996
|
+
getElementBounds(frame, elementsMap)
|
|
11997
|
+
)
|
|
11998
|
+
)
|
|
11999
|
+
);
|
|
11693
12000
|
};
|
|
11694
12001
|
var frameAndChildrenSelectedTogether = (selectedElements) => {
|
|
11695
12002
|
const selectedElementsMap = arrayToMap5(selectedElements);
|
|
@@ -11878,7 +12185,10 @@ var drawElementOnCanvas = (element, rc, context, renderConfig) => {
|
|
|
11878
12185
|
const shapes = ShapeCache.generateElementShape(element, renderConfig);
|
|
11879
12186
|
for (const shape of shapes) {
|
|
11880
12187
|
if (typeof shape === "string") {
|
|
11881
|
-
context.fillStyle =
|
|
12188
|
+
context.fillStyle = applyDarkModeFilter(
|
|
12189
|
+
element.strokeColor,
|
|
12190
|
+
renderConfig.theme === THEME.DARK
|
|
12191
|
+
);
|
|
11882
12192
|
context.fill(new Path2D(shape));
|
|
11883
12193
|
} else {
|
|
11884
12194
|
rc.draw(shape);
|
|
@@ -11986,7 +12296,10 @@ var drawElementOnCanvas = (element, rc, context, renderConfig) => {
|
|
|
11986
12296
|
context.canvas.setAttribute("dir", rtl ? "rtl" : "ltr");
|
|
11987
12297
|
context.save();
|
|
11988
12298
|
context.font = getFontString3(element);
|
|
11989
|
-
context.fillStyle =
|
|
12299
|
+
context.fillStyle = applyDarkModeFilter(
|
|
12300
|
+
element.strokeColor,
|
|
12301
|
+
renderConfig.theme === THEME.DARK
|
|
12302
|
+
);
|
|
11990
12303
|
context.textAlign = element.textAlign;
|
|
11991
12304
|
const lines = element.text.replace(/\r\n?/g, "\n").split("\n");
|
|
11992
12305
|
const horizontalOffset = element.textAlign === "center" ? element.width / 2 : element.textAlign === "right" ? element.width : 0;
|
|
@@ -12134,7 +12447,10 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
|
|
|
12134
12447
|
);
|
|
12135
12448
|
context.fillStyle = "rgba(0, 0, 200, 0.04)";
|
|
12136
12449
|
context.lineWidth = FRAME_STYLE.strokeWidth / appState.zoom.value;
|
|
12137
|
-
context.strokeStyle =
|
|
12450
|
+
context.strokeStyle = applyDarkModeFilter(
|
|
12451
|
+
FRAME_STYLE.strokeColor,
|
|
12452
|
+
appState.theme === THEME.DARK
|
|
12453
|
+
);
|
|
12138
12454
|
if (isMagicFrameElement(element)) {
|
|
12139
12455
|
context.strokeStyle = appState.theme === THEME.LIGHT ? "#7affd7" : applyDarkModeFilter("#1d8264");
|
|
12140
12456
|
}
|
|
@@ -12337,7 +12653,7 @@ function getFreedrawOutlineAsSegments(element, points, elementsMap) {
|
|
|
12337
12653
|
},
|
|
12338
12654
|
elementsMap
|
|
12339
12655
|
);
|
|
12340
|
-
const center =
|
|
12656
|
+
const center = pointFrom11(
|
|
12341
12657
|
(bounds[0] + bounds[2]) / 2,
|
|
12342
12658
|
(bounds[1] + bounds[3]) / 2
|
|
12343
12659
|
);
|
|
@@ -12347,8 +12663,8 @@ function getFreedrawOutlineAsSegments(element, points, elementsMap) {
|
|
|
12347
12663
|
acc.push(
|
|
12348
12664
|
lineSegment5(
|
|
12349
12665
|
acc[acc.length - 1][1],
|
|
12350
|
-
|
|
12351
|
-
|
|
12666
|
+
pointRotateRads10(
|
|
12667
|
+
pointFrom11(curr[0] + element.x, curr[1] + element.y),
|
|
12352
12668
|
center,
|
|
12353
12669
|
element.angle
|
|
12354
12670
|
)
|
|
@@ -12358,16 +12674,16 @@ function getFreedrawOutlineAsSegments(element, points, elementsMap) {
|
|
|
12358
12674
|
},
|
|
12359
12675
|
[
|
|
12360
12676
|
lineSegment5(
|
|
12361
|
-
|
|
12362
|
-
|
|
12677
|
+
pointRotateRads10(
|
|
12678
|
+
pointFrom11(
|
|
12363
12679
|
points[0][0] + element.x,
|
|
12364
12680
|
points[0][1] + element.y
|
|
12365
12681
|
),
|
|
12366
12682
|
center,
|
|
12367
12683
|
element.angle
|
|
12368
12684
|
),
|
|
12369
|
-
|
|
12370
|
-
|
|
12685
|
+
pointRotateRads10(
|
|
12686
|
+
pointFrom11(
|
|
12371
12687
|
points[1][0] + element.x,
|
|
12372
12688
|
points[1][1] + element.y
|
|
12373
12689
|
),
|
|
@@ -12379,16 +12695,6 @@ function getFreedrawOutlineAsSegments(element, points, elementsMap) {
|
|
|
12379
12695
|
);
|
|
12380
12696
|
}
|
|
12381
12697
|
|
|
12382
|
-
// src/comparisons.ts
|
|
12383
|
-
init_define_import_meta_env();
|
|
12384
|
-
var hasBackground = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "line" || type === "freedraw";
|
|
12385
|
-
var hasStrokeColor = (type) => type === "rectangle" || type === "ellipse" || type === "diamond" || type === "freedraw" || type === "arrow" || type === "line" || type === "text" || type === "embeddable";
|
|
12386
|
-
var hasStrokeWidth = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "freedraw" || type === "arrow" || type === "line";
|
|
12387
|
-
var hasStrokeStyle = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "arrow" || type === "line";
|
|
12388
|
-
var canChangeRoundness = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "line" || type === "diamond" || type === "image";
|
|
12389
|
-
var toolIsArrow = (type) => type === "arrow";
|
|
12390
|
-
var canHaveArrowheads = (type) => type === "arrow";
|
|
12391
|
-
|
|
12392
12698
|
// src/shape.ts
|
|
12393
12699
|
var ShapeCache = class _ShapeCache {
|
|
12394
12700
|
static rg = new RoughGenerator();
|
|
@@ -12472,7 +12778,7 @@ var generateRoughOptions = (element, continuousPath = false, isDarkMode = false)
|
|
|
12472
12778
|
fillWeight: element.strokeWidth / 2,
|
|
12473
12779
|
hachureGap: element.strokeWidth * 4,
|
|
12474
12780
|
roughness: adjustRoughness(element),
|
|
12475
|
-
stroke:
|
|
12781
|
+
stroke: applyDarkModeFilter2(element.strokeColor, isDarkMode),
|
|
12476
12782
|
preserveVertices: continuousPath || element.roughness < ROUGHNESS.cartoonist
|
|
12477
12783
|
};
|
|
12478
12784
|
switch (element.type) {
|
|
@@ -12482,7 +12788,7 @@ var generateRoughOptions = (element, continuousPath = false, isDarkMode = false)
|
|
|
12482
12788
|
case "diamond":
|
|
12483
12789
|
case "ellipse": {
|
|
12484
12790
|
options.fillStyle = element.fillStyle;
|
|
12485
|
-
options.fill = isTransparent3(element.backgroundColor) ? void 0 :
|
|
12791
|
+
options.fill = isTransparent3(element.backgroundColor) ? void 0 : applyDarkModeFilter2(element.backgroundColor, isDarkMode);
|
|
12486
12792
|
if (element.type === "ellipse") {
|
|
12487
12793
|
options.curveFitting = 1;
|
|
12488
12794
|
}
|
|
@@ -12492,7 +12798,7 @@ var generateRoughOptions = (element, continuousPath = false, isDarkMode = false)
|
|
|
12492
12798
|
case "freedraw": {
|
|
12493
12799
|
if (isPathALoop(element.points)) {
|
|
12494
12800
|
options.fillStyle = element.fillStyle;
|
|
12495
|
-
options.fill = element.backgroundColor === "transparent" ? void 0 :
|
|
12801
|
+
options.fill = element.backgroundColor === "transparent" ? void 0 : applyDarkModeFilter2(element.backgroundColor, isDarkMode);
|
|
12496
12802
|
}
|
|
12497
12803
|
return options;
|
|
12498
12804
|
}
|
|
@@ -12520,44 +12826,90 @@ var modifyIframeLikeForRoughOptions = (element, isExporting, embedsValidationSta
|
|
|
12520
12826
|
}
|
|
12521
12827
|
return element;
|
|
12522
12828
|
};
|
|
12523
|
-
var
|
|
12524
|
-
const arrowheadPoints = getArrowheadPoints(
|
|
12525
|
-
element,
|
|
12526
|
-
shape,
|
|
12527
|
-
position,
|
|
12528
|
-
arrowhead
|
|
12529
|
-
);
|
|
12829
|
+
var generateArrowheadCardinalityOne = (generator, arrowheadPoints, lineOptions) => {
|
|
12530
12830
|
if (arrowheadPoints === null) {
|
|
12531
12831
|
return [];
|
|
12532
12832
|
}
|
|
12533
|
-
const
|
|
12534
|
-
|
|
12535
|
-
|
|
12536
|
-
|
|
12537
|
-
|
|
12538
|
-
return [
|
|
12833
|
+
const [, , x3, y3, x4, y4] = arrowheadPoints;
|
|
12834
|
+
return [generator.line(x3, y3, x4, y4, lineOptions)];
|
|
12835
|
+
};
|
|
12836
|
+
var generateArrowheadLinesToTip = (generator, arrowheadPoints, lineOptions) => {
|
|
12837
|
+
if (arrowheadPoints === null) {
|
|
12838
|
+
return [];
|
|
12839
|
+
}
|
|
12840
|
+
const [x2, y2, x3, y3, x4, y4] = arrowheadPoints;
|
|
12841
|
+
return [
|
|
12842
|
+
generator.line(x3, y3, x2, y2, lineOptions),
|
|
12843
|
+
generator.line(x4, y4, x2, y2, lineOptions)
|
|
12844
|
+
];
|
|
12845
|
+
};
|
|
12846
|
+
var getArrowheadLineOptions = (element, options) => {
|
|
12847
|
+
const lineOptions = { ...options };
|
|
12848
|
+
if (element.strokeStyle === "dotted") {
|
|
12849
|
+
const dash = getDashArrayDotted(element.strokeWidth - 1);
|
|
12850
|
+
lineOptions.strokeLineDash = [dash[0], dash[1] - 1];
|
|
12851
|
+
} else {
|
|
12852
|
+
delete lineOptions.strokeLineDash;
|
|
12853
|
+
}
|
|
12854
|
+
lineOptions.roughness = Math.min(1, lineOptions.roughness || 0);
|
|
12855
|
+
return lineOptions;
|
|
12856
|
+
};
|
|
12857
|
+
var generateArrowheadOutlineCircle = (generator, options, strokeColor, arrowheadPoints, fill, diameterScale = 1) => {
|
|
12858
|
+
if (arrowheadPoints === null) {
|
|
12859
|
+
return [];
|
|
12860
|
+
}
|
|
12861
|
+
const [x, y, diameter] = arrowheadPoints;
|
|
12862
|
+
const circleOptions = {
|
|
12863
|
+
...options,
|
|
12864
|
+
fill,
|
|
12865
|
+
fillStyle: "solid",
|
|
12866
|
+
stroke: strokeColor,
|
|
12867
|
+
roughness: Math.min(0.5, options.roughness || 0)
|
|
12539
12868
|
};
|
|
12540
|
-
|
|
12869
|
+
delete circleOptions.strokeLineDash;
|
|
12870
|
+
return [generator.circle(x, y, diameter * diameterScale, circleOptions)];
|
|
12871
|
+
};
|
|
12872
|
+
var getArrowheadShapes = (element, shape, position, arrowhead, generator, options, canvasBackgroundColor, isDarkMode) => {
|
|
12873
|
+
if (arrowhead === null) {
|
|
12874
|
+
return [];
|
|
12875
|
+
}
|
|
12876
|
+
const strokeColor = applyDarkModeFilter2(element.strokeColor, isDarkMode);
|
|
12877
|
+
const backgroundFillColor = applyDarkModeFilter2(
|
|
12878
|
+
canvasBackgroundColor,
|
|
12879
|
+
isDarkMode
|
|
12880
|
+
);
|
|
12881
|
+
const cardinalityOneOrManyOffset = -0.25;
|
|
12882
|
+
const cardinalityZeroCircleScale = 0.8;
|
|
12541
12883
|
switch (arrowhead) {
|
|
12542
|
-
case "dot":
|
|
12543
12884
|
case "circle":
|
|
12544
12885
|
case "circle_outline": {
|
|
12545
|
-
|
|
12546
|
-
|
|
12547
|
-
|
|
12548
|
-
|
|
12549
|
-
|
|
12550
|
-
|
|
12551
|
-
|
|
12552
|
-
stroke: strokeColor,
|
|
12553
|
-
roughness: Math.min(0.5, options.roughness || 0)
|
|
12554
|
-
})
|
|
12555
|
-
];
|
|
12886
|
+
return generateArrowheadOutlineCircle(
|
|
12887
|
+
generator,
|
|
12888
|
+
options,
|
|
12889
|
+
strokeColor,
|
|
12890
|
+
getArrowheadPoints(element, shape, position, arrowhead),
|
|
12891
|
+
arrowhead === "circle_outline" ? backgroundFillColor : strokeColor
|
|
12892
|
+
);
|
|
12556
12893
|
}
|
|
12557
12894
|
case "triangle":
|
|
12558
12895
|
case "triangle_outline": {
|
|
12896
|
+
const arrowheadPoints = getArrowheadPoints(
|
|
12897
|
+
element,
|
|
12898
|
+
shape,
|
|
12899
|
+
position,
|
|
12900
|
+
arrowhead
|
|
12901
|
+
);
|
|
12902
|
+
if (arrowheadPoints === null) {
|
|
12903
|
+
return [];
|
|
12904
|
+
}
|
|
12559
12905
|
const [x, y, x2, y2, x3, y3] = arrowheadPoints;
|
|
12560
|
-
|
|
12906
|
+
const triangleOptions = {
|
|
12907
|
+
...options,
|
|
12908
|
+
fill: arrowhead === "triangle_outline" ? backgroundFillColor : strokeColor,
|
|
12909
|
+
fillStyle: "solid",
|
|
12910
|
+
roughness: Math.min(1, options.roughness || 0)
|
|
12911
|
+
};
|
|
12912
|
+
delete triangleOptions.strokeLineDash;
|
|
12561
12913
|
return [
|
|
12562
12914
|
generator.polygon(
|
|
12563
12915
|
[
|
|
@@ -12566,19 +12918,29 @@ var getArrowheadShapes = (element, shape, position, arrowhead, generator, option
|
|
|
12566
12918
|
[x3, y3],
|
|
12567
12919
|
[x, y]
|
|
12568
12920
|
],
|
|
12569
|
-
|
|
12570
|
-
...options,
|
|
12571
|
-
fill: arrowhead === "triangle_outline" ? canvasBackgroundColor : strokeColor,
|
|
12572
|
-
fillStyle: "solid",
|
|
12573
|
-
roughness: Math.min(1, options.roughness || 0)
|
|
12574
|
-
}
|
|
12921
|
+
triangleOptions
|
|
12575
12922
|
)
|
|
12576
12923
|
];
|
|
12577
12924
|
}
|
|
12578
12925
|
case "diamond":
|
|
12579
12926
|
case "diamond_outline": {
|
|
12927
|
+
const arrowheadPoints = getArrowheadPoints(
|
|
12928
|
+
element,
|
|
12929
|
+
shape,
|
|
12930
|
+
position,
|
|
12931
|
+
arrowhead
|
|
12932
|
+
);
|
|
12933
|
+
if (arrowheadPoints === null) {
|
|
12934
|
+
return [];
|
|
12935
|
+
}
|
|
12580
12936
|
const [x, y, x2, y2, x3, y3, x4, y4] = arrowheadPoints;
|
|
12581
|
-
|
|
12937
|
+
const diamondOptions = {
|
|
12938
|
+
...options,
|
|
12939
|
+
fill: arrowhead === "diamond_outline" ? backgroundFillColor : strokeColor,
|
|
12940
|
+
fillStyle: "solid",
|
|
12941
|
+
roughness: Math.min(1, options.roughness || 0)
|
|
12942
|
+
};
|
|
12943
|
+
delete diamondOptions.strokeLineDash;
|
|
12582
12944
|
return [
|
|
12583
12945
|
generator.polygon(
|
|
12584
12946
|
[
|
|
@@ -12588,42 +12950,106 @@ var getArrowheadShapes = (element, shape, position, arrowhead, generator, option
|
|
|
12588
12950
|
[x4, y4],
|
|
12589
12951
|
[x, y]
|
|
12590
12952
|
],
|
|
12591
|
-
|
|
12592
|
-
|
|
12593
|
-
|
|
12594
|
-
|
|
12595
|
-
|
|
12596
|
-
|
|
12953
|
+
diamondOptions
|
|
12954
|
+
)
|
|
12955
|
+
];
|
|
12956
|
+
}
|
|
12957
|
+
case "cardinality_one":
|
|
12958
|
+
return generateArrowheadCardinalityOne(
|
|
12959
|
+
generator,
|
|
12960
|
+
getArrowheadPoints(element, shape, position, arrowhead),
|
|
12961
|
+
getArrowheadLineOptions(element, options)
|
|
12962
|
+
);
|
|
12963
|
+
case "cardinality_many":
|
|
12964
|
+
return generateArrowheadLinesToTip(
|
|
12965
|
+
generator,
|
|
12966
|
+
getArrowheadPoints(element, shape, position, arrowhead),
|
|
12967
|
+
getArrowheadLineOptions(element, options)
|
|
12968
|
+
);
|
|
12969
|
+
case "cardinality_one_or_many": {
|
|
12970
|
+
const lineOptions = getArrowheadLineOptions(element, options);
|
|
12971
|
+
return [
|
|
12972
|
+
...generateArrowheadLinesToTip(
|
|
12973
|
+
generator,
|
|
12974
|
+
getArrowheadPoints(element, shape, position, "cardinality_many"),
|
|
12975
|
+
lineOptions
|
|
12976
|
+
),
|
|
12977
|
+
...generateArrowheadCardinalityOne(
|
|
12978
|
+
generator,
|
|
12979
|
+
getArrowheadPoints(
|
|
12980
|
+
element,
|
|
12981
|
+
shape,
|
|
12982
|
+
position,
|
|
12983
|
+
"cardinality_one",
|
|
12984
|
+
cardinalityOneOrManyOffset
|
|
12985
|
+
),
|
|
12986
|
+
lineOptions
|
|
12987
|
+
)
|
|
12988
|
+
];
|
|
12989
|
+
}
|
|
12990
|
+
case "cardinality_exactly_one": {
|
|
12991
|
+
const lineOptions = getArrowheadLineOptions(element, options);
|
|
12992
|
+
return [
|
|
12993
|
+
...generateArrowheadCardinalityOne(
|
|
12994
|
+
generator,
|
|
12995
|
+
getArrowheadPoints(element, shape, position, "cardinality_one", -0.5),
|
|
12996
|
+
lineOptions
|
|
12997
|
+
),
|
|
12998
|
+
...generateArrowheadCardinalityOne(
|
|
12999
|
+
generator,
|
|
13000
|
+
getArrowheadPoints(element, shape, position, "cardinality_one"),
|
|
13001
|
+
lineOptions
|
|
13002
|
+
)
|
|
13003
|
+
];
|
|
13004
|
+
}
|
|
13005
|
+
case "cardinality_zero_or_one": {
|
|
13006
|
+
const lineOptions = getArrowheadLineOptions(element, options);
|
|
13007
|
+
return [
|
|
13008
|
+
...generateArrowheadOutlineCircle(
|
|
13009
|
+
generator,
|
|
13010
|
+
options,
|
|
13011
|
+
strokeColor,
|
|
13012
|
+
getArrowheadPoints(element, shape, position, "circle_outline", 1.5),
|
|
13013
|
+
backgroundFillColor,
|
|
13014
|
+
cardinalityZeroCircleScale
|
|
13015
|
+
),
|
|
13016
|
+
...generateArrowheadCardinalityOne(
|
|
13017
|
+
generator,
|
|
13018
|
+
getArrowheadPoints(element, shape, position, "cardinality_one", -0.5),
|
|
13019
|
+
lineOptions
|
|
13020
|
+
)
|
|
13021
|
+
];
|
|
13022
|
+
}
|
|
13023
|
+
case "cardinality_zero_or_many": {
|
|
13024
|
+
const lineOptions = getArrowheadLineOptions(element, options);
|
|
13025
|
+
return [
|
|
13026
|
+
...generateArrowheadLinesToTip(
|
|
13027
|
+
generator,
|
|
13028
|
+
getArrowheadPoints(element, shape, position, "cardinality_many"),
|
|
13029
|
+
lineOptions
|
|
13030
|
+
),
|
|
13031
|
+
...generateArrowheadOutlineCircle(
|
|
13032
|
+
generator,
|
|
13033
|
+
options,
|
|
13034
|
+
strokeColor,
|
|
13035
|
+
getArrowheadPoints(element, shape, position, "circle_outline", 1.5),
|
|
13036
|
+
backgroundFillColor,
|
|
13037
|
+
cardinalityZeroCircleScale
|
|
12597
13038
|
)
|
|
12598
13039
|
];
|
|
12599
13040
|
}
|
|
12600
|
-
case "crowfoot_one":
|
|
12601
|
-
return generateCrowfootOne(arrowheadPoints, options);
|
|
12602
13041
|
case "bar":
|
|
12603
13042
|
case "arrow":
|
|
12604
|
-
case "crowfoot_many":
|
|
12605
|
-
case "crowfoot_one_or_many":
|
|
12606
13043
|
default: {
|
|
12607
|
-
|
|
12608
|
-
|
|
12609
|
-
|
|
12610
|
-
|
|
12611
|
-
|
|
12612
|
-
delete options.strokeLineDash;
|
|
12613
|
-
}
|
|
12614
|
-
options.roughness = Math.min(1, options.roughness || 0);
|
|
12615
|
-
return [
|
|
12616
|
-
generator.line(x3, y3, x2, y2, options),
|
|
12617
|
-
generator.line(x4, y4, x2, y2, options),
|
|
12618
|
-
...arrowhead === "crowfoot_one_or_many" ? generateCrowfootOne(
|
|
12619
|
-
getArrowheadPoints(element, shape, position, "crowfoot_one"),
|
|
12620
|
-
options
|
|
12621
|
-
) : []
|
|
12622
|
-
];
|
|
13044
|
+
return generateArrowheadLinesToTip(
|
|
13045
|
+
generator,
|
|
13046
|
+
getArrowheadPoints(element, shape, position, arrowhead),
|
|
13047
|
+
getArrowheadLineOptions(element, options)
|
|
13048
|
+
);
|
|
12623
13049
|
}
|
|
12624
13050
|
}
|
|
12625
13051
|
};
|
|
12626
|
-
var generateLinearCollisionShape = (element) => {
|
|
13052
|
+
var generateLinearCollisionShape = (element, elementsMap) => {
|
|
12627
13053
|
const generator = new RoughGenerator();
|
|
12628
13054
|
const options = {
|
|
12629
13055
|
seed: element.seed,
|
|
@@ -12632,43 +13058,30 @@ var generateLinearCollisionShape = (element) => {
|
|
|
12632
13058
|
roughness: 0,
|
|
12633
13059
|
preserveVertices: true
|
|
12634
13060
|
};
|
|
12635
|
-
const center =
|
|
12636
|
-
// Need a non-rotated center point
|
|
12637
|
-
element.points.reduce(
|
|
12638
|
-
(acc, point) => {
|
|
12639
|
-
return [
|
|
12640
|
-
Math.min(element.x + point[0], acc[0]),
|
|
12641
|
-
Math.min(element.y + point[1], acc[1]),
|
|
12642
|
-
Math.max(element.x + point[0], acc[2]),
|
|
12643
|
-
Math.max(element.y + point[1], acc[3])
|
|
12644
|
-
];
|
|
12645
|
-
},
|
|
12646
|
-
[Infinity, Infinity, -Infinity, -Infinity]
|
|
12647
|
-
)
|
|
12648
|
-
);
|
|
13061
|
+
const center = elementCenterPoint(element, elementsMap);
|
|
12649
13062
|
switch (element.type) {
|
|
12650
13063
|
case "line":
|
|
12651
13064
|
case "arrow": {
|
|
12652
|
-
const points = element.points.length ? element.points : [
|
|
13065
|
+
const points = element.points.length ? element.points : [pointFrom12(0, 0)];
|
|
12653
13066
|
if (isElbowArrow(element)) {
|
|
12654
13067
|
return generator.path(generateElbowArrowShape(points, 16), options).sets[0].ops;
|
|
12655
13068
|
} else if (!element.roundness) {
|
|
12656
13069
|
return points.map((point, idx) => {
|
|
12657
|
-
const p =
|
|
12658
|
-
|
|
13070
|
+
const p = pointRotateRads11(
|
|
13071
|
+
pointFrom12(element.x + point[0], element.y + point[1]),
|
|
12659
13072
|
center,
|
|
12660
13073
|
element.angle
|
|
12661
13074
|
);
|
|
12662
13075
|
return {
|
|
12663
13076
|
op: idx === 0 ? "move" : "lineTo",
|
|
12664
|
-
data:
|
|
13077
|
+
data: pointFrom12(p[0] - element.x, p[1] - element.y)
|
|
12665
13078
|
};
|
|
12666
13079
|
});
|
|
12667
13080
|
}
|
|
12668
13081
|
return generator.curve(points, options).sets[0].ops.slice(0, element.points.length).map((op, i) => {
|
|
12669
13082
|
if (i === 0) {
|
|
12670
|
-
const p =
|
|
12671
|
-
|
|
13083
|
+
const p = pointRotateRads11(
|
|
13084
|
+
pointFrom12(
|
|
12672
13085
|
element.x + op.data[0],
|
|
12673
13086
|
element.y + op.data[1]
|
|
12674
13087
|
),
|
|
@@ -12677,30 +13090,30 @@ var generateLinearCollisionShape = (element) => {
|
|
|
12677
13090
|
);
|
|
12678
13091
|
return {
|
|
12679
13092
|
op: "move",
|
|
12680
|
-
data:
|
|
13093
|
+
data: pointFrom12(p[0] - element.x, p[1] - element.y)
|
|
12681
13094
|
};
|
|
12682
13095
|
}
|
|
12683
13096
|
return {
|
|
12684
13097
|
op: "bcurveTo",
|
|
12685
13098
|
data: [
|
|
12686
|
-
|
|
12687
|
-
|
|
13099
|
+
pointRotateRads11(
|
|
13100
|
+
pointFrom12(
|
|
12688
13101
|
element.x + op.data[0],
|
|
12689
13102
|
element.y + op.data[1]
|
|
12690
13103
|
),
|
|
12691
13104
|
center,
|
|
12692
13105
|
element.angle
|
|
12693
13106
|
),
|
|
12694
|
-
|
|
12695
|
-
|
|
13107
|
+
pointRotateRads11(
|
|
13108
|
+
pointFrom12(
|
|
12696
13109
|
element.x + op.data[2],
|
|
12697
13110
|
element.y + op.data[3]
|
|
12698
13111
|
),
|
|
12699
13112
|
center,
|
|
12700
13113
|
element.angle
|
|
12701
13114
|
),
|
|
12702
|
-
|
|
12703
|
-
|
|
13115
|
+
pointRotateRads11(
|
|
13116
|
+
pointFrom12(
|
|
12704
13117
|
element.x + op.data[4],
|
|
12705
13118
|
element.y + op.data[5]
|
|
12706
13119
|
),
|
|
@@ -12708,7 +13121,7 @@ var generateLinearCollisionShape = (element) => {
|
|
|
12708
13121
|
element.angle
|
|
12709
13122
|
)
|
|
12710
13123
|
].map(
|
|
12711
|
-
(p) =>
|
|
13124
|
+
(p) => pointFrom12(p[0] - element.x, p[1] - element.y)
|
|
12712
13125
|
).flat()
|
|
12713
13126
|
};
|
|
12714
13127
|
});
|
|
@@ -12723,8 +13136,8 @@ var generateLinearCollisionShape = (element) => {
|
|
|
12723
13136
|
);
|
|
12724
13137
|
return generator.curve(simplifiedPoints, options).sets[0].ops.slice(0, element.points.length).map((op, i) => {
|
|
12725
13138
|
if (i === 0) {
|
|
12726
|
-
const p =
|
|
12727
|
-
|
|
13139
|
+
const p = pointRotateRads11(
|
|
13140
|
+
pointFrom12(
|
|
12728
13141
|
element.x + op.data[0],
|
|
12729
13142
|
element.y + op.data[1]
|
|
12730
13143
|
),
|
|
@@ -12733,30 +13146,30 @@ var generateLinearCollisionShape = (element) => {
|
|
|
12733
13146
|
);
|
|
12734
13147
|
return {
|
|
12735
13148
|
op: "move",
|
|
12736
|
-
data:
|
|
13149
|
+
data: pointFrom12(p[0] - element.x, p[1] - element.y)
|
|
12737
13150
|
};
|
|
12738
13151
|
}
|
|
12739
13152
|
return {
|
|
12740
13153
|
op: "bcurveTo",
|
|
12741
13154
|
data: [
|
|
12742
|
-
|
|
12743
|
-
|
|
13155
|
+
pointRotateRads11(
|
|
13156
|
+
pointFrom12(
|
|
12744
13157
|
element.x + op.data[0],
|
|
12745
13158
|
element.y + op.data[1]
|
|
12746
13159
|
),
|
|
12747
13160
|
center,
|
|
12748
13161
|
element.angle
|
|
12749
13162
|
),
|
|
12750
|
-
|
|
12751
|
-
|
|
13163
|
+
pointRotateRads11(
|
|
13164
|
+
pointFrom12(
|
|
12752
13165
|
element.x + op.data[2],
|
|
12753
13166
|
element.y + op.data[3]
|
|
12754
13167
|
),
|
|
12755
13168
|
center,
|
|
12756
13169
|
element.angle
|
|
12757
13170
|
),
|
|
12758
|
-
|
|
12759
|
-
|
|
13171
|
+
pointRotateRads11(
|
|
13172
|
+
pointFrom12(
|
|
12760
13173
|
element.x + op.data[4],
|
|
12761
13174
|
element.y + op.data[5]
|
|
12762
13175
|
),
|
|
@@ -12764,7 +13177,7 @@ var generateLinearCollisionShape = (element) => {
|
|
|
12764
13177
|
element.angle
|
|
12765
13178
|
)
|
|
12766
13179
|
].map(
|
|
12767
|
-
(p) =>
|
|
13180
|
+
(p) => pointFrom12(p[0] - element.x, p[1] - element.y)
|
|
12768
13181
|
).flat()
|
|
12769
13182
|
};
|
|
12770
13183
|
});
|
|
@@ -12865,7 +13278,7 @@ var _generateElementShape = (element, generator, {
|
|
|
12865
13278
|
case "arrow": {
|
|
12866
13279
|
let shape;
|
|
12867
13280
|
const options = generateRoughOptions(element, false, isDarkMode);
|
|
12868
|
-
const points = element.points.length ? element.points : [
|
|
13281
|
+
const points = element.points.length ? element.points : [pointFrom12(0, 0)];
|
|
12869
13282
|
if (isElbowArrow(element)) {
|
|
12870
13283
|
if (!points.every(
|
|
12871
13284
|
(point) => Math.abs(point[0]) <= 1e6 && Math.abs(point[1]) <= 1e6
|
|
@@ -13029,14 +13442,14 @@ var getElementShape = (element, elementsMap) => {
|
|
|
13029
13442
|
return shouldTestInside(element) ? getClosedCurveShape(
|
|
13030
13443
|
element,
|
|
13031
13444
|
roughShape,
|
|
13032
|
-
|
|
13445
|
+
pointFrom12(element.x, element.y),
|
|
13033
13446
|
element.angle,
|
|
13034
|
-
|
|
13447
|
+
pointFrom12(cx, cy)
|
|
13035
13448
|
) : getCurveShape(
|
|
13036
13449
|
roughShape,
|
|
13037
|
-
|
|
13450
|
+
pointFrom12(element.x, element.y),
|
|
13038
13451
|
element.angle,
|
|
13039
|
-
|
|
13452
|
+
pointFrom12(cx, cy)
|
|
13040
13453
|
);
|
|
13041
13454
|
}
|
|
13042
13455
|
case "ellipse":
|
|
@@ -13045,7 +13458,7 @@ var getElementShape = (element, elementsMap) => {
|
|
|
13045
13458
|
const [, , , , cx, cy] = getElementAbsoluteCoords2(element, elementsMap);
|
|
13046
13459
|
return getFreedrawShape(
|
|
13047
13460
|
element,
|
|
13048
|
-
|
|
13461
|
+
pointFrom12(cx, cy),
|
|
13049
13462
|
shouldTestInside(element)
|
|
13050
13463
|
);
|
|
13051
13464
|
}
|
|
@@ -13064,9 +13477,9 @@ var toggleLinePolygonState = (element, nextPolygonState) => {
|
|
|
13064
13477
|
firstPoint[1] - lastPoint[1]
|
|
13065
13478
|
);
|
|
13066
13479
|
if (distance3 > LINE_POLYGON_POINT_MERGE_DISTANCE || updatedPoints.length < 4) {
|
|
13067
|
-
updatedPoints.push(
|
|
13480
|
+
updatedPoints.push(pointFrom12(firstPoint[0], firstPoint[1]));
|
|
13068
13481
|
} else {
|
|
13069
|
-
updatedPoints[updatedPoints.length - 1] =
|
|
13482
|
+
updatedPoints[updatedPoints.length - 1] = pointFrom12(
|
|
13070
13483
|
firstPoint[0],
|
|
13071
13484
|
firstPoint[1]
|
|
13072
13485
|
);
|
|
@@ -13159,9 +13572,9 @@ var ElementBounds = class _ElementBounds {
|
|
|
13159
13572
|
if (isFreeDrawElement(element)) {
|
|
13160
13573
|
const [minX, minY, maxX, maxY] = getBoundsFromPoints(
|
|
13161
13574
|
element.points.map(
|
|
13162
|
-
([x, y]) =>
|
|
13163
|
-
|
|
13164
|
-
|
|
13575
|
+
([x, y]) => pointRotateRads12(
|
|
13576
|
+
pointFrom13(x, y),
|
|
13577
|
+
pointFrom13(cx - element.x, cy - element.y),
|
|
13165
13578
|
element.angle
|
|
13166
13579
|
)
|
|
13167
13580
|
)
|
|
@@ -13175,24 +13588,24 @@ var ElementBounds = class _ElementBounds {
|
|
|
13175
13588
|
} else if (isLinearElement(element)) {
|
|
13176
13589
|
bounds = getLinearElementRotatedBounds(element, cx, cy, elementsMap);
|
|
13177
13590
|
} else if (element.type === "diamond") {
|
|
13178
|
-
const [x11, y11] =
|
|
13179
|
-
|
|
13180
|
-
|
|
13591
|
+
const [x11, y11] = pointRotateRads12(
|
|
13592
|
+
pointFrom13(cx, y1),
|
|
13593
|
+
pointFrom13(cx, cy),
|
|
13181
13594
|
element.angle
|
|
13182
13595
|
);
|
|
13183
|
-
const [x12, y12] =
|
|
13184
|
-
|
|
13185
|
-
|
|
13596
|
+
const [x12, y12] = pointRotateRads12(
|
|
13597
|
+
pointFrom13(cx, y2),
|
|
13598
|
+
pointFrom13(cx, cy),
|
|
13186
13599
|
element.angle
|
|
13187
13600
|
);
|
|
13188
|
-
const [x22, y22] =
|
|
13189
|
-
|
|
13190
|
-
|
|
13601
|
+
const [x22, y22] = pointRotateRads12(
|
|
13602
|
+
pointFrom13(x1, cy),
|
|
13603
|
+
pointFrom13(cx, cy),
|
|
13191
13604
|
element.angle
|
|
13192
13605
|
);
|
|
13193
|
-
const [x21, y21] =
|
|
13194
|
-
|
|
13195
|
-
|
|
13606
|
+
const [x21, y21] = pointRotateRads12(
|
|
13607
|
+
pointFrom13(x2, cy),
|
|
13608
|
+
pointFrom13(cx, cy),
|
|
13196
13609
|
element.angle
|
|
13197
13610
|
);
|
|
13198
13611
|
const minX = Math.min(x11, x12, x22, x21);
|
|
@@ -13209,24 +13622,24 @@ var ElementBounds = class _ElementBounds {
|
|
|
13209
13622
|
const hh = Math.hypot(h * cos, w * sin);
|
|
13210
13623
|
bounds = [cx - ww, cy - hh, cx + ww, cy + hh];
|
|
13211
13624
|
} else {
|
|
13212
|
-
const [x11, y11] =
|
|
13213
|
-
|
|
13214
|
-
|
|
13625
|
+
const [x11, y11] = pointRotateRads12(
|
|
13626
|
+
pointFrom13(x1, y1),
|
|
13627
|
+
pointFrom13(cx, cy),
|
|
13215
13628
|
element.angle
|
|
13216
13629
|
);
|
|
13217
|
-
const [x12, y12] =
|
|
13218
|
-
|
|
13219
|
-
|
|
13630
|
+
const [x12, y12] = pointRotateRads12(
|
|
13631
|
+
pointFrom13(x1, y2),
|
|
13632
|
+
pointFrom13(cx, cy),
|
|
13220
13633
|
element.angle
|
|
13221
13634
|
);
|
|
13222
|
-
const [x22, y22] =
|
|
13223
|
-
|
|
13224
|
-
|
|
13635
|
+
const [x22, y22] = pointRotateRads12(
|
|
13636
|
+
pointFrom13(x2, y2),
|
|
13637
|
+
pointFrom13(cx, cy),
|
|
13225
13638
|
element.angle
|
|
13226
13639
|
);
|
|
13227
|
-
const [x21, y21] =
|
|
13228
|
-
|
|
13229
|
-
|
|
13640
|
+
const [x21, y21] = pointRotateRads12(
|
|
13641
|
+
pointFrom13(x2, y1),
|
|
13642
|
+
pointFrom13(cx, cy),
|
|
13230
13643
|
element.angle
|
|
13231
13644
|
);
|
|
13232
13645
|
const minX = Math.min(x11, x12, x22, x21);
|
|
@@ -13280,7 +13693,7 @@ var getElementLineSegments = (element, elementsMap) => {
|
|
|
13280
13693
|
element,
|
|
13281
13694
|
elementsMap
|
|
13282
13695
|
);
|
|
13283
|
-
const center =
|
|
13696
|
+
const center = pointFrom13(cx, cy);
|
|
13284
13697
|
if (shape.type === "polycurve") {
|
|
13285
13698
|
const curves = shape.data;
|
|
13286
13699
|
const pointsOnCurves = curves.map(
|
|
@@ -13293,8 +13706,8 @@ var getElementLineSegments = (element, elementsMap) => {
|
|
|
13293
13706
|
while (i < points.length - 1) {
|
|
13294
13707
|
segments.push(
|
|
13295
13708
|
lineSegment6(
|
|
13296
|
-
|
|
13297
|
-
|
|
13709
|
+
pointFrom13(points[i][0], points[i][1]),
|
|
13710
|
+
pointFrom13(points[i + 1][0], points[i + 1][1])
|
|
13298
13711
|
)
|
|
13299
13712
|
);
|
|
13300
13713
|
i++;
|
|
@@ -13306,8 +13719,8 @@ var getElementLineSegments = (element, elementsMap) => {
|
|
|
13306
13719
|
while (i < points.length - 1) {
|
|
13307
13720
|
segments.push(
|
|
13308
13721
|
lineSegment6(
|
|
13309
|
-
|
|
13310
|
-
|
|
13722
|
+
pointFrom13(points[i][0], points[i][1]),
|
|
13723
|
+
pointFrom13(points[i + 1][0], points[i + 1][1])
|
|
13311
13724
|
)
|
|
13312
13725
|
);
|
|
13313
13726
|
i++;
|
|
@@ -13331,10 +13744,10 @@ var getElementLineSegments = (element, elementsMap) => {
|
|
|
13331
13744
|
const container = getContainerElement(element, elementsMap);
|
|
13332
13745
|
if (container && isLinearElement(container)) {
|
|
13333
13746
|
const segments2 = [
|
|
13334
|
-
lineSegment6(
|
|
13335
|
-
lineSegment6(
|
|
13336
|
-
lineSegment6(
|
|
13337
|
-
lineSegment6(
|
|
13747
|
+
lineSegment6(pointFrom13(x1, y1), pointFrom13(x2, y1)),
|
|
13748
|
+
lineSegment6(pointFrom13(x2, y1), pointFrom13(x2, y2)),
|
|
13749
|
+
lineSegment6(pointFrom13(x2, y2), pointFrom13(x1, y2)),
|
|
13750
|
+
lineSegment6(pointFrom13(x1, y2), pointFrom13(x1, y1))
|
|
13338
13751
|
];
|
|
13339
13752
|
return segments2;
|
|
13340
13753
|
}
|
|
@@ -13357,7 +13770,7 @@ var getElementLineSegments = (element, elementsMap) => {
|
|
|
13357
13770
|
[cx, y2],
|
|
13358
13771
|
[x1, cy],
|
|
13359
13772
|
[x2, cy]
|
|
13360
|
-
].map((point) =>
|
|
13773
|
+
].map((point) => pointRotateRads12(point, center, element.angle));
|
|
13361
13774
|
return [
|
|
13362
13775
|
lineSegment6(nw, ne),
|
|
13363
13776
|
lineSegment6(sw, se2),
|
|
@@ -13375,8 +13788,8 @@ var _isRectanguloidElement = (element) => {
|
|
|
13375
13788
|
var getRotatedSides = (sides, center, angle) => {
|
|
13376
13789
|
return sides.map((side) => {
|
|
13377
13790
|
return lineSegment6(
|
|
13378
|
-
|
|
13379
|
-
|
|
13791
|
+
pointRotateRads12(side[0], center, angle),
|
|
13792
|
+
pointRotateRads12(side[1], center, angle)
|
|
13380
13793
|
);
|
|
13381
13794
|
});
|
|
13382
13795
|
};
|
|
@@ -13387,13 +13800,13 @@ var getSegmentsOnCurve = (curve4, center, angle) => {
|
|
|
13387
13800
|
while (i < points.length - 1) {
|
|
13388
13801
|
segments.push(
|
|
13389
13802
|
lineSegment6(
|
|
13390
|
-
|
|
13391
|
-
|
|
13803
|
+
pointRotateRads12(
|
|
13804
|
+
pointFrom13(points[i][0], points[i][1]),
|
|
13392
13805
|
center,
|
|
13393
13806
|
angle
|
|
13394
13807
|
),
|
|
13395
|
-
|
|
13396
|
-
|
|
13808
|
+
pointRotateRads12(
|
|
13809
|
+
pointFrom13(points[i + 1][0], points[i + 1][1]),
|
|
13397
13810
|
center,
|
|
13398
13811
|
angle
|
|
13399
13812
|
)
|
|
@@ -13404,7 +13817,7 @@ var getSegmentsOnCurve = (curve4, center, angle) => {
|
|
|
13404
13817
|
return segments;
|
|
13405
13818
|
};
|
|
13406
13819
|
var getSegmentsOnEllipse = (ellipse4) => {
|
|
13407
|
-
const center =
|
|
13820
|
+
const center = pointFrom13(
|
|
13408
13821
|
ellipse4.x + ellipse4.width / 2,
|
|
13409
13822
|
ellipse4.y + ellipse4.height / 2
|
|
13410
13823
|
);
|
|
@@ -13418,7 +13831,7 @@ var getSegmentsOnEllipse = (ellipse4) => {
|
|
|
13418
13831
|
const t = i * deltaT;
|
|
13419
13832
|
const x = center[0] + a2 * Math.cos(t);
|
|
13420
13833
|
const y = center[1] + b2 * Math.sin(t);
|
|
13421
|
-
points.push(
|
|
13834
|
+
points.push(pointRotateRads12(pointFrom13(x, y), center, ellipse4.angle));
|
|
13422
13835
|
}
|
|
13423
13836
|
for (let i = 0; i < points.length - 1; i++) {
|
|
13424
13837
|
segments.push(lineSegment6(points[i], points[i + 1]));
|
|
@@ -13501,7 +13914,7 @@ var getCubicBezierCurveBound = (p0, p1, p2, p3) => {
|
|
|
13501
13914
|
return [minX, minY, maxX, maxY];
|
|
13502
13915
|
};
|
|
13503
13916
|
var getMinMaxXYFromCurvePathOps = (ops, transformXY) => {
|
|
13504
|
-
let currentP =
|
|
13917
|
+
let currentP = pointFrom13(0, 0);
|
|
13505
13918
|
const { minX, minY, maxX, maxY } = ops.reduce(
|
|
13506
13919
|
(limits, { op, data }) => {
|
|
13507
13920
|
if (op === "move") {
|
|
@@ -13509,9 +13922,9 @@ var getMinMaxXYFromCurvePathOps = (ops, transformXY) => {
|
|
|
13509
13922
|
invariant10(p != null, "Op data is not a point");
|
|
13510
13923
|
currentP = p;
|
|
13511
13924
|
} else if (op === "bcurveTo") {
|
|
13512
|
-
const _p1 =
|
|
13513
|
-
const _p2 =
|
|
13514
|
-
const _p3 =
|
|
13925
|
+
const _p1 = pointFrom13(data[0], data[1]);
|
|
13926
|
+
const _p2 = pointFrom13(data[2], data[3]);
|
|
13927
|
+
const _p3 = pointFrom13(data[4], data[5]);
|
|
13515
13928
|
const p1 = transformXY ? transformXY(_p1) : _p1;
|
|
13516
13929
|
const p2 = transformXY ? transformXY(_p2) : _p2;
|
|
13517
13930
|
const p3 = transformXY ? transformXY(_p3) : _p3;
|
|
@@ -13536,7 +13949,7 @@ var getMinMaxXYFromCurvePathOps = (ops, transformXY) => {
|
|
|
13536
13949
|
);
|
|
13537
13950
|
return [minX, minY, maxX, maxY];
|
|
13538
13951
|
};
|
|
13539
|
-
var getBoundsFromPoints = (points) => {
|
|
13952
|
+
var getBoundsFromPoints = (points, padding = 0) => {
|
|
13540
13953
|
let minX = Infinity;
|
|
13541
13954
|
let minY = Infinity;
|
|
13542
13955
|
let maxX = -Infinity;
|
|
@@ -13547,7 +13960,7 @@ var getBoundsFromPoints = (points) => {
|
|
|
13547
13960
|
maxX = Math.max(maxX, x);
|
|
13548
13961
|
maxY = Math.max(maxY, y);
|
|
13549
13962
|
}
|
|
13550
|
-
return [minX, minY, maxX, maxY];
|
|
13963
|
+
return [minX - padding, minY - padding, maxX + padding, maxY + padding];
|
|
13551
13964
|
};
|
|
13552
13965
|
var getFreeDrawElementAbsoluteCoords = (element) => {
|
|
13553
13966
|
const [minX, minY, maxX, maxY] = getBoundsFromPoints(element.points);
|
|
@@ -13557,6 +13970,8 @@ var getFreeDrawElementAbsoluteCoords = (element) => {
|
|
|
13557
13970
|
const y2 = maxY + element.y;
|
|
13558
13971
|
return [x1, y1, x2, y2, (x1 + x2) / 2, (y1 + y2) / 2];
|
|
13559
13972
|
};
|
|
13973
|
+
var CARDINALITY_MARKER_SIZE = 20;
|
|
13974
|
+
var CROWFOOT_ARROWHEAD_SIZE = 15;
|
|
13560
13975
|
var getArrowheadSize = (arrowhead) => {
|
|
13561
13976
|
switch (arrowhead) {
|
|
13562
13977
|
case "arrow":
|
|
@@ -13564,10 +13979,14 @@ var getArrowheadSize = (arrowhead) => {
|
|
|
13564
13979
|
case "diamond":
|
|
13565
13980
|
case "diamond_outline":
|
|
13566
13981
|
return 12;
|
|
13567
|
-
case "
|
|
13568
|
-
case "
|
|
13569
|
-
case "
|
|
13570
|
-
return
|
|
13982
|
+
case "cardinality_many":
|
|
13983
|
+
case "cardinality_one_or_many":
|
|
13984
|
+
case "cardinality_zero_or_many":
|
|
13985
|
+
return CROWFOOT_ARROWHEAD_SIZE;
|
|
13986
|
+
case "cardinality_one":
|
|
13987
|
+
case "cardinality_exactly_one":
|
|
13988
|
+
case "cardinality_zero_or_one":
|
|
13989
|
+
return CARDINALITY_MARKER_SIZE;
|
|
13571
13990
|
default:
|
|
13572
13991
|
return 15;
|
|
13573
13992
|
}
|
|
@@ -13582,7 +14001,10 @@ var getArrowheadAngle = (arrowhead) => {
|
|
|
13582
14001
|
return 25;
|
|
13583
14002
|
}
|
|
13584
14003
|
};
|
|
13585
|
-
var getArrowheadPoints = (element, shape, position, arrowhead) => {
|
|
14004
|
+
var getArrowheadPoints = (element, shape, position, arrowhead, offsetMultiplier = 0) => {
|
|
14005
|
+
if (arrowhead === null) {
|
|
14006
|
+
return null;
|
|
14007
|
+
}
|
|
13586
14008
|
if (shape.length < 1) {
|
|
13587
14009
|
return null;
|
|
13588
14010
|
}
|
|
@@ -13593,17 +14015,17 @@ var getArrowheadPoints = (element, shape, position, arrowhead) => {
|
|
|
13593
14015
|
const index = position === "start" ? 1 : ops.length - 1;
|
|
13594
14016
|
const data = ops[index].data;
|
|
13595
14017
|
invariant10(data.length === 6, "Op data length is not 6");
|
|
13596
|
-
const p3 =
|
|
13597
|
-
const p2 =
|
|
13598
|
-
const p1 =
|
|
14018
|
+
const p3 = pointFrom13(data[4], data[5]);
|
|
14019
|
+
const p2 = pointFrom13(data[2], data[3]);
|
|
14020
|
+
const p1 = pointFrom13(data[0], data[1]);
|
|
13599
14021
|
const prevOp = ops[index - 1];
|
|
13600
|
-
let p0 =
|
|
14022
|
+
let p0 = pointFrom13(0, 0);
|
|
13601
14023
|
if (prevOp.op === "move") {
|
|
13602
14024
|
const p = pointFromArray3(prevOp.data);
|
|
13603
14025
|
invariant10(p != null, "Op data is not a point");
|
|
13604
14026
|
p0 = p;
|
|
13605
14027
|
} else if (prevOp.op === "bcurveTo") {
|
|
13606
|
-
p0 =
|
|
14028
|
+
p0 = pointFrom13(prevOp.data[4], prevOp.data[5]);
|
|
13607
14029
|
}
|
|
13608
14030
|
const equation = (t, idx) => Math.pow(1 - t, 3) * p3[idx] + 3 * t * Math.pow(1 - t, 2) * p2[idx] + 3 * Math.pow(t, 2) * (1 - t) * p1[idx] + p0[idx] * Math.pow(t, 3);
|
|
13609
14031
|
const [x2, y2] = position === "start" ? p0 : p3;
|
|
@@ -13620,34 +14042,36 @@ var getArrowheadPoints = (element, shape, position, arrowhead) => {
|
|
|
13620
14042
|
}
|
|
13621
14043
|
const lengthMultiplier = arrowhead === "diamond" || arrowhead === "diamond_outline" ? 0.25 : 0.5;
|
|
13622
14044
|
const minSize = Math.min(size, length * lengthMultiplier);
|
|
13623
|
-
const
|
|
13624
|
-
const
|
|
13625
|
-
|
|
13626
|
-
|
|
13627
|
-
|
|
14045
|
+
const tx = x2 - nx * minSize * offsetMultiplier;
|
|
14046
|
+
const ty = y2 - ny * minSize * offsetMultiplier;
|
|
14047
|
+
const xs = tx - nx * minSize;
|
|
14048
|
+
const ys = ty - ny * minSize;
|
|
14049
|
+
if (arrowhead === "circle" || arrowhead === "circle_outline") {
|
|
14050
|
+
const diameter = Math.hypot(ys - ty, xs - tx) + element.strokeWidth - 2;
|
|
14051
|
+
return [tx, ty, diameter];
|
|
13628
14052
|
}
|
|
13629
14053
|
const angle = getArrowheadAngle(arrowhead);
|
|
13630
|
-
if (arrowhead === "
|
|
13631
|
-
const [x32, y32] =
|
|
13632
|
-
|
|
13633
|
-
|
|
14054
|
+
if (arrowhead === "cardinality_many" || arrowhead === "cardinality_one_or_many") {
|
|
14055
|
+
const [x32, y32] = pointRotateRads12(
|
|
14056
|
+
pointFrom13(tx, ty),
|
|
14057
|
+
pointFrom13(xs, ys),
|
|
13634
14058
|
degreesToRadians(-angle)
|
|
13635
14059
|
);
|
|
13636
|
-
const [x42, y42] =
|
|
13637
|
-
|
|
13638
|
-
|
|
14060
|
+
const [x42, y42] = pointRotateRads12(
|
|
14061
|
+
pointFrom13(tx, ty),
|
|
14062
|
+
pointFrom13(xs, ys),
|
|
13639
14063
|
degreesToRadians(angle)
|
|
13640
14064
|
);
|
|
13641
14065
|
return [xs, ys, x32, y32, x42, y42];
|
|
13642
14066
|
}
|
|
13643
|
-
const [x3, y3] =
|
|
13644
|
-
|
|
13645
|
-
|
|
14067
|
+
const [x3, y3] = pointRotateRads12(
|
|
14068
|
+
pointFrom13(xs, ys),
|
|
14069
|
+
pointFrom13(tx, ty),
|
|
13646
14070
|
-angle * Math.PI / 180
|
|
13647
14071
|
);
|
|
13648
|
-
const [x4, y4] =
|
|
13649
|
-
|
|
13650
|
-
|
|
14072
|
+
const [x4, y4] = pointRotateRads12(
|
|
14073
|
+
pointFrom13(xs, ys),
|
|
14074
|
+
pointFrom13(tx, ty),
|
|
13651
14075
|
degreesToRadians(angle)
|
|
13652
14076
|
);
|
|
13653
14077
|
if (arrowhead === "diamond" || arrowhead === "diamond_outline") {
|
|
@@ -13655,22 +14079,22 @@ var getArrowheadPoints = (element, shape, position, arrowhead) => {
|
|
|
13655
14079
|
let oy;
|
|
13656
14080
|
if (position === "start") {
|
|
13657
14081
|
const [px, py] = element.points.length > 1 ? element.points[1] : [0, 0];
|
|
13658
|
-
[ox, oy] =
|
|
13659
|
-
|
|
13660
|
-
|
|
13661
|
-
Math.atan2(py -
|
|
14082
|
+
[ox, oy] = pointRotateRads12(
|
|
14083
|
+
pointFrom13(tx + minSize * 2, ty),
|
|
14084
|
+
pointFrom13(tx, ty),
|
|
14085
|
+
Math.atan2(py - ty, px - tx)
|
|
13662
14086
|
);
|
|
13663
14087
|
} else {
|
|
13664
14088
|
const [px, py] = element.points.length > 1 ? element.points[element.points.length - 2] : [0, 0];
|
|
13665
|
-
[ox, oy] =
|
|
13666
|
-
|
|
13667
|
-
|
|
13668
|
-
Math.atan2(
|
|
14089
|
+
[ox, oy] = pointRotateRads12(
|
|
14090
|
+
pointFrom13(tx - minSize * 2, ty),
|
|
14091
|
+
pointFrom13(tx, ty),
|
|
14092
|
+
Math.atan2(ty - py, tx - px)
|
|
13669
14093
|
);
|
|
13670
14094
|
}
|
|
13671
|
-
return [
|
|
14095
|
+
return [tx, ty, x3, y3, ox, oy, x4, y4];
|
|
13672
14096
|
}
|
|
13673
|
-
return [
|
|
14097
|
+
return [tx, ty, x3, y3, x4, y4];
|
|
13674
14098
|
};
|
|
13675
14099
|
var generateLinearElementShape = (element) => {
|
|
13676
14100
|
const generator = rough_default.generator();
|
|
@@ -13693,9 +14117,9 @@ var getLinearElementRotatedBounds = (element, cx, cy, elementsMap) => {
|
|
|
13693
14117
|
const boundTextElement = getBoundTextElement(element, elementsMap);
|
|
13694
14118
|
if (element.points.length < 2) {
|
|
13695
14119
|
const [pointX, pointY] = element.points[0];
|
|
13696
|
-
const [x, y] =
|
|
13697
|
-
|
|
13698
|
-
|
|
14120
|
+
const [x, y] = pointRotateRads12(
|
|
14121
|
+
pointFrom13(element.x + pointX, element.y + pointY),
|
|
14122
|
+
pointFrom13(cx, cy),
|
|
13699
14123
|
element.angle
|
|
13700
14124
|
);
|
|
13701
14125
|
let coords2 = [x, y, x, y];
|
|
@@ -13718,9 +14142,9 @@ var getLinearElementRotatedBounds = (element, cx, cy, elementsMap) => {
|
|
|
13718
14142
|
const cachedShape = ShapeCache.get(element, null)?.[0];
|
|
13719
14143
|
const shape = cachedShape ?? generateLinearElementShape(element);
|
|
13720
14144
|
const ops = getCurvePathOps(shape);
|
|
13721
|
-
const transformXY = ([x, y]) =>
|
|
13722
|
-
|
|
13723
|
-
|
|
14145
|
+
const transformXY = ([x, y]) => pointRotateRads12(
|
|
14146
|
+
pointFrom13(element.x + x, element.y + y),
|
|
14147
|
+
pointFrom13(cx, cy),
|
|
13724
14148
|
element.angle
|
|
13725
14149
|
);
|
|
13726
14150
|
const res = getMinMaxXYFromCurvePathOps(ops, transformXY);
|
|
@@ -13831,8 +14255,8 @@ var getClosestElementBounds = (elements, from) => {
|
|
|
13831
14255
|
elements.forEach((element) => {
|
|
13832
14256
|
const [x1, y1, x2, y2] = getElementBounds(element, elementsMap);
|
|
13833
14257
|
const distance3 = pointDistance7(
|
|
13834
|
-
|
|
13835
|
-
|
|
14258
|
+
pointFrom13((x1 + x2) / 2, (y1 + y2) / 2),
|
|
14259
|
+
pointFrom13(from.x, from.y)
|
|
13836
14260
|
);
|
|
13837
14261
|
if (distance3 < minDistance) {
|
|
13838
14262
|
minDistance = distance3;
|
|
@@ -13868,7 +14292,7 @@ var getVisibleSceneBounds = ({
|
|
|
13868
14292
|
-scrollY + height / zoom.value
|
|
13869
14293
|
];
|
|
13870
14294
|
};
|
|
13871
|
-
var getCenterForBounds = (bounds) =>
|
|
14295
|
+
var getCenterForBounds = (bounds) => pointFrom13(
|
|
13872
14296
|
bounds[0] + (bounds[2] - bounds[0]) / 2,
|
|
13873
14297
|
bounds[1] + (bounds[3] - bounds[1]) / 2
|
|
13874
14298
|
);
|
|
@@ -13882,23 +14306,23 @@ var aabbForElement = (element, elementsMap, offset) => {
|
|
|
13882
14306
|
midY: element.y + element.height / 2
|
|
13883
14307
|
};
|
|
13884
14308
|
const center = elementCenterPoint(element, elementsMap);
|
|
13885
|
-
const [topLeftX, topLeftY] =
|
|
13886
|
-
|
|
14309
|
+
const [topLeftX, topLeftY] = pointRotateRads12(
|
|
14310
|
+
pointFrom13(bbox.minX, bbox.minY),
|
|
13887
14311
|
center,
|
|
13888
14312
|
element.angle
|
|
13889
14313
|
);
|
|
13890
|
-
const [topRightX, topRightY] =
|
|
13891
|
-
|
|
14314
|
+
const [topRightX, topRightY] = pointRotateRads12(
|
|
14315
|
+
pointFrom13(bbox.maxX, bbox.minY),
|
|
13892
14316
|
center,
|
|
13893
14317
|
element.angle
|
|
13894
14318
|
);
|
|
13895
|
-
const [bottomRightX, bottomRightY] =
|
|
13896
|
-
|
|
14319
|
+
const [bottomRightX, bottomRightY] = pointRotateRads12(
|
|
14320
|
+
pointFrom13(bbox.maxX, bbox.maxY),
|
|
13897
14321
|
center,
|
|
13898
14322
|
element.angle
|
|
13899
14323
|
);
|
|
13900
|
-
const [bottomLeftX, bottomLeftY] =
|
|
13901
|
-
|
|
14324
|
+
const [bottomLeftX, bottomLeftY] = pointRotateRads12(
|
|
14325
|
+
pointFrom13(bbox.minX, bbox.maxY),
|
|
13902
14326
|
center,
|
|
13903
14327
|
element.angle
|
|
13904
14328
|
);
|
|
@@ -13920,6 +14344,7 @@ var aabbForElement = (element, elementsMap, offset) => {
|
|
|
13920
14344
|
return bounds;
|
|
13921
14345
|
};
|
|
13922
14346
|
var pointInsideBounds = (p, bounds) => p[0] > bounds[0] && p[0] < bounds[2] && p[1] > bounds[1] && p[1] < bounds[3];
|
|
14347
|
+
var pointInsideBoundsInclusive = (p, bounds) => p[0] >= bounds[0] && p[0] <= bounds[2] && p[1] >= bounds[1] && p[1] <= bounds[3];
|
|
13923
14348
|
var doBoundsIntersect = (bounds1, bounds2) => {
|
|
13924
14349
|
if (bounds1 == null || bounds2 == null) {
|
|
13925
14350
|
return false;
|
|
@@ -13928,14 +14353,225 @@ var doBoundsIntersect = (bounds1, bounds2) => {
|
|
|
13928
14353
|
const [minX2, minY2, maxX2, maxY2] = bounds2;
|
|
13929
14354
|
return minX1 < maxX2 && maxX1 > minX2 && minY1 < maxY2 && maxY1 > minY2;
|
|
13930
14355
|
};
|
|
14356
|
+
var boundsContainBounds = (outerBounds, innerBounds) => [
|
|
14357
|
+
pointFrom13(innerBounds[0], innerBounds[1]),
|
|
14358
|
+
pointFrom13(innerBounds[0], innerBounds[3]),
|
|
14359
|
+
pointFrom13(innerBounds[2], innerBounds[1]),
|
|
14360
|
+
pointFrom13(innerBounds[2], innerBounds[3])
|
|
14361
|
+
].every((point) => pointInsideBoundsInclusive(point, outerBounds));
|
|
14362
|
+
var elementsOverlappingBBox = ({
|
|
14363
|
+
elements,
|
|
14364
|
+
elementsMap,
|
|
14365
|
+
bounds,
|
|
14366
|
+
type,
|
|
14367
|
+
excludeElementsInFrames,
|
|
14368
|
+
shouldIgnoreElementFromSelection: shouldIgnoreElementFromSelection2
|
|
14369
|
+
}) => {
|
|
14370
|
+
if (!elementsMap) {
|
|
14371
|
+
elementsMap = arrayToMap6(elements);
|
|
14372
|
+
}
|
|
14373
|
+
const selectionBounds = isExcalidrawElement(bounds) ? getElementBounds(bounds, elementsMap) : bounds;
|
|
14374
|
+
const [selectionX1, selectionY1, selectionX2, selectionY2] = selectionBounds;
|
|
14375
|
+
const selectionEdges = [
|
|
14376
|
+
lineSegment6(
|
|
14377
|
+
pointFrom13(selectionX1, selectionY1),
|
|
14378
|
+
pointFrom13(selectionX2, selectionY1)
|
|
14379
|
+
),
|
|
14380
|
+
lineSegment6(
|
|
14381
|
+
pointFrom13(selectionX2, selectionY1),
|
|
14382
|
+
pointFrom13(selectionX2, selectionY2)
|
|
14383
|
+
),
|
|
14384
|
+
lineSegment6(
|
|
14385
|
+
pointFrom13(selectionX2, selectionY2),
|
|
14386
|
+
pointFrom13(selectionX1, selectionY2)
|
|
14387
|
+
),
|
|
14388
|
+
lineSegment6(
|
|
14389
|
+
pointFrom13(selectionX1, selectionY2),
|
|
14390
|
+
pointFrom13(selectionX1, selectionY1)
|
|
14391
|
+
)
|
|
14392
|
+
];
|
|
14393
|
+
const framesInSelection = excludeElementsInFrames ? /* @__PURE__ */ new Set() : null;
|
|
14394
|
+
const groups = {};
|
|
14395
|
+
const elementsInSelection = /* @__PURE__ */ new Set();
|
|
14396
|
+
for (const element of elements) {
|
|
14397
|
+
if (shouldIgnoreElementFromSelection2?.(element)) {
|
|
14398
|
+
continue;
|
|
14399
|
+
}
|
|
14400
|
+
const groupId = element.groupIds.at(-1);
|
|
14401
|
+
if (groupId) {
|
|
14402
|
+
if (!groups[groupId]) {
|
|
14403
|
+
groups[groupId] = [];
|
|
14404
|
+
}
|
|
14405
|
+
groups[groupId].push(element);
|
|
14406
|
+
}
|
|
14407
|
+
const strokeWidth = element.strokeWidth;
|
|
14408
|
+
let labelAABB = null;
|
|
14409
|
+
let elementAABB = getElementBounds(element, elementsMap);
|
|
14410
|
+
elementAABB = [
|
|
14411
|
+
elementAABB[0] - strokeWidth / 2,
|
|
14412
|
+
elementAABB[1] - strokeWidth / 2,
|
|
14413
|
+
elementAABB[2] + strokeWidth / 2,
|
|
14414
|
+
elementAABB[3] + strokeWidth / 2
|
|
14415
|
+
];
|
|
14416
|
+
const boundTextElement = isArrowElement(element) && getBoundTextElement(element, elementsMap);
|
|
14417
|
+
if (boundTextElement) {
|
|
14418
|
+
const { x, y } = LinearElementEditor.getBoundTextElementPosition(
|
|
14419
|
+
element,
|
|
14420
|
+
boundTextElement,
|
|
14421
|
+
elementsMap
|
|
14422
|
+
);
|
|
14423
|
+
labelAABB = [
|
|
14424
|
+
x,
|
|
14425
|
+
y,
|
|
14426
|
+
x + boundTextElement.width,
|
|
14427
|
+
y + boundTextElement.height
|
|
14428
|
+
];
|
|
14429
|
+
}
|
|
14430
|
+
const associatedFrame = getContainingFrame(element, elementsMap);
|
|
14431
|
+
if (associatedFrame && elementOverlapsWithFrame(element, associatedFrame, elementsMap)) {
|
|
14432
|
+
const frameAABB = getElementBounds(associatedFrame, elementsMap);
|
|
14433
|
+
elementAABB = [
|
|
14434
|
+
Math.max(elementAABB[0], frameAABB[0]),
|
|
14435
|
+
Math.max(elementAABB[1], frameAABB[1]),
|
|
14436
|
+
Math.min(elementAABB[2], frameAABB[2]),
|
|
14437
|
+
Math.min(elementAABB[3], frameAABB[3])
|
|
14438
|
+
];
|
|
14439
|
+
labelAABB = labelAABB ? [
|
|
14440
|
+
Math.max(labelAABB[0], frameAABB[0]),
|
|
14441
|
+
Math.max(labelAABB[1], frameAABB[1]),
|
|
14442
|
+
Math.min(labelAABB[2], frameAABB[2]),
|
|
14443
|
+
Math.min(labelAABB[3], frameAABB[3])
|
|
14444
|
+
] : null;
|
|
14445
|
+
}
|
|
14446
|
+
const commonAABB2 = labelAABB ? [
|
|
14447
|
+
Math.min(labelAABB[0], elementAABB[0]),
|
|
14448
|
+
Math.min(labelAABB[1], elementAABB[1]),
|
|
14449
|
+
Math.max(labelAABB[2], elementAABB[2]),
|
|
14450
|
+
Math.max(labelAABB[3], elementAABB[3])
|
|
14451
|
+
] : elementAABB;
|
|
14452
|
+
if (boundsContainBounds(selectionBounds, commonAABB2)) {
|
|
14453
|
+
if (framesInSelection && isFrameLikeElement(element)) {
|
|
14454
|
+
framesInSelection.add(element.id);
|
|
14455
|
+
}
|
|
14456
|
+
elementsInSelection.add(element);
|
|
14457
|
+
continue;
|
|
14458
|
+
}
|
|
14459
|
+
if (type === "overlap" && labelAABB && doBoundsIntersect(selectionBounds, labelAABB)) {
|
|
14460
|
+
elementsInSelection.add(element);
|
|
14461
|
+
continue;
|
|
14462
|
+
}
|
|
14463
|
+
if (type === "overlap" && doBoundsIntersect(selectionBounds, elementAABB)) {
|
|
14464
|
+
let hasIntersection = false;
|
|
14465
|
+
if (isLinearElement(element) || isFreeDrawElement(element)) {
|
|
14466
|
+
const center = elementCenterPoint(element, elementsMap);
|
|
14467
|
+
hasIntersection = element.points.some((point) => {
|
|
14468
|
+
const rotatedPoint = pointRotateRads12(
|
|
14469
|
+
pointFrom13(element.x + point[0], element.y + point[1]),
|
|
14470
|
+
center,
|
|
14471
|
+
element.angle
|
|
14472
|
+
);
|
|
14473
|
+
return pointInsideBounds(rotatedPoint, selectionBounds);
|
|
14474
|
+
});
|
|
14475
|
+
} else {
|
|
14476
|
+
const nonRotatedElementBounds = getElementBounds(
|
|
14477
|
+
element,
|
|
14478
|
+
elementsMap,
|
|
14479
|
+
true
|
|
14480
|
+
);
|
|
14481
|
+
const center = elementCenterPoint(element, elementsMap);
|
|
14482
|
+
hasIntersection = [
|
|
14483
|
+
pointRotateRads12(
|
|
14484
|
+
pointFrom13(
|
|
14485
|
+
(nonRotatedElementBounds[0] + nonRotatedElementBounds[2]) / 2,
|
|
14486
|
+
nonRotatedElementBounds[1]
|
|
14487
|
+
),
|
|
14488
|
+
center,
|
|
14489
|
+
element.angle
|
|
14490
|
+
),
|
|
14491
|
+
pointRotateRads12(
|
|
14492
|
+
pointFrom13(
|
|
14493
|
+
nonRotatedElementBounds[2],
|
|
14494
|
+
(nonRotatedElementBounds[1] + nonRotatedElementBounds[3]) / 2
|
|
14495
|
+
),
|
|
14496
|
+
center,
|
|
14497
|
+
element.angle
|
|
14498
|
+
),
|
|
14499
|
+
pointRotateRads12(
|
|
14500
|
+
pointFrom13(
|
|
14501
|
+
(nonRotatedElementBounds[0] + nonRotatedElementBounds[2]) / 2,
|
|
14502
|
+
nonRotatedElementBounds[3]
|
|
14503
|
+
),
|
|
14504
|
+
center,
|
|
14505
|
+
element.angle
|
|
14506
|
+
),
|
|
14507
|
+
pointRotateRads12(
|
|
14508
|
+
pointFrom13(
|
|
14509
|
+
nonRotatedElementBounds[0],
|
|
14510
|
+
(nonRotatedElementBounds[1] + nonRotatedElementBounds[3]) / 2
|
|
14511
|
+
),
|
|
14512
|
+
center,
|
|
14513
|
+
element.angle
|
|
14514
|
+
)
|
|
14515
|
+
].some((point) => {
|
|
14516
|
+
return pointInsideBounds(
|
|
14517
|
+
pointRotateRads12(point, center, element.angle),
|
|
14518
|
+
selectionBounds
|
|
14519
|
+
);
|
|
14520
|
+
});
|
|
14521
|
+
}
|
|
14522
|
+
if (!hasIntersection) {
|
|
14523
|
+
hasIntersection = selectionEdges.some(
|
|
14524
|
+
(selectionEdge) => intersectElementWithLineSegment(
|
|
14525
|
+
element,
|
|
14526
|
+
elementsMap,
|
|
14527
|
+
selectionEdge,
|
|
14528
|
+
strokeWidth / 2,
|
|
14529
|
+
true
|
|
14530
|
+
// Stop at first hit for better performance
|
|
14531
|
+
).length > 0
|
|
14532
|
+
);
|
|
14533
|
+
}
|
|
14534
|
+
if (hasIntersection) {
|
|
14535
|
+
if (framesInSelection && isFrameLikeElement(element)) {
|
|
14536
|
+
framesInSelection.add(element.id);
|
|
14537
|
+
}
|
|
14538
|
+
elementsInSelection.add(element);
|
|
14539
|
+
continue;
|
|
14540
|
+
}
|
|
14541
|
+
}
|
|
14542
|
+
}
|
|
14543
|
+
if (framesInSelection) {
|
|
14544
|
+
elementsInSelection.forEach((element) => {
|
|
14545
|
+
if (element.frameId && framesInSelection.has(element.frameId)) {
|
|
14546
|
+
elementsInSelection.delete(element);
|
|
14547
|
+
}
|
|
14548
|
+
});
|
|
14549
|
+
}
|
|
14550
|
+
if (type === "overlap") {
|
|
14551
|
+
Array.from(elementsInSelection).forEach((element) => {
|
|
14552
|
+
const groupId = element.groupIds.at(-1);
|
|
14553
|
+
const group = groupId ? groups[groupId] : null;
|
|
14554
|
+
group?.forEach((groupElement) => elementsInSelection.add(groupElement));
|
|
14555
|
+
});
|
|
14556
|
+
} else if (type === "contain") {
|
|
14557
|
+
elementsInSelection.forEach((element) => {
|
|
14558
|
+
const groupId = element.groupIds.at(-1);
|
|
14559
|
+
const group = groupId ? groups[groupId] : null;
|
|
14560
|
+
if (group && !group.every((groupElement) => elementsInSelection.has(groupElement))) {
|
|
14561
|
+
elementsInSelection.delete(element);
|
|
14562
|
+
}
|
|
14563
|
+
});
|
|
14564
|
+
}
|
|
14565
|
+
return elements.filter((element) => elementsInSelection.has(element));
|
|
14566
|
+
};
|
|
13931
14567
|
var elementCenterPoint = (element, elementsMap, xOffset = 0, yOffset = 0) => {
|
|
13932
|
-
if (isLinearElement(element)) {
|
|
14568
|
+
if (isLinearElement(element) || isFreeDrawElement(element)) {
|
|
13933
14569
|
const [x1, y1, x2, y2] = getElementAbsoluteCoords2(element, elementsMap);
|
|
13934
|
-
const [x3, y3] =
|
|
13935
|
-
return
|
|
14570
|
+
const [x3, y3] = pointFrom13((x1 + x2) / 2, (y1 + y2) / 2);
|
|
14571
|
+
return pointFrom13(x3 + xOffset, y3 + yOffset);
|
|
13936
14572
|
}
|
|
13937
14573
|
const [x, y] = getCenterForBounds(getElementBounds(element, elementsMap));
|
|
13938
|
-
return
|
|
14574
|
+
return pointFrom13(x + xOffset, y + yOffset);
|
|
13939
14575
|
};
|
|
13940
14576
|
|
|
13941
14577
|
// src/sizeHelpers.ts
|
|
@@ -14140,7 +14776,7 @@ import {
|
|
|
14140
14776
|
ORIG_ID,
|
|
14141
14777
|
randomId,
|
|
14142
14778
|
randomInteger as randomInteger2,
|
|
14143
|
-
arrayToMap as
|
|
14779
|
+
arrayToMap as arrayToMap8,
|
|
14144
14780
|
castArray,
|
|
14145
14781
|
findLastIndex,
|
|
14146
14782
|
getUpdatedTimestamp as getUpdatedTimestamp2,
|
|
@@ -14149,79 +14785,61 @@ import {
|
|
|
14149
14785
|
|
|
14150
14786
|
// src/sortElements.ts
|
|
14151
14787
|
init_define_import_meta_env();
|
|
14152
|
-
import {
|
|
14153
|
-
var
|
|
14154
|
-
const
|
|
14155
|
-
|
|
14156
|
-
const orderInnerGroups = (elements2) => {
|
|
14157
|
-
const firstGroupSig = elements2[0]?.groupIds?.join("");
|
|
14158
|
-
const aGroup = [elements2[0]];
|
|
14159
|
-
const bGroup = [];
|
|
14160
|
-
for (const element of elements2.slice(1)) {
|
|
14161
|
-
if (element.groupIds?.join("") === firstGroupSig) {
|
|
14162
|
-
aGroup.push(element);
|
|
14163
|
-
} else {
|
|
14164
|
-
bGroup.push(element);
|
|
14165
|
-
}
|
|
14166
|
-
}
|
|
14167
|
-
return bGroup.length ? [...aGroup, ...orderInnerGroups(bGroup)] : aGroup;
|
|
14788
|
+
import { arrayToMap as arrayToMap7 } from "@excalidraw/common";
|
|
14789
|
+
var defragmentGroups = (elements) => {
|
|
14790
|
+
const groupIdAtLevel = (element, level) => {
|
|
14791
|
+
return element.groupIds[element.groupIds.length - level - 1];
|
|
14168
14792
|
};
|
|
14169
|
-
const
|
|
14170
|
-
|
|
14171
|
-
|
|
14172
|
-
|
|
14173
|
-
|
|
14174
|
-
|
|
14175
|
-
|
|
14176
|
-
|
|
14177
|
-
const ret = element2?.groupIds?.some((id) => id === topGroup);
|
|
14178
|
-
if (ret) {
|
|
14179
|
-
groupHandledElements.set(element2.id, true);
|
|
14180
|
-
}
|
|
14181
|
-
return ret;
|
|
14182
|
-
});
|
|
14183
|
-
for (const elem of orderInnerGroups(groupElements)) {
|
|
14184
|
-
sortedElements.add(elem);
|
|
14793
|
+
const orderLevel = (levelElements, level) => {
|
|
14794
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
14795
|
+
const slots = [];
|
|
14796
|
+
for (const element of levelElements) {
|
|
14797
|
+
const groupId = groupIdAtLevel(element, level);
|
|
14798
|
+
if (groupId === void 0) {
|
|
14799
|
+
slots.push(element);
|
|
14800
|
+
continue;
|
|
14185
14801
|
}
|
|
14186
|
-
|
|
14187
|
-
|
|
14802
|
+
let bucket = buckets.get(groupId);
|
|
14803
|
+
if (!bucket) {
|
|
14804
|
+
bucket = [];
|
|
14805
|
+
buckets.set(groupId, bucket);
|
|
14806
|
+
slots.push(groupId);
|
|
14807
|
+
}
|
|
14808
|
+
bucket.push(element);
|
|
14188
14809
|
}
|
|
14189
|
-
|
|
14190
|
-
|
|
14191
|
-
|
|
14810
|
+
return slots.flatMap(
|
|
14811
|
+
(slot) => typeof slot === "string" ? orderLevel(buckets.get(slot), level + 1) : [slot]
|
|
14812
|
+
);
|
|
14813
|
+
};
|
|
14814
|
+
const sortedElements = orderLevel(elements, 0);
|
|
14815
|
+
if (sortedElements.length !== elements.length) {
|
|
14816
|
+
console.error("defragmentGroups: lost some elements... bailing!");
|
|
14192
14817
|
return elements;
|
|
14193
14818
|
}
|
|
14194
|
-
return
|
|
14819
|
+
return sortedElements;
|
|
14195
14820
|
};
|
|
14196
14821
|
var normalizeBoundElementsOrder = (elements) => {
|
|
14197
|
-
const elementsMap =
|
|
14198
|
-
const origElements = elements.slice();
|
|
14822
|
+
const elementsMap = arrayToMap7(elements);
|
|
14199
14823
|
const sortedElements = /* @__PURE__ */ new Set();
|
|
14200
|
-
|
|
14201
|
-
if (
|
|
14202
|
-
|
|
14824
|
+
for (const element of elements) {
|
|
14825
|
+
if (sortedElements.has(element)) {
|
|
14826
|
+
continue;
|
|
14203
14827
|
}
|
|
14204
14828
|
if (element.boundElements?.length) {
|
|
14205
14829
|
sortedElements.add(element);
|
|
14206
|
-
|
|
14207
|
-
element.boundElements.forEach((boundElement) => {
|
|
14830
|
+
for (const boundElement of element.boundElements) {
|
|
14208
14831
|
const child = elementsMap.get(boundElement.id);
|
|
14209
14832
|
if (child && boundElement.type === "text") {
|
|
14210
|
-
sortedElements.add(child
|
|
14211
|
-
origElements[child[1]] = null;
|
|
14833
|
+
sortedElements.add(child);
|
|
14212
14834
|
}
|
|
14213
|
-
});
|
|
14214
|
-
} else if (element.type === "text" && element.containerId) {
|
|
14215
|
-
const parent = elementsMap.get(element.containerId);
|
|
14216
|
-
if (!parent?.[0].boundElements?.find((x) => x.id === element.id)) {
|
|
14217
|
-
sortedElements.add(element);
|
|
14218
|
-
origElements[idx] = null;
|
|
14219
14835
|
}
|
|
14220
|
-
|
|
14221
|
-
sortedElements.add(element);
|
|
14222
|
-
origElements[idx] = null;
|
|
14836
|
+
continue;
|
|
14223
14837
|
}
|
|
14224
|
-
|
|
14838
|
+
if (element.type === "text" && element.containerId && elementsMap.get(element.containerId)?.boundElements?.some((el) => el.id === element.id)) {
|
|
14839
|
+
continue;
|
|
14840
|
+
}
|
|
14841
|
+
sortedElements.add(element);
|
|
14842
|
+
}
|
|
14225
14843
|
if (sortedElements.size !== elements.length) {
|
|
14226
14844
|
console.error(
|
|
14227
14845
|
"normalizeBoundElementsOrder: lost some elements... bailing!"
|
|
@@ -14231,7 +14849,7 @@ var normalizeBoundElementsOrder = (elements) => {
|
|
|
14231
14849
|
return [...sortedElements];
|
|
14232
14850
|
};
|
|
14233
14851
|
var normalizeElementOrder = (elements) => {
|
|
14234
|
-
return normalizeBoundElementsOrder(
|
|
14852
|
+
return normalizeBoundElementsOrder(defragmentGroups(elements));
|
|
14235
14853
|
};
|
|
14236
14854
|
|
|
14237
14855
|
// src/duplicate.ts
|
|
@@ -14271,8 +14889,9 @@ var duplicateElements = (opts) => {
|
|
|
14271
14889
|
const origIdToDuplicateId = /* @__PURE__ */ new Map();
|
|
14272
14890
|
const duplicateIdToOrigElement = /* @__PURE__ */ new Map();
|
|
14273
14891
|
const duplicateElementsMap = /* @__PURE__ */ new Map();
|
|
14274
|
-
const elementsMap =
|
|
14892
|
+
const elementsMap = arrayToMap8(elements);
|
|
14275
14893
|
const _idsOfElementsToDuplicate = opts.type === "in-place" ? opts.idsOfElementsToDuplicate : new Map(elements.map((el) => [el.id, el]));
|
|
14894
|
+
const preserveFrameChildrenOrder = opts.type === "everything" && opts.preserveFrameChildrenOrder;
|
|
14276
14895
|
if (opts.type === "in-place") {
|
|
14277
14896
|
for (const groupId of Object.keys(opts.appState.selectedGroupIds)) {
|
|
14278
14897
|
elements.filter((el) => el.groupIds?.includes(groupId)).forEach((el) => _idsOfElementsToDuplicate.set(el.id, el));
|
|
@@ -14332,7 +14951,7 @@ var duplicateElements = (opts) => {
|
|
|
14332
14951
|
const groupId = getSelectedGroupForElement(appState, element);
|
|
14333
14952
|
if (groupId) {
|
|
14334
14953
|
const groupElements = getElementsInGroup(elements, groupId).flatMap(
|
|
14335
|
-
(element2) => isFrameLikeElement(element2) ? [...getFrameChildren(elements, element2.id), element2] : [element2]
|
|
14954
|
+
(element2) => isFrameLikeElement(element2) && !preserveFrameChildrenOrder ? [...getFrameChildren(elements, element2.id), element2] : [element2]
|
|
14336
14955
|
);
|
|
14337
14956
|
const targetIndex = findLastIndex(elementsWithDuplicates, (el) => {
|
|
14338
14957
|
return el.groupIds?.includes(groupId);
|
|
@@ -14340,11 +14959,18 @@ var duplicateElements = (opts) => {
|
|
|
14340
14959
|
insertBeforeOrAfterIndex(targetIndex, copyElements(groupElements));
|
|
14341
14960
|
continue;
|
|
14342
14961
|
}
|
|
14343
|
-
if (element.frameId && frameIdsToDuplicate.has(element.frameId)) {
|
|
14962
|
+
if (!preserveFrameChildrenOrder && element.frameId && frameIdsToDuplicate.has(element.frameId)) {
|
|
14344
14963
|
continue;
|
|
14345
14964
|
}
|
|
14346
14965
|
if (isFrameLikeElement(element)) {
|
|
14347
14966
|
const frameId = element.id;
|
|
14967
|
+
if (preserveFrameChildrenOrder) {
|
|
14968
|
+
insertBeforeOrAfterIndex(
|
|
14969
|
+
findLastIndex(elementsWithDuplicates, (el) => el.id === frameId),
|
|
14970
|
+
copyElements(element)
|
|
14971
|
+
);
|
|
14972
|
+
continue;
|
|
14973
|
+
}
|
|
14348
14974
|
const frameChildren = getFrameChildren(elements, frameId);
|
|
14349
14975
|
const targetIndex = findLastIndex(elementsWithDuplicates, (el) => {
|
|
14350
14976
|
return el.frameId === frameId || el.id === frameId;
|
|
@@ -14998,586 +15624,132 @@ var StoreSnapshot = class _StoreSnapshot {
|
|
|
14998
15624
|
if (!didAppStateChange) {
|
|
14999
15625
|
return this.appState;
|
|
15000
15626
|
}
|
|
15001
|
-
return nextAppStateSnapshot;
|
|
15002
|
-
}
|
|
15003
|
-
maybeCreateElementsSnapshot(elements, options = {
|
|
15004
|
-
shouldCompareHashes: false
|
|
15005
|
-
}) {
|
|
15006
|
-
if (!elements) {
|
|
15007
|
-
return this.elements;
|
|
15008
|
-
}
|
|
15009
|
-
const changedElements = this.detectChangedElements(elements, options);
|
|
15010
|
-
if (!changedElements?.size) {
|
|
15011
|
-
return this.elements;
|
|
15012
|
-
}
|
|
15013
|
-
const elementsSnapshot = this.createElementsSnapshot(changedElements);
|
|
15014
|
-
return elementsSnapshot;
|
|
15015
|
-
}
|
|
15016
|
-
detectChangedAppState(nextObservedAppState, options = {
|
|
15017
|
-
shouldCompareHashes: false
|
|
15018
|
-
}) {
|
|
15019
|
-
if (this.appState === nextObservedAppState) {
|
|
15020
|
-
return;
|
|
15021
|
-
}
|
|
15022
|
-
const didAppStateChange = Delta.isRightDifferent(
|
|
15023
|
-
this.appState,
|
|
15024
|
-
nextObservedAppState
|
|
15025
|
-
);
|
|
15026
|
-
if (!didAppStateChange) {
|
|
15027
|
-
return;
|
|
15028
|
-
}
|
|
15029
|
-
const changedAppStateHash = hashString(
|
|
15030
|
-
JSON.stringify(nextObservedAppState)
|
|
15031
|
-
);
|
|
15032
|
-
if (options.shouldCompareHashes && this._lastChangedAppStateHash === changedAppStateHash) {
|
|
15033
|
-
return;
|
|
15034
|
-
}
|
|
15035
|
-
this._lastChangedAppStateHash = changedAppStateHash;
|
|
15036
|
-
return didAppStateChange;
|
|
15037
|
-
}
|
|
15038
|
-
/**
|
|
15039
|
-
* Detect if there are any changed elements.
|
|
15040
|
-
*/
|
|
15041
|
-
detectChangedElements(nextElements, options = {
|
|
15042
|
-
shouldCompareHashes: false
|
|
15043
|
-
}) {
|
|
15044
|
-
if (this.elements === nextElements) {
|
|
15045
|
-
return;
|
|
15046
|
-
}
|
|
15047
|
-
const changedElements = /* @__PURE__ */ new Map();
|
|
15048
|
-
for (const prevElement of toIterable(this.elements)) {
|
|
15049
|
-
const nextElement = nextElements.get(prevElement.id);
|
|
15050
|
-
if (!nextElement) {
|
|
15051
|
-
changedElements.set(
|
|
15052
|
-
prevElement.id,
|
|
15053
|
-
newElementWith(prevElement, { isDeleted: true })
|
|
15054
|
-
);
|
|
15055
|
-
}
|
|
15056
|
-
}
|
|
15057
|
-
for (const nextElement of toIterable(nextElements)) {
|
|
15058
|
-
const prevElement = this.elements.get(nextElement.id);
|
|
15059
|
-
if (!prevElement || // element was added
|
|
15060
|
-
prevElement.version < nextElement.version) {
|
|
15061
|
-
if (isImageElement(nextElement) && !isInitializedImageElement(nextElement)) {
|
|
15062
|
-
continue;
|
|
15063
|
-
}
|
|
15064
|
-
changedElements.set(nextElement.id, nextElement);
|
|
15065
|
-
}
|
|
15066
|
-
}
|
|
15067
|
-
if (!changedElements.size) {
|
|
15068
|
-
return;
|
|
15069
|
-
}
|
|
15070
|
-
const changedElementsHash = hashElementsVersion(changedElements);
|
|
15071
|
-
if (options.shouldCompareHashes && this._lastChangedElementsHash === changedElementsHash) {
|
|
15072
|
-
return;
|
|
15073
|
-
}
|
|
15074
|
-
this._lastChangedElementsHash = changedElementsHash;
|
|
15075
|
-
return changedElements;
|
|
15076
|
-
}
|
|
15077
|
-
/**
|
|
15078
|
-
* Perform structural clone, deep cloning only elements that changed.
|
|
15079
|
-
*/
|
|
15080
|
-
createElementsSnapshot(changedElements) {
|
|
15081
|
-
const clonedElements = /* @__PURE__ */ new Map();
|
|
15082
|
-
for (const prevElement of toIterable(this.elements)) {
|
|
15083
|
-
clonedElements.set(prevElement.id, prevElement);
|
|
15084
|
-
}
|
|
15085
|
-
for (const changedElement of toIterable(changedElements)) {
|
|
15086
|
-
clonedElements.set(changedElement.id, deepCopyElement(changedElement));
|
|
15087
|
-
}
|
|
15088
|
-
return clonedElements;
|
|
15089
|
-
}
|
|
15090
|
-
};
|
|
15091
|
-
var hiddenObservedAppStateProp = "__observedAppState";
|
|
15092
|
-
var getDefaultObservedAppState = () => {
|
|
15093
|
-
return {
|
|
15094
|
-
name: null,
|
|
15095
|
-
editingGroupId: null,
|
|
15096
|
-
viewBackgroundColor: COLOR_PALETTE2.white,
|
|
15097
|
-
selectedElementIds: {},
|
|
15098
|
-
selectedGroupIds: {},
|
|
15099
|
-
selectedLinearElement: null,
|
|
15100
|
-
croppingElementId: null,
|
|
15101
|
-
activeLockedId: null,
|
|
15102
|
-
lockedMultiSelections: {}
|
|
15103
|
-
};
|
|
15104
|
-
};
|
|
15105
|
-
var getObservedAppState = (appState) => {
|
|
15106
|
-
const observedAppState = {
|
|
15107
|
-
name: appState.name,
|
|
15108
|
-
editingGroupId: appState.editingGroupId,
|
|
15109
|
-
viewBackgroundColor: appState.viewBackgroundColor,
|
|
15110
|
-
selectedElementIds: appState.selectedElementIds,
|
|
15111
|
-
selectedGroupIds: appState.selectedGroupIds,
|
|
15112
|
-
croppingElementId: appState.croppingElementId,
|
|
15113
|
-
activeLockedId: appState.activeLockedId,
|
|
15114
|
-
lockedMultiSelections: appState.lockedMultiSelections,
|
|
15115
|
-
selectedLinearElement: appState.selectedLinearElement ? {
|
|
15116
|
-
elementId: appState.selectedLinearElement.elementId,
|
|
15117
|
-
isEditing: !!appState.selectedLinearElement.isEditing
|
|
15118
|
-
} : null
|
|
15119
|
-
};
|
|
15120
|
-
Reflect.defineProperty(observedAppState, hiddenObservedAppStateProp, {
|
|
15121
|
-
value: true,
|
|
15122
|
-
enumerable: false
|
|
15123
|
-
});
|
|
15124
|
-
return observedAppState;
|
|
15125
|
-
};
|
|
15126
|
-
var isObservedAppState = (appState) => !!Reflect.get(appState, hiddenObservedAppStateProp);
|
|
15127
|
-
|
|
15128
|
-
// src/fractionalIndex.ts
|
|
15129
|
-
init_define_import_meta_env();
|
|
15130
|
-
|
|
15131
|
-
// ../../node_modules/fractional-indexing/src/index.js
|
|
15132
|
-
init_define_import_meta_env();
|
|
15133
|
-
var BASE_62_DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
15134
|
-
function midpoint(a2, b2, digits) {
|
|
15135
|
-
const zero = digits[0];
|
|
15136
|
-
if (b2 != null && a2 >= b2) {
|
|
15137
|
-
throw new Error(a2 + " >= " + b2);
|
|
15138
|
-
}
|
|
15139
|
-
if (a2.slice(-1) === zero || b2 && b2.slice(-1) === zero) {
|
|
15140
|
-
throw new Error("trailing zero");
|
|
15141
|
-
}
|
|
15142
|
-
if (b2) {
|
|
15143
|
-
let n = 0;
|
|
15144
|
-
while ((a2[n] || zero) === b2[n]) {
|
|
15145
|
-
n++;
|
|
15146
|
-
}
|
|
15147
|
-
if (n > 0) {
|
|
15148
|
-
return b2.slice(0, n) + midpoint(a2.slice(n), b2.slice(n), digits);
|
|
15149
|
-
}
|
|
15150
|
-
}
|
|
15151
|
-
const digitA = a2 ? digits.indexOf(a2[0]) : 0;
|
|
15152
|
-
const digitB = b2 != null ? digits.indexOf(b2[0]) : digits.length;
|
|
15153
|
-
if (digitB - digitA > 1) {
|
|
15154
|
-
const midDigit = Math.round(0.5 * (digitA + digitB));
|
|
15155
|
-
return digits[midDigit];
|
|
15156
|
-
} else {
|
|
15157
|
-
if (b2 && b2.length > 1) {
|
|
15158
|
-
return b2.slice(0, 1);
|
|
15159
|
-
} else {
|
|
15160
|
-
return digits[digitA] + midpoint(a2.slice(1), null, digits);
|
|
15161
|
-
}
|
|
15162
|
-
}
|
|
15163
|
-
}
|
|
15164
|
-
function validateInteger(int) {
|
|
15165
|
-
if (int.length !== getIntegerLength(int[0])) {
|
|
15166
|
-
throw new Error("invalid integer part of order key: " + int);
|
|
15167
|
-
}
|
|
15168
|
-
}
|
|
15169
|
-
function getIntegerLength(head) {
|
|
15170
|
-
if (head >= "a" && head <= "z") {
|
|
15171
|
-
return head.charCodeAt(0) - "a".charCodeAt(0) + 2;
|
|
15172
|
-
} else if (head >= "A" && head <= "Z") {
|
|
15173
|
-
return "Z".charCodeAt(0) - head.charCodeAt(0) + 2;
|
|
15174
|
-
} else {
|
|
15175
|
-
throw new Error("invalid order key head: " + head);
|
|
15176
|
-
}
|
|
15177
|
-
}
|
|
15178
|
-
function getIntegerPart(key) {
|
|
15179
|
-
const integerPartLength = getIntegerLength(key[0]);
|
|
15180
|
-
if (integerPartLength > key.length) {
|
|
15181
|
-
throw new Error("invalid order key: " + key);
|
|
15182
|
-
}
|
|
15183
|
-
return key.slice(0, integerPartLength);
|
|
15184
|
-
}
|
|
15185
|
-
function validateOrderKey(key, digits) {
|
|
15186
|
-
if (key === "A" + digits[0].repeat(26)) {
|
|
15187
|
-
throw new Error("invalid order key: " + key);
|
|
15188
|
-
}
|
|
15189
|
-
const i = getIntegerPart(key);
|
|
15190
|
-
const f = key.slice(i.length);
|
|
15191
|
-
if (f.slice(-1) === digits[0]) {
|
|
15192
|
-
throw new Error("invalid order key: " + key);
|
|
15193
|
-
}
|
|
15194
|
-
}
|
|
15195
|
-
function incrementInteger(x, digits) {
|
|
15196
|
-
validateInteger(x);
|
|
15197
|
-
const [head, ...digs] = x.split("");
|
|
15198
|
-
let carry = true;
|
|
15199
|
-
for (let i = digs.length - 1; carry && i >= 0; i--) {
|
|
15200
|
-
const d = digits.indexOf(digs[i]) + 1;
|
|
15201
|
-
if (d === digits.length) {
|
|
15202
|
-
digs[i] = digits[0];
|
|
15203
|
-
} else {
|
|
15204
|
-
digs[i] = digits[d];
|
|
15205
|
-
carry = false;
|
|
15206
|
-
}
|
|
15207
|
-
}
|
|
15208
|
-
if (carry) {
|
|
15209
|
-
if (head === "Z") {
|
|
15210
|
-
return "a" + digits[0];
|
|
15211
|
-
}
|
|
15212
|
-
if (head === "z") {
|
|
15213
|
-
return null;
|
|
15214
|
-
}
|
|
15215
|
-
const h = String.fromCharCode(head.charCodeAt(0) + 1);
|
|
15216
|
-
if (h > "a") {
|
|
15217
|
-
digs.push(digits[0]);
|
|
15218
|
-
} else {
|
|
15219
|
-
digs.pop();
|
|
15220
|
-
}
|
|
15221
|
-
return h + digs.join("");
|
|
15222
|
-
} else {
|
|
15223
|
-
return head + digs.join("");
|
|
15224
|
-
}
|
|
15225
|
-
}
|
|
15226
|
-
function decrementInteger(x, digits) {
|
|
15227
|
-
validateInteger(x);
|
|
15228
|
-
const [head, ...digs] = x.split("");
|
|
15229
|
-
let borrow = true;
|
|
15230
|
-
for (let i = digs.length - 1; borrow && i >= 0; i--) {
|
|
15231
|
-
const d = digits.indexOf(digs[i]) - 1;
|
|
15232
|
-
if (d === -1) {
|
|
15233
|
-
digs[i] = digits.slice(-1);
|
|
15234
|
-
} else {
|
|
15235
|
-
digs[i] = digits[d];
|
|
15236
|
-
borrow = false;
|
|
15237
|
-
}
|
|
15238
|
-
}
|
|
15239
|
-
if (borrow) {
|
|
15240
|
-
if (head === "a") {
|
|
15241
|
-
return "Z" + digits.slice(-1);
|
|
15242
|
-
}
|
|
15243
|
-
if (head === "A") {
|
|
15244
|
-
return null;
|
|
15245
|
-
}
|
|
15246
|
-
const h = String.fromCharCode(head.charCodeAt(0) - 1);
|
|
15247
|
-
if (h < "Z") {
|
|
15248
|
-
digs.push(digits.slice(-1));
|
|
15249
|
-
} else {
|
|
15250
|
-
digs.pop();
|
|
15251
|
-
}
|
|
15252
|
-
return h + digs.join("");
|
|
15253
|
-
} else {
|
|
15254
|
-
return head + digs.join("");
|
|
15255
|
-
}
|
|
15256
|
-
}
|
|
15257
|
-
function generateKeyBetween(a2, b2, digits = BASE_62_DIGITS) {
|
|
15258
|
-
if (a2 != null) {
|
|
15259
|
-
validateOrderKey(a2, digits);
|
|
15260
|
-
}
|
|
15261
|
-
if (b2 != null) {
|
|
15262
|
-
validateOrderKey(b2, digits);
|
|
15263
|
-
}
|
|
15264
|
-
if (a2 != null && b2 != null && a2 >= b2) {
|
|
15265
|
-
throw new Error(a2 + " >= " + b2);
|
|
15266
|
-
}
|
|
15267
|
-
if (a2 == null) {
|
|
15268
|
-
if (b2 == null) {
|
|
15269
|
-
return "a" + digits[0];
|
|
15270
|
-
}
|
|
15271
|
-
const ib2 = getIntegerPart(b2);
|
|
15272
|
-
const fb2 = b2.slice(ib2.length);
|
|
15273
|
-
if (ib2 === "A" + digits[0].repeat(26)) {
|
|
15274
|
-
return ib2 + midpoint("", fb2, digits);
|
|
15275
|
-
}
|
|
15276
|
-
if (ib2 < b2) {
|
|
15277
|
-
return ib2;
|
|
15278
|
-
}
|
|
15279
|
-
const res = decrementInteger(ib2, digits);
|
|
15280
|
-
if (res == null) {
|
|
15281
|
-
throw new Error("cannot decrement any more");
|
|
15282
|
-
}
|
|
15283
|
-
return res;
|
|
15284
|
-
}
|
|
15285
|
-
if (b2 == null) {
|
|
15286
|
-
const ia2 = getIntegerPart(a2);
|
|
15287
|
-
const fa2 = a2.slice(ia2.length);
|
|
15288
|
-
const i2 = incrementInteger(ia2, digits);
|
|
15289
|
-
return i2 == null ? ia2 + midpoint(fa2, null, digits) : i2;
|
|
15290
|
-
}
|
|
15291
|
-
const ia = getIntegerPart(a2);
|
|
15292
|
-
const fa = a2.slice(ia.length);
|
|
15293
|
-
const ib = getIntegerPart(b2);
|
|
15294
|
-
const fb = b2.slice(ib.length);
|
|
15295
|
-
if (ia === ib) {
|
|
15296
|
-
return ia + midpoint(fa, fb, digits);
|
|
15297
|
-
}
|
|
15298
|
-
const i = incrementInteger(ia, digits);
|
|
15299
|
-
if (i == null) {
|
|
15300
|
-
throw new Error("cannot increment any more");
|
|
15301
|
-
}
|
|
15302
|
-
if (i < b2) {
|
|
15303
|
-
return i;
|
|
15304
|
-
}
|
|
15305
|
-
return ia + midpoint(fa, null, digits);
|
|
15306
|
-
}
|
|
15307
|
-
function generateNKeysBetween(a2, b2, n, digits = BASE_62_DIGITS) {
|
|
15308
|
-
if (n === 0) {
|
|
15309
|
-
return [];
|
|
15310
|
-
}
|
|
15311
|
-
if (n === 1) {
|
|
15312
|
-
return [generateKeyBetween(a2, b2, digits)];
|
|
15313
|
-
}
|
|
15314
|
-
if (b2 == null) {
|
|
15315
|
-
let c2 = generateKeyBetween(a2, b2, digits);
|
|
15316
|
-
const result = [c2];
|
|
15317
|
-
for (let i = 0; i < n - 1; i++) {
|
|
15318
|
-
c2 = generateKeyBetween(c2, b2, digits);
|
|
15319
|
-
result.push(c2);
|
|
15320
|
-
}
|
|
15321
|
-
return result;
|
|
15322
|
-
}
|
|
15323
|
-
if (a2 == null) {
|
|
15324
|
-
let c2 = generateKeyBetween(a2, b2, digits);
|
|
15325
|
-
const result = [c2];
|
|
15326
|
-
for (let i = 0; i < n - 1; i++) {
|
|
15327
|
-
c2 = generateKeyBetween(a2, c2, digits);
|
|
15328
|
-
result.push(c2);
|
|
15329
|
-
}
|
|
15330
|
-
result.reverse();
|
|
15331
|
-
return result;
|
|
15332
|
-
}
|
|
15333
|
-
const mid = Math.floor(n / 2);
|
|
15334
|
-
const c = generateKeyBetween(a2, b2, digits);
|
|
15335
|
-
return [
|
|
15336
|
-
...generateNKeysBetween(a2, c, mid, digits),
|
|
15337
|
-
c,
|
|
15338
|
-
...generateNKeysBetween(c, b2, n - mid - 1, digits)
|
|
15339
|
-
];
|
|
15340
|
-
}
|
|
15341
|
-
|
|
15342
|
-
// src/fractionalIndex.ts
|
|
15343
|
-
import { arrayToMap as arrayToMap8 } from "@excalidraw/common";
|
|
15344
|
-
var InvalidFractionalIndexError = class extends Error {
|
|
15345
|
-
code = "ELEMENT_HAS_INVALID_INDEX";
|
|
15346
|
-
};
|
|
15347
|
-
var validateFractionalIndices = (elements, {
|
|
15348
|
-
shouldThrow = false,
|
|
15349
|
-
includeBoundTextValidation = false,
|
|
15350
|
-
ignoreLogs,
|
|
15351
|
-
reconciliationContext
|
|
15352
|
-
}) => {
|
|
15353
|
-
const errorMessages = [];
|
|
15354
|
-
const stringifyElement = (element) => `${element?.index}:${element?.id}:${element?.type}:${element?.isDeleted}:${element?.version}:${element?.versionNonce}`;
|
|
15355
|
-
const indices = elements.map((x) => x.index);
|
|
15356
|
-
for (const [i, index] of indices.entries()) {
|
|
15357
|
-
const predecessorIndex = indices[i - 1];
|
|
15358
|
-
const successorIndex = indices[i + 1];
|
|
15359
|
-
if (!isValidFractionalIndex(index, predecessorIndex, successorIndex)) {
|
|
15360
|
-
errorMessages.push(
|
|
15361
|
-
`Fractional indices invariant has been compromised: "${stringifyElement(
|
|
15362
|
-
elements[i - 1]
|
|
15363
|
-
)}", "${stringifyElement(elements[i])}", "${stringifyElement(
|
|
15364
|
-
elements[i + 1]
|
|
15365
|
-
)}"`
|
|
15366
|
-
);
|
|
15367
|
-
}
|
|
15368
|
-
if (includeBoundTextValidation && hasBoundTextElement(elements[i])) {
|
|
15369
|
-
const container = elements[i];
|
|
15370
|
-
const text = getBoundTextElement(container, arrayToMap8(elements));
|
|
15371
|
-
if (text && text.index <= container.index) {
|
|
15372
|
-
errorMessages.push(
|
|
15373
|
-
`Fractional indices invariant for bound elements has been compromised: "${stringifyElement(
|
|
15374
|
-
text
|
|
15375
|
-
)}", "${stringifyElement(container)}"`
|
|
15376
|
-
);
|
|
15377
|
-
}
|
|
15378
|
-
}
|
|
15379
|
-
}
|
|
15380
|
-
if (errorMessages.length) {
|
|
15381
|
-
const error = new InvalidFractionalIndexError();
|
|
15382
|
-
const additionalContext = [];
|
|
15383
|
-
if (reconciliationContext) {
|
|
15384
|
-
additionalContext.push("Additional reconciliation context:");
|
|
15385
|
-
additionalContext.push(
|
|
15386
|
-
reconciliationContext.localElements.map((x) => stringifyElement(x))
|
|
15387
|
-
);
|
|
15388
|
-
additionalContext.push(
|
|
15389
|
-
reconciliationContext.remoteElements.map((x) => stringifyElement(x))
|
|
15390
|
-
);
|
|
15391
|
-
}
|
|
15392
|
-
if (!ignoreLogs) {
|
|
15393
|
-
console.error(
|
|
15394
|
-
errorMessages.join("\n\n"),
|
|
15395
|
-
error.stack,
|
|
15396
|
-
elements.map((x) => stringifyElement(x)),
|
|
15397
|
-
...additionalContext
|
|
15398
|
-
);
|
|
15399
|
-
}
|
|
15400
|
-
if (shouldThrow) {
|
|
15401
|
-
throw error;
|
|
15402
|
-
}
|
|
15403
|
-
}
|
|
15404
|
-
};
|
|
15405
|
-
var orderByFractionalIndex = (elements) => {
|
|
15406
|
-
return elements.sort((a2, b2) => {
|
|
15407
|
-
if (isOrderedElement(a2) && isOrderedElement(b2)) {
|
|
15408
|
-
if (a2.index < b2.index) {
|
|
15409
|
-
return -1;
|
|
15410
|
-
} else if (a2.index > b2.index) {
|
|
15411
|
-
return 1;
|
|
15412
|
-
}
|
|
15413
|
-
return a2.id < b2.id ? -1 : 1;
|
|
15414
|
-
}
|
|
15415
|
-
return 1;
|
|
15416
|
-
});
|
|
15417
|
-
};
|
|
15418
|
-
var syncMovedIndices = (elements, movedElements) => {
|
|
15419
|
-
try {
|
|
15420
|
-
const elementsMap = arrayToMap8(elements);
|
|
15421
|
-
const indicesGroups = getMovedIndicesGroups(elements, movedElements);
|
|
15422
|
-
const elementsUpdates = generateIndices(elements, indicesGroups);
|
|
15423
|
-
const elementsCandidates = elements.map((x) => {
|
|
15424
|
-
const elementUpdates = elementsUpdates.get(x);
|
|
15425
|
-
if (elementUpdates) {
|
|
15426
|
-
return { ...x, index: elementUpdates.index };
|
|
15427
|
-
}
|
|
15428
|
-
return x;
|
|
15429
|
-
});
|
|
15430
|
-
validateFractionalIndices(
|
|
15431
|
-
elementsCandidates,
|
|
15432
|
-
// we don't autofix invalid bound text indices, hence don't include it in the validation
|
|
15433
|
-
{
|
|
15434
|
-
includeBoundTextValidation: false,
|
|
15435
|
-
shouldThrow: true,
|
|
15436
|
-
ignoreLogs: true
|
|
15437
|
-
}
|
|
15438
|
-
);
|
|
15439
|
-
for (const [element, { index }] of elementsUpdates) {
|
|
15440
|
-
mutateElement(element, elementsMap, { index });
|
|
15441
|
-
}
|
|
15442
|
-
} catch (e) {
|
|
15443
|
-
syncInvalidIndices(elements);
|
|
15444
|
-
}
|
|
15445
|
-
return elements;
|
|
15446
|
-
};
|
|
15447
|
-
var syncInvalidIndices = (elements) => {
|
|
15448
|
-
const elementsMap = arrayToMap8(elements);
|
|
15449
|
-
const indicesGroups = getInvalidIndicesGroups(elements);
|
|
15450
|
-
const elementsUpdates = generateIndices(elements, indicesGroups);
|
|
15451
|
-
for (const [element, { index }] of elementsUpdates) {
|
|
15452
|
-
mutateElement(element, elementsMap, { index });
|
|
15453
|
-
}
|
|
15454
|
-
return elements;
|
|
15455
|
-
};
|
|
15456
|
-
var syncInvalidIndicesImmutable = (elements) => {
|
|
15457
|
-
const syncedElements = arrayToMap8(elements);
|
|
15458
|
-
const indicesGroups = getInvalidIndicesGroups(elements);
|
|
15459
|
-
const elementsUpdates = generateIndices(elements, indicesGroups);
|
|
15460
|
-
for (const [element, { index }] of elementsUpdates) {
|
|
15461
|
-
syncedElements.set(element.id, newElementWith(element, { index }));
|
|
15462
|
-
}
|
|
15463
|
-
return syncedElements;
|
|
15464
|
-
};
|
|
15465
|
-
var getMovedIndicesGroups = (elements, movedElements) => {
|
|
15466
|
-
const indicesGroups = [];
|
|
15467
|
-
let i = 0;
|
|
15468
|
-
while (i < elements.length) {
|
|
15469
|
-
if (movedElements.has(elements[i].id)) {
|
|
15470
|
-
const indicesGroup = [i - 1, i];
|
|
15471
|
-
while (++i < elements.length) {
|
|
15472
|
-
if (!movedElements.has(elements[i].id)) {
|
|
15473
|
-
break;
|
|
15474
|
-
}
|
|
15475
|
-
indicesGroup.push(i);
|
|
15476
|
-
}
|
|
15477
|
-
indicesGroup.push(i);
|
|
15478
|
-
indicesGroups.push(indicesGroup);
|
|
15479
|
-
} else {
|
|
15480
|
-
i++;
|
|
15481
|
-
}
|
|
15627
|
+
return nextAppStateSnapshot;
|
|
15482
15628
|
}
|
|
15483
|
-
|
|
15484
|
-
|
|
15485
|
-
|
|
15486
|
-
|
|
15487
|
-
|
|
15488
|
-
let upperBound = void 0;
|
|
15489
|
-
let lowerBoundIndex = -1;
|
|
15490
|
-
let upperBoundIndex = 0;
|
|
15491
|
-
const getLowerBound = (index) => {
|
|
15492
|
-
const lowerBound2 = elements[lowerBoundIndex] ? elements[lowerBoundIndex].index : void 0;
|
|
15493
|
-
const candidate = elements[index - 1]?.index;
|
|
15494
|
-
if (!lowerBound2 && candidate || // first lowerBound
|
|
15495
|
-
lowerBound2 && candidate && candidate > lowerBound2) {
|
|
15496
|
-
return [candidate, index - 1];
|
|
15629
|
+
maybeCreateElementsSnapshot(elements, options = {
|
|
15630
|
+
shouldCompareHashes: false
|
|
15631
|
+
}) {
|
|
15632
|
+
if (!elements) {
|
|
15633
|
+
return this.elements;
|
|
15497
15634
|
}
|
|
15498
|
-
|
|
15499
|
-
|
|
15500
|
-
|
|
15501
|
-
const upperBound2 = elements[upperBoundIndex] ? elements[upperBoundIndex].index : void 0;
|
|
15502
|
-
if (upperBound2 && index < upperBoundIndex) {
|
|
15503
|
-
return [upperBound2, upperBoundIndex];
|
|
15635
|
+
const changedElements = this.detectChangedElements(elements, options);
|
|
15636
|
+
if (!changedElements?.size) {
|
|
15637
|
+
return this.elements;
|
|
15504
15638
|
}
|
|
15505
|
-
|
|
15506
|
-
|
|
15507
|
-
|
|
15508
|
-
|
|
15509
|
-
|
|
15510
|
-
|
|
15639
|
+
const elementsSnapshot = this.createElementsSnapshot(changedElements);
|
|
15640
|
+
return elementsSnapshot;
|
|
15641
|
+
}
|
|
15642
|
+
detectChangedAppState(nextObservedAppState, options = {
|
|
15643
|
+
shouldCompareHashes: false
|
|
15644
|
+
}) {
|
|
15645
|
+
if (this.appState === nextObservedAppState) {
|
|
15646
|
+
return;
|
|
15647
|
+
}
|
|
15648
|
+
const didAppStateChange = Delta.isRightDifferent(
|
|
15649
|
+
this.appState,
|
|
15650
|
+
nextObservedAppState
|
|
15651
|
+
);
|
|
15652
|
+
if (!didAppStateChange) {
|
|
15653
|
+
return;
|
|
15654
|
+
}
|
|
15655
|
+
const changedAppStateHash = hashString(
|
|
15656
|
+
JSON.stringify(nextObservedAppState)
|
|
15657
|
+
);
|
|
15658
|
+
if (options.shouldCompareHashes && this._lastChangedAppStateHash === changedAppStateHash) {
|
|
15659
|
+
return;
|
|
15660
|
+
}
|
|
15661
|
+
this._lastChangedAppStateHash = changedAppStateHash;
|
|
15662
|
+
return didAppStateChange;
|
|
15663
|
+
}
|
|
15664
|
+
/**
|
|
15665
|
+
* Detect if there are any changed elements.
|
|
15666
|
+
*/
|
|
15667
|
+
detectChangedElements(nextElements, options = {
|
|
15668
|
+
shouldCompareHashes: false
|
|
15669
|
+
}) {
|
|
15670
|
+
if (this.elements === nextElements) {
|
|
15671
|
+
return;
|
|
15672
|
+
}
|
|
15673
|
+
const changedElements = /* @__PURE__ */ new Map();
|
|
15674
|
+
for (const prevElement of toIterable(this.elements)) {
|
|
15675
|
+
const nextElement = nextElements.get(prevElement.id);
|
|
15676
|
+
if (!nextElement) {
|
|
15677
|
+
changedElements.set(
|
|
15678
|
+
prevElement.id,
|
|
15679
|
+
newElementWith(prevElement, { isDeleted: true })
|
|
15680
|
+
);
|
|
15511
15681
|
}
|
|
15512
15682
|
}
|
|
15513
|
-
|
|
15514
|
-
|
|
15515
|
-
|
|
15516
|
-
|
|
15517
|
-
|
|
15518
|
-
|
|
15519
|
-
[upperBound, upperBoundIndex] = getUpperBound(i);
|
|
15520
|
-
if (!isValidFractionalIndex(current, lowerBound, upperBound)) {
|
|
15521
|
-
const indicesGroup = [lowerBoundIndex, i];
|
|
15522
|
-
while (++i < elements.length) {
|
|
15523
|
-
const current2 = elements[i].index;
|
|
15524
|
-
const [nextLowerBound, nextLowerBoundIndex] = getLowerBound(i);
|
|
15525
|
-
const [nextUpperBound, nextUpperBoundIndex] = getUpperBound(i);
|
|
15526
|
-
if (isValidFractionalIndex(current2, nextLowerBound, nextUpperBound)) {
|
|
15527
|
-
break;
|
|
15683
|
+
for (const nextElement of toIterable(nextElements)) {
|
|
15684
|
+
const prevElement = this.elements.get(nextElement.id);
|
|
15685
|
+
if (!prevElement || // element was added
|
|
15686
|
+
prevElement.version < nextElement.version) {
|
|
15687
|
+
if (isImageElement(nextElement) && !isInitializedImageElement(nextElement)) {
|
|
15688
|
+
continue;
|
|
15528
15689
|
}
|
|
15529
|
-
|
|
15530
|
-
[upperBound, upperBoundIndex] = [nextUpperBound, nextUpperBoundIndex];
|
|
15531
|
-
indicesGroup.push(i);
|
|
15690
|
+
changedElements.set(nextElement.id, nextElement);
|
|
15532
15691
|
}
|
|
15533
|
-
indicesGroup.push(upperBoundIndex);
|
|
15534
|
-
indicesGroups.push(indicesGroup);
|
|
15535
|
-
} else {
|
|
15536
|
-
i++;
|
|
15537
15692
|
}
|
|
15693
|
+
if (!changedElements.size) {
|
|
15694
|
+
return;
|
|
15695
|
+
}
|
|
15696
|
+
const changedElementsHash = hashElementsVersion(changedElements);
|
|
15697
|
+
if (options.shouldCompareHashes && this._lastChangedElementsHash === changedElementsHash) {
|
|
15698
|
+
return;
|
|
15699
|
+
}
|
|
15700
|
+
this._lastChangedElementsHash = changedElementsHash;
|
|
15701
|
+
return changedElements;
|
|
15538
15702
|
}
|
|
15539
|
-
|
|
15540
|
-
|
|
15541
|
-
|
|
15542
|
-
|
|
15543
|
-
|
|
15544
|
-
|
|
15545
|
-
|
|
15546
|
-
|
|
15547
|
-
|
|
15548
|
-
|
|
15549
|
-
return index < successor;
|
|
15550
|
-
}
|
|
15551
|
-
if (predecessor && !successor) {
|
|
15552
|
-
return predecessor < index;
|
|
15553
|
-
}
|
|
15554
|
-
return !!index;
|
|
15555
|
-
};
|
|
15556
|
-
var generateIndices = (elements, indicesGroups) => {
|
|
15557
|
-
const elementsUpdates = /* @__PURE__ */ new Map();
|
|
15558
|
-
for (const indices of indicesGroups) {
|
|
15559
|
-
const lowerBoundIndex = indices.shift();
|
|
15560
|
-
const upperBoundIndex = indices.pop();
|
|
15561
|
-
const fractionalIndices = generateNKeysBetween(
|
|
15562
|
-
elements[lowerBoundIndex]?.index,
|
|
15563
|
-
elements[upperBoundIndex]?.index,
|
|
15564
|
-
indices.length
|
|
15565
|
-
);
|
|
15566
|
-
for (let i = 0; i < indices.length; i++) {
|
|
15567
|
-
const element = elements[indices[i]];
|
|
15568
|
-
elementsUpdates.set(element, {
|
|
15569
|
-
index: fractionalIndices[i]
|
|
15570
|
-
});
|
|
15703
|
+
/**
|
|
15704
|
+
* Perform structural clone, deep cloning only elements that changed.
|
|
15705
|
+
*/
|
|
15706
|
+
createElementsSnapshot(changedElements) {
|
|
15707
|
+
const clonedElements = /* @__PURE__ */ new Map();
|
|
15708
|
+
for (const prevElement of toIterable(this.elements)) {
|
|
15709
|
+
clonedElements.set(prevElement.id, prevElement);
|
|
15710
|
+
}
|
|
15711
|
+
for (const changedElement of toIterable(changedElements)) {
|
|
15712
|
+
clonedElements.set(changedElement.id, deepCopyElement(changedElement));
|
|
15571
15713
|
}
|
|
15714
|
+
return clonedElements;
|
|
15572
15715
|
}
|
|
15573
|
-
return elementsUpdates;
|
|
15574
15716
|
};
|
|
15575
|
-
var
|
|
15576
|
-
|
|
15577
|
-
|
|
15578
|
-
|
|
15579
|
-
|
|
15717
|
+
var hiddenObservedAppStateProp = "__observedAppState";
|
|
15718
|
+
var getDefaultObservedAppState = () => {
|
|
15719
|
+
return {
|
|
15720
|
+
name: null,
|
|
15721
|
+
editingGroupId: null,
|
|
15722
|
+
viewBackgroundColor: COLOR_PALETTE2.white,
|
|
15723
|
+
selectedElementIds: {},
|
|
15724
|
+
selectedGroupIds: {},
|
|
15725
|
+
selectedLinearElement: null,
|
|
15726
|
+
croppingElementId: null,
|
|
15727
|
+
activeLockedId: null,
|
|
15728
|
+
lockedMultiSelections: {}
|
|
15729
|
+
};
|
|
15730
|
+
};
|
|
15731
|
+
var getObservedAppState = (appState) => {
|
|
15732
|
+
const observedAppState = {
|
|
15733
|
+
name: appState.name,
|
|
15734
|
+
editingGroupId: appState.editingGroupId,
|
|
15735
|
+
viewBackgroundColor: appState.viewBackgroundColor,
|
|
15736
|
+
selectedElementIds: appState.selectedElementIds,
|
|
15737
|
+
selectedGroupIds: appState.selectedGroupIds,
|
|
15738
|
+
croppingElementId: appState.croppingElementId,
|
|
15739
|
+
activeLockedId: appState.activeLockedId,
|
|
15740
|
+
lockedMultiSelections: appState.lockedMultiSelections,
|
|
15741
|
+
selectedLinearElement: appState.selectedLinearElement ? {
|
|
15742
|
+
elementId: appState.selectedLinearElement.elementId,
|
|
15743
|
+
isEditing: !!appState.selectedLinearElement.isEditing
|
|
15744
|
+
} : null
|
|
15745
|
+
};
|
|
15746
|
+
Reflect.defineProperty(observedAppState, hiddenObservedAppStateProp, {
|
|
15747
|
+
value: true,
|
|
15748
|
+
enumerable: false
|
|
15749
|
+
});
|
|
15750
|
+
return observedAppState;
|
|
15580
15751
|
};
|
|
15752
|
+
var isObservedAppState = (appState) => !!Reflect.get(appState, hiddenObservedAppStateProp);
|
|
15581
15753
|
|
|
15582
15754
|
// src/Scene.ts
|
|
15583
15755
|
init_define_import_meta_env();
|
|
@@ -15796,24 +15968,14 @@ var Scene = class {
|
|
|
15796
15968
|
this.selectedElementsCache.cache.clear();
|
|
15797
15969
|
this.callbacks.clear();
|
|
15798
15970
|
}
|
|
15799
|
-
|
|
15800
|
-
if (!Number.isFinite(index) || index < 0) {
|
|
15801
|
-
throw new Error(
|
|
15802
|
-
"insertElementAtIndex can only be called with index >= 0"
|
|
15803
|
-
);
|
|
15804
|
-
}
|
|
15805
|
-
const nextElements = [
|
|
15806
|
-
...this.elements.slice(0, index),
|
|
15807
|
-
element,
|
|
15808
|
-
...this.elements.slice(index)
|
|
15809
|
-
];
|
|
15810
|
-
syncMovedIndices2(nextElements, arrayToMap9([element]));
|
|
15811
|
-
this.replaceAllElements(nextElements);
|
|
15812
|
-
}
|
|
15971
|
+
/** low-level - generally use app.insertNewElements() */
|
|
15813
15972
|
insertElementsAtIndex(elements, index) {
|
|
15814
15973
|
if (!elements.length) {
|
|
15815
15974
|
return;
|
|
15816
15975
|
}
|
|
15976
|
+
if (index === null) {
|
|
15977
|
+
index = this.elements.length;
|
|
15978
|
+
}
|
|
15817
15979
|
if (!Number.isFinite(index) || index < 0) {
|
|
15818
15980
|
throw new Error(
|
|
15819
15981
|
"insertElementAtIndex can only be called with index >= 0"
|
|
@@ -15827,16 +15989,9 @@ var Scene = class {
|
|
|
15827
15989
|
syncMovedIndices2(nextElements, arrayToMap9(elements));
|
|
15828
15990
|
this.replaceAllElements(nextElements);
|
|
15829
15991
|
}
|
|
15992
|
+
/** low-level - generally use app.insertNewElement() */
|
|
15830
15993
|
insertElement = (element) => {
|
|
15831
|
-
|
|
15832
|
-
this.insertElementAtIndex(element, index);
|
|
15833
|
-
};
|
|
15834
|
-
insertElements = (elements) => {
|
|
15835
|
-
if (!elements.length) {
|
|
15836
|
-
return;
|
|
15837
|
-
}
|
|
15838
|
-
const index = elements[0]?.frameId ? this.getElementIndex(elements[0].frameId) : this.elements.length;
|
|
15839
|
-
this.insertElementsAtIndex(elements, index);
|
|
15994
|
+
this.insertElementsAtIndex([element], null);
|
|
15840
15995
|
};
|
|
15841
15996
|
getElementIndex(elementId) {
|
|
15842
15997
|
return this.elements.findIndex((element) => element.id === elementId);
|
|
@@ -18252,19 +18407,19 @@ var embeddableURLValidator = (url, validateEmbeddable) => {
|
|
|
18252
18407
|
|
|
18253
18408
|
// src/flowchart.ts
|
|
18254
18409
|
init_define_import_meta_env();
|
|
18255
|
-
import { KEYS as
|
|
18256
|
-
import { pointFrom as
|
|
18410
|
+
import { KEYS as KEYS2, invariant as invariant11, toBrandedType as toBrandedType2 } from "@excalidraw/common";
|
|
18411
|
+
import { pointFrom as pointFrom14 } from "@excalidraw/math";
|
|
18257
18412
|
var VERTICAL_OFFSET = 100;
|
|
18258
18413
|
var HORIZONTAL_OFFSET = 100;
|
|
18259
18414
|
var getLinkDirectionFromKey = (key) => {
|
|
18260
18415
|
switch (key) {
|
|
18261
|
-
case
|
|
18416
|
+
case KEYS2.ARROW_UP:
|
|
18262
18417
|
return "up";
|
|
18263
|
-
case
|
|
18418
|
+
case KEYS2.ARROW_DOWN:
|
|
18264
18419
|
return "down";
|
|
18265
|
-
case
|
|
18420
|
+
case KEYS2.ARROW_RIGHT:
|
|
18266
18421
|
return "right";
|
|
18267
|
-
case
|
|
18422
|
+
case KEYS2.ARROW_LEFT:
|
|
18268
18423
|
return "left";
|
|
18269
18424
|
default:
|
|
18270
18425
|
return "right";
|
|
@@ -18533,7 +18688,7 @@ var createBindingArrow = (startBindingElement, endBindingElement, direction, app
|
|
|
18533
18688
|
strokeWidth: startBindingElement.strokeWidth,
|
|
18534
18689
|
opacity: startBindingElement.opacity,
|
|
18535
18690
|
roughness: startBindingElement.roughness,
|
|
18536
|
-
points: [
|
|
18691
|
+
points: [pointFrom14(0, 0), pointFrom14(endX, endY)],
|
|
18537
18692
|
elbowed: true
|
|
18538
18693
|
});
|
|
18539
18694
|
const elementsMap = scene.getNonDeletedElementsMap();
|
|
@@ -18721,12 +18876,13 @@ var isNodeInFlowchart = (element, elementsMap) => {
|
|
|
18721
18876
|
|
|
18722
18877
|
// src/arrows/focus.ts
|
|
18723
18878
|
init_define_import_meta_env();
|
|
18724
|
-
import { pointDistance as pointDistance8, pointFrom as
|
|
18879
|
+
import { pointDistance as pointDistance8, pointFrom as pointFrom15 } from "@excalidraw/math";
|
|
18725
18880
|
import { invariant as invariant12 } from "@excalidraw/common";
|
|
18726
18881
|
|
|
18727
18882
|
// src/zindex.ts
|
|
18728
18883
|
init_define_import_meta_env();
|
|
18729
18884
|
import { arrayToMap as arrayToMap11, findIndex, findLastIndex as findLastIndex2 } from "@excalidraw/common";
|
|
18885
|
+
import { isFiniteNumber } from "@excalidraw/math";
|
|
18730
18886
|
var isOfTargetFrame = (element, frameId) => {
|
|
18731
18887
|
return element.frameId === frameId || element.id === frameId;
|
|
18732
18888
|
};
|
|
@@ -18906,7 +19062,34 @@ var getTargetElementsMap = (elements, indices) => {
|
|
|
18906
19062
|
return acc;
|
|
18907
19063
|
}, /* @__PURE__ */ new Map());
|
|
18908
19064
|
};
|
|
19065
|
+
var hasSameElementIds = (prevElements, nextElements) => {
|
|
19066
|
+
if (prevElements.length !== nextElements.length) {
|
|
19067
|
+
console.error(
|
|
19068
|
+
"z-index reordering failed: resulting array have different lengths"
|
|
19069
|
+
);
|
|
19070
|
+
return false;
|
|
19071
|
+
}
|
|
19072
|
+
const prevElementIdCounts = /* @__PURE__ */ new Map();
|
|
19073
|
+
for (const element of prevElements) {
|
|
19074
|
+
prevElementIdCounts.set(
|
|
19075
|
+
element.id,
|
|
19076
|
+
(prevElementIdCounts.get(element.id) || 0) + 1
|
|
19077
|
+
);
|
|
19078
|
+
}
|
|
19079
|
+
for (const element of nextElements) {
|
|
19080
|
+
const count = prevElementIdCounts.get(element.id);
|
|
19081
|
+
if (!count) {
|
|
19082
|
+
console.error(
|
|
19083
|
+
"z-index reordering failed: element id mismatch / duplicate ids"
|
|
19084
|
+
);
|
|
19085
|
+
return false;
|
|
19086
|
+
}
|
|
19087
|
+
prevElementIdCounts.set(element.id, count - 1);
|
|
19088
|
+
}
|
|
19089
|
+
return true;
|
|
19090
|
+
};
|
|
18909
19091
|
var shiftElementsByOne = (elements, appState, direction, scene) => {
|
|
19092
|
+
const originalElements = elements;
|
|
18910
19093
|
const indicesToMove = getIndicesToMove(elements, appState);
|
|
18911
19094
|
const targetElementsMap = getTargetElementsMap(elements, indicesToMove);
|
|
18912
19095
|
let groupedIndices = toContiguousGroups(indicesToMove);
|
|
@@ -18951,11 +19134,17 @@ var shiftElementsByOne = (elements, appState, direction, scene) => {
|
|
|
18951
19134
|
...trailingElements
|
|
18952
19135
|
];
|
|
18953
19136
|
});
|
|
19137
|
+
if (!hasSameElementIds(originalElements, elements)) {
|
|
19138
|
+
return originalElements;
|
|
19139
|
+
}
|
|
18954
19140
|
syncMovedIndices(elements, targetElementsMap);
|
|
18955
19141
|
return elements;
|
|
18956
19142
|
};
|
|
18957
19143
|
var shiftElementsToEnd = (elements, appState, direction, containingFrame, elementsToBeMoved) => {
|
|
18958
19144
|
const indicesToMove = getIndicesToMove(elements, appState, elementsToBeMoved);
|
|
19145
|
+
if (indicesToMove.length === 0) {
|
|
19146
|
+
return elements;
|
|
19147
|
+
}
|
|
18959
19148
|
const targetElementsMap = getTargetElementsMap(elements, indicesToMove);
|
|
18960
19149
|
const displacedElements = [];
|
|
18961
19150
|
let leadingIndex;
|
|
@@ -19002,6 +19191,12 @@ var shiftElementsToEnd = (elements, appState, direction, containingFrame, elemen
|
|
|
19002
19191
|
if (leadingIndex === -1) {
|
|
19003
19192
|
leadingIndex = 0;
|
|
19004
19193
|
}
|
|
19194
|
+
const isValidIndex = (index) => {
|
|
19195
|
+
return isFiniteNumber(index) && index >= 0;
|
|
19196
|
+
};
|
|
19197
|
+
if (!isValidIndex(leadingIndex) || !isValidIndex(trailingIndex) || leadingIndex > trailingIndex || indicesToMove.some((index) => index < leadingIndex || index > trailingIndex)) {
|
|
19198
|
+
return elements;
|
|
19199
|
+
}
|
|
19005
19200
|
for (let index = leadingIndex; index < trailingIndex + 1; index++) {
|
|
19006
19201
|
if (!indicesToMove.includes(index)) {
|
|
19007
19202
|
displacedElements.push(elements[index]);
|
|
@@ -19021,6 +19216,9 @@ var shiftElementsToEnd = (elements, appState, direction, containingFrame, elemen
|
|
|
19021
19216
|
...targetElements,
|
|
19022
19217
|
...trailingElements
|
|
19023
19218
|
];
|
|
19219
|
+
if (!hasSameElementIds(elements, nextElements)) {
|
|
19220
|
+
return elements;
|
|
19221
|
+
}
|
|
19024
19222
|
syncMovedIndices(nextElements, targetElementsMap);
|
|
19025
19223
|
return nextElements;
|
|
19026
19224
|
};
|
|
@@ -19062,7 +19260,7 @@ function shiftElementsAccountingForFrames(allElements, appState, direction, shif
|
|
|
19062
19260
|
);
|
|
19063
19261
|
for (const [frameId, children] of frameChildrenSets) {
|
|
19064
19262
|
nextElements = shiftFunction(
|
|
19065
|
-
|
|
19263
|
+
nextElements,
|
|
19066
19264
|
appState,
|
|
19067
19265
|
direction,
|
|
19068
19266
|
frameId,
|
|
@@ -19211,7 +19409,7 @@ var handleFocusPointDrag = (linearElementEditor, elementsMap, pointerCoords, sce
|
|
|
19211
19409
|
const isStartBinding = linearElementEditor.draggedFocusPointBinding === "start";
|
|
19212
19410
|
const binding = isStartBinding ? arrow.startBinding : arrow.endBinding;
|
|
19213
19411
|
const { x: offsetX, y: offsetY } = linearElementEditor.pointerOffset;
|
|
19214
|
-
const point =
|
|
19412
|
+
const point = pointFrom15(
|
|
19215
19413
|
pointerCoords.x - offsetX,
|
|
19216
19414
|
pointerCoords.y - offsetY
|
|
19217
19415
|
);
|
|
@@ -19294,7 +19492,7 @@ var handleFocusPointDrag = (linearElementEditor, elementsMap, pointerCoords, sce
|
|
|
19294
19492
|
}
|
|
19295
19493
|
};
|
|
19296
19494
|
var handleFocusPointPointerDown = (arrow, pointerDownState, elementsMap, appState) => {
|
|
19297
|
-
const pointerPos =
|
|
19495
|
+
const pointerPos = pointFrom15(
|
|
19298
19496
|
pointerDownState.origin.x,
|
|
19299
19497
|
pointerDownState.origin.y
|
|
19300
19498
|
);
|
|
@@ -19397,7 +19595,7 @@ var handleFocusPointPointerUp = (linearElementEditor, scene) => {
|
|
|
19397
19595
|
};
|
|
19398
19596
|
var handleFocusPointHover = (arrow, scenePointerX, scenePointerY, scene, appState) => {
|
|
19399
19597
|
const elementsMap = scene.getNonDeletedElementsMap();
|
|
19400
|
-
const pointerPos =
|
|
19598
|
+
const pointerPos = pointFrom15(scenePointerX, scenePointerY);
|
|
19401
19599
|
const hitThreshold = FOCUS_POINT_SIZE * 1.5 / appState.zoom.value;
|
|
19402
19600
|
if (arrow.startBinding?.elementId) {
|
|
19403
19601
|
const bindableElement = elementsMap.get(arrow.startBinding.elementId);
|
|
@@ -19618,8 +19816,8 @@ init_define_import_meta_env();
|
|
|
19618
19816
|
import {
|
|
19619
19817
|
pointCenter as pointCenter3,
|
|
19620
19818
|
normalizeRadians as normalizeRadians2,
|
|
19621
|
-
pointFrom as
|
|
19622
|
-
pointRotateRads as
|
|
19819
|
+
pointFrom as pointFrom16,
|
|
19820
|
+
pointRotateRads as pointRotateRads13
|
|
19623
19821
|
} from "@excalidraw/math";
|
|
19624
19822
|
import {
|
|
19625
19823
|
MIN_FONT_SIZE,
|
|
@@ -19807,7 +20005,7 @@ var resizeSingleTextElement = (origElement, element, scene, transformHandleType,
|
|
|
19807
20005
|
return;
|
|
19808
20006
|
}
|
|
19809
20007
|
if (transformHandleType.includes("n") || transformHandleType.includes("s")) {
|
|
19810
|
-
const previousOrigin =
|
|
20008
|
+
const previousOrigin = pointFrom16(origElement.x, origElement.y);
|
|
19811
20009
|
const newOrigin = getResizedOrigin(
|
|
19812
20010
|
previousOrigin,
|
|
19813
20011
|
origElement.width,
|
|
@@ -19848,7 +20046,7 @@ var resizeSingleTextElement = (origElement, element, scene, transformHandleType,
|
|
|
19848
20046
|
element.lineHeight
|
|
19849
20047
|
);
|
|
19850
20048
|
const newHeight = metrics2.height;
|
|
19851
|
-
const previousOrigin =
|
|
20049
|
+
const previousOrigin = pointFrom16(origElement.x, origElement.y);
|
|
19852
20050
|
const newOrigin = getResizedOrigin(
|
|
19853
20051
|
previousOrigin,
|
|
19854
20052
|
origElement.width,
|
|
@@ -19885,9 +20083,9 @@ var rotateMultipleElements = (originalElements, elements, scene, pointerX, point
|
|
|
19885
20083
|
const cx = (x1 + x2) / 2;
|
|
19886
20084
|
const cy = (y1 + y2) / 2;
|
|
19887
20085
|
const origAngle = originalElements.get(element.id)?.angle ?? element.angle;
|
|
19888
|
-
const [rotatedCX, rotatedCY] =
|
|
19889
|
-
|
|
19890
|
-
|
|
20086
|
+
const [rotatedCX, rotatedCY] = pointRotateRads13(
|
|
20087
|
+
pointFrom16(cx, cy),
|
|
20088
|
+
pointFrom16(centerX, centerY),
|
|
19891
20089
|
centerAngle + origAngle - element.angle
|
|
19892
20090
|
);
|
|
19893
20091
|
const updates = isElbowArrow(element) ? {
|
|
@@ -19936,44 +20134,44 @@ var getResizeOffsetXY = (transformHandleType, selectedElements, elementsMap, x,
|
|
|
19936
20134
|
const cx = (x1 + x2) / 2;
|
|
19937
20135
|
const cy = (y1 + y2) / 2;
|
|
19938
20136
|
const angle = selectedElements.length === 1 ? selectedElements[0].angle : 0;
|
|
19939
|
-
[x, y] =
|
|
19940
|
-
|
|
19941
|
-
|
|
20137
|
+
[x, y] = pointRotateRads13(
|
|
20138
|
+
pointFrom16(x, y),
|
|
20139
|
+
pointFrom16(cx, cy),
|
|
19942
20140
|
-angle
|
|
19943
20141
|
);
|
|
19944
20142
|
switch (transformHandleType) {
|
|
19945
20143
|
case "n":
|
|
19946
|
-
return
|
|
19947
|
-
|
|
19948
|
-
|
|
20144
|
+
return pointRotateRads13(
|
|
20145
|
+
pointFrom16(x - (x1 + x2) / 2, y - y1),
|
|
20146
|
+
pointFrom16(0, 0),
|
|
19949
20147
|
angle
|
|
19950
20148
|
);
|
|
19951
20149
|
case "s":
|
|
19952
|
-
return
|
|
19953
|
-
|
|
19954
|
-
|
|
20150
|
+
return pointRotateRads13(
|
|
20151
|
+
pointFrom16(x - (x1 + x2) / 2, y - y2),
|
|
20152
|
+
pointFrom16(0, 0),
|
|
19955
20153
|
angle
|
|
19956
20154
|
);
|
|
19957
20155
|
case "w":
|
|
19958
|
-
return
|
|
19959
|
-
|
|
19960
|
-
|
|
20156
|
+
return pointRotateRads13(
|
|
20157
|
+
pointFrom16(x - x1, y - (y1 + y2) / 2),
|
|
20158
|
+
pointFrom16(0, 0),
|
|
19961
20159
|
angle
|
|
19962
20160
|
);
|
|
19963
20161
|
case "e":
|
|
19964
|
-
return
|
|
19965
|
-
|
|
19966
|
-
|
|
20162
|
+
return pointRotateRads13(
|
|
20163
|
+
pointFrom16(x - x2, y - (y1 + y2) / 2),
|
|
20164
|
+
pointFrom16(0, 0),
|
|
19967
20165
|
angle
|
|
19968
20166
|
);
|
|
19969
20167
|
case "nw":
|
|
19970
|
-
return
|
|
20168
|
+
return pointRotateRads13(pointFrom16(x - x1, y - y1), pointFrom16(0, 0), angle);
|
|
19971
20169
|
case "ne":
|
|
19972
|
-
return
|
|
20170
|
+
return pointRotateRads13(pointFrom16(x - x2, y - y1), pointFrom16(0, 0), angle);
|
|
19973
20171
|
case "sw":
|
|
19974
|
-
return
|
|
20172
|
+
return pointRotateRads13(pointFrom16(x - x1, y - y2), pointFrom16(0, 0), angle);
|
|
19975
20173
|
case "se":
|
|
19976
|
-
return
|
|
20174
|
+
return pointRotateRads13(pointFrom16(x - x2, y - y2), pointFrom16(0, 0), angle);
|
|
19977
20175
|
default:
|
|
19978
20176
|
return [0, 0];
|
|
19979
20177
|
}
|
|
@@ -20136,10 +20334,10 @@ var resizeSingleElement = (nextWidth, nextHeight, latestElement, origElement, or
|
|
|
20136
20334
|
nextHeight,
|
|
20137
20335
|
true
|
|
20138
20336
|
);
|
|
20139
|
-
let previousOrigin =
|
|
20337
|
+
let previousOrigin = pointFrom16(origElement.x, origElement.y);
|
|
20140
20338
|
if (isLinearElement(origElement)) {
|
|
20141
20339
|
const [x1, y1] = getElementBounds(origElement, originalElementsMap);
|
|
20142
|
-
previousOrigin =
|
|
20340
|
+
previousOrigin = pointFrom16(x1, y1);
|
|
20143
20341
|
}
|
|
20144
20342
|
const newOrigin = getResizedOrigin(
|
|
20145
20343
|
previousOrigin,
|
|
@@ -20162,7 +20360,7 @@ var resizeSingleElement = (nextWidth, nextHeight, latestElement, origElement, or
|
|
|
20162
20360
|
newOrigin.x += scaledX;
|
|
20163
20361
|
newOrigin.y += scaledY;
|
|
20164
20362
|
rescaledPoints.points = rescaledPoints.points.map(
|
|
20165
|
-
(p) =>
|
|
20363
|
+
(p) => pointFrom16(p[0] - scaledX, p[1] - scaledY)
|
|
20166
20364
|
);
|
|
20167
20365
|
}
|
|
20168
20366
|
if (nextWidth < 0) {
|
|
@@ -20238,11 +20436,11 @@ var getNextSingleWidthAndHeightFromPointer = (latestElement, origElement, handle
|
|
|
20238
20436
|
origElement.height,
|
|
20239
20437
|
true
|
|
20240
20438
|
);
|
|
20241
|
-
const startTopLeft =
|
|
20242
|
-
const startBottomRight =
|
|
20439
|
+
const startTopLeft = pointFrom16(x1, y1);
|
|
20440
|
+
const startBottomRight = pointFrom16(x2, y2);
|
|
20243
20441
|
const startCenter = pointCenter3(startTopLeft, startBottomRight);
|
|
20244
|
-
const rotatedPointer =
|
|
20245
|
-
|
|
20442
|
+
const rotatedPointer = pointRotateRads13(
|
|
20443
|
+
pointFrom16(pointerX, pointerY),
|
|
20246
20444
|
startCenter,
|
|
20247
20445
|
-origElement.angle
|
|
20248
20446
|
);
|
|
@@ -20612,9 +20810,9 @@ var resizeMultipleElements = (selectedElements, elementsMap, handleDirection, sc
|
|
|
20612
20810
|
// src/resizeTest.ts
|
|
20613
20811
|
init_define_import_meta_env();
|
|
20614
20812
|
import {
|
|
20615
|
-
pointFrom as
|
|
20813
|
+
pointFrom as pointFrom18,
|
|
20616
20814
|
pointOnLineSegment,
|
|
20617
|
-
pointRotateRads as
|
|
20815
|
+
pointRotateRads as pointRotateRads15
|
|
20618
20816
|
} from "@excalidraw/math";
|
|
20619
20817
|
import {
|
|
20620
20818
|
SIDE_RESIZING_THRESHOLD
|
|
@@ -20625,7 +20823,7 @@ init_define_import_meta_env();
|
|
|
20625
20823
|
import {
|
|
20626
20824
|
DEFAULT_TRANSFORM_HANDLE_SPACING
|
|
20627
20825
|
} from "@excalidraw/common";
|
|
20628
|
-
import { pointFrom as
|
|
20826
|
+
import { pointFrom as pointFrom17, pointRotateRads as pointRotateRads14 } from "@excalidraw/math";
|
|
20629
20827
|
var transformHandleSizes = {
|
|
20630
20828
|
mouse: 8,
|
|
20631
20829
|
pen: 16,
|
|
@@ -20666,9 +20864,9 @@ var OMIT_SIDES_FOR_LINE_BACKSLASH = {
|
|
|
20666
20864
|
w: true
|
|
20667
20865
|
};
|
|
20668
20866
|
var generateTransformHandle = (x, y, width, height, cx, cy, angle) => {
|
|
20669
|
-
const [xx, yy] =
|
|
20670
|
-
|
|
20671
|
-
|
|
20867
|
+
const [xx, yy] = pointRotateRads14(
|
|
20868
|
+
pointFrom17(x + width / 2, y + height / 2),
|
|
20869
|
+
pointFrom17(cx, cy),
|
|
20672
20870
|
angle
|
|
20673
20871
|
);
|
|
20674
20872
|
return [xx - width / 2, yy - height / 2, width, height];
|
|
@@ -20882,14 +21080,14 @@ var resizeTest = (element, elementsMap, appState, x, y, zoom, pointerType, edito
|
|
|
20882
21080
|
const SPACING = isImageElement(element) ? 0 : SIDE_RESIZING_THRESHOLD / zoom.value;
|
|
20883
21081
|
const ZOOMED_SIDE_RESIZING_THRESHOLD = SIDE_RESIZING_THRESHOLD / zoom.value;
|
|
20884
21082
|
const sides = getSelectionBorders(
|
|
20885
|
-
|
|
20886
|
-
|
|
20887
|
-
|
|
21083
|
+
pointFrom18(x1 - SPACING, y1 - SPACING),
|
|
21084
|
+
pointFrom18(x2 + SPACING, y2 + SPACING),
|
|
21085
|
+
pointFrom18(cx, cy),
|
|
20888
21086
|
element.angle
|
|
20889
21087
|
);
|
|
20890
21088
|
for (const [dir, side] of Object.entries(sides)) {
|
|
20891
21089
|
if (pointOnLineSegment(
|
|
20892
|
-
|
|
21090
|
+
pointFrom18(x, y),
|
|
20893
21091
|
side,
|
|
20894
21092
|
ZOOMED_SIDE_RESIZING_THRESHOLD
|
|
20895
21093
|
)) {
|
|
@@ -20938,14 +21136,14 @@ var getTransformHandleTypeFromCoords = ([x1, y1, x2, y2], scenePointerX, scenePo
|
|
|
20938
21136
|
const cy = (y1 + y2) / 2;
|
|
20939
21137
|
const SPACING = SIDE_RESIZING_THRESHOLD / zoom.value;
|
|
20940
21138
|
const sides = getSelectionBorders(
|
|
20941
|
-
|
|
20942
|
-
|
|
20943
|
-
|
|
21139
|
+
pointFrom18(x1 - SPACING, y1 - SPACING),
|
|
21140
|
+
pointFrom18(x2 + SPACING, y2 + SPACING),
|
|
21141
|
+
pointFrom18(cx, cy),
|
|
20944
21142
|
0
|
|
20945
21143
|
);
|
|
20946
21144
|
for (const [dir, side] of Object.entries(sides)) {
|
|
20947
21145
|
if (pointOnLineSegment(
|
|
20948
|
-
|
|
21146
|
+
pointFrom18(scenePointerX, scenePointerY),
|
|
20949
21147
|
side,
|
|
20950
21148
|
SPACING
|
|
20951
21149
|
)) {
|
|
@@ -21002,10 +21200,10 @@ var getCursorForResizingElement = (resizingElement) => {
|
|
|
21002
21200
|
return cursor ? `${cursor}-resize` : "";
|
|
21003
21201
|
};
|
|
21004
21202
|
var getSelectionBorders = ([x1, y1], [x2, y2], center, angle) => {
|
|
21005
|
-
const topLeft =
|
|
21006
|
-
const topRight =
|
|
21007
|
-
const bottomLeft =
|
|
21008
|
-
const bottomRight =
|
|
21203
|
+
const topLeft = pointRotateRads15(pointFrom18(x1, y1), center, angle);
|
|
21204
|
+
const topRight = pointRotateRads15(pointFrom18(x2, y1), center, angle);
|
|
21205
|
+
const bottomLeft = pointRotateRads15(pointFrom18(x1, y2), center, angle);
|
|
21206
|
+
const bottomRight = pointRotateRads15(pointFrom18(x2, y2), center, angle);
|
|
21009
21207
|
return {
|
|
21010
21208
|
n: [topLeft, topRight],
|
|
21011
21209
|
e: [topRight, bottomRight],
|
|
@@ -21022,7 +21220,7 @@ var showSelectedShapeActions = (appState, elements) => Boolean(
|
|
|
21022
21220
|
|
|
21023
21221
|
// src/transform.ts
|
|
21024
21222
|
init_define_import_meta_env();
|
|
21025
|
-
import { pointFrom as
|
|
21223
|
+
import { pointFrom as pointFrom19 } from "@excalidraw/math";
|
|
21026
21224
|
import {
|
|
21027
21225
|
DEFAULT_FONT_FAMILY as DEFAULT_FONT_FAMILY3,
|
|
21028
21226
|
DEFAULT_FONT_SIZE as DEFAULT_FONT_SIZE4,
|
|
@@ -21304,7 +21502,7 @@ var convertToExcalidrawElements = (elementsSkeleton, opts) => {
|
|
|
21304
21502
|
excalidrawElement = newLinearElement({
|
|
21305
21503
|
width,
|
|
21306
21504
|
height,
|
|
21307
|
-
points: [
|
|
21505
|
+
points: [pointFrom19(0, 0), pointFrom19(width, height)],
|
|
21308
21506
|
...element
|
|
21309
21507
|
});
|
|
21310
21508
|
break;
|
|
@@ -21316,7 +21514,7 @@ var convertToExcalidrawElements = (elementsSkeleton, opts) => {
|
|
|
21316
21514
|
width,
|
|
21317
21515
|
height,
|
|
21318
21516
|
endArrowhead: "arrow",
|
|
21319
|
-
points: [
|
|
21517
|
+
points: [pointFrom19(0, 0), pointFrom19(width, height)],
|
|
21320
21518
|
...element,
|
|
21321
21519
|
type: "arrow"
|
|
21322
21520
|
});
|
|
@@ -21559,6 +21757,33 @@ var maybeHandleArrowPointlikeDrag = ({
|
|
|
21559
21757
|
return false;
|
|
21560
21758
|
};
|
|
21561
21759
|
|
|
21760
|
+
// src/arrowheads.ts
|
|
21761
|
+
init_define_import_meta_env();
|
|
21762
|
+
var normalizeArrowhead = (arrowhead) => {
|
|
21763
|
+
switch (arrowhead) {
|
|
21764
|
+
case void 0:
|
|
21765
|
+
case null:
|
|
21766
|
+
return null;
|
|
21767
|
+
case "dot":
|
|
21768
|
+
return "circle";
|
|
21769
|
+
case "crowfoot_one":
|
|
21770
|
+
return "cardinality_one";
|
|
21771
|
+
case "crowfoot_many":
|
|
21772
|
+
return "cardinality_many";
|
|
21773
|
+
case "crowfoot_one_or_many":
|
|
21774
|
+
return "cardinality_one_or_many";
|
|
21775
|
+
default:
|
|
21776
|
+
return arrowhead;
|
|
21777
|
+
}
|
|
21778
|
+
};
|
|
21779
|
+
var getArrowheadForPicker = (arrowhead) => {
|
|
21780
|
+
const normalizedArrowhead = normalizeArrowhead(arrowhead);
|
|
21781
|
+
if (normalizedArrowhead === null) {
|
|
21782
|
+
return null;
|
|
21783
|
+
}
|
|
21784
|
+
return normalizedArrowhead;
|
|
21785
|
+
};
|
|
21786
|
+
|
|
21562
21787
|
// src/index.ts
|
|
21563
21788
|
var getSceneVersion = (elements) => elements.reduce((acc, el) => acc + el.version, 0);
|
|
21564
21789
|
var hashElementsVersion = (elements) => {
|
|
@@ -21629,6 +21854,7 @@ export {
|
|
|
21629
21854
|
bindOrUnbindBindingElements,
|
|
21630
21855
|
bindPointToSnapToElementOutline,
|
|
21631
21856
|
bindingProperties,
|
|
21857
|
+
boundsContainBounds,
|
|
21632
21858
|
bumpVersion,
|
|
21633
21859
|
calculateFixedPointForElbowArrowBinding,
|
|
21634
21860
|
calculateFixedPointForNonElbowArrowBinding,
|
|
@@ -21666,6 +21892,7 @@ export {
|
|
|
21666
21892
|
elementWithCanvasCache,
|
|
21667
21893
|
elementsAreInFrameBounds,
|
|
21668
21894
|
elementsAreInSameGroup,
|
|
21895
|
+
elementsOverlappingBBox,
|
|
21669
21896
|
embeddableURLValidator,
|
|
21670
21897
|
excludeElementsInFramesFromSelection,
|
|
21671
21898
|
filterElementsEligibleAsFrameChildren,
|
|
@@ -21675,11 +21902,13 @@ export {
|
|
|
21675
21902
|
frameAndChildrenSelectedTogether,
|
|
21676
21903
|
generateLinearCollisionShape,
|
|
21677
21904
|
generateRoughOptions,
|
|
21905
|
+
getActiveTextElement,
|
|
21678
21906
|
getAllHoveredElementAtPoint,
|
|
21679
21907
|
getApproxMinLineHeight,
|
|
21680
21908
|
getApproxMinLineWidth,
|
|
21681
21909
|
getArrowLocalFixedPoints,
|
|
21682
21910
|
getArrowheadAngle,
|
|
21911
|
+
getArrowheadForPicker,
|
|
21683
21912
|
getArrowheadPoints,
|
|
21684
21913
|
getArrowheadSize,
|
|
21685
21914
|
getBindingGap,
|
|
@@ -21695,6 +21924,7 @@ export {
|
|
|
21695
21924
|
getClosestElementBounds,
|
|
21696
21925
|
getCommonBoundingBox,
|
|
21697
21926
|
getCommonBounds,
|
|
21927
|
+
getCommonFrameId,
|
|
21698
21928
|
getContainerCenter,
|
|
21699
21929
|
getContainerCoords,
|
|
21700
21930
|
getContainerElement,
|
|
@@ -21724,6 +21954,7 @@ export {
|
|
|
21724
21954
|
getEmbedLink,
|
|
21725
21955
|
getFlipAdjustedCropPosition,
|
|
21726
21956
|
getFrameChildren,
|
|
21957
|
+
getFrameChildrenInsertionIndex,
|
|
21727
21958
|
getFrameLikeElements,
|
|
21728
21959
|
getFrameLikeTitle,
|
|
21729
21960
|
getFreedrawOutlineAsSegments,
|
|
@@ -21782,6 +22013,7 @@ export {
|
|
|
21782
22013
|
getVisibleAndNonSelectedElements,
|
|
21783
22014
|
getVisibleElements,
|
|
21784
22015
|
getVisibleSceneBounds,
|
|
22016
|
+
getWrappedTextLines,
|
|
21785
22017
|
groupByFrameLikes,
|
|
21786
22018
|
groupsAreAtLeastIntersectingTheFrame,
|
|
21787
22019
|
groupsAreCompletelyOutOfFrame,
|
|
@@ -21826,6 +22058,7 @@ export {
|
|
|
21826
22058
|
isElementInViewport,
|
|
21827
22059
|
isElementIntersectingFrame,
|
|
21828
22060
|
isElementLink,
|
|
22061
|
+
isEligibleFrameChildType,
|
|
21829
22062
|
isEmbeddableElement,
|
|
21830
22063
|
isExcalidrawElement,
|
|
21831
22064
|
isFixedPoint,
|
|
@@ -21887,6 +22120,7 @@ export {
|
|
|
21887
22120
|
newLinearElement,
|
|
21888
22121
|
newMagicFrameElement,
|
|
21889
22122
|
newTextElement,
|
|
22123
|
+
normalizeArrowhead,
|
|
21890
22124
|
normalizeElementOrder,
|
|
21891
22125
|
normalizeFixedPoint,
|
|
21892
22126
|
normalizeSVG,
|
|
@@ -21898,6 +22132,7 @@ export {
|
|
|
21898
22132
|
parseElementLinkFromURL,
|
|
21899
22133
|
parseTokens,
|
|
21900
22134
|
pointInsideBounds,
|
|
22135
|
+
pointInsideBoundsInclusive,
|
|
21901
22136
|
positionElementsOnGrid,
|
|
21902
22137
|
projectFixedPointOntoDiagonal,
|
|
21903
22138
|
redrawTextBoundingBox,
|
|
@@ -21920,7 +22155,6 @@ export {
|
|
|
21920
22155
|
setCustomTextMetricsProvider,
|
|
21921
22156
|
shouldAllowVerticalAlign,
|
|
21922
22157
|
shouldApplyFrameClip,
|
|
21923
|
-
shouldEnableBindingForPointerEvent,
|
|
21924
22158
|
shouldTestInside,
|
|
21925
22159
|
showSelectedShapeActions,
|
|
21926
22160
|
snapToMid,
|