@excalidraw/element 0.18.0-4e758db → 0.18.0-4f68076
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 +936 -437
- package/dist/dev/index.js.map +4 -4
- package/dist/prod/index.js +16 -15
- package/dist/types/common/src/constants.d.ts +10 -0
- package/dist/types/common/src/utils.d.ts +5 -0
- package/dist/types/element/src/binding.d.ts +13 -7
- package/dist/types/element/src/collision.d.ts +14 -5
- package/dist/types/element/src/duplicate.d.ts +60 -0
- package/dist/types/element/src/index.d.ts +1 -0
- package/dist/types/element/src/listMarker.d.ts +34 -0
- package/dist/types/element/src/newElement.d.ts +15 -1
- package/dist/types/element/src/renderElement.d.ts +21 -4
- package/dist/types/element/src/shape.d.ts +15 -1
- package/dist/types/element/src/textElement.d.ts +7 -0
- package/dist/types/element/src/utils.d.ts +8 -1
- package/dist/types/element/src/zindex.d.ts +1 -1
- package/dist/types/excalidraw/actions/actionAddToLibrary.d.ts +30 -3
- package/dist/types/excalidraw/actions/actionBoundText.d.ts +20 -2
- package/dist/types/excalidraw/actions/actionCanvas.d.ts +70 -7
- package/dist/types/excalidraw/actions/actionClipboard.d.ts +20 -2
- package/dist/types/excalidraw/actions/actionCropEditor.d.ts +10 -1
- package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +30 -3
- package/dist/types/excalidraw/actions/actionDeselect.d.ts +13 -1
- package/dist/types/excalidraw/actions/actionElementLink.d.ts +10 -1
- package/dist/types/excalidraw/actions/actionElementLock.d.ts +20 -2
- package/dist/types/excalidraw/actions/actionExport.d.ts +20 -2
- package/dist/types/excalidraw/actions/actionFrame.d.ts +30 -3
- package/dist/types/excalidraw/actions/actionGroup.d.ts +20 -2
- package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +10 -1
- package/dist/types/excalidraw/actions/actionLink.d.ts +10 -1
- package/dist/types/excalidraw/actions/actionMenu.d.ts +10 -1
- package/dist/types/excalidraw/actions/actionProperties.d.ts +20 -2
- package/dist/types/excalidraw/actions/actionSelectAll.d.ts +10 -1
- package/dist/types/excalidraw/actions/actionStyles.d.ts +10 -1
- package/dist/types/excalidraw/actions/actionToggleArrowBinding.d.ts +10 -1
- package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +10 -1
- package/dist/types/excalidraw/actions/actionToggleMidpointSnapping.d.ts +10 -1
- package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +10 -1
- package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +10 -1
- package/dist/types/excalidraw/actions/actionToggleShowHints.d.ts +197 -0
- package/dist/types/excalidraw/actions/actionToggleStats.d.ts +10 -1
- package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +10 -1
- package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +10 -1
- package/dist/types/excalidraw/actions/index.d.ts +1 -0
- package/dist/types/excalidraw/actions/types.d.ts +1 -1
- package/dist/types/excalidraw/appState.d.ts +2 -0
- package/dist/types/excalidraw/components/App.arrowText.d.ts +5 -39
- package/dist/types/excalidraw/components/App.clipboard.d.ts +31 -0
- package/dist/types/excalidraw/components/App.d.ts +82 -262
- package/dist/types/excalidraw/components/App.duplicate.d.ts +101 -0
- package/dist/types/excalidraw/components/App.modifiers.d.ts +38 -0
- package/dist/types/excalidraw/components/App.pan.d.ts +62 -0
- package/dist/types/excalidraw/components/App.selectionTool.d.ts +57 -0
- package/dist/types/excalidraw/components/App.text.d.ts +146 -0
- package/dist/types/excalidraw/components/App.textTool.d.ts +140 -0
- package/dist/types/excalidraw/components/App.viewport.d.ts +41 -1
- package/dist/types/excalidraw/components/App.wheel.d.ts +3 -10
- package/dist/types/excalidraw/components/ColorPicker/Picker.d.ts +2 -0
- package/dist/types/excalidraw/components/ColorPicker/colorTopPicksDnD.d.ts +11 -0
- package/dist/types/excalidraw/components/FileDropOverlay.d.ts +2 -0
- package/dist/types/excalidraw/components/FontPicker/FontPicker.d.ts +4 -1
- package/dist/types/excalidraw/components/FontPicker/FontPickerList.d.ts +6 -1
- package/dist/types/excalidraw/components/FontPicker/fontTopPicksDnD.d.ts +12 -0
- package/dist/types/excalidraw/components/LibraryMenuSection.d.ts +6 -2
- package/dist/types/excalidraw/components/LibraryUnit.d.ts +7 -2
- package/dist/types/excalidraw/components/Tooltip.d.ts +15 -1
- package/dist/types/excalidraw/components/TopPicksDnD/TopPicksContextMenu.d.ts +14 -0
- package/dist/types/excalidraw/components/TopPicksDnD/TopPicksTip.d.ts +11 -0
- package/dist/types/excalidraw/components/TopPicksDnD/topPicksDnD.d.ts +58 -0
- package/dist/types/excalidraw/components/main-menu/DefaultItems.d.ts +1 -0
- package/dist/types/excalidraw/data/blob.d.ts +20 -2
- package/dist/types/excalidraw/data/json.d.ts +10 -1
- package/dist/types/excalidraw/renderOverrides.d.ts +9 -0
- package/dist/types/excalidraw/scene/Renderer.d.ts +14 -1
- package/dist/types/excalidraw/scene/types.d.ts +2 -1
- package/dist/types/excalidraw/types.d.ts +92 -19
- package/dist/types/excalidraw/viewport.d.ts +23 -1
- package/dist/types/excalidraw/wysiwyg/textWysiwyg.d.ts +12 -1
- package/package.json +4 -4
- package/dist/types/excalidraw/components/ColorPicker/topPicksDnD.d.ts +0 -31
package/dist/dev/index.js
CHANGED
|
@@ -2970,7 +2970,8 @@ var LaserPointer = class _LaserPointer {
|
|
|
2970
2970
|
import {
|
|
2971
2971
|
pointFrom as pointFrom12,
|
|
2972
2972
|
pointDistance as pointDistance6,
|
|
2973
|
-
pointRotateRads as pointRotateRads11
|
|
2973
|
+
pointRotateRads as pointRotateRads11,
|
|
2974
|
+
polygonFromPoints as polygonFromPoints2
|
|
2974
2975
|
} from "@excalidraw/math";
|
|
2975
2976
|
import {
|
|
2976
2977
|
ROUGHNESS,
|
|
@@ -2986,6 +2987,7 @@ import {
|
|
|
2986
2987
|
// src/renderElement.ts
|
|
2987
2988
|
init_define_import_meta_env();
|
|
2988
2989
|
import {
|
|
2990
|
+
clamp as clamp8,
|
|
2989
2991
|
isRightAngleRads,
|
|
2990
2992
|
lineSegment as lineSegment5,
|
|
2991
2993
|
pointFrom as pointFrom11,
|
|
@@ -3009,7 +3011,8 @@ import {
|
|
|
3009
3011
|
STICKY_NOTE_EDGE_SHADOW_OPACITY,
|
|
3010
3012
|
STICKY_NOTE_EDGE_SHADOW_WIDTH,
|
|
3011
3013
|
STICKY_NOTE_FOOTER as STICKY_NOTE_FOOTER2,
|
|
3012
|
-
STICKY_NOTE_SHADOW_OPACITY
|
|
3014
|
+
STICKY_NOTE_SHADOW_OPACITY,
|
|
3015
|
+
DEFAULT_ZOOM as DEFAULT_ZOOM2
|
|
3013
3016
|
} from "@excalidraw/common";
|
|
3014
3017
|
|
|
3015
3018
|
// src/cropElement.ts
|
|
@@ -3485,7 +3488,7 @@ import {
|
|
|
3485
3488
|
lineSegmentClosestParameter,
|
|
3486
3489
|
lineSegmentPointAt,
|
|
3487
3490
|
curveClosestParameter,
|
|
3488
|
-
clamp as
|
|
3491
|
+
clamp as clamp7,
|
|
3489
3492
|
bezierEquation as bezierEquation2,
|
|
3490
3493
|
isCurve
|
|
3491
3494
|
} from "@excalidraw/math";
|
|
@@ -3518,7 +3521,7 @@ import {
|
|
|
3518
3521
|
} from "@excalidraw/common";
|
|
3519
3522
|
import {
|
|
3520
3523
|
PRECISION as PRECISION2,
|
|
3521
|
-
clamp as
|
|
3524
|
+
clamp as clamp6,
|
|
3522
3525
|
lineSegment as lineSegment4,
|
|
3523
3526
|
pointDistance as pointDistance4,
|
|
3524
3527
|
pointDistanceSq,
|
|
@@ -3544,6 +3547,7 @@ import {
|
|
|
3544
3547
|
pointFromVector as pointFromVector5,
|
|
3545
3548
|
pointRotateRads as pointRotateRads7,
|
|
3546
3549
|
pointsEqual as pointsEqual4,
|
|
3550
|
+
polygonIncludesPoint,
|
|
3547
3551
|
vectorFromPoint as vectorFromPoint6,
|
|
3548
3552
|
vectorNormalize as vectorNormalize3,
|
|
3549
3553
|
vectorScale as vectorScale6
|
|
@@ -3564,6 +3568,7 @@ import {
|
|
|
3564
3568
|
} from "@excalidraw/common";
|
|
3565
3569
|
import {
|
|
3566
3570
|
bezierEquation,
|
|
3571
|
+
clamp as clamp5,
|
|
3567
3572
|
curve as curve3,
|
|
3568
3573
|
curveCatmullRomCubicApproxPoints,
|
|
3569
3574
|
curveOffsetPoints,
|
|
@@ -3820,7 +3825,8 @@ import {
|
|
|
3820
3825
|
isAnyTrue,
|
|
3821
3826
|
getSizeFromPoints,
|
|
3822
3827
|
isDevEnv as isDevEnv2,
|
|
3823
|
-
arrayToMap
|
|
3828
|
+
arrayToMap,
|
|
3829
|
+
DEFAULT_ZOOM
|
|
3824
3830
|
} from "@excalidraw/common";
|
|
3825
3831
|
|
|
3826
3832
|
// src/distance.ts
|
|
@@ -3828,7 +3834,8 @@ init_define_import_meta_env();
|
|
|
3828
3834
|
import {
|
|
3829
3835
|
curvePointDistance,
|
|
3830
3836
|
distanceToLineSegment,
|
|
3831
|
-
pointRotateRads as pointRotateRads3
|
|
3837
|
+
pointRotateRads as pointRotateRads3,
|
|
3838
|
+
polygonIncludesPointNonZero
|
|
3832
3839
|
} from "@excalidraw/math";
|
|
3833
3840
|
import { ellipse as ellipse2, ellipseDistanceFromPoint } from "@excalidraw/math/ellipse";
|
|
3834
3841
|
var distanceToElement = (element, elementsMap, p) => {
|
|
@@ -3849,8 +3856,9 @@ var distanceToElement = (element, elementsMap, p) => {
|
|
|
3849
3856
|
return distanceToEllipseElement(element, elementsMap, p);
|
|
3850
3857
|
case "line":
|
|
3851
3858
|
case "arrow":
|
|
3852
|
-
case "freedraw":
|
|
3853
3859
|
return distanceToLinearOrFreeDraElement(element, elementsMap, p);
|
|
3860
|
+
case "freedraw":
|
|
3861
|
+
return distanceToFreeDrawElement(element, elementsMap, p);
|
|
3854
3862
|
}
|
|
3855
3863
|
};
|
|
3856
3864
|
var distanceToRectanguloidElement = (element, elementsMap, p) => {
|
|
@@ -3889,6 +3897,17 @@ var distanceToLinearOrFreeDraElement = (element, elementsMap, p) => {
|
|
|
3889
3897
|
...curves.map((a2) => curvePointDistance(a2, p))
|
|
3890
3898
|
);
|
|
3891
3899
|
};
|
|
3900
|
+
var distanceToFreeDrawElement = (element, elementsMap, p) => {
|
|
3901
|
+
const [lines] = deconstructLinearOrFreeDrawElement(element, elementsMap);
|
|
3902
|
+
if (lines.length === 0) {
|
|
3903
|
+
return Infinity;
|
|
3904
|
+
}
|
|
3905
|
+
const polygon3 = lines.map((line2) => line2[0]);
|
|
3906
|
+
if (polygonIncludesPointNonZero(p, polygon3)) {
|
|
3907
|
+
return 0;
|
|
3908
|
+
}
|
|
3909
|
+
return Math.min(...lines.map((s) => distanceToLineSegment(p, s)));
|
|
3910
|
+
};
|
|
3892
3911
|
|
|
3893
3912
|
// src/heading.ts
|
|
3894
3913
|
init_define_import_meta_env();
|
|
@@ -4802,22 +4821,13 @@ var updateElbowArrowPoints = (arrow, elementsMap, updates, options) => {
|
|
|
4802
4821
|
var getElbowArrowData = (arrow, elementsMap, nextPoints, options) => {
|
|
4803
4822
|
const origStartGlobalPoint = pointTranslate(nextPoints[0], vector2(arrow.x, arrow.y));
|
|
4804
4823
|
const origEndGlobalPoint = pointTranslate(nextPoints[nextPoints.length - 1], vector2(arrow.x, arrow.y));
|
|
4824
|
+
const zoom = options?.zoom ?? DEFAULT_ZOOM;
|
|
4805
4825
|
let hoveredStartElement = null;
|
|
4806
4826
|
let hoveredEndElement = null;
|
|
4807
4827
|
if (options?.isDragging && options?.isBindingEnabled !== false) {
|
|
4808
4828
|
const elements = Array.from(elementsMap.values());
|
|
4809
|
-
hoveredStartElement = getHoveredElement(
|
|
4810
|
-
|
|
4811
|
-
elementsMap,
|
|
4812
|
-
elements,
|
|
4813
|
-
options?.zoom
|
|
4814
|
-
) || null;
|
|
4815
|
-
hoveredEndElement = getHoveredElement(
|
|
4816
|
-
origEndGlobalPoint,
|
|
4817
|
-
elementsMap,
|
|
4818
|
-
elements,
|
|
4819
|
-
options?.zoom
|
|
4820
|
-
) || null;
|
|
4829
|
+
hoveredStartElement = getHoveredElement(origStartGlobalPoint, elementsMap, elements, zoom) || null;
|
|
4830
|
+
hoveredEndElement = getHoveredElement(origEndGlobalPoint, elementsMap, elements, zoom) || null;
|
|
4821
4831
|
} else {
|
|
4822
4832
|
hoveredStartElement = arrow.startBinding ? getBindableElementForId(arrow.startBinding.elementId, elementsMap) || null : null;
|
|
4823
4833
|
hoveredEndElement = arrow.endBinding ? getBindableElementForId(arrow.endBinding.elementId, elementsMap) || null : null;
|
|
@@ -4833,6 +4843,7 @@ var getElbowArrowData = (arrow, elementsMap, nextPoints, options) => {
|
|
|
4833
4843
|
"start",
|
|
4834
4844
|
arrow.startBinding?.fixedPoint,
|
|
4835
4845
|
origStartGlobalPoint,
|
|
4846
|
+
zoom,
|
|
4836
4847
|
hoveredStartElement,
|
|
4837
4848
|
elementsMap,
|
|
4838
4849
|
options?.isDragging,
|
|
@@ -4850,6 +4861,7 @@ var getElbowArrowData = (arrow, elementsMap, nextPoints, options) => {
|
|
|
4850
4861
|
"end",
|
|
4851
4862
|
arrow.endBinding?.fixedPoint,
|
|
4852
4863
|
origEndGlobalPoint,
|
|
4864
|
+
zoom,
|
|
4853
4865
|
hoveredEndElement,
|
|
4854
4866
|
elementsMap,
|
|
4855
4867
|
options?.isDragging,
|
|
@@ -4862,7 +4874,7 @@ var getElbowArrowData = (arrow, elementsMap, nextPoints, options) => {
|
|
|
4862
4874
|
hoveredStartElement,
|
|
4863
4875
|
origStartGlobalPoint,
|
|
4864
4876
|
elementsMap,
|
|
4865
|
-
|
|
4877
|
+
zoom
|
|
4866
4878
|
);
|
|
4867
4879
|
const endHeading = getBindPointHeading(
|
|
4868
4880
|
endGlobalPoint,
|
|
@@ -4870,7 +4882,7 @@ var getElbowArrowData = (arrow, elementsMap, nextPoints, options) => {
|
|
|
4870
4882
|
hoveredEndElement,
|
|
4871
4883
|
origEndGlobalPoint,
|
|
4872
4884
|
elementsMap,
|
|
4873
|
-
|
|
4885
|
+
zoom
|
|
4874
4886
|
);
|
|
4875
4887
|
const startPointBounds = [
|
|
4876
4888
|
startGlobalPoint[0] - 2,
|
|
@@ -4889,7 +4901,7 @@ var getElbowArrowData = (arrow, elementsMap, nextPoints, options) => {
|
|
|
4889
4901
|
elementsMap,
|
|
4890
4902
|
offsetFromHeading(
|
|
4891
4903
|
startHeading,
|
|
4892
|
-
arrow.startArrowhead ? getBindingGap(hoveredStartElement
|
|
4904
|
+
arrow.startArrowhead ? getBindingGap(hoveredStartElement) * 6 : getBindingGap(hoveredStartElement) * 2,
|
|
4893
4905
|
1
|
|
4894
4906
|
)
|
|
4895
4907
|
) : startPointBounds;
|
|
@@ -4898,7 +4910,7 @@ var getElbowArrowData = (arrow, elementsMap, nextPoints, options) => {
|
|
|
4898
4910
|
elementsMap,
|
|
4899
4911
|
offsetFromHeading(
|
|
4900
4912
|
endHeading,
|
|
4901
|
-
arrow.endArrowhead ? getBindingGap(hoveredEndElement
|
|
4913
|
+
arrow.endArrowhead ? getBindingGap(hoveredEndElement) * 6 : getBindingGap(hoveredEndElement) * 2,
|
|
4902
4914
|
1
|
|
4903
4915
|
)
|
|
4904
4916
|
) : endPointBounds;
|
|
@@ -4930,7 +4942,7 @@ var getElbowArrowData = (arrow, elementsMap, nextPoints, options) => {
|
|
|
4930
4942
|
0
|
|
4931
4943
|
) : offsetFromHeading(
|
|
4932
4944
|
startHeading,
|
|
4933
|
-
!hoveredStartElement && !hoveredEndElement ? 0 : BASE_PADDING - (arrow.startArrowhead ?
|
|
4945
|
+
!hoveredStartElement && !hoveredEndElement ? 0 : BASE_PADDING - (arrow.startArrowhead ? BASE_BINDING_GAP * 6 : BASE_BINDING_GAP * 2),
|
|
4934
4946
|
BASE_PADDING
|
|
4935
4947
|
),
|
|
4936
4948
|
boundsOverlap ? offsetFromHeading(
|
|
@@ -4939,7 +4951,7 @@ var getElbowArrowData = (arrow, elementsMap, nextPoints, options) => {
|
|
|
4939
4951
|
0
|
|
4940
4952
|
) : offsetFromHeading(
|
|
4941
4953
|
endHeading,
|
|
4942
|
-
!hoveredStartElement && !hoveredEndElement ? 0 : BASE_PADDING - (arrow.endArrowhead ?
|
|
4954
|
+
!hoveredStartElement && !hoveredEndElement ? 0 : BASE_PADDING - (arrow.endArrowhead ? BASE_BINDING_GAP * 6 : BASE_BINDING_GAP * 2),
|
|
4943
4955
|
BASE_PADDING
|
|
4944
4956
|
),
|
|
4945
4957
|
boundsOverlap,
|
|
@@ -5477,7 +5489,7 @@ var neighborIndexToHeading = (idx) => {
|
|
|
5477
5489
|
}
|
|
5478
5490
|
return HEADING_LEFT;
|
|
5479
5491
|
};
|
|
5480
|
-
var getGlobalPoint = (arrow, startOrEnd, fixedPointRatio, initialPoint, element, elementsMap, isDragging, isBindingEnabled2 = true, isMidpointSnappingEnabled = true) => {
|
|
5492
|
+
var getGlobalPoint = (arrow, startOrEnd, fixedPointRatio, initialPoint, zoom, element, elementsMap, isDragging, isBindingEnabled2 = true, isMidpointSnappingEnabled = true) => {
|
|
5481
5493
|
if (isDragging) {
|
|
5482
5494
|
if (isBindingEnabled2 && element && elementsMap) {
|
|
5483
5495
|
return bindPointToSnapToElementOutline(
|
|
@@ -5485,6 +5497,7 @@ var getGlobalPoint = (arrow, startOrEnd, fixedPointRatio, initialPoint, element,
|
|
|
5485
5497
|
element,
|
|
5486
5498
|
startOrEnd,
|
|
5487
5499
|
elementsMap,
|
|
5500
|
+
zoom,
|
|
5488
5501
|
void 0,
|
|
5489
5502
|
isMidpointSnappingEnabled
|
|
5490
5503
|
);
|
|
@@ -5514,12 +5527,7 @@ var getBindPointHeading = (p, otherPoint, hoveredElement, origPoint, elementsMap
|
|
|
5514
5527
|
zoom
|
|
5515
5528
|
);
|
|
5516
5529
|
var getHoveredElement = (origPoint, elementsMap, elements, zoom) => {
|
|
5517
|
-
return getHoveredElementForBinding(
|
|
5518
|
-
origPoint,
|
|
5519
|
-
elements,
|
|
5520
|
-
elementsMap,
|
|
5521
|
-
maxBindingDistance_simple(zoom)
|
|
5522
|
-
);
|
|
5530
|
+
return getHoveredElementForBinding(origPoint, elements, elementsMap, zoom);
|
|
5523
5531
|
};
|
|
5524
5532
|
var gridAddressesEqual = (a2, b2) => a2[0] === b2[0] && a2[1] === b2[1];
|
|
5525
5533
|
var validateElbowPoints = (points, tolerance = DEDUP_TRESHOLD) => points.slice(1).map(
|
|
@@ -6526,6 +6534,23 @@ var getBoundTextElementPosition = (container, boundTextElement, elementsMap) =>
|
|
|
6526
6534
|
);
|
|
6527
6535
|
}
|
|
6528
6536
|
};
|
|
6537
|
+
var getTextElementWithAccuratePosition = (textElement, elementsMap) => {
|
|
6538
|
+
if (!textElement.containerId) {
|
|
6539
|
+
return textElement;
|
|
6540
|
+
}
|
|
6541
|
+
const container = elementsMap.get(textElement.containerId);
|
|
6542
|
+
if (!container || !isArrowElement(container)) {
|
|
6543
|
+
return textElement;
|
|
6544
|
+
}
|
|
6545
|
+
return {
|
|
6546
|
+
...textElement,
|
|
6547
|
+
...LinearElementEditor.getBoundTextElementPosition(
|
|
6548
|
+
container,
|
|
6549
|
+
textElement,
|
|
6550
|
+
elementsMap
|
|
6551
|
+
)
|
|
6552
|
+
};
|
|
6553
|
+
};
|
|
6529
6554
|
var shouldAllowVerticalAlign = (selectedElements, elementsMap) => {
|
|
6530
6555
|
return selectedElements.some((element) => {
|
|
6531
6556
|
if (isBoundToContainer(element)) {
|
|
@@ -7580,71 +7605,127 @@ var getDiagonalsForBindableElement = (element, elementsMap) => {
|
|
|
7580
7605
|
);
|
|
7581
7606
|
return [diagonalOne, diagonalTwo];
|
|
7582
7607
|
};
|
|
7583
|
-
var
|
|
7584
|
-
const
|
|
7585
|
-
const
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
return
|
|
7589
|
-
}
|
|
7590
|
-
|
|
7591
|
-
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
|
|
7599
|
-
|
|
7600
|
-
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
|
|
7604
|
-
|
|
7605
|
-
|
|
7606
|
-
|
|
7607
|
-
|
|
7608
|
-
|
|
7609
|
-
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7608
|
+
var getSnappedMidpointForElbowArrow = (element, point, elementsMap, center, horizontalThreshold, verticalThreshold) => {
|
|
7609
|
+
const { x, y, width, height, angle: angle2 } = element;
|
|
7610
|
+
const nonRotated = pointRotateRads6(point, center, -angle2);
|
|
7611
|
+
const bindingGap = getBindingGap(element);
|
|
7612
|
+
if (pointDistance3(center, nonRotated) < bindingGap) {
|
|
7613
|
+
return void 0;
|
|
7614
|
+
}
|
|
7615
|
+
const [right, bottom, left, top] = getAllMidpoints(element, elementsMap);
|
|
7616
|
+
if (nonRotated[0] <= x + width / 2 && nonRotated[1] > center[1] - verticalThreshold && nonRotated[1] < center[1] + verticalThreshold) {
|
|
7617
|
+
return { point: left, onAxis: true };
|
|
7618
|
+
} else if (nonRotated[1] <= y + height / 2 && nonRotated[0] > center[0] - horizontalThreshold && nonRotated[0] < center[0] + horizontalThreshold) {
|
|
7619
|
+
return { point: top, onAxis: true };
|
|
7620
|
+
} else if (nonRotated[0] >= x + width / 2 && nonRotated[1] > center[1] - verticalThreshold && nonRotated[1] < center[1] + verticalThreshold) {
|
|
7621
|
+
return { point: right, onAxis: true };
|
|
7622
|
+
} else if (nonRotated[1] >= y + height / 2 && nonRotated[0] > center[0] - horizontalThreshold && nonRotated[0] < center[0] + horizontalThreshold) {
|
|
7623
|
+
return { point: bottom, onAxis: true };
|
|
7624
|
+
} else if (element.type === "diamond") {
|
|
7625
|
+
const threshold = Math.max(horizontalThreshold, verticalThreshold);
|
|
7626
|
+
const edgeMidpoints = [
|
|
7627
|
+
// top-left, top-right, bottom-left, bottom-right
|
|
7628
|
+
[x + width / 4, y + height / 4, -1, -1],
|
|
7629
|
+
[x + 3 * width / 4, y + height / 4, 1, -1],
|
|
7630
|
+
[x + width / 4, y + 3 * height / 4, -1, 1],
|
|
7631
|
+
[x + 3 * width / 4, y + 3 * height / 4, 1, 1]
|
|
7632
|
+
];
|
|
7633
|
+
for (const [edgeX, edgeY, dirX, dirY] of edgeMidpoints) {
|
|
7634
|
+
const zoneCenter = pointFrom6(
|
|
7635
|
+
edgeX + dirX * bindingGap,
|
|
7636
|
+
edgeY + dirY * bindingGap
|
|
7637
|
+
);
|
|
7638
|
+
if (pointDistance3(zoneCenter, nonRotated) < threshold) {
|
|
7639
|
+
return {
|
|
7640
|
+
point: pointRotateRads6(
|
|
7641
|
+
pointFrom6(edgeX, edgeY),
|
|
7642
|
+
center,
|
|
7643
|
+
angle2
|
|
7644
|
+
),
|
|
7645
|
+
onAxis: false
|
|
7646
|
+
};
|
|
7647
|
+
}
|
|
7648
|
+
}
|
|
7649
|
+
}
|
|
7650
|
+
return void 0;
|
|
7651
|
+
};
|
|
7652
|
+
var getSnappedMidpointIndexForSimpleArrow = (element, point, elementsMap, threshold) => {
|
|
7653
|
+
const baseMidpoints = getAllMidpoints(element, elementsMap);
|
|
7654
|
+
for (let i = 0; i < baseMidpoints.length; i++) {
|
|
7655
|
+
if (pointDistance3(baseMidpoints[i], point) <= threshold && !hitElementItself({
|
|
7623
7656
|
point,
|
|
7624
7657
|
element,
|
|
7625
7658
|
threshold: 0,
|
|
7626
7659
|
elementsMap,
|
|
7627
7660
|
overrideShouldTestInside: true
|
|
7628
|
-
})
|
|
7661
|
+
})) {
|
|
7662
|
+
return i;
|
|
7663
|
+
}
|
|
7664
|
+
}
|
|
7665
|
+
return -1;
|
|
7666
|
+
};
|
|
7667
|
+
var getAllMidpoints = (element, elementsMap) => {
|
|
7668
|
+
const center = elementCenterPoint(element, elementsMap);
|
|
7669
|
+
if (element.type === "diamond") {
|
|
7670
|
+
return getDiamondBaseCorners(element).map(
|
|
7671
|
+
(curve4) => pointRotateRads6(bezierEquation(curve4, 0.5), center, element.angle)
|
|
7672
|
+
);
|
|
7673
|
+
}
|
|
7674
|
+
return [
|
|
7675
|
+
pointFrom6(element.width, element.height / 2),
|
|
7676
|
+
pointFrom6(element.width / 2, element.height),
|
|
7677
|
+
pointFrom6(0, element.height / 2),
|
|
7678
|
+
pointFrom6(element.width / 2, 0)
|
|
7679
|
+
].map(
|
|
7680
|
+
([x, y]) => pointRotateRads6(
|
|
7681
|
+
pointFrom6(element.x + x, element.y + y),
|
|
7682
|
+
center,
|
|
7683
|
+
element.angle
|
|
7684
|
+
)
|
|
7685
|
+
);
|
|
7686
|
+
};
|
|
7687
|
+
var getElbowArrowSnapMidPoint = (point, element, elementsMap, zoom) => {
|
|
7688
|
+
const TOLERANCE = 0.05;
|
|
7689
|
+
const maxDistance = maxBindingDistance_simple(zoom) + element.strokeWidth / 2;
|
|
7690
|
+
return getSnappedMidpointForElbowArrow(
|
|
7691
|
+
element,
|
|
7692
|
+
point,
|
|
7693
|
+
elementsMap,
|
|
7694
|
+
elementCenterPoint(element, elementsMap),
|
|
7695
|
+
clamp5(TOLERANCE * element.width, 5, maxDistance),
|
|
7696
|
+
clamp5(TOLERANCE * element.height, 5, maxDistance)
|
|
7697
|
+
);
|
|
7698
|
+
};
|
|
7699
|
+
var getSnapOutlineMidPoint = (point, element, elementsMap, zoom, arrow) => {
|
|
7700
|
+
if (arrow.elbowed) {
|
|
7701
|
+
return getElbowArrowSnapMidPoint(point, element, elementsMap, zoom)?.point;
|
|
7702
|
+
}
|
|
7703
|
+
const maxDistance = maxBindingDistance_simple(zoom) + element.strokeWidth / 2;
|
|
7704
|
+
const idx = getSnappedMidpointIndexForSimpleArrow(
|
|
7705
|
+
element,
|
|
7706
|
+
point,
|
|
7707
|
+
elementsMap,
|
|
7708
|
+
maxDistance
|
|
7629
7709
|
);
|
|
7630
|
-
return
|
|
7710
|
+
return idx === -1 ? void 0 : getAllMidpoints(element, elementsMap)[idx];
|
|
7631
7711
|
};
|
|
7632
7712
|
var projectFixedPointOntoDiagonal = (arrow, point, element, startOrEnd, elementsMap, zoom, isMidpointSnappingEnabled = true) => {
|
|
7633
7713
|
invariant5(arrow.points.length >= 2, "Arrow must have at least two points");
|
|
7634
|
-
if (arrow.width < 3 && arrow.height < 3) {
|
|
7635
|
-
return null;
|
|
7636
|
-
}
|
|
7637
7714
|
if (isMidpointSnappingEnabled) {
|
|
7638
7715
|
const sideMidPoint = getSnapOutlineMidPoint(
|
|
7639
7716
|
point,
|
|
7640
7717
|
element,
|
|
7641
7718
|
elementsMap,
|
|
7642
|
-
zoom
|
|
7719
|
+
zoom,
|
|
7720
|
+
arrow
|
|
7643
7721
|
);
|
|
7644
7722
|
if (sideMidPoint) {
|
|
7645
7723
|
return sideMidPoint;
|
|
7646
7724
|
}
|
|
7647
7725
|
}
|
|
7726
|
+
if (arrow.width < 3 && arrow.height < 3) {
|
|
7727
|
+
return null;
|
|
7728
|
+
}
|
|
7648
7729
|
const [diagonalOne, diagonalTwo] = getDiagonalsForBindableElement(
|
|
7649
7730
|
element,
|
|
7650
7731
|
elementsMap
|
|
@@ -7736,7 +7817,7 @@ var hitElementItself = ({
|
|
|
7736
7817
|
frameNameBound = null,
|
|
7737
7818
|
overrideShouldTestInside = false
|
|
7738
7819
|
}) => {
|
|
7739
|
-
if (cachedPoint && pointsEqual4(point, cachedPoint) && (cachedHit ? cachedThreshold <= threshold : cachedThreshold >= threshold) && overrideShouldTestInside === cachedOverrideShouldTestInside && frameNameBoundsEqual(frameNameBound, cachedFrameNameBound)) {
|
|
7820
|
+
if (!isBoundToContainer(element) && cachedPoint && pointsEqual4(point, cachedPoint) && (cachedHit ? cachedThreshold <= threshold : cachedThreshold >= threshold) && overrideShouldTestInside === cachedOverrideShouldTestInside && frameNameBoundsEqual(frameNameBound, cachedFrameNameBound)) {
|
|
7740
7821
|
const derefElement = cachedElement?.deref();
|
|
7741
7822
|
if (derefElement && derefElement.id === element.id && derefElement.version === element.version && derefElement.versionNonce === element.versionNonce) {
|
|
7742
7823
|
return cachedHit;
|
|
@@ -7755,11 +7836,15 @@ var hitElementItself = ({
|
|
|
7755
7836
|
point,
|
|
7756
7837
|
bounds,
|
|
7757
7838
|
element.angle,
|
|
7758
|
-
|
|
7839
|
+
// Freedraw bounds follow the centerline points, but the ink extends past them
|
|
7840
|
+
isFreeDrawElement(element) ? threshold + getFreedrawMaxStrokeRadius(element) : threshold
|
|
7759
7841
|
);
|
|
7760
7842
|
if (!hitBounds && !hitFrameName) {
|
|
7761
7843
|
return false;
|
|
7762
7844
|
}
|
|
7845
|
+
if (isTextElement(element)) {
|
|
7846
|
+
element = getTextElementWithAccuratePosition(element, elementsMap);
|
|
7847
|
+
}
|
|
7763
7848
|
const hitElement = (overrideShouldTestInside ? true : shouldTestInside(element)) ? (
|
|
7764
7849
|
// Since `inShape` tests STRICTLY againt the insides of a shape
|
|
7765
7850
|
// we would need `onShape` as well to include the "borders"
|
|
@@ -7793,110 +7878,111 @@ var hitElementBoundText = (point, element, elementsMap) => {
|
|
|
7793
7878
|
if (!boundTextElementCandidate) {
|
|
7794
7879
|
return false;
|
|
7795
7880
|
}
|
|
7796
|
-
const boundTextElement =
|
|
7797
|
-
|
|
7798
|
-
|
|
7799
|
-
|
|
7800
|
-
...LinearElementEditor.getBoundTextElementPosition(
|
|
7801
|
-
element,
|
|
7802
|
-
boundTextElementCandidate,
|
|
7803
|
-
elementsMap
|
|
7804
|
-
)
|
|
7805
|
-
} : boundTextElementCandidate;
|
|
7881
|
+
const boundTextElement = getTextElementWithAccuratePosition(
|
|
7882
|
+
boundTextElementCandidate,
|
|
7883
|
+
elementsMap
|
|
7884
|
+
);
|
|
7806
7885
|
return isPointInElement(point, boundTextElement, elementsMap);
|
|
7807
7886
|
};
|
|
7808
|
-
var
|
|
7809
|
-
|
|
7810
|
-
|
|
7811
|
-
|
|
7812
|
-
|
|
7813
|
-
|
|
7814
|
-
|
|
7887
|
+
var isPointClippedByEnclosingFrame = (element, point, elementsMap) => {
|
|
7888
|
+
if (!element.frameId) {
|
|
7889
|
+
return false;
|
|
7890
|
+
}
|
|
7891
|
+
const enclosingFrame = elementsMap.get(element.frameId);
|
|
7892
|
+
return !!enclosingFrame && isFrameLikeElement(enclosingFrame) && !pointInsideBounds(point, getElementBounds(enclosingFrame, elementsMap));
|
|
7893
|
+
};
|
|
7894
|
+
var bindableElementBorderDistanceIfClose = (element, point, elementsMap, tolerance = 0) => {
|
|
7895
|
+
const [x, y] = point;
|
|
7815
7896
|
const t = Math.max(1, tolerance);
|
|
7816
7897
|
const bounds = [x - t, y - t, x + t, y + t];
|
|
7817
7898
|
const elementBounds = getElementBounds(element, elementsMap);
|
|
7818
7899
|
if (!doBoundsIntersect(bounds, elementBounds)) {
|
|
7819
|
-
return
|
|
7900
|
+
return -Infinity;
|
|
7820
7901
|
}
|
|
7821
|
-
if (element
|
|
7822
|
-
|
|
7823
|
-
if (enclosingFrame && isFrameLikeElement(enclosingFrame)) {
|
|
7824
|
-
const enclosingFrameBounds = getElementBounds(
|
|
7825
|
-
enclosingFrame,
|
|
7826
|
-
elementsMap
|
|
7827
|
-
);
|
|
7828
|
-
if (!pointInsideBounds(p, enclosingFrameBounds)) {
|
|
7829
|
-
return false;
|
|
7830
|
-
}
|
|
7831
|
-
}
|
|
7902
|
+
if (isPointClippedByEnclosingFrame(element, point, elementsMap)) {
|
|
7903
|
+
return -Infinity;
|
|
7832
7904
|
}
|
|
7833
|
-
const
|
|
7834
|
-
|
|
7835
|
-
|
|
7836
|
-
|
|
7837
|
-
);
|
|
7838
|
-
|
|
7839
|
-
|
|
7905
|
+
const isInside = isPointInElement(point, element, elementsMap);
|
|
7906
|
+
if (isInside && isFrameLikeElement(element)) {
|
|
7907
|
+
return -Infinity;
|
|
7908
|
+
}
|
|
7909
|
+
const distance3 = distanceToElement(element, elementsMap, point);
|
|
7910
|
+
if (isInside) {
|
|
7911
|
+
return distance3;
|
|
7912
|
+
}
|
|
7913
|
+
return distance3 > tolerance ? -Infinity : -distance3;
|
|
7840
7914
|
};
|
|
7841
|
-
var
|
|
7842
|
-
|
|
7915
|
+
var isOpaqueForBinding = (element) => isImageElement(element) || hasBackground(element.type) && !isTransparent2(element.backgroundColor);
|
|
7916
|
+
var getBindingCandidates = (point, elements, elementsMap, zoom) => {
|
|
7917
|
+
const maxDistance = maxBindingDistance_simple(zoom);
|
|
7918
|
+
const candidates = [];
|
|
7919
|
+
let occludingFrameId = null;
|
|
7843
7920
|
for (let index = elements.length - 1; index >= 0; --index) {
|
|
7844
7921
|
const element = elements[index];
|
|
7845
7922
|
invariant6(
|
|
7846
7923
|
!element.isDeleted,
|
|
7847
|
-
"Elements
|
|
7924
|
+
"Elements passed to binding hit tests should not contain deleted elements"
|
|
7848
7925
|
);
|
|
7849
|
-
if (
|
|
7850
|
-
|
|
7851
|
-
|
|
7852
|
-
|
|
7926
|
+
if (occludingFrameId && element.frameId !== occludingFrameId) {
|
|
7927
|
+
continue;
|
|
7928
|
+
}
|
|
7929
|
+
if (!isBindableElement(element)) {
|
|
7930
|
+
continue;
|
|
7931
|
+
}
|
|
7932
|
+
if (isFrameLikeElement(element)) {
|
|
7933
|
+
if (isOpaqueForBinding(element) && isPointInElement(point, element, elementsMap)) {
|
|
7934
|
+
occludingFrameId = element.id;
|
|
7853
7935
|
}
|
|
7854
7936
|
}
|
|
7855
|
-
|
|
7856
|
-
|
|
7857
|
-
|
|
7858
|
-
|
|
7859
|
-
|
|
7860
|
-
point,
|
|
7861
|
-
elements,
|
|
7862
|
-
elementsMap,
|
|
7863
|
-
tolerance
|
|
7864
|
-
);
|
|
7865
|
-
if (!candidateElements || candidateElements.length === 0) {
|
|
7866
|
-
return null;
|
|
7867
|
-
}
|
|
7868
|
-
if (candidateElements.length === 1) {
|
|
7869
|
-
return candidateElements[0];
|
|
7870
|
-
}
|
|
7871
|
-
return candidateElements.sort(
|
|
7872
|
-
(a2, b2) => b2.width ** 2 + b2.height ** 2 - (a2.width ** 2 + a2.height ** 2)
|
|
7873
|
-
).pop();
|
|
7874
|
-
};
|
|
7875
|
-
var getHoveredElementForFocusPoint = (point, arrow, elements, elementsMap, tolerance) => {
|
|
7876
|
-
const candidateElements = [];
|
|
7877
|
-
for (let index = elements.length - 1; index >= 0; --index) {
|
|
7878
|
-
const element = elements[index];
|
|
7879
|
-
invariant6(
|
|
7880
|
-
!element.isDeleted,
|
|
7881
|
-
"Elements in the function parameter for getAllElementsAtPositionForBinding() should not contain deleted elements"
|
|
7937
|
+
const distance3 = bindableElementBorderDistanceIfClose(
|
|
7938
|
+
element,
|
|
7939
|
+
point,
|
|
7940
|
+
elementsMap,
|
|
7941
|
+
maxDistance
|
|
7882
7942
|
);
|
|
7883
|
-
if (
|
|
7884
|
-
|
|
7943
|
+
if (distance3 > -maxDistance) {
|
|
7944
|
+
if (!element.locked) {
|
|
7945
|
+
candidates.push({ element, distance: distance3 });
|
|
7946
|
+
}
|
|
7947
|
+
if (distance3 >= 0 && isOpaqueForBinding(element)) {
|
|
7948
|
+
break;
|
|
7949
|
+
}
|
|
7885
7950
|
}
|
|
7886
7951
|
}
|
|
7887
|
-
|
|
7952
|
+
return candidates;
|
|
7953
|
+
};
|
|
7954
|
+
var getAllHoveredElementAtPoint = (point, elements, elementsMap, zoom) => getBindingCandidates(point, elements, elementsMap, zoom).map(
|
|
7955
|
+
({ element }) => element
|
|
7956
|
+
);
|
|
7957
|
+
var getHoveredElementForBinding = (point, elements, elementsMap, zoom) => {
|
|
7958
|
+
const candidates = getBindingCandidates(point, elements, elementsMap, zoom);
|
|
7959
|
+
if (candidates.length === 0) {
|
|
7888
7960
|
return null;
|
|
7889
7961
|
}
|
|
7890
|
-
if (
|
|
7891
|
-
return
|
|
7962
|
+
if (candidates.length === 1) {
|
|
7963
|
+
return candidates[0].element;
|
|
7892
7964
|
}
|
|
7893
|
-
const
|
|
7894
|
-
(
|
|
7965
|
+
const closestElements = candidates.sort(
|
|
7966
|
+
(a2, b2) => Math.abs(a2.distance) - Math.abs(b2.distance)
|
|
7895
7967
|
);
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
|
|
7899
|
-
|
|
7968
|
+
const candidate = closestElements[0];
|
|
7969
|
+
const [cx1, cy1, cx2, cy2] = getElementBounds(candidate.element, elementsMap);
|
|
7970
|
+
const candidateArea = Math.max(
|
|
7971
|
+
1e-5,
|
|
7972
|
+
Math.abs(cx2 - cx1) * Math.abs(cy2 - cy1)
|
|
7973
|
+
);
|
|
7974
|
+
const overlaps = closestElements.filter((c) => c.element !== candidate.element && c.distance >= 0).map((c) => {
|
|
7975
|
+
const [x1, y1, x2, y2] = getElementBounds(c.element, elementsMap);
|
|
7976
|
+
const overlapWidth = Math.max(0, Math.min(x2, cx2) - Math.max(x1, cx1));
|
|
7977
|
+
const overlapHeight = Math.max(0, Math.min(y2, cy2) - Math.max(y1, cy1));
|
|
7978
|
+
const area = Math.max(1e-5, Math.abs(x2 - x1) * Math.abs(y2 - y1));
|
|
7979
|
+
return {
|
|
7980
|
+
...c,
|
|
7981
|
+
overlapPercent: overlapHeight * overlapWidth / area,
|
|
7982
|
+
relativeArea: area / candidateArea
|
|
7983
|
+
};
|
|
7984
|
+
}).filter((c) => c.overlapPercent > 0.25 && c.relativeArea < 0.75);
|
|
7985
|
+
return candidate.distance >= 0 && overlaps.length > 0 ? overlaps[0].element : candidate.element;
|
|
7900
7986
|
};
|
|
7901
7987
|
var intersectElementWithLineSegment = (element, elementsMap, line2, offset = 0, onlyFirst = false) => {
|
|
7902
7988
|
const intersectorBounds = [
|
|
@@ -7952,15 +8038,16 @@ var intersectElementWithLineSegment = (element, elementsMap, line2, offset = 0,
|
|
|
7952
8038
|
);
|
|
7953
8039
|
}
|
|
7954
8040
|
};
|
|
8041
|
+
var CURVE_BOUNDS_EPSILON = 1e-6;
|
|
7955
8042
|
var curveIntersections = (curves, segment, intersections, center, angle2, onlyFirst = false) => {
|
|
8043
|
+
const b2 = [
|
|
8044
|
+
Math.min(segment[0][0], segment[1][0]) - CURVE_BOUNDS_EPSILON,
|
|
8045
|
+
Math.min(segment[0][1], segment[1][1]) - CURVE_BOUNDS_EPSILON,
|
|
8046
|
+
Math.max(segment[0][0], segment[1][0]) + CURVE_BOUNDS_EPSILON,
|
|
8047
|
+
Math.max(segment[0][1], segment[1][1]) + CURVE_BOUNDS_EPSILON
|
|
8048
|
+
];
|
|
7956
8049
|
for (const c of curves) {
|
|
7957
8050
|
const b1 = getCubicBezierCurveBound(c[0], c[1], c[2], c[3]);
|
|
7958
|
-
const b2 = [
|
|
7959
|
-
Math.min(segment[0][0], segment[1][0]),
|
|
7960
|
-
Math.min(segment[0][1], segment[1][1]),
|
|
7961
|
-
Math.max(segment[0][0], segment[1][0]),
|
|
7962
|
-
Math.max(segment[0][1], segment[1][1])
|
|
7963
|
-
];
|
|
7964
8051
|
if (!doBoundsIntersect(b1, b2)) {
|
|
7965
8052
|
continue;
|
|
7966
8053
|
}
|
|
@@ -8104,6 +8191,18 @@ var isPointInElement = (point, element, elementsMap) => {
|
|
|
8104
8191
|
if ((isLinearElement(element) || isFreeDrawElement(element)) && !isPathALoop(element.points)) {
|
|
8105
8192
|
return false;
|
|
8106
8193
|
}
|
|
8194
|
+
if (isFreeDrawElement(element)) {
|
|
8195
|
+
const [x12, y12, x22, y22] = getElementBounds(element, elementsMap, true);
|
|
8196
|
+
const [px, py] = pointRotateRads7(
|
|
8197
|
+
point,
|
|
8198
|
+
pointFrom7((x12 + x22) / 2, (y12 + y22) / 2),
|
|
8199
|
+
-element.angle
|
|
8200
|
+
);
|
|
8201
|
+
return polygonIncludesPoint(
|
|
8202
|
+
pointFrom7(px - element.x, py - element.y),
|
|
8203
|
+
getFreedrawFillPolygon(element)
|
|
8204
|
+
);
|
|
8205
|
+
}
|
|
8107
8206
|
const [x1, y1, x2, y2] = getElementBounds(element, elementsMap);
|
|
8108
8207
|
if (!isPointWithinBounds(pointFrom7(x1, y1), point, pointFrom7(x2, y2))) {
|
|
8109
8208
|
return false;
|
|
@@ -8180,17 +8279,16 @@ var isBindableElementInsideOtherBindable = (innerElement, outerElement, elements
|
|
|
8180
8279
|
|
|
8181
8280
|
// src/binding.ts
|
|
8182
8281
|
var BASE_BINDING_GAP = 5;
|
|
8183
|
-
var BASE_BINDING_GAP_ELBOW = 5;
|
|
8184
8282
|
var BASE_ARROW_MIN_LENGTH = 10;
|
|
8185
8283
|
var FOCUS_POINT_SIZE = 10 / 1.5;
|
|
8186
8284
|
var MIN_BINDABLE_SIZE = 1;
|
|
8187
|
-
var getBindingGap = (bindTarget
|
|
8188
|
-
return
|
|
8285
|
+
var getBindingGap = (bindTarget) => {
|
|
8286
|
+
return BASE_BINDING_GAP + bindTarget.strokeWidth / 2;
|
|
8189
8287
|
};
|
|
8190
8288
|
var maxBindingDistance_simple = (zoom) => {
|
|
8191
8289
|
const BASE_BINDING_DISTANCE = Math.max(BASE_BINDING_GAP, 15);
|
|
8192
8290
|
const zoomValue = zoom?.value && zoom.value < 1 ? zoom.value : 1;
|
|
8193
|
-
return
|
|
8291
|
+
return clamp6(
|
|
8194
8292
|
// reducing zoom impact so that the diff between binding distance and
|
|
8195
8293
|
// binding gap is kept to minimum when possible
|
|
8196
8294
|
BASE_BINDING_DISTANCE / (zoomValue * 1.5),
|
|
@@ -8221,6 +8319,7 @@ var bindOrUnbindBindingElement = (arrow, draggingPoints, scenePointerX, scenePoi
|
|
|
8221
8319
|
start,
|
|
8222
8320
|
"start",
|
|
8223
8321
|
scene,
|
|
8322
|
+
appState.zoom,
|
|
8224
8323
|
appState.isBindingEnabled,
|
|
8225
8324
|
isMidpointSnappingEnabled
|
|
8226
8325
|
);
|
|
@@ -8229,6 +8328,7 @@ var bindOrUnbindBindingElement = (arrow, draggingPoints, scenePointerX, scenePoi
|
|
|
8229
8328
|
end,
|
|
8230
8329
|
"end",
|
|
8231
8330
|
scene,
|
|
8331
|
+
appState.zoom,
|
|
8232
8332
|
appState.isBindingEnabled,
|
|
8233
8333
|
isMidpointSnappingEnabled
|
|
8234
8334
|
);
|
|
@@ -8260,7 +8360,7 @@ var bindOrUnbindBindingElement = (arrow, draggingPoints, scenePointerX, scenePoi
|
|
|
8260
8360
|
}
|
|
8261
8361
|
return { start, end };
|
|
8262
8362
|
};
|
|
8263
|
-
var bindOrUnbindBindingElementEdge = (arrow, { mode, element, focusPoint }, startOrEnd, scene, shouldSnapToOutline = true, isMidpointSnappingEnabled = true) => {
|
|
8363
|
+
var bindOrUnbindBindingElementEdge = (arrow, { mode, element, focusPoint }, startOrEnd, scene, zoom, shouldSnapToOutline = true, isMidpointSnappingEnabled = true) => {
|
|
8264
8364
|
if (mode === null) {
|
|
8265
8365
|
unbindBindingElement(arrow, startOrEnd, scene);
|
|
8266
8366
|
} else if (mode !== void 0) {
|
|
@@ -8270,6 +8370,7 @@ var bindOrUnbindBindingElementEdge = (arrow, { mode, element, focusPoint }, star
|
|
|
8270
8370
|
mode,
|
|
8271
8371
|
startOrEnd,
|
|
8272
8372
|
scene,
|
|
8373
|
+
zoom,
|
|
8273
8374
|
focusPoint,
|
|
8274
8375
|
shouldSnapToOutline,
|
|
8275
8376
|
isMidpointSnappingEnabled
|
|
@@ -8293,7 +8394,7 @@ var bindingStrategyForElbowArrowEndpointDragging = (arrow, draggingPoints, eleme
|
|
|
8293
8394
|
globalPoint,
|
|
8294
8395
|
elements,
|
|
8295
8396
|
elementsMap,
|
|
8296
|
-
|
|
8397
|
+
zoom
|
|
8297
8398
|
);
|
|
8298
8399
|
const current = hit ? {
|
|
8299
8400
|
element: hit,
|
|
@@ -8318,7 +8419,12 @@ var bindingStrategyForNewSimpleArrowEndpointDragging = (arrow, draggingPoints, e
|
|
|
8318
8419
|
draggingPoints.get(startDragged ? startIdx : endIdx).point,
|
|
8319
8420
|
elementsMap
|
|
8320
8421
|
);
|
|
8321
|
-
const hit = getHoveredElementForBinding(
|
|
8422
|
+
const hit = getHoveredElementForBinding(
|
|
8423
|
+
point,
|
|
8424
|
+
elements,
|
|
8425
|
+
elementsMap,
|
|
8426
|
+
appState.zoom
|
|
8427
|
+
);
|
|
8322
8428
|
if (startDragged) {
|
|
8323
8429
|
if (hit) {
|
|
8324
8430
|
start = {
|
|
@@ -8349,7 +8455,12 @@ var bindingStrategyForNewSimpleArrowEndpointDragging = (arrow, draggingPoints, e
|
|
|
8349
8455
|
}
|
|
8350
8456
|
if (hit && arrow.startBinding) {
|
|
8351
8457
|
const startBinding = arrow.startBinding;
|
|
8352
|
-
const allHits = getAllHoveredElementAtPoint(
|
|
8458
|
+
const allHits = getAllHoveredElementAtPoint(
|
|
8459
|
+
point,
|
|
8460
|
+
elements,
|
|
8461
|
+
elementsMap,
|
|
8462
|
+
appState.zoom
|
|
8463
|
+
);
|
|
8353
8464
|
if (allHits.find((el) => el.id === startBinding.elementId)) {
|
|
8354
8465
|
const otherElement = elementsMap.get(
|
|
8355
8466
|
arrow.startBinding.elementId
|
|
@@ -8413,12 +8524,12 @@ var bindingStrategyForNewSimpleArrowEndpointDragging = (arrow, draggingPoints, e
|
|
|
8413
8524
|
}
|
|
8414
8525
|
invariant7(false, "New arrow creation should not reach here");
|
|
8415
8526
|
};
|
|
8416
|
-
var bindingStrategyForSimpleArrowEndpointDragging_complex = (point, currentBinding, oppositeBinding, elementsMap, elements, globalBindMode, arrow, finalize) => {
|
|
8527
|
+
var bindingStrategyForSimpleArrowEndpointDragging_complex = (point, currentBinding, oppositeBinding, elementsMap, elements, globalBindMode, arrow, zoom, finalize) => {
|
|
8417
8528
|
let current = { mode: void 0 };
|
|
8418
8529
|
let other = { mode: void 0 };
|
|
8419
8530
|
const isMultiPoint = arrow.points.length > 2;
|
|
8420
|
-
const hit = getHoveredElementForBinding(point, elements, elementsMap);
|
|
8421
|
-
const isOverlapping = oppositeBinding ? getAllHoveredElementAtPoint(point, elements, elementsMap).some(
|
|
8531
|
+
const hit = getHoveredElementForBinding(point, elements, elementsMap, zoom);
|
|
8532
|
+
const isOverlapping = oppositeBinding ? getAllHoveredElementAtPoint(point, elements, elementsMap, zoom).some(
|
|
8422
8533
|
(el) => el.id === oppositeBinding.elementId
|
|
8423
8534
|
) : false;
|
|
8424
8535
|
const oppositeElement = oppositeBinding ? elementsMap.get(
|
|
@@ -8531,7 +8642,7 @@ var getBindingStrategyForDraggingBindingElementEndpoints_simple = (arrow, draggi
|
|
|
8531
8642
|
draggingPoints,
|
|
8532
8643
|
elementsMap,
|
|
8533
8644
|
elements,
|
|
8534
|
-
|
|
8645
|
+
appState.zoom
|
|
8535
8646
|
);
|
|
8536
8647
|
}
|
|
8537
8648
|
const otherBinding = startDragged ? arrow.endBinding : arrow.startBinding;
|
|
@@ -8551,7 +8662,7 @@ var getBindingStrategyForDraggingBindingElementEndpoints_simple = (arrow, draggi
|
|
|
8551
8662
|
opts?.angleLocked || appState.gridModeEnabled ? pointFrom8(scenePointerX, scenePointerY) : globalPoint,
|
|
8552
8663
|
elements,
|
|
8553
8664
|
elementsMap,
|
|
8554
|
-
|
|
8665
|
+
appState.zoom
|
|
8555
8666
|
);
|
|
8556
8667
|
const pointInElement = hit && (opts?.angleLocked ? isPointInElement(
|
|
8557
8668
|
pointFrom8(scenePointerX, scenePointerY),
|
|
@@ -8736,7 +8847,8 @@ var getBindingStrategyForDraggingBindingElementEndpoints_complex = (arrow, dragg
|
|
|
8736
8847
|
arrow,
|
|
8737
8848
|
draggingPoints,
|
|
8738
8849
|
elementsMap,
|
|
8739
|
-
elements
|
|
8850
|
+
elements,
|
|
8851
|
+
appState.zoom
|
|
8740
8852
|
);
|
|
8741
8853
|
}
|
|
8742
8854
|
if (opts?.newArrow) {
|
|
@@ -8771,6 +8883,7 @@ var getBindingStrategyForDraggingBindingElementEndpoints_complex = (arrow, dragg
|
|
|
8771
8883
|
elements,
|
|
8772
8884
|
globalBindMode,
|
|
8773
8885
|
arrow,
|
|
8886
|
+
appState.zoom,
|
|
8774
8887
|
opts?.finalize
|
|
8775
8888
|
);
|
|
8776
8889
|
return { start: current, end: other };
|
|
@@ -8791,6 +8904,7 @@ var getBindingStrategyForDraggingBindingElementEndpoints_complex = (arrow, dragg
|
|
|
8791
8904
|
elements,
|
|
8792
8905
|
globalBindMode,
|
|
8793
8906
|
arrow,
|
|
8907
|
+
appState.zoom,
|
|
8794
8908
|
opts?.finalize
|
|
8795
8909
|
);
|
|
8796
8910
|
return { start: other, end: current };
|
|
@@ -8824,7 +8938,7 @@ var applyBinding = (arrow, bindableElement, binding, startOrEnd, scene) => {
|
|
|
8824
8938
|
});
|
|
8825
8939
|
}
|
|
8826
8940
|
};
|
|
8827
|
-
var bindBindingElement = (arrow, hoveredElement, mode, startOrEnd, scene, focusPoint, shouldSnapToOutline = true, isMidpointSnappingEnabled = true) => {
|
|
8941
|
+
var bindBindingElement = (arrow, hoveredElement, mode, startOrEnd, scene, zoom, focusPoint, shouldSnapToOutline = true, isMidpointSnappingEnabled = true) => {
|
|
8828
8942
|
const elementsMap = scene.getNonDeletedElementsMap();
|
|
8829
8943
|
let binding;
|
|
8830
8944
|
if (isElbowArrow(arrow)) {
|
|
@@ -8836,6 +8950,7 @@ var bindBindingElement = (arrow, hoveredElement, mode, startOrEnd, scene, focusP
|
|
|
8836
8950
|
hoveredElement,
|
|
8837
8951
|
startOrEnd,
|
|
8838
8952
|
elementsMap,
|
|
8953
|
+
zoom,
|
|
8839
8954
|
shouldSnapToOutline,
|
|
8840
8955
|
isMidpointSnappingEnabled
|
|
8841
8956
|
)
|
|
@@ -8873,6 +8988,84 @@ var unbindBindingElement = (arrow, startOrEnd, scene) => {
|
|
|
8873
8988
|
scene.mutateElement(arrow, { [field]: null });
|
|
8874
8989
|
return binding.elementId;
|
|
8875
8990
|
};
|
|
8991
|
+
var reanchorBindingsToOutline = (changedElement, scene, zoom) => {
|
|
8992
|
+
const elementsMap = scene.getNonDeletedElementsMap();
|
|
8993
|
+
const center = elementCenterPoint(changedElement, elementsMap);
|
|
8994
|
+
const reach = Math.max(changedElement.width, changedElement.height) * 2;
|
|
8995
|
+
boundElementsVisitor(elementsMap, changedElement, (element) => {
|
|
8996
|
+
if (!isArrowElement(element) || !isNonDeletedElement(element)) {
|
|
8997
|
+
return;
|
|
8998
|
+
}
|
|
8999
|
+
const updates = {};
|
|
9000
|
+
for (const startOrEnd of ["startBinding", "endBinding"]) {
|
|
9001
|
+
const binding = element[startOrEnd];
|
|
9002
|
+
if (binding?.elementId !== changedElement.id) {
|
|
9003
|
+
continue;
|
|
9004
|
+
}
|
|
9005
|
+
const startOrEndName = startOrEnd === "startBinding" ? "start" : "end";
|
|
9006
|
+
if (isElbowArrow(element)) {
|
|
9007
|
+
updates[startOrEnd] = {
|
|
9008
|
+
...binding,
|
|
9009
|
+
...calculateFixedPointForElbowArrowBinding(
|
|
9010
|
+
element,
|
|
9011
|
+
changedElement,
|
|
9012
|
+
startOrEndName,
|
|
9013
|
+
elementsMap,
|
|
9014
|
+
zoom
|
|
9015
|
+
)
|
|
9016
|
+
};
|
|
9017
|
+
continue;
|
|
9018
|
+
}
|
|
9019
|
+
const focusPoint = getGlobalFixedPointForBindableElement(
|
|
9020
|
+
binding.fixedPoint,
|
|
9021
|
+
changedElement,
|
|
9022
|
+
elementsMap
|
|
9023
|
+
);
|
|
9024
|
+
if (hitElementItself({
|
|
9025
|
+
element: changedElement,
|
|
9026
|
+
point: focusPoint,
|
|
9027
|
+
elementsMap,
|
|
9028
|
+
threshold: getBindingGap(changedElement),
|
|
9029
|
+
overrideShouldTestInside: true
|
|
9030
|
+
})) {
|
|
9031
|
+
continue;
|
|
9032
|
+
}
|
|
9033
|
+
const direction = vectorFromPoint7(focusPoint, center);
|
|
9034
|
+
if (direction[0] === 0 && direction[1] === 0) {
|
|
9035
|
+
continue;
|
|
9036
|
+
}
|
|
9037
|
+
const outlinePoint = intersectElementWithLineSegment(
|
|
9038
|
+
changedElement,
|
|
9039
|
+
elementsMap,
|
|
9040
|
+
lineSegment4(
|
|
9041
|
+
center,
|
|
9042
|
+
pointFromVector6(
|
|
9043
|
+
vectorScale7(vectorNormalize4(direction), reach),
|
|
9044
|
+
center
|
|
9045
|
+
)
|
|
9046
|
+
)
|
|
9047
|
+
).sort(
|
|
9048
|
+
(a2, b2) => pointDistanceSq(a2, focusPoint) - pointDistanceSq(b2, focusPoint)
|
|
9049
|
+
)[0];
|
|
9050
|
+
if (!outlinePoint) {
|
|
9051
|
+
continue;
|
|
9052
|
+
}
|
|
9053
|
+
updates[startOrEnd] = {
|
|
9054
|
+
...binding,
|
|
9055
|
+
...calculateFixedPointForNonElbowArrowBinding(
|
|
9056
|
+
element,
|
|
9057
|
+
changedElement,
|
|
9058
|
+
startOrEndName,
|
|
9059
|
+
elementsMap,
|
|
9060
|
+
outlinePoint
|
|
9061
|
+
)
|
|
9062
|
+
};
|
|
9063
|
+
}
|
|
9064
|
+
if (updates.startBinding || updates.endBinding) {
|
|
9065
|
+
mutateElement(element, elementsMap, updates);
|
|
9066
|
+
}
|
|
9067
|
+
});
|
|
9068
|
+
};
|
|
8876
9069
|
var updateBoundElements = (changedElement, scene, options) => {
|
|
8877
9070
|
if (!isBindableElement(changedElement)) {
|
|
8878
9071
|
return;
|
|
@@ -8983,6 +9176,7 @@ var updateArrowBindings = (latestElement, startOrEnd, elementsMap, scene, appSta
|
|
|
8983
9176
|
strategy[strategyName].mode,
|
|
8984
9177
|
strategyName,
|
|
8985
9178
|
scene,
|
|
9179
|
+
appState.zoom,
|
|
8986
9180
|
strategy[strategyName].focusPoint
|
|
8987
9181
|
);
|
|
8988
9182
|
}
|
|
@@ -9019,8 +9213,17 @@ var updateBindings = (latestElement, scene, appState, options) => {
|
|
|
9019
9213
|
var doesNeedUpdate = (boundElement, changedElement) => {
|
|
9020
9214
|
return boundElement.startBinding?.elementId === changedElement.id || boundElement.endBinding?.elementId === changedElement.id;
|
|
9021
9215
|
};
|
|
9216
|
+
var simultaneouslyUpdatedElementIdsCache = /* @__PURE__ */ new WeakMap();
|
|
9022
9217
|
var getSimultaneouslyUpdatedElementIds = (simultaneouslyUpdated) => {
|
|
9023
|
-
|
|
9218
|
+
if (!simultaneouslyUpdated) {
|
|
9219
|
+
return /* @__PURE__ */ new Set();
|
|
9220
|
+
}
|
|
9221
|
+
let ids = simultaneouslyUpdatedElementIdsCache.get(simultaneouslyUpdated);
|
|
9222
|
+
if (!ids) {
|
|
9223
|
+
ids = new Set(simultaneouslyUpdated.map((element) => element.id));
|
|
9224
|
+
simultaneouslyUpdatedElementIdsCache.set(simultaneouslyUpdated, ids);
|
|
9225
|
+
}
|
|
9226
|
+
return ids;
|
|
9024
9227
|
};
|
|
9025
9228
|
var getHeadingForElbowArrowSnap = (p, otherPoint, bindableElement, aabb, origPoint, elementsMap, zoom) => {
|
|
9026
9229
|
const otherPointHeading = vectorToHeading(vectorFromPoint7(otherPoint, p));
|
|
@@ -9045,7 +9248,7 @@ var getDistanceForBinding = (point, bindableElement, elementsMap, zoom) => {
|
|
|
9045
9248
|
const bindDistance = maxBindingDistance_simple(zoom);
|
|
9046
9249
|
return distance3 > bindDistance ? null : distance3;
|
|
9047
9250
|
};
|
|
9048
|
-
var bindPointToSnapToElementOutline = (arrowElement, bindableElement, startOrEnd, elementsMap, customIntersector, isMidpointSnappingEnabled = true) => {
|
|
9251
|
+
var bindPointToSnapToElementOutline = (arrowElement, bindableElement, startOrEnd, elementsMap, zoom, customIntersector, isMidpointSnappingEnabled = true) => {
|
|
9049
9252
|
const elbowed = isElbowArrow(arrowElement);
|
|
9050
9253
|
const point = LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
|
9051
9254
|
arrowElement,
|
|
@@ -9066,16 +9269,16 @@ var bindPointToSnapToElementOutline = (arrowElement, bindableElement, startOrEnd
|
|
|
9066
9269
|
startOrEnd === "start" ? 1 : -2,
|
|
9067
9270
|
elementsMap
|
|
9068
9271
|
);
|
|
9069
|
-
const bindingGap = getBindingGap(bindableElement
|
|
9272
|
+
const bindingGap = getBindingGap(bindableElement);
|
|
9070
9273
|
const aabb = aabbForElement(bindableElement, elementsMap);
|
|
9071
9274
|
const bindableCenter = getCenterForBounds(aabb);
|
|
9072
9275
|
let intersection = null;
|
|
9073
9276
|
if (elbowed) {
|
|
9277
|
+
const snap = isMidpointSnappingEnabled ? getElbowArrowSnapMidPoint(edgePoint, bindableElement, elementsMap, zoom) : void 0;
|
|
9278
|
+
const resolved = snap?.point ?? point;
|
|
9074
9279
|
const isHorizontal = headingIsHorizontal(
|
|
9075
|
-
headingForPointFromElement(bindableElement, aabb, point)
|
|
9280
|
+
snap?.onAxis ? vectorToHeading(vectorFromPoint7(snap.point, bindableCenter)) : headingForPointFromElement(bindableElement, aabb, point)
|
|
9076
9281
|
);
|
|
9077
|
-
const snapPoint = isMidpointSnappingEnabled ? snapToMid(bindableElement, elementsMap, edgePoint, 0.05, arrowElement) : void 0;
|
|
9078
|
-
const resolved = snapPoint || point;
|
|
9079
9282
|
const otherPoint = pointFrom8(
|
|
9080
9283
|
isHorizontal ? bindableCenter[0] : resolved[0],
|
|
9081
9284
|
!isHorizontal ? bindableCenter[1] : resolved[1]
|
|
@@ -9090,12 +9293,13 @@ var bindPointToSnapToElementOutline = (arrowElement, bindableElement, startOrEnd
|
|
|
9090
9293
|
otherPoint
|
|
9091
9294
|
)
|
|
9092
9295
|
);
|
|
9296
|
+
const byDistanceToResolved = (a2, b2) => pointDistanceSq(a2, resolved) - pointDistanceSq(b2, resolved);
|
|
9093
9297
|
intersection = intersectElementWithLineSegment(
|
|
9094
9298
|
bindableElement,
|
|
9095
9299
|
elementsMap,
|
|
9096
9300
|
intersector,
|
|
9097
9301
|
bindingGap
|
|
9098
|
-
).sort(
|
|
9302
|
+
).sort(byDistanceToResolved)[0];
|
|
9099
9303
|
if (!intersection) {
|
|
9100
9304
|
const anotherPoint = pointFrom8(
|
|
9101
9305
|
!isHorizontal ? bindableCenter[0] : resolved[0],
|
|
@@ -9115,8 +9319,8 @@ var bindPointToSnapToElementOutline = (arrowElement, bindableElement, startOrEnd
|
|
|
9115
9319
|
bindableElement,
|
|
9116
9320
|
elementsMap,
|
|
9117
9321
|
anotherIntersector,
|
|
9118
|
-
|
|
9119
|
-
).sort(
|
|
9322
|
+
BASE_BINDING_GAP
|
|
9323
|
+
).sort(byDistanceToResolved)[0];
|
|
9120
9324
|
}
|
|
9121
9325
|
} else {
|
|
9122
9326
|
let intersector = customIntersector;
|
|
@@ -9152,7 +9356,7 @@ var avoidRectangularCorner = (arrowElement, bindTarget, elementsMap, p) => {
|
|
|
9152
9356
|
center,
|
|
9153
9357
|
-bindTarget.angle
|
|
9154
9358
|
);
|
|
9155
|
-
const bindingGap = getBindingGap(bindTarget
|
|
9359
|
+
const bindingGap = getBindingGap(bindTarget);
|
|
9156
9360
|
if (nonRotatedPoint[0] < bindTarget.x && nonRotatedPoint[1] < bindTarget.y) {
|
|
9157
9361
|
if (nonRotatedPoint[1] - bindTarget.y > -bindingGap) {
|
|
9158
9362
|
return pointRotateRads8(
|
|
@@ -9214,73 +9418,6 @@ var avoidRectangularCorner = (arrowElement, bindTarget, elementsMap, p) => {
|
|
|
9214
9418
|
}
|
|
9215
9419
|
return p;
|
|
9216
9420
|
};
|
|
9217
|
-
var snapToMid = (bindTarget, elementsMap, p, tolerance = 0.05, arrowElement) => {
|
|
9218
|
-
const { x, y, width, height, angle: angle2 } = bindTarget;
|
|
9219
|
-
const center = elementCenterPoint(bindTarget, elementsMap, -0.1, -0.1);
|
|
9220
|
-
const nonRotated = pointRotateRads8(p, center, -angle2);
|
|
9221
|
-
const bindingGap = arrowElement ? getBindingGap(bindTarget, arrowElement) : 0;
|
|
9222
|
-
const verticalThreshold = clamp5(tolerance * height, 5, 80);
|
|
9223
|
-
const horizontalThreshold = clamp5(tolerance * width, 5, 80);
|
|
9224
|
-
if (pointDistance4(center, nonRotated) < bindingGap) {
|
|
9225
|
-
return void 0;
|
|
9226
|
-
}
|
|
9227
|
-
if (nonRotated[0] <= x + width / 2 && nonRotated[1] > center[1] - verticalThreshold && nonRotated[1] < center[1] + verticalThreshold) {
|
|
9228
|
-
return pointRotateRads8(
|
|
9229
|
-
pointFrom8(x - bindingGap, center[1]),
|
|
9230
|
-
center,
|
|
9231
|
-
angle2
|
|
9232
|
-
);
|
|
9233
|
-
} else if (nonRotated[1] <= y + height / 2 && nonRotated[0] > center[0] - horizontalThreshold && nonRotated[0] < center[0] + horizontalThreshold) {
|
|
9234
|
-
return pointRotateRads8(
|
|
9235
|
-
pointFrom8(center[0], y - bindingGap),
|
|
9236
|
-
center,
|
|
9237
|
-
angle2
|
|
9238
|
-
);
|
|
9239
|
-
} else if (nonRotated[0] >= x + width / 2 && nonRotated[1] > center[1] - verticalThreshold && nonRotated[1] < center[1] + verticalThreshold) {
|
|
9240
|
-
return pointRotateRads8(
|
|
9241
|
-
pointFrom8(x + width + bindingGap, center[1]),
|
|
9242
|
-
center,
|
|
9243
|
-
angle2
|
|
9244
|
-
);
|
|
9245
|
-
} else if (nonRotated[1] >= y + height / 2 && nonRotated[0] > center[0] - horizontalThreshold && nonRotated[0] < center[0] + horizontalThreshold) {
|
|
9246
|
-
return pointRotateRads8(
|
|
9247
|
-
pointFrom8(center[0], y + height + bindingGap),
|
|
9248
|
-
center,
|
|
9249
|
-
angle2
|
|
9250
|
-
);
|
|
9251
|
-
} else if (bindTarget.type === "diamond") {
|
|
9252
|
-
const distance3 = bindingGap;
|
|
9253
|
-
const topLeft = pointFrom8(
|
|
9254
|
-
x + width / 4 - distance3,
|
|
9255
|
-
y + height / 4 - distance3
|
|
9256
|
-
);
|
|
9257
|
-
const topRight = pointFrom8(
|
|
9258
|
-
x + 3 * width / 4 + distance3,
|
|
9259
|
-
y + height / 4 - distance3
|
|
9260
|
-
);
|
|
9261
|
-
const bottomLeft = pointFrom8(
|
|
9262
|
-
x + width / 4 - distance3,
|
|
9263
|
-
y + 3 * height / 4 + distance3
|
|
9264
|
-
);
|
|
9265
|
-
const bottomRight = pointFrom8(
|
|
9266
|
-
x + 3 * width / 4 + distance3,
|
|
9267
|
-
y + 3 * height / 4 + distance3
|
|
9268
|
-
);
|
|
9269
|
-
if (pointDistance4(topLeft, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {
|
|
9270
|
-
return pointRotateRads8(topLeft, center, angle2);
|
|
9271
|
-
}
|
|
9272
|
-
if (pointDistance4(topRight, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {
|
|
9273
|
-
return pointRotateRads8(topRight, center, angle2);
|
|
9274
|
-
}
|
|
9275
|
-
if (pointDistance4(bottomLeft, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {
|
|
9276
|
-
return pointRotateRads8(bottomLeft, center, angle2);
|
|
9277
|
-
}
|
|
9278
|
-
if (pointDistance4(bottomRight, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {
|
|
9279
|
-
return pointRotateRads8(bottomRight, center, angle2);
|
|
9280
|
-
}
|
|
9281
|
-
}
|
|
9282
|
-
return void 0;
|
|
9283
|
-
};
|
|
9284
9421
|
var extractBinding = (arrow, startOrEnd, elementsMap) => {
|
|
9285
9422
|
const binding = arrow[startOrEnd];
|
|
9286
9423
|
if (!binding) {
|
|
@@ -9313,7 +9450,7 @@ var snapBoundPointToGrid = (outlinePoint, bindableElement, elementsMap, gridSize
|
|
|
9313
9450
|
}
|
|
9314
9451
|
const aabb = aabbForElement(bindableElement, elementsMap);
|
|
9315
9452
|
const heading = adjacentPoint && (bindableElement.type === "ellipse" || bindableElement.type === "diamond") ? vectorToHeading(vectorFromPoint7(adjacentPoint, outlinePoint)) : headingForPointFromElement(bindableElement, aabb, outlinePoint);
|
|
9316
|
-
const bindingGap = getBindingGap(bindableElement
|
|
9453
|
+
const bindingGap = getBindingGap(bindableElement);
|
|
9317
9454
|
const extent = Math.max(bindableElement.width, bindableElement.height) + bindingGap * 2;
|
|
9318
9455
|
const center = getCenterForBounds(aabb);
|
|
9319
9456
|
const absNX = Math.abs(heading[0]);
|
|
@@ -9393,7 +9530,7 @@ var updateBoundPoint = (arrow, startOrEnd, binding, bindableElement, elementsMap
|
|
|
9393
9530
|
otherBindable,
|
|
9394
9531
|
elementsMap,
|
|
9395
9532
|
intersector,
|
|
9396
|
-
getBindingGap(otherBindable
|
|
9533
|
+
getBindingGap(otherBindable)
|
|
9397
9534
|
).sort(
|
|
9398
9535
|
(a2, b2) => pointDistanceSq(a2, focusPoint) - pointDistanceSq(b2, focusPoint)
|
|
9399
9536
|
)[0];
|
|
@@ -9401,7 +9538,7 @@ var updateBoundPoint = (arrow, startOrEnd, binding, bindableElement, elementsMap
|
|
|
9401
9538
|
bindableElement,
|
|
9402
9539
|
elementsMap,
|
|
9403
9540
|
intersector,
|
|
9404
|
-
getBindingGap(bindableElement
|
|
9541
|
+
getBindingGap(bindableElement)
|
|
9405
9542
|
).sort(
|
|
9406
9543
|
(a2, b2) => pointDistanceSq(a2, otherFocusPointOrArrowPoint) - pointDistanceSq(b2, otherFocusPointOrArrowPoint)
|
|
9407
9544
|
)[0];
|
|
@@ -9413,7 +9550,7 @@ var updateBoundPoint = (arrow, startOrEnd, binding, bindableElement, elementsMap
|
|
|
9413
9550
|
element: otherBindable,
|
|
9414
9551
|
point: outlinePoint,
|
|
9415
9552
|
elementsMap,
|
|
9416
|
-
threshold: getBindingGap(otherBindable
|
|
9553
|
+
threshold: getBindingGap(otherBindable),
|
|
9417
9554
|
overrideShouldTestInside: true
|
|
9418
9555
|
})) {
|
|
9419
9556
|
return LinearElementEditor.createPointAt(
|
|
@@ -9452,7 +9589,7 @@ var updateBoundPoint = (arrow, startOrEnd, binding, bindableElement, elementsMap
|
|
|
9452
9589
|
null
|
|
9453
9590
|
);
|
|
9454
9591
|
};
|
|
9455
|
-
var calculateFixedPointForElbowArrowBinding = (linearElement, hoveredElement, startOrEnd, elementsMap, shouldSnapToOutline = true, isMidpointSnappingEnabled = true) => {
|
|
9592
|
+
var calculateFixedPointForElbowArrowBinding = (linearElement, hoveredElement, startOrEnd, elementsMap, zoom, shouldSnapToOutline = true, isMidpointSnappingEnabled = true) => {
|
|
9456
9593
|
const bounds = [
|
|
9457
9594
|
hoveredElement.x,
|
|
9458
9595
|
hoveredElement.y,
|
|
@@ -9464,6 +9601,7 @@ var calculateFixedPointForElbowArrowBinding = (linearElement, hoveredElement, st
|
|
|
9464
9601
|
hoveredElement,
|
|
9465
9602
|
startOrEnd,
|
|
9466
9603
|
elementsMap,
|
|
9604
|
+
zoom,
|
|
9467
9605
|
void 0,
|
|
9468
9606
|
isMidpointSnappingEnabled
|
|
9469
9607
|
) : LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
|
@@ -9483,7 +9621,7 @@ var calculateFixedPointForElbowArrowBinding = (linearElement, hoveredElement, st
|
|
|
9483
9621
|
if (hoveredElement.width < MIN_BINDABLE_SIZE || hoveredElement.height < MIN_BINDABLE_SIZE) {
|
|
9484
9622
|
return { fixedPoint: normalizeFixedPoint([0.5, 0.5]) };
|
|
9485
9623
|
}
|
|
9486
|
-
const sizeFloor = getBindingGap(hoveredElement
|
|
9624
|
+
const sizeFloor = getBindingGap(hoveredElement);
|
|
9487
9625
|
return {
|
|
9488
9626
|
fixedPoint: normalizeFixedPoint([
|
|
9489
9627
|
(nonRotatedSnappedGlobalPoint[0] - hoveredElement.x) / Math.max(hoveredElement.width, sizeFloor),
|
|
@@ -9506,7 +9644,7 @@ var calculateFixedPointForNonElbowArrowBinding = (linearElement, hoveredElement,
|
|
|
9506
9644
|
if (hoveredElement.width < MIN_BINDABLE_SIZE || hoveredElement.height < MIN_BINDABLE_SIZE) {
|
|
9507
9645
|
return { fixedPoint: normalizeFixedPoint([0.5, 0.5]) };
|
|
9508
9646
|
}
|
|
9509
|
-
const sizeFloor = getBindingGap(hoveredElement
|
|
9647
|
+
const sizeFloor = getBindingGap(hoveredElement);
|
|
9510
9648
|
const fixedPointX = (nonRotatedPoint[0] - hoveredElement.x) / Math.max(hoveredElement.width, sizeFloor);
|
|
9511
9649
|
const fixedPointY = (nonRotatedPoint[1] - hoveredElement.y) / Math.max(hoveredElement.height, sizeFloor);
|
|
9512
9650
|
return {
|
|
@@ -9840,7 +9978,7 @@ var normalizeFixedPoint = (fixedPoint) => {
|
|
|
9840
9978
|
}
|
|
9841
9979
|
const EPSILON = 1e-4;
|
|
9842
9980
|
const clamped = fixedPoint.map(
|
|
9843
|
-
(ratio) =>
|
|
9981
|
+
(ratio) => clamp6(ratio, -FIXED_POINT_BOUND, FIXED_POINT_BOUND)
|
|
9844
9982
|
);
|
|
9845
9983
|
if (Math.abs(clamped[0] - 0.5) < EPSILON || Math.abs(clamped[1] - 0.5) < EPSILON) {
|
|
9846
9984
|
return clamped.map(
|
|
@@ -10373,7 +10511,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
10373
10511
|
deltaY = newDraggingPointPosition[1] - point[1];
|
|
10374
10512
|
}
|
|
10375
10513
|
let suggestedBinding = null;
|
|
10376
|
-
const { positions, updates } = pointDraggingUpdates(
|
|
10514
|
+
const { positions, updates, hit } = pointDraggingUpdates(
|
|
10377
10515
|
[idx],
|
|
10378
10516
|
deltaX,
|
|
10379
10517
|
deltaY,
|
|
@@ -10408,17 +10546,20 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
10408
10546
|
}
|
|
10409
10547
|
}
|
|
10410
10548
|
if (isBindingElement(element)) {
|
|
10411
|
-
|
|
10412
|
-
|
|
10549
|
+
if (hit) {
|
|
10550
|
+
moveArrowAboveBindable(
|
|
10551
|
+
_LinearElementEditor.getPointGlobalCoordinates(
|
|
10552
|
+
element,
|
|
10553
|
+
element.points[element.points.length - 1],
|
|
10554
|
+
elementsMap
|
|
10555
|
+
),
|
|
10413
10556
|
element,
|
|
10414
|
-
|
|
10415
|
-
elementsMap
|
|
10416
|
-
|
|
10417
|
-
|
|
10418
|
-
|
|
10419
|
-
|
|
10420
|
-
app.scene
|
|
10421
|
-
);
|
|
10557
|
+
elements,
|
|
10558
|
+
elementsMap,
|
|
10559
|
+
app.scene,
|
|
10560
|
+
hit
|
|
10561
|
+
);
|
|
10562
|
+
}
|
|
10422
10563
|
}
|
|
10423
10564
|
if (app.state.selectedLinearElement?.customLineAngle === customLineAngle && linearElementEditor.initialState.altFocusPoint && (!suggestedBinding || isShallowEqual(app.state.suggestedBinding ?? [], suggestedBinding))) {
|
|
10424
10565
|
return null;
|
|
@@ -10517,7 +10658,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
10517
10658
|
deltaY = newDraggingPointPosition[1] - draggingPoint[1];
|
|
10518
10659
|
}
|
|
10519
10660
|
let suggestedBinding = null;
|
|
10520
|
-
const { positions, updates } = pointDraggingUpdates(
|
|
10661
|
+
const { positions, updates, hit } = pointDraggingUpdates(
|
|
10521
10662
|
selectedPointsIndices,
|
|
10522
10663
|
deltaX,
|
|
10523
10664
|
deltaY,
|
|
@@ -10552,17 +10693,20 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
10552
10693
|
}
|
|
10553
10694
|
}
|
|
10554
10695
|
if (isBindingElement(element) && startIsSelected !== endIsSelected) {
|
|
10555
|
-
|
|
10556
|
-
|
|
10696
|
+
if (hit) {
|
|
10697
|
+
moveArrowAboveBindable(
|
|
10698
|
+
_LinearElementEditor.getPointGlobalCoordinates(
|
|
10699
|
+
element,
|
|
10700
|
+
startIsSelected ? element.points[0] : element.points[element.points.length - 1],
|
|
10701
|
+
elementsMap
|
|
10702
|
+
),
|
|
10557
10703
|
element,
|
|
10558
|
-
|
|
10559
|
-
elementsMap
|
|
10560
|
-
|
|
10561
|
-
|
|
10562
|
-
|
|
10563
|
-
|
|
10564
|
-
app.scene
|
|
10565
|
-
);
|
|
10704
|
+
elements,
|
|
10705
|
+
elementsMap,
|
|
10706
|
+
app.scene,
|
|
10707
|
+
hit
|
|
10708
|
+
);
|
|
10709
|
+
}
|
|
10566
10710
|
}
|
|
10567
10711
|
const boundTextElement = getBoundTextElement(element, elementsMap);
|
|
10568
10712
|
if (boundTextElement) {
|
|
@@ -11511,7 +11655,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
11511
11655
|
bestParameter,
|
|
11512
11656
|
lengths[bestSegmentIndex]
|
|
11513
11657
|
);
|
|
11514
|
-
const labelPosition =
|
|
11658
|
+
const labelPosition = clamp7(
|
|
11515
11659
|
(prefixSums[bestSegmentIndex] + lengthWithinSegment) / totalLength,
|
|
11516
11660
|
0,
|
|
11517
11661
|
1
|
|
@@ -11542,12 +11686,12 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
11542
11686
|
if (segments.length === 0) {
|
|
11543
11687
|
return null;
|
|
11544
11688
|
}
|
|
11545
|
-
const targetLength =
|
|
11689
|
+
const targetLength = clamp7(pathParameter, 0, 1) * totalLength;
|
|
11546
11690
|
const found = segments.findIndex(
|
|
11547
11691
|
(_, i2) => targetLength <= prefixSums[i2 + 1]
|
|
11548
11692
|
);
|
|
11549
11693
|
const i = found === -1 ? segments.length - 1 : found;
|
|
11550
|
-
const lengthFraction = lengths[i] === 0 ? 0 :
|
|
11694
|
+
const lengthFraction = lengths[i] === 0 ? 0 : clamp7((targetLength - prefixSums[i]) / lengths[i], 0, 1);
|
|
11551
11695
|
return pathSegmentPointAtLength(segments[i], lengthFraction, lengths[i]);
|
|
11552
11696
|
}
|
|
11553
11697
|
static getBoundTextElementPosition = (element, boundTextElement, elementsMap) => {
|
|
@@ -11815,16 +11959,19 @@ var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, scenePointerX
|
|
|
11815
11959
|
updates: {
|
|
11816
11960
|
suggestedBinding: suggestedBindingElement ? {
|
|
11817
11961
|
element: suggestedBindingElement,
|
|
11818
|
-
midPoint: app.state.isMidpointSnappingEnabled ?
|
|
11819
|
-
suggestedBindingElement,
|
|
11820
|
-
elementsMap,
|
|
11962
|
+
midPoint: app.state.isMidpointSnappingEnabled ? getSnapOutlineMidPoint2(
|
|
11821
11963
|
pointFrom9(
|
|
11822
11964
|
scenePointerX - linearElementEditor.pointerOffset.x,
|
|
11823
11965
|
scenePointerY - linearElementEditor.pointerOffset.y
|
|
11824
|
-
)
|
|
11966
|
+
),
|
|
11967
|
+
suggestedBindingElement,
|
|
11968
|
+
elementsMap,
|
|
11969
|
+
app.state.zoom,
|
|
11970
|
+
element
|
|
11825
11971
|
) : void 0
|
|
11826
11972
|
} : null
|
|
11827
|
-
}
|
|
11973
|
+
},
|
|
11974
|
+
hit: suggestedBindingElement
|
|
11828
11975
|
};
|
|
11829
11976
|
}
|
|
11830
11977
|
if (!startIsDragged && !endIsDragged) {
|
|
@@ -11904,7 +12051,8 @@ var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, scenePointerX
|
|
|
11904
12051
|
),
|
|
11905
12052
|
start.element,
|
|
11906
12053
|
elementsMap,
|
|
11907
|
-
app.state.zoom
|
|
12054
|
+
app.state.zoom,
|
|
12055
|
+
element
|
|
11908
12056
|
)
|
|
11909
12057
|
} : null;
|
|
11910
12058
|
}
|
|
@@ -11935,7 +12083,8 @@ var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, scenePointerX
|
|
|
11935
12083
|
),
|
|
11936
12084
|
end.element,
|
|
11937
12085
|
elementsMap,
|
|
11938
|
-
app.state.zoom
|
|
12086
|
+
app.state.zoom,
|
|
12087
|
+
element
|
|
11939
12088
|
)
|
|
11940
12089
|
} : null;
|
|
11941
12090
|
}
|
|
@@ -12010,7 +12159,8 @@ var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, scenePointerX
|
|
|
12010
12159
|
} : naiveDraggingPoints.get(idx)
|
|
12011
12160
|
];
|
|
12012
12161
|
})
|
|
12013
|
-
)
|
|
12162
|
+
),
|
|
12163
|
+
hit: startIsDragged ? start.element : end.element
|
|
12014
12164
|
};
|
|
12015
12165
|
};
|
|
12016
12166
|
var determineCustomLinearAngle = (pivotPoint, draggedPoint) => Math.atan2(draggedPoint[1] - pivotPoint[1], draggedPoint[0] - pivotPoint[0]);
|
|
@@ -13318,12 +13468,44 @@ var getCanvasPadding = (element) => {
|
|
|
13318
13468
|
return 20;
|
|
13319
13469
|
}
|
|
13320
13470
|
};
|
|
13321
|
-
var
|
|
13322
|
-
|
|
13323
|
-
|
|
13471
|
+
var ZERO_RENDER_OFFSET = { x: 0, y: 0 };
|
|
13472
|
+
var getElementRenderOffset = (element, elementsMap, overrides) => {
|
|
13473
|
+
const container = isTextElement(element) ? getContainerElement(element, elementsMap) : null;
|
|
13474
|
+
return overrides?.get((container ?? element).id)?.offset;
|
|
13475
|
+
};
|
|
13476
|
+
var getRenderElementWithPositionOverride = (element, positionOffset) => {
|
|
13477
|
+
if (positionOffset.x === 0 && positionOffset.y === 0) {
|
|
13478
|
+
return element;
|
|
13479
|
+
}
|
|
13480
|
+
return {
|
|
13481
|
+
...element,
|
|
13482
|
+
x: element.x + positionOffset.x,
|
|
13483
|
+
y: element.y + positionOffset.y
|
|
13484
|
+
};
|
|
13485
|
+
};
|
|
13486
|
+
var resolveElementRenderState = (element, elementsMap, renderConfig, allElementsMap = elementsMap) => {
|
|
13487
|
+
const {
|
|
13488
|
+
elementRenderOverrides,
|
|
13489
|
+
elementsPendingErasure,
|
|
13490
|
+
pendingFlowchartNodes
|
|
13491
|
+
} = renderConfig;
|
|
13492
|
+
const override = elementRenderOverrides?.get(element.id);
|
|
13493
|
+
const containingFrame = getContainingFrame(element, elementsMap);
|
|
13494
|
+
const frameOpacity = containingFrame ? clamp8(
|
|
13495
|
+
elementRenderOverrides?.get(containingFrame.id)?.opacity ?? containingFrame.opacity,
|
|
13496
|
+
0,
|
|
13497
|
+
100
|
|
13498
|
+
) : 100;
|
|
13499
|
+
let opacity = frameOpacity * clamp8(override?.opacity ?? element.opacity, 0, 100) / 1e4;
|
|
13500
|
+
if (elementsPendingErasure.has(element.id) || pendingFlowchartNodes?.some((node) => node.id === element.id) || containingFrame && elementsPendingErasure.has(containingFrame.id)) {
|
|
13324
13501
|
opacity *= ELEMENT_READY_TO_ERASE_OPACITY / 100;
|
|
13325
13502
|
}
|
|
13326
|
-
|
|
13503
|
+
const offset = getElementRenderOffset(
|
|
13504
|
+
element,
|
|
13505
|
+
allElementsMap,
|
|
13506
|
+
elementRenderOverrides
|
|
13507
|
+
);
|
|
13508
|
+
return { opacity, offset: offset ?? ZERO_RENDER_OFFSET };
|
|
13327
13509
|
};
|
|
13328
13510
|
var cappedElementCanvasSize = (element, elementsMap, zoom) => {
|
|
13329
13511
|
const AREA_LIMIT = 16777216;
|
|
@@ -13648,9 +13830,7 @@ var drawElementOnCanvas = (element, rc, context, renderConfig) => {
|
|
|
13648
13830
|
};
|
|
13649
13831
|
var elementWithCanvasCache = /* @__PURE__ */ new WeakMap();
|
|
13650
13832
|
var generateElementWithCanvas = (element, elementsMap, renderConfig, appState) => {
|
|
13651
|
-
const zoom = renderConfig ? appState.zoom :
|
|
13652
|
-
value: 1
|
|
13653
|
-
};
|
|
13833
|
+
const zoom = renderConfig ? appState.zoom : DEFAULT_ZOOM2;
|
|
13654
13834
|
const prevElementWithCanvas = elementWithCanvasCache.get(element);
|
|
13655
13835
|
const shouldRegenerateBecauseZoom = prevElementWithCanvas && prevElementWithCanvas.zoomValue !== zoom.value && !appState?.shouldCacheIgnoreZoom;
|
|
13656
13836
|
const imageCrop = isImageElement(element) ? element.crop : null;
|
|
@@ -13673,13 +13853,13 @@ var generateElementWithCanvas = (element, elementsMap, renderConfig, appState) =
|
|
|
13673
13853
|
};
|
|
13674
13854
|
var canSnapElement = (element, appState) => !appState?.shouldCacheIgnoreZoom && (!element.angle || isRightAngleRads(element.angle));
|
|
13675
13855
|
var SNAP_TIE_BIAS = 1e-6;
|
|
13676
|
-
var drawElementFromCanvas = (elementWithCanvas, context, renderConfig, appState, allElementsMap) => {
|
|
13856
|
+
var drawElementFromCanvas = (elementWithCanvas, context, renderConfig, appState, allElementsMap, positionOffset) => {
|
|
13677
13857
|
const element = elementWithCanvas.element;
|
|
13678
13858
|
const devicePixelRatio = window.devicePixelRatio;
|
|
13679
13859
|
const padding = getCanvasPadding(element);
|
|
13680
13860
|
const [x1, y1, x2, y2] = getElementAbsoluteCoords2(element, allElementsMap);
|
|
13681
|
-
const cx = ((x1 + x2) / 2 + appState.scrollX) * devicePixelRatio;
|
|
13682
|
-
const cy = ((y1 + y2) / 2 + appState.scrollY) * devicePixelRatio;
|
|
13861
|
+
const cx = ((x1 + x2) / 2 + positionOffset.x + appState.scrollX) * devicePixelRatio;
|
|
13862
|
+
const cy = ((y1 + y2) / 2 + positionOffset.y + appState.scrollY) * devicePixelRatio;
|
|
13683
13863
|
context.save();
|
|
13684
13864
|
context.scale(1 / devicePixelRatio, 1 / devicePixelRatio);
|
|
13685
13865
|
const boundTextElement = getBoundTextElement(element, allElementsMap);
|
|
@@ -13692,8 +13872,8 @@ var drawElementFromCanvas = (elementWithCanvas, context, renderConfig, appState,
|
|
|
13692
13872
|
context.beginPath();
|
|
13693
13873
|
context.rect(cx - outerHalf, cy - outerHalf, outerHalf * 2, outerHalf * 2);
|
|
13694
13874
|
context.rect(
|
|
13695
|
-
(boundTextCx - boundTextElement.width / 2 - BOUND_TEXT_PADDING3 + appState.scrollX) * devicePixelRatio,
|
|
13696
|
-
(boundTextCy - boundTextElement.height / 2 - BOUND_TEXT_PADDING3 + appState.scrollY) * devicePixelRatio,
|
|
13875
|
+
(boundTextCx - boundTextElement.width / 2 - BOUND_TEXT_PADDING3 + positionOffset.x + appState.scrollX) * devicePixelRatio,
|
|
13876
|
+
(boundTextCy - boundTextElement.height / 2 - BOUND_TEXT_PADDING3 + positionOffset.y + appState.scrollY) * devicePixelRatio,
|
|
13697
13877
|
(boundTextElement.width + BOUND_TEXT_PADDING3 * 2) * devicePixelRatio,
|
|
13698
13878
|
(boundTextElement.height + BOUND_TEXT_PADDING3 * 2) * devicePixelRatio
|
|
13699
13879
|
);
|
|
@@ -13708,8 +13888,8 @@ var drawElementFromCanvas = (elementWithCanvas, context, renderConfig, appState,
|
|
|
13708
13888
|
);
|
|
13709
13889
|
}
|
|
13710
13890
|
context.translate(-cx, -cy);
|
|
13711
|
-
let drawX = (x1 + appState.scrollX) * devicePixelRatio - padding;
|
|
13712
|
-
let drawY = (y1 + appState.scrollY) * devicePixelRatio - padding;
|
|
13891
|
+
let drawX = (x1 + positionOffset.x + appState.scrollX) * devicePixelRatio - padding;
|
|
13892
|
+
let drawY = (y1 + positionOffset.y + appState.scrollY) * devicePixelRatio - padding;
|
|
13713
13893
|
const transform = context.getTransform();
|
|
13714
13894
|
if (canSnapElement(element, appState)) {
|
|
13715
13895
|
const { a: a2, b: b2, c, d, e, f } = transform;
|
|
@@ -13719,8 +13899,8 @@ var drawElementFromCanvas = (elementWithCanvas, context, renderConfig, appState,
|
|
|
13719
13899
|
const anchorSceneX = anchorCoords?.[0] ?? x1;
|
|
13720
13900
|
const anchorSceneY = anchorCoords?.[1] ?? y1;
|
|
13721
13901
|
const anchorPadding = anchor === element ? padding : getCanvasPadding(anchor);
|
|
13722
|
-
const anchorX = (anchorSceneX + appState.scrollX) * devicePixelRatio - anchorPadding;
|
|
13723
|
-
const anchorY = (anchorSceneY + appState.scrollY) * devicePixelRatio - anchorPadding;
|
|
13902
|
+
const anchorX = (anchorSceneX + positionOffset.x + appState.scrollX) * devicePixelRatio - anchorPadding;
|
|
13903
|
+
const anchorY = (anchorSceneY + positionOffset.y + appState.scrollY) * devicePixelRatio - anchorPadding;
|
|
13724
13904
|
const dx = (x1 - anchorSceneX) * devicePixelRatio + anchorPadding - padding;
|
|
13725
13905
|
const dy = (y1 - anchorSceneY) * devicePixelRatio + anchorPadding - padding;
|
|
13726
13906
|
context.setTransform(
|
|
@@ -13751,8 +13931,8 @@ var drawElementFromCanvas = (elementWithCanvas, context, renderConfig, appState,
|
|
|
13751
13931
|
context.strokeStyle = "#c92a2a";
|
|
13752
13932
|
context.lineWidth = 3;
|
|
13753
13933
|
context.strokeRect(
|
|
13754
|
-
(coords.x + appState.scrollX) * devicePixelRatio,
|
|
13755
|
-
(coords.y + appState.scrollY) * devicePixelRatio,
|
|
13934
|
+
(coords.x + positionOffset.x + appState.scrollX) * devicePixelRatio,
|
|
13935
|
+
(coords.y + positionOffset.y + appState.scrollY) * devicePixelRatio,
|
|
13756
13936
|
getBoundTextMaxWidth(element, textElement) * devicePixelRatio,
|
|
13757
13937
|
getBoundTextMaxHeight(element, textElement) * devicePixelRatio
|
|
13758
13938
|
);
|
|
@@ -13773,15 +13953,34 @@ var renderSelectionElement = (element, context, appState, selectionColor) => {
|
|
|
13773
13953
|
context.strokeRect(offset, offset, element.width, element.height);
|
|
13774
13954
|
context.restore();
|
|
13775
13955
|
};
|
|
13776
|
-
var renderElement = (element, elementsMap, allElementsMap, rc, context, renderConfig, appState
|
|
13956
|
+
var renderElement = (element, elementsMap, allElementsMap, rc, context, renderConfig, appState, renderState = resolveElementRenderState(
|
|
13957
|
+
element,
|
|
13958
|
+
elementsMap,
|
|
13959
|
+
renderConfig,
|
|
13960
|
+
allElementsMap
|
|
13961
|
+
)) => {
|
|
13777
13962
|
const reduceAlphaForSelection = appState.openDialog?.name === "elementLinkSelector" && !appState.selectedElementIds[element.id] && !appState.hoveredElementIds[element.id];
|
|
13778
|
-
context.
|
|
13779
|
-
|
|
13780
|
-
|
|
13781
|
-
|
|
13782
|
-
|
|
13783
|
-
|
|
13784
|
-
|
|
13963
|
+
context.save();
|
|
13964
|
+
context.globalAlpha = renderState.opacity * (reduceAlphaForSelection ? DEFAULT_REDUCED_GLOBAL_ALPHA : 1);
|
|
13965
|
+
if ((renderConfig.isExporting || isFrameLikeElement(element)) && (renderState.offset.x || renderState.offset.y)) {
|
|
13966
|
+
context.translate(renderState.offset.x, renderState.offset.y);
|
|
13967
|
+
}
|
|
13968
|
+
try {
|
|
13969
|
+
drawElement(
|
|
13970
|
+
element,
|
|
13971
|
+
elementsMap,
|
|
13972
|
+
allElementsMap,
|
|
13973
|
+
rc,
|
|
13974
|
+
context,
|
|
13975
|
+
renderConfig,
|
|
13976
|
+
appState,
|
|
13977
|
+
renderState
|
|
13978
|
+
);
|
|
13979
|
+
} finally {
|
|
13980
|
+
context.restore();
|
|
13981
|
+
}
|
|
13982
|
+
};
|
|
13983
|
+
var drawElement = (element, elementsMap, allElementsMap, rc, context, renderConfig, appState, renderState) => {
|
|
13785
13984
|
switch (element.type) {
|
|
13786
13985
|
case "magicframe":
|
|
13787
13986
|
case "frame": {
|
|
@@ -13846,7 +14045,8 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
|
|
|
13846
14045
|
context,
|
|
13847
14046
|
renderConfig,
|
|
13848
14047
|
appState,
|
|
13849
|
-
allElementsMap
|
|
14048
|
+
allElementsMap,
|
|
14049
|
+
renderState.offset
|
|
13850
14050
|
);
|
|
13851
14051
|
}
|
|
13852
14052
|
break;
|
|
@@ -13947,7 +14147,9 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
|
|
|
13947
14147
|
context,
|
|
13948
14148
|
renderConfig,
|
|
13949
14149
|
appState,
|
|
13950
|
-
allElementsMap
|
|
14150
|
+
allElementsMap,
|
|
14151
|
+
// The crop editor's uncropped preview stays at document coordinates.
|
|
14152
|
+
ZERO_RENDER_OFFSET
|
|
13951
14153
|
);
|
|
13952
14154
|
}
|
|
13953
14155
|
context.restore();
|
|
@@ -13957,7 +14159,8 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
|
|
|
13957
14159
|
context,
|
|
13958
14160
|
renderConfig,
|
|
13959
14161
|
appState,
|
|
13960
|
-
allElementsMap
|
|
14162
|
+
allElementsMap,
|
|
14163
|
+
renderState.offset
|
|
13961
14164
|
);
|
|
13962
14165
|
context.imageSmoothingEnabled = currentImageSmoothingStatus;
|
|
13963
14166
|
}
|
|
@@ -13967,7 +14170,6 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
|
|
|
13967
14170
|
throw new Error(`Unimplemented type ${element.type}`);
|
|
13968
14171
|
}
|
|
13969
14172
|
}
|
|
13970
|
-
context.globalAlpha = 1;
|
|
13971
14173
|
};
|
|
13972
14174
|
function getFreedrawOutlineAsSegments(element, points, elementsMap) {
|
|
13973
14175
|
const bounds = getElementBounds(
|
|
@@ -14373,6 +14575,29 @@ var getArrowheadShapes = (element, shape, position, arrowhead, generator, option
|
|
|
14373
14575
|
}
|
|
14374
14576
|
}
|
|
14375
14577
|
};
|
|
14578
|
+
var getFreedrawFillCurvePoints = (element) => simplify(element.points, 0.75);
|
|
14579
|
+
var freedrawFillPolygonCache = /* @__PURE__ */ new WeakMap();
|
|
14580
|
+
var getFreedrawFillPolygon = (element) => {
|
|
14581
|
+
const cached = freedrawFillPolygonCache.get(element);
|
|
14582
|
+
if (cached?.version === element.version) {
|
|
14583
|
+
return cached.polygon;
|
|
14584
|
+
}
|
|
14585
|
+
const ops = new RoughGenerator().curve(getFreedrawFillCurvePoints(element), {
|
|
14586
|
+
roughness: 0,
|
|
14587
|
+
disableMultiStroke: true
|
|
14588
|
+
}).sets[0].ops;
|
|
14589
|
+
const bezierPoints = [];
|
|
14590
|
+
for (const { data } of ops) {
|
|
14591
|
+
for (let i = 0; i < data.length; i += 2) {
|
|
14592
|
+
bezierPoints.push(pointFrom12(data[i], data[i + 1]));
|
|
14593
|
+
}
|
|
14594
|
+
}
|
|
14595
|
+
const polygon3 = polygonFromPoints2(
|
|
14596
|
+
pointsOnBezierCurves(bezierPoints, 0.5)
|
|
14597
|
+
);
|
|
14598
|
+
freedrawFillPolygonCache.set(element, { version: element.version, polygon: polygon3 });
|
|
14599
|
+
return polygon3;
|
|
14600
|
+
};
|
|
14376
14601
|
var generateLinearCollisionShape = (element, elementsMap) => {
|
|
14377
14602
|
const generator = new RoughGenerator();
|
|
14378
14603
|
const options = {
|
|
@@ -14451,58 +14676,29 @@ var generateLinearCollisionShape = (element, elementsMap) => {
|
|
|
14451
14676
|
});
|
|
14452
14677
|
}
|
|
14453
14678
|
case "freedraw": {
|
|
14454
|
-
|
|
14679
|
+
const outlinePoints = getFreedrawOutlinePoints(element);
|
|
14680
|
+
if (outlinePoints.length < 2) {
|
|
14455
14681
|
return [];
|
|
14456
14682
|
}
|
|
14457
|
-
const
|
|
14458
|
-
|
|
14459
|
-
|
|
14460
|
-
);
|
|
14461
|
-
|
|
14462
|
-
|
|
14463
|
-
|
|
14464
|
-
|
|
14465
|
-
|
|
14466
|
-
|
|
14467
|
-
|
|
14468
|
-
|
|
14469
|
-
|
|
14470
|
-
|
|
14471
|
-
|
|
14472
|
-
|
|
14473
|
-
data: pointFrom12(p[0] - element.x, p[1] - element.y)
|
|
14474
|
-
};
|
|
14475
|
-
}
|
|
14683
|
+
const collisionOutline = element.strokeOptions?.variability === "constant" ? simplify(
|
|
14684
|
+
outlinePoints,
|
|
14685
|
+
CONSTANT_WIDTH_FREEDRAW.COLLISION_SIMPLIFY_TOLERANCE
|
|
14686
|
+
) : outlinePoints;
|
|
14687
|
+
if (collisionOutline.length < 2) {
|
|
14688
|
+
return [];
|
|
14689
|
+
}
|
|
14690
|
+
const [firstX, firstY] = collisionOutline[0];
|
|
14691
|
+
const [lastX, lastY] = collisionOutline[collisionOutline.length - 1];
|
|
14692
|
+
const closedOutline = firstX === lastX && firstY === lastY ? collisionOutline : [...collisionOutline, collisionOutline[0]];
|
|
14693
|
+
return closedOutline.map((point, idx) => {
|
|
14694
|
+
const p = pointRotateRads11(
|
|
14695
|
+
pointFrom12(element.x + point[0], element.y + point[1]),
|
|
14696
|
+
center,
|
|
14697
|
+
element.angle
|
|
14698
|
+
);
|
|
14476
14699
|
return {
|
|
14477
|
-
op: "
|
|
14478
|
-
data: [
|
|
14479
|
-
pointRotateRads11(
|
|
14480
|
-
pointFrom12(
|
|
14481
|
-
element.x + op.data[0],
|
|
14482
|
-
element.y + op.data[1]
|
|
14483
|
-
),
|
|
14484
|
-
center,
|
|
14485
|
-
element.angle
|
|
14486
|
-
),
|
|
14487
|
-
pointRotateRads11(
|
|
14488
|
-
pointFrom12(
|
|
14489
|
-
element.x + op.data[2],
|
|
14490
|
-
element.y + op.data[3]
|
|
14491
|
-
),
|
|
14492
|
-
center,
|
|
14493
|
-
element.angle
|
|
14494
|
-
),
|
|
14495
|
-
pointRotateRads11(
|
|
14496
|
-
pointFrom12(
|
|
14497
|
-
element.x + op.data[4],
|
|
14498
|
-
element.y + op.data[5]
|
|
14499
|
-
),
|
|
14500
|
-
center,
|
|
14501
|
-
element.angle
|
|
14502
|
-
)
|
|
14503
|
-
].map(
|
|
14504
|
-
(p) => pointFrom12(p[0] - element.x, p[1] - element.y)
|
|
14505
|
-
).flat()
|
|
14700
|
+
op: idx === 0 ? "move" : "lineTo",
|
|
14701
|
+
data: pointFrom12(p[0] - element.x, p[1] - element.y)
|
|
14506
14702
|
};
|
|
14507
14703
|
});
|
|
14508
14704
|
}
|
|
@@ -14670,12 +14866,8 @@ var _generateElementShape = (element, generator, {
|
|
|
14670
14866
|
case "freedraw": {
|
|
14671
14867
|
const shapes = [];
|
|
14672
14868
|
if (isPathALoop(element.points)) {
|
|
14673
|
-
const simplifiedPoints = simplify(
|
|
14674
|
-
element.points,
|
|
14675
|
-
0.75
|
|
14676
|
-
);
|
|
14677
14869
|
shapes.push(
|
|
14678
|
-
generator.curve(
|
|
14870
|
+
generator.curve(getFreedrawFillCurvePoints(element), {
|
|
14679
14871
|
...generateRoughOptions(element, false, isDarkMode),
|
|
14680
14872
|
stroke: "none"
|
|
14681
14873
|
})
|
|
@@ -14830,7 +15022,12 @@ var VARIABLE_WIDTH_FREEDRAW = {
|
|
|
14830
15022
|
};
|
|
14831
15023
|
var CONSTANT_WIDTH_FREEDRAW = {
|
|
14832
15024
|
/** Stroke size relative to `strokeWidth` for uniform (laser) strokes. */
|
|
14833
|
-
SIZE_FACTOR: 1.4
|
|
15025
|
+
SIZE_FACTOR: 1.4,
|
|
15026
|
+
/**
|
|
15027
|
+
* Max deviation (px) when dropping vertices of the dense laser outline for
|
|
15028
|
+
* collision. Perfect-freehand outlines are already thinned by `smoothing`.
|
|
15029
|
+
*/
|
|
15030
|
+
COLLISION_SIMPLIFY_TOLERANCE: 0.2
|
|
14834
15031
|
};
|
|
14835
15032
|
var getFreedrawStreamline = (element) => element.strokeOptions?.streamline ?? DEFAULT_STROKE_STREAMLINE;
|
|
14836
15033
|
var getVariableWidthFreedrawOutline = (element) => {
|
|
@@ -14862,6 +15059,7 @@ var getConstantWidthFreedrawOutline = (element) => {
|
|
|
14862
15059
|
var getFreedrawOutlinePoints = (element) => {
|
|
14863
15060
|
return element.strokeOptions?.variability === "constant" ? getConstantWidthFreedrawOutline(element) : getVariableWidthFreedrawOutline(element);
|
|
14864
15061
|
};
|
|
15062
|
+
var getFreedrawMaxStrokeRadius = (element) => element.strokeOptions?.variability === "constant" ? element.strokeWidth * CONSTANT_WIDTH_FREEDRAW.SIZE_FACTOR : element.strokeWidth * VARIABLE_WIDTH_FREEDRAW.SIZE_FACTOR + 3;
|
|
14865
15063
|
var getFreedrawStrokeCenterPoints = (element) => me(element.points, {
|
|
14866
15064
|
size: element.strokeWidth * VARIABLE_WIDTH_FREEDRAW.SIZE_FACTOR,
|
|
14867
15065
|
streamline: getFreedrawStreamline(element),
|
|
@@ -16313,13 +16511,15 @@ var newTextElement = (opts) => {
|
|
|
16313
16511
|
);
|
|
16314
16512
|
return textElement;
|
|
16315
16513
|
};
|
|
16316
|
-
var getAdjustedDimensions = (element, elementsMap, nextText) => {
|
|
16514
|
+
var getAdjustedDimensions = (element, elementsMap, nextText, nextFixedWidth) => {
|
|
16317
16515
|
let { width: nextWidth, height: nextHeight } = measureText(
|
|
16318
16516
|
nextText,
|
|
16319
16517
|
getFontString5(element),
|
|
16320
16518
|
element.lineHeight
|
|
16321
16519
|
);
|
|
16322
|
-
if (
|
|
16520
|
+
if (nextFixedWidth !== void 0) {
|
|
16521
|
+
nextWidth = nextFixedWidth;
|
|
16522
|
+
} else if (!element.autoResize) {
|
|
16323
16523
|
nextWidth = element.width;
|
|
16324
16524
|
}
|
|
16325
16525
|
const { textAlign, verticalAlign } = element;
|
|
@@ -16403,10 +16603,26 @@ var adjustXYWithRotation = (sides, x, y, angle2, deltaX1, deltaY1, deltaX2, delt
|
|
|
16403
16603
|
}
|
|
16404
16604
|
return [x, y];
|
|
16405
16605
|
};
|
|
16406
|
-
var refreshTextDimensions = (textElement, container, elementsMap, text = textElement.text) => {
|
|
16606
|
+
var refreshTextDimensions = (textElement, container, elementsMap, text = textElement.text, maxWidth) => {
|
|
16407
16607
|
if (textElement.isDeleted) {
|
|
16408
16608
|
return;
|
|
16409
16609
|
}
|
|
16610
|
+
if (maxWidth !== void 0 && !container && textElement.autoResize && textElement.width <= maxWidth) {
|
|
16611
|
+
const font = getFontString5(textElement);
|
|
16612
|
+
if (measureText(text, font, textElement.lineHeight).width > maxWidth) {
|
|
16613
|
+
const wrappedText = wrapText(text, font, maxWidth);
|
|
16614
|
+
return {
|
|
16615
|
+
text: wrappedText,
|
|
16616
|
+
autoResize: false,
|
|
16617
|
+
...getAdjustedDimensions(
|
|
16618
|
+
textElement,
|
|
16619
|
+
elementsMap,
|
|
16620
|
+
wrappedText,
|
|
16621
|
+
maxWidth
|
|
16622
|
+
)
|
|
16623
|
+
};
|
|
16624
|
+
}
|
|
16625
|
+
}
|
|
16410
16626
|
if (container || !textElement.autoResize) {
|
|
16411
16627
|
text = wrapText(
|
|
16412
16628
|
text,
|
|
@@ -16530,7 +16746,7 @@ var getTextBindingForArrowEndpoint = (arrow, startOrEnd, elementsMap, targetStro
|
|
|
16530
16746
|
}
|
|
16531
16747
|
const direction = vectorFromPoint9(endpoint, neighbor);
|
|
16532
16748
|
const heading = Math.abs(direction[0]) >= Math.abs(direction[1]) ? direction[0] >= 0 ? HEADING_RIGHT : HEADING_LEFT : direction[1] >= 0 ? HEADING_DOWN : HEADING_UP;
|
|
16533
|
-
const gap = isElbowArrow(arrow) ? 0 : getBindingGap({ strokeWidth: targetStrokeWidth }
|
|
16749
|
+
const gap = isElbowArrow(arrow) ? 0 : getBindingGap({ strokeWidth: targetStrokeWidth });
|
|
16534
16750
|
const awayFromTip = vectorNormalize5(vectorFromPoint9(neighbor, endpoint));
|
|
16535
16751
|
const alongHeading = Math.abs(
|
|
16536
16752
|
vectorDot(awayFromTip, vector3(heading[0], heading[1]))
|
|
@@ -16595,8 +16811,8 @@ import {
|
|
|
16595
16811
|
pointFrom as pointFrom14,
|
|
16596
16812
|
pointRotateRads as pointRotateRads13,
|
|
16597
16813
|
polygonArea,
|
|
16598
|
-
polygonIncludesPoint,
|
|
16599
|
-
polygonIncludesPointNonZero,
|
|
16814
|
+
polygonIncludesPoint as polygonIncludesPoint2,
|
|
16815
|
+
polygonIncludesPointNonZero as polygonIncludesPointNonZero2,
|
|
16600
16816
|
polygonSignedArea
|
|
16601
16817
|
} from "@excalidraw/math";
|
|
16602
16818
|
import { isOpaqueColor, isTransparent as isTransparent5 } from "@excalidraw/common";
|
|
@@ -17267,7 +17483,7 @@ var selectFaceFromArrangement = (faces, point, options) => {
|
|
|
17267
17483
|
if (absArea < options.minArea) {
|
|
17268
17484
|
continue;
|
|
17269
17485
|
}
|
|
17270
|
-
if (!
|
|
17486
|
+
if (!polygonIncludesPointNonZero2(point, face.ring)) {
|
|
17271
17487
|
continue;
|
|
17272
17488
|
}
|
|
17273
17489
|
if (absArea < bestArea) {
|
|
@@ -17283,13 +17499,13 @@ var selectFaceFromArrangement = (faces, point, options) => {
|
|
|
17283
17499
|
(face) => face.componentId !== selected.componentId && // a component's outside contour shares the unbounded face's orientation
|
|
17284
17500
|
Math.sign(areaOf.get(face)) === outerSign && Math.abs(areaOf.get(face)) >= options.minArea && // the click face never sits inside one of its own holes (defensive —
|
|
17285
17501
|
// the smallest-containing-face selection above already guarantees it)
|
|
17286
|
-
!
|
|
17502
|
+
!polygonIncludesPointNonZero2(point, face.ring) && // components never intersect (crossings would have merged them), so a
|
|
17287
17503
|
// single-vertex test decides containment
|
|
17288
|
-
|
|
17504
|
+
polygonIncludesPointNonZero2(face.ring[0], selected.ring)
|
|
17289
17505
|
);
|
|
17290
17506
|
const holes = islandCandidates.filter(
|
|
17291
17507
|
(hole) => !islandCandidates.some(
|
|
17292
|
-
(other) => other !== hole &&
|
|
17508
|
+
(other) => other !== hole && polygonIncludesPointNonZero2(hole.ring[0], other.ring)
|
|
17293
17509
|
)
|
|
17294
17510
|
);
|
|
17295
17511
|
return { face: selected, holes };
|
|
@@ -17575,7 +17791,7 @@ var computeBucketFillPolygon = (args) => {
|
|
|
17575
17791
|
);
|
|
17576
17792
|
}
|
|
17577
17793
|
}
|
|
17578
|
-
return samples.some((sample) =>
|
|
17794
|
+
return samples.some((sample) => polygonIncludesPoint2(sample, fillRegion));
|
|
17579
17795
|
};
|
|
17580
17796
|
const paintOverlapsRegion = (element) => {
|
|
17581
17797
|
const [minX, minY, maxX, maxY] = getElementBounds(element, elementsMap);
|
|
@@ -17588,7 +17804,7 @@ var computeBucketFillPolygon = (args) => {
|
|
|
17588
17804
|
const outline = getElementLineSegments(element, elementsMap);
|
|
17589
17805
|
const outlineStep = Math.max(1, Math.floor(outline.length / 16));
|
|
17590
17806
|
for (let i = 0; i < outline.length; i += outlineStep) {
|
|
17591
|
-
if (
|
|
17807
|
+
if (polygonIncludesPoint2(outline[i][0], fillRegion)) {
|
|
17592
17808
|
return true;
|
|
17593
17809
|
}
|
|
17594
17810
|
}
|
|
@@ -17789,8 +18005,9 @@ var duplicateElements = (opts) => {
|
|
|
17789
18005
|
const duplicatedElements = [];
|
|
17790
18006
|
const origElements = [];
|
|
17791
18007
|
const origIdToDuplicateId = /* @__PURE__ */ new Map();
|
|
17792
|
-
const
|
|
18008
|
+
const duplicateIdToOrigId = /* @__PURE__ */ new Map();
|
|
17793
18009
|
const duplicateElementsMap = /* @__PURE__ */ new Map();
|
|
18010
|
+
const origElementsMap = /* @__PURE__ */ new Map();
|
|
17794
18011
|
const elementsMap = arrayToMap9(elements);
|
|
17795
18012
|
const _idsOfElementsToDuplicate = opts.type === "in-place" ? opts.idsOfElementsToDuplicate : new Map(elements.map((el) => [el.id, el]));
|
|
17796
18013
|
const preserveFrameChildrenOrder = opts.type === "everything" && opts.preserveFrameChildrenOrder;
|
|
@@ -17822,8 +18039,9 @@ var duplicateElements = (opts) => {
|
|
|
17822
18039
|
);
|
|
17823
18040
|
processedIds.set(newElement3.id, true);
|
|
17824
18041
|
duplicateElementsMap.set(newElement3.id, newElement3);
|
|
18042
|
+
origElementsMap.set(element2.id, element2);
|
|
17825
18043
|
origIdToDuplicateId.set(element2.id, newElement3.id);
|
|
17826
|
-
|
|
18044
|
+
duplicateIdToOrigId.set(newElement3.id, element2.id);
|
|
17827
18045
|
origElements.push(element2);
|
|
17828
18046
|
duplicatedElements.push(newElement3);
|
|
17829
18047
|
acc.push(newElement3);
|
|
@@ -17935,7 +18153,9 @@ var duplicateElements = (opts) => {
|
|
|
17935
18153
|
);
|
|
17936
18154
|
if (opts.overrides) {
|
|
17937
18155
|
for (const duplicateElement2 of duplicatedElements) {
|
|
17938
|
-
const origElement =
|
|
18156
|
+
const origElement = origElementsMap.get(
|
|
18157
|
+
duplicateIdToOrigId.get(duplicateElement2.id)
|
|
18158
|
+
);
|
|
17939
18159
|
if (origElement) {
|
|
17940
18160
|
Object.assign(
|
|
17941
18161
|
duplicateElement2,
|
|
@@ -17951,10 +18171,82 @@ var duplicateElements = (opts) => {
|
|
|
17951
18171
|
return {
|
|
17952
18172
|
duplicatedElements,
|
|
17953
18173
|
duplicateElementsMap,
|
|
18174
|
+
origElementsMap,
|
|
17954
18175
|
elementsWithDuplicates,
|
|
17955
|
-
origIdToDuplicateId
|
|
18176
|
+
origIdToDuplicateId,
|
|
18177
|
+
duplicateIdToOrigId
|
|
17956
18178
|
};
|
|
17957
18179
|
};
|
|
18180
|
+
var reconcileDuplicatedElements = (hostElements, nextElements, duplicatedElements) => {
|
|
18181
|
+
if (hostElements === false) {
|
|
18182
|
+
return { elements: nextElements, duplicatedElements: [] };
|
|
18183
|
+
}
|
|
18184
|
+
if (!hostElements) {
|
|
18185
|
+
return { elements: nextElements, duplicatedElements };
|
|
18186
|
+
}
|
|
18187
|
+
const duplicatesMap = arrayToMap9(duplicatedElements);
|
|
18188
|
+
const hostDuplicates = /* @__PURE__ */ new Map();
|
|
18189
|
+
for (const element of hostElements) {
|
|
18190
|
+
if (duplicatesMap.has(element.id)) {
|
|
18191
|
+
hostDuplicates.set(element.id, element);
|
|
18192
|
+
}
|
|
18193
|
+
}
|
|
18194
|
+
const survivedIds = /* @__PURE__ */ new Set();
|
|
18195
|
+
for (const [id, element] of hostDuplicates) {
|
|
18196
|
+
const duplicate = duplicatesMap.get(id);
|
|
18197
|
+
if (element !== duplicate) {
|
|
18198
|
+
Object.assign(duplicate, element);
|
|
18199
|
+
ShapeCache.delete(duplicate);
|
|
18200
|
+
bumpVersion(duplicate);
|
|
18201
|
+
}
|
|
18202
|
+
if (!duplicate.isDeleted) {
|
|
18203
|
+
survivedIds.add(id);
|
|
18204
|
+
}
|
|
18205
|
+
}
|
|
18206
|
+
const isVetoed = (id) => duplicatesMap.has(id) && !survivedIds.has(id);
|
|
18207
|
+
for (const id of survivedIds) {
|
|
18208
|
+
const duplicate = duplicatesMap.get(id);
|
|
18209
|
+
if (isBoundToContainer(duplicate) && isVetoed(duplicate.containerId)) {
|
|
18210
|
+
survivedIds.delete(id);
|
|
18211
|
+
}
|
|
18212
|
+
}
|
|
18213
|
+
const elements = [];
|
|
18214
|
+
for (const element of hostElements) {
|
|
18215
|
+
const duplicate = duplicatesMap.get(element.id);
|
|
18216
|
+
if (!duplicate) {
|
|
18217
|
+
elements.push(element);
|
|
18218
|
+
} else if (survivedIds.has(element.id) && hostDuplicates.get(element.id) === element) {
|
|
18219
|
+
elements.push(duplicate);
|
|
18220
|
+
}
|
|
18221
|
+
}
|
|
18222
|
+
if (survivedIds.size === duplicatedElements.length) {
|
|
18223
|
+
return { elements, duplicatedElements };
|
|
18224
|
+
}
|
|
18225
|
+
const survivedDuplicates = duplicatedElements.filter(
|
|
18226
|
+
(duplicate) => survivedIds.has(duplicate.id)
|
|
18227
|
+
);
|
|
18228
|
+
for (const duplicate of survivedDuplicates) {
|
|
18229
|
+
const updates = {};
|
|
18230
|
+
if (duplicate.boundElements?.some((binding) => isVetoed(binding.id))) {
|
|
18231
|
+
updates.boundElements = duplicate.boundElements.filter(
|
|
18232
|
+
(binding) => !isVetoed(binding.id)
|
|
18233
|
+
);
|
|
18234
|
+
}
|
|
18235
|
+
if (duplicate.frameId && isVetoed(duplicate.frameId)) {
|
|
18236
|
+
updates.frameId = null;
|
|
18237
|
+
}
|
|
18238
|
+
if (isArrowElement(duplicate)) {
|
|
18239
|
+
if (duplicate.startBinding && isVetoed(duplicate.startBinding.elementId)) {
|
|
18240
|
+
updates.startBinding = null;
|
|
18241
|
+
}
|
|
18242
|
+
if (duplicate.endBinding && isVetoed(duplicate.endBinding.elementId)) {
|
|
18243
|
+
updates.endBinding = null;
|
|
18244
|
+
}
|
|
18245
|
+
}
|
|
18246
|
+
Object.assign(duplicate, updates);
|
|
18247
|
+
}
|
|
18248
|
+
return { elements, duplicatedElements: survivedDuplicates };
|
|
18249
|
+
};
|
|
17958
18250
|
var _deepCopyElement = (val, depth = 0) => {
|
|
17959
18251
|
if (val == null || typeof val !== "object") {
|
|
17960
18252
|
return val;
|
|
@@ -20430,13 +20722,11 @@ var dragSelectedElements = (pointerDownState, _selectedElements, offset, scene,
|
|
|
20430
20722
|
snapOffset,
|
|
20431
20723
|
gridSize
|
|
20432
20724
|
);
|
|
20433
|
-
const
|
|
20434
|
-
|
|
20725
|
+
const elementsToUpdateArray = Array.from(elementsToUpdate);
|
|
20726
|
+
const elementsToUpdateIds = getSimultaneouslyUpdatedElementIds(
|
|
20727
|
+
elementsToUpdateArray
|
|
20435
20728
|
);
|
|
20436
20729
|
elementsToUpdate.forEach((element) => {
|
|
20437
|
-
const isArrow = !isArrowElement(element);
|
|
20438
|
-
const isStartBoundElementSelected = isArrow || (element.startBinding ? elementsToUpdateIds.has(element.startBinding.elementId) : false);
|
|
20439
|
-
const isEndBoundElementSelected = isArrow || (element.endBinding ? elementsToUpdateIds.has(element.endBinding.elementId) : false);
|
|
20440
20730
|
if (!isArrowElement(element)) {
|
|
20441
20731
|
updateElementCoords(pointerDownState, element, scene, adjustedOffset);
|
|
20442
20732
|
const textElement = getBoundTextElement(
|
|
@@ -20452,7 +20742,7 @@ var dragSelectedElements = (pointerDownState, _selectedElements, offset, scene,
|
|
|
20452
20742
|
);
|
|
20453
20743
|
}
|
|
20454
20744
|
updateBoundElements(element, scene, {
|
|
20455
|
-
simultaneouslyUpdated:
|
|
20745
|
+
simultaneouslyUpdated: elementsToUpdateArray
|
|
20456
20746
|
});
|
|
20457
20747
|
} else if (
|
|
20458
20748
|
// NOTE: Add a little initial drag to the arrow dragging when the arrow
|
|
@@ -20461,8 +20751,8 @@ var dragSelectedElements = (pointerDownState, _selectedElements, offset, scene,
|
|
|
20461
20751
|
elementsToUpdate.size > 1 || Math.max(Math.abs(adjustedOffset.x), Math.abs(adjustedOffset.y)) > DRAGGING_THRESHOLD2 || !element.startBinding && !element.endBinding
|
|
20462
20752
|
) {
|
|
20463
20753
|
updateElementCoords(pointerDownState, element, scene, adjustedOffset);
|
|
20464
|
-
const shouldUnbindStart = element.startBinding
|
|
20465
|
-
const shouldUnbindEnd = element.endBinding
|
|
20754
|
+
const shouldUnbindStart = element.startBinding ? !elementsToUpdateIds.has(element.startBinding.elementId) : true;
|
|
20755
|
+
const shouldUnbindEnd = element.endBinding ? !elementsToUpdateIds.has(element.endBinding.elementId) : true;
|
|
20466
20756
|
if (shouldUnbindStart || shouldUnbindEnd) {
|
|
20467
20757
|
if (shouldUnbindStart) {
|
|
20468
20758
|
unbindBindingElement(element, "start", scene);
|
|
@@ -20701,7 +20991,7 @@ import {
|
|
|
20701
20991
|
getFontString as getFontString7
|
|
20702
20992
|
} from "@excalidraw/common";
|
|
20703
20993
|
var embeddedLinkCache = /* @__PURE__ */ new Map();
|
|
20704
|
-
var RE_YOUTUBE = /^(?:http(?:s)?:\/\/)?(?:www\.)?youtu(?:be\.com|\.be)\/(embed\/|watch\?v=|shorts\/|playlist\?list=|embed\/videoseries\?list=)?([a-zA-Z0-9_-]+)/;
|
|
20994
|
+
var RE_YOUTUBE = /^(?:http(?:s)?:\/\/)?(?:www\.)?youtu(?:be\.com|\.be)\/(embed\/|watch\?v=|shorts\/|live\/|playlist\?list=|embed\/videoseries\?list=)?([a-zA-Z0-9_-]+)/;
|
|
20705
20995
|
var RE_VIMEO = /^(?:http(?:s)?:\/\/)?(?:(?:w){3}\.)?(?:player\.)?vimeo\.com\/(?:video\/)?([^?\s]+)(?:\?.*)?$/;
|
|
20706
20996
|
var RE_FIGMA = /^https:\/\/(?:www\.)?figma\.com/;
|
|
20707
20997
|
var RE_GH_GIST = /^https:\/\/gist\.github\.com\/([\w_-]+)\/([\w_-]+)/;
|
|
@@ -21110,7 +21400,7 @@ var embeddableURLValidator = (url, validateEmbeddable) => {
|
|
|
21110
21400
|
init_define_import_meta_env();
|
|
21111
21401
|
import { invariant as invariant11, toBrandedType as toBrandedType2 } from "@excalidraw/common";
|
|
21112
21402
|
import {
|
|
21113
|
-
clamp as
|
|
21403
|
+
clamp as clamp9,
|
|
21114
21404
|
pointFrom as pointFrom15
|
|
21115
21405
|
} from "@excalidraw/math";
|
|
21116
21406
|
var VERTICAL_OFFSET = 100;
|
|
@@ -21141,7 +21431,7 @@ var findNearestFreeSlot = (ideal, size, occupied) => {
|
|
|
21141
21431
|
if (gapEnds[i] - gapStarts[i] < size) {
|
|
21142
21432
|
continue;
|
|
21143
21433
|
}
|
|
21144
|
-
const start =
|
|
21434
|
+
const start = clamp9(ideal, gapStarts[i], gapEnds[i] - size);
|
|
21145
21435
|
const distance3 = Math.abs(start - ideal);
|
|
21146
21436
|
if (distance3 <= bestDistance) {
|
|
21147
21437
|
best = start;
|
|
@@ -21339,9 +21629,17 @@ var createBindingArrow = (startBindingElement, endBindingElement, direction, app
|
|
|
21339
21629
|
startBindingElement,
|
|
21340
21630
|
"orbit",
|
|
21341
21631
|
"start",
|
|
21342
|
-
scene
|
|
21632
|
+
scene,
|
|
21633
|
+
appState.zoom
|
|
21634
|
+
);
|
|
21635
|
+
bindBindingElement(
|
|
21636
|
+
bindingArrow,
|
|
21637
|
+
endBindingElement,
|
|
21638
|
+
"orbit",
|
|
21639
|
+
"end",
|
|
21640
|
+
scene,
|
|
21641
|
+
appState.zoom
|
|
21343
21642
|
);
|
|
21344
|
-
bindBindingElement(bindingArrow, endBindingElement, "orbit", "end", scene);
|
|
21345
21643
|
const changedElements = /* @__PURE__ */ new Map();
|
|
21346
21644
|
changedElements.set(
|
|
21347
21645
|
startBindingElement.id,
|
|
@@ -21670,13 +21968,7 @@ var getContiguousFrameRangeElements = (allElements, frameId) => {
|
|
|
21670
21968
|
}
|
|
21671
21969
|
return allElements.slice(rangeStart, rangeEnd + 1);
|
|
21672
21970
|
};
|
|
21673
|
-
var moveArrowAboveBindable2 = (point, arrow, elements, elementsMap, scene,
|
|
21674
|
-
const hoveredElement = hit ? hit : getHoveredElementForBinding(
|
|
21675
|
-
point,
|
|
21676
|
-
// SAFETY: callers that omit `hit` pass non-deleted elements
|
|
21677
|
-
getNonDeletedElements(elements),
|
|
21678
|
-
elementsMap
|
|
21679
|
-
);
|
|
21971
|
+
var moveArrowAboveBindable2 = (point, arrow, elements, elementsMap, scene, hoveredElement) => {
|
|
21680
21972
|
if (!hoveredElement) {
|
|
21681
21973
|
return elements;
|
|
21682
21974
|
}
|
|
@@ -22027,7 +22319,7 @@ var isFocusPointVisible = (focusPoint, arrow, bindableElement, elementsMap, appS
|
|
|
22027
22319
|
element: bindableElement,
|
|
22028
22320
|
elementsMap,
|
|
22029
22321
|
point: focusPoint,
|
|
22030
|
-
threshold: getBindingGap(bindableElement
|
|
22322
|
+
threshold: getBindingGap(bindableElement),
|
|
22031
22323
|
overrideShouldTestInside: true
|
|
22032
22324
|
});
|
|
22033
22325
|
};
|
|
@@ -22119,12 +22411,11 @@ var handleFocusPointDrag = (linearElementEditor, elementsMap, pointerCoords, sce
|
|
|
22119
22411
|
pointerCoords.y - offsetY
|
|
22120
22412
|
);
|
|
22121
22413
|
const bindingField = isStartBinding ? "startBinding" : "endBinding";
|
|
22122
|
-
const hit =
|
|
22414
|
+
const hit = getHoveredElementForBinding(
|
|
22123
22415
|
point,
|
|
22124
|
-
arrow,
|
|
22125
22416
|
scene.getNonDeletedElements(),
|
|
22126
22417
|
elementsMap,
|
|
22127
|
-
|
|
22418
|
+
appState.zoom
|
|
22128
22419
|
);
|
|
22129
22420
|
if (hit && isBindingEnabled(appState)) {
|
|
22130
22421
|
if (arrow[bindingField] && hit.id !== binding?.elementId) {
|
|
@@ -22142,6 +22433,7 @@ var handleFocusPointDrag = (linearElementEditor, elementsMap, pointerCoords, sce
|
|
|
22142
22433
|
newMode || "orbit",
|
|
22143
22434
|
linearElementEditor.draggedFocusPointBinding,
|
|
22144
22435
|
scene,
|
|
22436
|
+
appState.zoom,
|
|
22145
22437
|
point
|
|
22146
22438
|
);
|
|
22147
22439
|
}
|
|
@@ -22455,6 +22747,198 @@ var normalizeSVG = (SVGString) => {
|
|
|
22455
22747
|
}
|
|
22456
22748
|
};
|
|
22457
22749
|
|
|
22750
|
+
// src/listMarker.ts
|
|
22751
|
+
init_define_import_meta_env();
|
|
22752
|
+
import { arrayToMap as arrayToMap13 } from "@excalidraw/common";
|
|
22753
|
+
var LIST_MARKER_REGEX = /^(\s*)(?:\((\d{1,9}|[a-zA-Z]+)\)|\[(\d{1,9})\]|(\d{1,9}|[a-zA-Z]+)([.)]))(?=\s|$)/;
|
|
22754
|
+
var LONE_NUMBER_REGEX = /^(\s*)(\d{1,9})\s*$/;
|
|
22755
|
+
var LAST_ALPHA_ORDINAL = "h".charCodeAt(0) - "a".charCodeAt(0) + 1;
|
|
22756
|
+
var MAX_ORDINAL = {
|
|
22757
|
+
decimal: 42,
|
|
22758
|
+
alpha: 9,
|
|
22759
|
+
// i. (then switching to roman)
|
|
22760
|
+
roman: 99
|
|
22761
|
+
};
|
|
22762
|
+
var toRoman = (value) => ["", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc"][Math.floor(value / 10)] + ["", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix"][value % 10];
|
|
22763
|
+
var ROMAN_VALUES = new Map(
|
|
22764
|
+
Array.from({ length: MAX_ORDINAL.roman }, (_, index) => [
|
|
22765
|
+
toRoman(index + 1),
|
|
22766
|
+
index + 1
|
|
22767
|
+
])
|
|
22768
|
+
);
|
|
22769
|
+
var parseLoneNumber = (text) => {
|
|
22770
|
+
const match = text.match(LONE_NUMBER_REGEX);
|
|
22771
|
+
if (!match) {
|
|
22772
|
+
return null;
|
|
22773
|
+
}
|
|
22774
|
+
const [, indent, value] = match;
|
|
22775
|
+
return {
|
|
22776
|
+
index: indent.length,
|
|
22777
|
+
value,
|
|
22778
|
+
kind: "decimal",
|
|
22779
|
+
isUpperCase: false,
|
|
22780
|
+
style: "decimal",
|
|
22781
|
+
ordinal: parseInt(value, 10),
|
|
22782
|
+
contentIndex: text.length
|
|
22783
|
+
};
|
|
22784
|
+
};
|
|
22785
|
+
var parseListMarker = (text) => {
|
|
22786
|
+
const match = text.match(LIST_MARKER_REGEX);
|
|
22787
|
+
if (!match) {
|
|
22788
|
+
return null;
|
|
22789
|
+
}
|
|
22790
|
+
const [, indent, parenValue, bracketValue, plainValue, plainSuffix] = match;
|
|
22791
|
+
const value = parenValue ?? bracketValue ?? plainValue;
|
|
22792
|
+
const lowerCaseValue = value.toLowerCase();
|
|
22793
|
+
const isUpperCase = /[A-Z]/.test(value);
|
|
22794
|
+
const alphaOrdinal = lowerCaseValue.charCodeAt(0) - "a".charCodeAt(0) + 1;
|
|
22795
|
+
let kind;
|
|
22796
|
+
let ordinal;
|
|
22797
|
+
if (/\d/.test(value)) {
|
|
22798
|
+
kind = "decimal";
|
|
22799
|
+
ordinal = parseInt(value, 10);
|
|
22800
|
+
} else if (isUpperCase && /[a-z]/.test(value)) {
|
|
22801
|
+
return null;
|
|
22802
|
+
} else if (value.length === 1 && alphaOrdinal <= LAST_ALPHA_ORDINAL) {
|
|
22803
|
+
kind = "alpha";
|
|
22804
|
+
ordinal = alphaOrdinal;
|
|
22805
|
+
} else if (ROMAN_VALUES.has(lowerCaseValue)) {
|
|
22806
|
+
kind = "roman";
|
|
22807
|
+
ordinal = ROMAN_VALUES.get(lowerCaseValue);
|
|
22808
|
+
} else {
|
|
22809
|
+
return null;
|
|
22810
|
+
}
|
|
22811
|
+
const affixes = parenValue !== void 0 ? "()" : bracketValue !== void 0 ? "[]" : plainSuffix;
|
|
22812
|
+
return {
|
|
22813
|
+
index: indent.length + (plainValue !== void 0 ? 0 : 1),
|
|
22814
|
+
value,
|
|
22815
|
+
kind,
|
|
22816
|
+
isUpperCase,
|
|
22817
|
+
style: `${kind}${isUpperCase ? "-upper" : ""}${affixes}`,
|
|
22818
|
+
ordinal,
|
|
22819
|
+
contentIndex: match[0].length + text.slice(match[0].length).match(/^\s*/)[0].length
|
|
22820
|
+
};
|
|
22821
|
+
};
|
|
22822
|
+
var getListItemMarker = (text) => {
|
|
22823
|
+
const marker = parseLoneNumber(text) ?? parseListMarker(text);
|
|
22824
|
+
if (!marker || marker.ordinal > MAX_ORDINAL[marker.kind]) {
|
|
22825
|
+
return null;
|
|
22826
|
+
}
|
|
22827
|
+
const otherLines = text.slice(marker.index).split("\n").slice(1);
|
|
22828
|
+
if (otherLines.some((line2) => parseListMarker(line2)?.style === marker.style)) {
|
|
22829
|
+
return null;
|
|
22830
|
+
}
|
|
22831
|
+
return marker;
|
|
22832
|
+
};
|
|
22833
|
+
var renumberListMarker = (text, marker, ordinal) => {
|
|
22834
|
+
if (ordinal > MAX_ORDINAL[marker.kind]) {
|
|
22835
|
+
return null;
|
|
22836
|
+
}
|
|
22837
|
+
let value;
|
|
22838
|
+
if (marker.kind === "decimal") {
|
|
22839
|
+
value = String(ordinal).padStart(
|
|
22840
|
+
marker.value.startsWith("0") ? marker.value.length : 0,
|
|
22841
|
+
"0"
|
|
22842
|
+
);
|
|
22843
|
+
} else if (marker.kind === "alpha") {
|
|
22844
|
+
value = String.fromCharCode("a".charCodeAt(0) + ordinal - 1);
|
|
22845
|
+
} else {
|
|
22846
|
+
value = toRoman(ordinal);
|
|
22847
|
+
}
|
|
22848
|
+
if (marker.isUpperCase) {
|
|
22849
|
+
value = value.toUpperCase();
|
|
22850
|
+
}
|
|
22851
|
+
return text.slice(0, marker.index) + value + text.slice(marker.index + marker.value.length);
|
|
22852
|
+
};
|
|
22853
|
+
var setText = (element, container, originalText, scene) => {
|
|
22854
|
+
if (container) {
|
|
22855
|
+
scene.mutateElement(element, { originalText });
|
|
22856
|
+
redrawTextBoundingBox(element, container, scene);
|
|
22857
|
+
} else {
|
|
22858
|
+
scene.mutateElement(element, {
|
|
22859
|
+
originalText,
|
|
22860
|
+
// re-wraps the text, and keeps it anchored as per its alignment
|
|
22861
|
+
...refreshTextDimensions(
|
|
22862
|
+
element,
|
|
22863
|
+
null,
|
|
22864
|
+
scene.getNonDeletedElementsMap(),
|
|
22865
|
+
originalText
|
|
22866
|
+
)
|
|
22867
|
+
});
|
|
22868
|
+
}
|
|
22869
|
+
};
|
|
22870
|
+
var advanceDuplicatedListMarkers = (duplicatedElements, scene) => {
|
|
22871
|
+
const duplicatesMap = arrayToMap13(duplicatedElements);
|
|
22872
|
+
const elementsMap = scene.getNonDeletedElementsMap();
|
|
22873
|
+
const itemsByStyle = /* @__PURE__ */ new Map();
|
|
22874
|
+
for (const element of duplicatedElements) {
|
|
22875
|
+
if (isBoundToContainer(element) && duplicatesMap.has(element.containerId)) {
|
|
22876
|
+
continue;
|
|
22877
|
+
}
|
|
22878
|
+
const text = isTextElement(element) ? element : getBoundTextElement(element, elementsMap);
|
|
22879
|
+
const marker = text && getListItemMarker(text.originalText);
|
|
22880
|
+
if (!text || !marker) {
|
|
22881
|
+
return [];
|
|
22882
|
+
}
|
|
22883
|
+
const items = itemsByStyle.get(marker.style) ?? [];
|
|
22884
|
+
items.push({
|
|
22885
|
+
element: text,
|
|
22886
|
+
container: text === element ? null : element,
|
|
22887
|
+
marker
|
|
22888
|
+
});
|
|
22889
|
+
itemsByStyle.set(marker.style, items);
|
|
22890
|
+
}
|
|
22891
|
+
const allItems = [...itemsByStyle.values()].flat();
|
|
22892
|
+
if (allItems.length > 1 && allItems.some(
|
|
22893
|
+
({ element, marker }) => marker.contentIndex < element.originalText.length
|
|
22894
|
+
)) {
|
|
22895
|
+
return [];
|
|
22896
|
+
}
|
|
22897
|
+
const advances = [];
|
|
22898
|
+
for (const items of itemsByStyle.values()) {
|
|
22899
|
+
const maxOrdinal = Math.max(...items.map((item) => item.marker.ordinal));
|
|
22900
|
+
items.sort((a2, b2) => a2.marker.ordinal - b2.marker.ordinal);
|
|
22901
|
+
for (const [index, { element, container, marker }] of items.entries()) {
|
|
22902
|
+
const nextOriginalText = renumberListMarker(
|
|
22903
|
+
element.originalText,
|
|
22904
|
+
marker,
|
|
22905
|
+
maxOrdinal + 1 + index
|
|
22906
|
+
);
|
|
22907
|
+
if (nextOriginalText === null) {
|
|
22908
|
+
continue;
|
|
22909
|
+
}
|
|
22910
|
+
advances.push({
|
|
22911
|
+
elementId: element.id,
|
|
22912
|
+
prevOriginalText: element.originalText,
|
|
22913
|
+
nextOriginalText,
|
|
22914
|
+
contentStart: marker.contentIndex + nextOriginalText.length - element.originalText.length,
|
|
22915
|
+
prevContainerSize: container ? { width: container.width, height: container.height } : null
|
|
22916
|
+
});
|
|
22917
|
+
setText(element, container, nextOriginalText, scene);
|
|
22918
|
+
}
|
|
22919
|
+
}
|
|
22920
|
+
return advances;
|
|
22921
|
+
};
|
|
22922
|
+
var applyListMarkerAdvances = (advances, direction, scene) => {
|
|
22923
|
+
const elementsMap = scene.getNonDeletedElementsMap();
|
|
22924
|
+
for (const advance of advances) {
|
|
22925
|
+
const element = elementsMap.get(advance.elementId);
|
|
22926
|
+
if (!element || !isTextElement(element)) {
|
|
22927
|
+
continue;
|
|
22928
|
+
}
|
|
22929
|
+
const container = getContainerElement(element, elementsMap);
|
|
22930
|
+
if (direction === "prev" && container && advance.prevContainerSize) {
|
|
22931
|
+
scene.mutateElement(container, advance.prevContainerSize);
|
|
22932
|
+
}
|
|
22933
|
+
setText(
|
|
22934
|
+
element,
|
|
22935
|
+
container,
|
|
22936
|
+
direction === "prev" ? advance.prevOriginalText : advance.nextOriginalText,
|
|
22937
|
+
scene
|
|
22938
|
+
);
|
|
22939
|
+
}
|
|
22940
|
+
};
|
|
22941
|
+
|
|
22458
22942
|
// src/positionElementsOnGrid.ts
|
|
22459
22943
|
init_define_import_meta_env();
|
|
22460
22944
|
var positionElementsOnGrid = (elements, centerX, centerY, padding = 50) => {
|
|
@@ -24008,7 +24492,7 @@ import {
|
|
|
24008
24492
|
VERTICAL_ALIGN as VERTICAL_ALIGN5,
|
|
24009
24493
|
getSizeFromPoints as getSizeFromPoints3,
|
|
24010
24494
|
randomId as randomId4,
|
|
24011
|
-
arrayToMap as
|
|
24495
|
+
arrayToMap as arrayToMap14,
|
|
24012
24496
|
assertNever as assertNever5,
|
|
24013
24497
|
cloneJSON,
|
|
24014
24498
|
getFontString as getFontString9,
|
|
@@ -24017,7 +24501,8 @@ import {
|
|
|
24017
24501
|
toBrandedType as toBrandedType3,
|
|
24018
24502
|
getLineHeight as getLineHeight3,
|
|
24019
24503
|
DEFAULT_STICKY_NOTE_SIZE as DEFAULT_STICKY_NOTE_SIZE2,
|
|
24020
|
-
isTransparent as isTransparent6
|
|
24504
|
+
isTransparent as isTransparent6,
|
|
24505
|
+
DEFAULT_ZOOM as DEFAULT_ZOOM3
|
|
24021
24506
|
} from "@excalidraw/common";
|
|
24022
24507
|
var DEFAULT_LINEAR_ELEMENT_PROPS = {
|
|
24023
24508
|
width: 100,
|
|
@@ -24048,7 +24533,7 @@ var bindTextToContainer = (container, textProps, scene) => {
|
|
|
24048
24533
|
redrawTextBoundingBox(textElement, container, scene);
|
|
24049
24534
|
return [container, textElement];
|
|
24050
24535
|
};
|
|
24051
|
-
var bindLinearElementToElement = (linearElement, start, end, elementStore, scene) => {
|
|
24536
|
+
var bindLinearElementToElement = (linearElement, start, end, elementStore, scene, zoom) => {
|
|
24052
24537
|
let startBoundElement;
|
|
24053
24538
|
let endBoundElement;
|
|
24054
24539
|
Object.assign(linearElement, {
|
|
@@ -24123,7 +24608,8 @@ var bindLinearElementToElement = (linearElement, start, end, elementStore, scene
|
|
|
24123
24608
|
startBoundElement,
|
|
24124
24609
|
"orbit",
|
|
24125
24610
|
"start",
|
|
24126
|
-
scene
|
|
24611
|
+
scene,
|
|
24612
|
+
zoom
|
|
24127
24613
|
);
|
|
24128
24614
|
}
|
|
24129
24615
|
}
|
|
@@ -24194,7 +24680,8 @@ var bindLinearElementToElement = (linearElement, start, end, elementStore, scene
|
|
|
24194
24680
|
endBoundElement,
|
|
24195
24681
|
"orbit",
|
|
24196
24682
|
"end",
|
|
24197
|
-
scene
|
|
24683
|
+
scene,
|
|
24684
|
+
zoom
|
|
24198
24685
|
);
|
|
24199
24686
|
}
|
|
24200
24687
|
}
|
|
@@ -24252,7 +24739,7 @@ var ElementStore = class {
|
|
|
24252
24739
|
};
|
|
24253
24740
|
getElementsMap = () => {
|
|
24254
24741
|
return toBrandedType3(
|
|
24255
|
-
|
|
24742
|
+
arrayToMap14(this.getElements())
|
|
24256
24743
|
);
|
|
24257
24744
|
};
|
|
24258
24745
|
getElement = (id) => {
|
|
@@ -24443,7 +24930,8 @@ var convertToExcalidrawElements = (elementsSkeleton, opts) => {
|
|
|
24443
24930
|
originalStart,
|
|
24444
24931
|
originalEnd,
|
|
24445
24932
|
elementStore,
|
|
24446
|
-
scene
|
|
24933
|
+
scene,
|
|
24934
|
+
DEFAULT_ZOOM3
|
|
24447
24935
|
);
|
|
24448
24936
|
container = linearElement;
|
|
24449
24937
|
elementStore.add(linearElement);
|
|
@@ -24467,7 +24955,8 @@ var convertToExcalidrawElements = (elementsSkeleton, opts) => {
|
|
|
24467
24955
|
start,
|
|
24468
24956
|
end,
|
|
24469
24957
|
elementStore,
|
|
24470
|
-
scene
|
|
24958
|
+
scene,
|
|
24959
|
+
DEFAULT_ZOOM3
|
|
24471
24960
|
);
|
|
24472
24961
|
elementStore.add(linearElement);
|
|
24473
24962
|
elementStore.add(startBoundElement);
|
|
@@ -25117,7 +25606,6 @@ export {
|
|
|
25117
25606
|
AppStateDelta,
|
|
25118
25607
|
BASE_ARROW_MIN_LENGTH,
|
|
25119
25608
|
BASE_BINDING_GAP,
|
|
25120
|
-
BASE_BINDING_GAP_ELBOW,
|
|
25121
25609
|
BASE_PADDING,
|
|
25122
25610
|
BindableElement,
|
|
25123
25611
|
BoundElement,
|
|
@@ -25155,7 +25643,9 @@ export {
|
|
|
25155
25643
|
addElementsToFrame,
|
|
25156
25644
|
addNewNodes,
|
|
25157
25645
|
addToGroup,
|
|
25646
|
+
advanceDuplicatedListMarkers,
|
|
25158
25647
|
alignElements,
|
|
25648
|
+
applyListMarkerAdvances,
|
|
25159
25649
|
avoidRectangularCorner,
|
|
25160
25650
|
bindBindingElement,
|
|
25161
25651
|
bindBindingElementToFixedPoint,
|
|
@@ -25218,6 +25708,7 @@ export {
|
|
|
25218
25708
|
generateRoughOptions,
|
|
25219
25709
|
getActiveTextElement,
|
|
25220
25710
|
getAllHoveredElementAtPoint,
|
|
25711
|
+
getAllMidpoints,
|
|
25221
25712
|
getApproxMinLineHeight,
|
|
25222
25713
|
getApproxMinLineWidth,
|
|
25223
25714
|
getArrowLocalFixedPoints,
|
|
@@ -25255,10 +25746,12 @@ export {
|
|
|
25255
25746
|
getDiamondPoints,
|
|
25256
25747
|
getDragOffsetXY,
|
|
25257
25748
|
getDraggedElementsBounds,
|
|
25749
|
+
getElbowArrowSnapMidPoint,
|
|
25258
25750
|
getElementAbsoluteCoords2 as getElementAbsoluteCoords,
|
|
25259
25751
|
getElementBounds,
|
|
25260
25752
|
getElementLineSegments,
|
|
25261
25753
|
getElementPointsCoords,
|
|
25754
|
+
getElementRenderOffset,
|
|
25262
25755
|
getElementShape,
|
|
25263
25756
|
getElementWithTransformHandleType,
|
|
25264
25757
|
getElementsCompletelyInFrame,
|
|
@@ -25275,6 +25768,8 @@ export {
|
|
|
25275
25768
|
getFrameChildrenInsertionIndex,
|
|
25276
25769
|
getFrameLikeElements,
|
|
25277
25770
|
getFrameLikeTitle,
|
|
25771
|
+
getFreedrawFillPolygon,
|
|
25772
|
+
getFreedrawMaxStrokeRadius,
|
|
25278
25773
|
getFreedrawOutlineAsSegments,
|
|
25279
25774
|
getFreedrawOutlinePoints,
|
|
25280
25775
|
getFreedrawStrokeCenterPoints,
|
|
@@ -25282,7 +25777,6 @@ export {
|
|
|
25282
25777
|
getGlobalFixedPoints,
|
|
25283
25778
|
getHeadingForElbowArrowSnap,
|
|
25284
25779
|
getHoveredElementForBinding,
|
|
25285
|
-
getHoveredElementForFocusPoint,
|
|
25286
25780
|
getInitializedImageElements,
|
|
25287
25781
|
getLineHeightInPx,
|
|
25288
25782
|
getLineWidth,
|
|
@@ -25305,7 +25799,7 @@ export {
|
|
|
25305
25799
|
getPerfectElementSize,
|
|
25306
25800
|
getPositionAfterHeightChange,
|
|
25307
25801
|
getRectangleBoxAbsoluteCoords,
|
|
25308
|
-
|
|
25802
|
+
getRenderElementWithPositionOverride,
|
|
25309
25803
|
getResizeArrowDirection,
|
|
25310
25804
|
getResizeOffsetXY,
|
|
25311
25805
|
getResizedElementAbsoluteCoords,
|
|
@@ -25317,6 +25811,7 @@ export {
|
|
|
25317
25811
|
getSelectedGroupIdForElement,
|
|
25318
25812
|
getSelectedGroupIds,
|
|
25319
25813
|
getSelectionStateForElements,
|
|
25814
|
+
getSimultaneouslyUpdatedElementIds,
|
|
25320
25815
|
getSnapOutlineMidPoint,
|
|
25321
25816
|
getStickyNoteCornerRadius,
|
|
25322
25817
|
getStickyNoteDateLabel,
|
|
@@ -25331,6 +25826,7 @@ export {
|
|
|
25331
25826
|
getTextAnchorRatios,
|
|
25332
25827
|
getTextBindingForArrowEndpoint,
|
|
25333
25828
|
getTextElementAngle,
|
|
25829
|
+
getTextElementWithAccuratePosition,
|
|
25334
25830
|
getTextFromElements,
|
|
25335
25831
|
getTextHeight,
|
|
25336
25832
|
getTextWidth,
|
|
@@ -25417,6 +25913,7 @@ export {
|
|
|
25417
25913
|
isMeasureTextSupported,
|
|
25418
25914
|
isNodeInFlowchart,
|
|
25419
25915
|
isNonDeletedElement,
|
|
25916
|
+
isOpaqueForBinding,
|
|
25420
25917
|
isPathALoop,
|
|
25421
25918
|
isPointInElement,
|
|
25422
25919
|
isRectangularElement,
|
|
@@ -25481,7 +25978,9 @@ export {
|
|
|
25481
25978
|
pointInsideBoundsInclusive,
|
|
25482
25979
|
positionElementsOnGrid,
|
|
25483
25980
|
projectFixedPointOntoDiagonal,
|
|
25981
|
+
reanchorBindingsToOutline,
|
|
25484
25982
|
recognizeShape,
|
|
25983
|
+
reconcileDuplicatedElements,
|
|
25485
25984
|
redrawTextBoundingBox,
|
|
25486
25985
|
refreshTextDimensions,
|
|
25487
25986
|
relayoutStickyNotes,
|
|
@@ -25498,6 +25997,7 @@ export {
|
|
|
25498
25997
|
resizeSingleElement,
|
|
25499
25998
|
resizeSingleTextElement,
|
|
25500
25999
|
resizeTest,
|
|
26000
|
+
resolveElementRenderState,
|
|
25501
26001
|
selectGroup,
|
|
25502
26002
|
selectGroupsForSelectedElements,
|
|
25503
26003
|
selectGroupsFromGivenElements,
|
|
@@ -25506,7 +26006,6 @@ export {
|
|
|
25506
26006
|
shouldApplyFrameClip,
|
|
25507
26007
|
shouldTestInside,
|
|
25508
26008
|
showSelectedShapeActions,
|
|
25509
|
-
snapToMid,
|
|
25510
26009
|
suppportsHorizontalAlign,
|
|
25511
26010
|
syncInvalidIndices,
|
|
25512
26011
|
syncInvalidIndicesImmutable,
|