@excalidraw/element 0.18.0-0457ac9 → 0.18.0-063e025
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 +1305 -895
- package/dist/dev/index.js.map +4 -4
- package/dist/prod/index.js +18 -18
- package/dist/types/common/src/colors.d.ts +1 -1
- package/dist/types/common/src/constants.d.ts +9 -7
- package/dist/types/common/src/utils.d.ts +0 -42
- package/dist/types/element/src/Scene.d.ts +1 -1
- package/dist/types/element/src/align.d.ts +2 -2
- package/dist/types/element/src/binding.d.ts +6 -6
- package/dist/types/element/src/bounds.d.ts +19 -6
- package/dist/types/element/src/collision.d.ts +1 -1
- package/dist/types/element/src/comparisons.d.ts +1 -0
- package/dist/types/element/src/distribute.d.ts +2 -2
- package/dist/types/element/src/duplicate.d.ts +3 -3
- package/dist/types/element/src/embeddable.d.ts +2 -2
- package/dist/types/element/src/flowchart.d.ts +3 -3
- package/dist/types/element/src/fractionalIndex.d.ts +2 -2
- package/dist/types/element/src/frame.d.ts +4 -4
- package/dist/types/element/src/groups.d.ts +9 -9
- package/dist/types/element/src/index.d.ts +1 -1
- package/dist/types/element/src/linearElementEditor.d.ts +10 -10
- package/dist/types/element/src/newElement.d.ts +1 -0
- package/dist/types/element/src/renderElement.d.ts +0 -3
- package/dist/types/element/src/resizeElements.d.ts +2 -2
- package/dist/types/element/src/selection.d.ts +5 -5
- package/dist/types/element/src/textElement.d.ts +7 -7
- package/dist/types/element/src/transform.d.ts +2 -2
- package/dist/types/element/src/typeChecks.d.ts +25 -25
- package/dist/types/element/src/types.d.ts +8 -1
- package/dist/types/element/src/visualdebug.d.ts +1 -2
- package/dist/types/element/src/zindex.d.ts +2 -2
- package/dist/types/excalidraw/actions/actionAddToLibrary.d.ts +12 -6
- package/dist/types/excalidraw/actions/actionAlign.d.ts +6 -6
- package/dist/types/excalidraw/actions/actionBoundText.d.ts +8 -4
- package/dist/types/excalidraw/actions/actionCanvas.d.ts +61 -389
- package/dist/types/excalidraw/actions/actionClipboard.d.ts +8 -4
- package/dist/types/excalidraw/actions/actionCropEditor.d.ts +4 -2
- package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +13 -7
- package/dist/types/excalidraw/actions/actionDeselect.d.ts +4 -2
- package/dist/types/excalidraw/actions/actionDistribute.d.ts +2 -3
- package/dist/types/excalidraw/actions/actionElementLink.d.ts +4 -2
- package/dist/types/excalidraw/actions/actionElementLock.d.ts +9 -5
- package/dist/types/excalidraw/actions/actionEmbeddable.d.ts +4 -2
- package/dist/types/excalidraw/actions/actionExport.d.ts +8 -4
- package/dist/types/excalidraw/actions/actionFrame.d.ts +29 -20
- package/dist/types/excalidraw/actions/actionGroup.d.ts +23 -19
- package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +7 -4
- package/dist/types/excalidraw/actions/actionLink.d.ts +5 -3
- package/dist/types/excalidraw/actions/actionMenu.d.ts +4 -2
- package/dist/types/excalidraw/actions/actionProperties.d.ts +35 -22
- package/dist/types/excalidraw/actions/actionSelectAll.d.ts +9 -7
- package/dist/types/excalidraw/actions/actionStyles.d.ts +4 -2
- package/dist/types/excalidraw/actions/actionToggleArrowBinding.d.ts +5 -3
- package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +8 -7
- package/dist/types/excalidraw/actions/actionToggleMidpointSnapping.d.ts +5 -3
- package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +5 -3
- package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +8 -7
- package/dist/types/excalidraw/actions/actionToggleShapeSwitch.d.ts +1 -1
- package/dist/types/excalidraw/actions/actionToggleStats.d.ts +5 -3
- package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +5 -3
- package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +5 -3
- package/dist/types/excalidraw/actions/index.d.ts +1 -1
- package/dist/types/excalidraw/actions/types.d.ts +4 -4
- package/dist/types/excalidraw/{animated-trail.d.ts → animatedTrail.d.ts} +4 -3
- package/dist/types/excalidraw/appState.d.ts +2 -1
- package/dist/types/excalidraw/components/Actions.d.ts +2 -3
- package/dist/types/excalidraw/components/ActiveConfirmDialog.d.ts +1 -1
- package/dist/types/excalidraw/components/App.d.ts +61 -32
- package/dist/types/excalidraw/components/ColorPicker/ColorPicker.d.ts +2 -2
- package/dist/types/excalidraw/components/ColorPicker/colorPickerUtils.d.ts +1 -1
- package/dist/types/excalidraw/components/CommandPalette/defaultCommandPaletteItems.d.ts +1 -2
- package/dist/types/excalidraw/components/ConvertElementTypePopup.d.ts +2 -2
- package/dist/types/excalidraw/components/CursorHint.d.ts +46 -0
- package/dist/types/excalidraw/components/EyeDropper.d.ts +1 -1
- package/dist/types/excalidraw/components/Island.d.ts +7 -0
- package/dist/types/excalidraw/components/LibraryMenu.d.ts +1 -1
- package/dist/types/excalidraw/components/OverwriteConfirm/OverwriteConfirmState.d.ts +1 -1
- package/dist/types/excalidraw/components/SVGLayer.d.ts +1 -1
- package/dist/types/excalidraw/components/SearchMenu.d.ts +1 -1
- package/dist/types/excalidraw/components/Sidebar/Sidebar.d.ts +1 -1
- package/dist/types/excalidraw/components/Stats/Angle.d.ts +2 -2
- package/dist/types/excalidraw/components/Stats/Dimension.d.ts +2 -2
- package/dist/types/excalidraw/components/Stats/DragInput.d.ts +2 -2
- package/dist/types/excalidraw/components/Stats/MultiAngle.d.ts +2 -2
- package/dist/types/excalidraw/components/Stats/MultiDimension.d.ts +2 -2
- package/dist/types/excalidraw/components/Stats/MultiPosition.d.ts +2 -2
- package/dist/types/excalidraw/components/Stats/Position.d.ts +3 -3
- package/dist/types/excalidraw/components/Stats/utils.d.ts +1 -1
- package/dist/types/excalidraw/components/TTDDialog/TTDContext.d.ts +4 -4
- package/dist/types/excalidraw/components/TTDDialog/useTTDChatStorage.d.ts +3 -3
- package/dist/types/excalidraw/components/hyperlink/helpers.d.ts +2 -2
- package/dist/types/excalidraw/components/icons.d.ts +2 -0
- package/dist/types/excalidraw/components/main-menu/DefaultItems.d.ts +6 -3
- package/dist/types/excalidraw/data/blob.d.ts +8 -4
- package/dist/types/excalidraw/data/index.d.ts +4 -4
- package/dist/types/excalidraw/data/json.d.ts +10 -8
- package/dist/types/excalidraw/data/library.d.ts +1 -1
- package/dist/types/excalidraw/eraser/index.d.ts +2 -3
- package/dist/types/excalidraw/hooks/useAppStateValue.d.ts +29 -0
- package/dist/types/excalidraw/hooks/useLibraryItemSvg.d.ts +1 -1
- package/dist/types/excalidraw/{laser-trails.d.ts → laserTrails.d.ts} +5 -7
- package/dist/types/excalidraw/lasso/index.d.ts +2 -3
- package/dist/types/excalidraw/renderer/animation.d.ts +5 -1
- package/dist/types/excalidraw/renderer/interactiveScene.d.ts +1 -3
- package/dist/types/excalidraw/scene/Renderer.d.ts +12 -11
- package/dist/types/excalidraw/scene/export.d.ts +3 -3
- package/dist/types/excalidraw/scene/index.d.ts +2 -2
- package/dist/types/excalidraw/scene/types.d.ts +1 -3
- package/dist/types/excalidraw/snapping.d.ts +7 -7
- package/dist/types/excalidraw/types.d.ts +168 -11
- package/dist/types/excalidraw/viewport.d.ts +316 -0
- package/dist/types/excalidraw/wysiwyg/textWysiwyg.d.ts +2 -3
- package/dist/types/laser-pointer/src/index.d.ts +2 -0
- package/dist/types/laser-pointer/src/math.d.ts +16 -0
- package/dist/types/laser-pointer/src/simplify.d.ts +2 -0
- package/dist/types/laser-pointer/src/state.d.ts +35 -0
- package/dist/types/utils/src/export.d.ts +3 -3
- package/dist/types/utils/src/index.d.ts +1 -2
- package/package.json +4 -4
- package/dist/types/excalidraw/animation-frame-handler.d.ts +0 -16
- package/dist/types/excalidraw/scene/scroll.d.ts +0 -18
- package/dist/types/utils/src/bbox.d.ts +0 -9
- package/dist/types/utils/src/withinBounds.d.ts +0 -19
package/dist/dev/index.js
CHANGED
|
@@ -230,9 +230,9 @@ init_define_import_meta_env();
|
|
|
230
230
|
function rotatePoints(points, center, degrees) {
|
|
231
231
|
if (points && points.length) {
|
|
232
232
|
const [cx, cy] = center;
|
|
233
|
-
const
|
|
234
|
-
const cos = Math.cos(
|
|
235
|
-
const sin = Math.sin(
|
|
233
|
+
const angle2 = Math.PI / 180 * degrees;
|
|
234
|
+
const cos = Math.cos(angle2);
|
|
235
|
+
const sin = Math.sin(angle2);
|
|
236
236
|
for (const p of points) {
|
|
237
237
|
const [x, y] = p;
|
|
238
238
|
p[0] = (x - cx) * cos - (y - cy) * sin + cx;
|
|
@@ -249,21 +249,21 @@ function areSamePoints(p1, p2) {
|
|
|
249
249
|
return p1[0] === p2[0] && p1[1] === p2[1];
|
|
250
250
|
}
|
|
251
251
|
function hachureLines(polygons, hachureGap, hachureAngle, hachureStepOffset = 1) {
|
|
252
|
-
const
|
|
252
|
+
const angle2 = hachureAngle;
|
|
253
253
|
const gap = Math.max(hachureGap, 0.1);
|
|
254
254
|
const polygonList = polygons[0] && polygons[0][0] && typeof polygons[0][0] === "number" ? [polygons] : polygons;
|
|
255
255
|
const rotationCenter = [0, 0];
|
|
256
|
-
if (
|
|
256
|
+
if (angle2) {
|
|
257
257
|
for (const polygon3 of polygonList) {
|
|
258
|
-
rotatePoints(polygon3, rotationCenter,
|
|
258
|
+
rotatePoints(polygon3, rotationCenter, angle2);
|
|
259
259
|
}
|
|
260
260
|
}
|
|
261
261
|
const lines = straightHachureLines(polygonList, gap, hachureStepOffset);
|
|
262
|
-
if (
|
|
262
|
+
if (angle2) {
|
|
263
263
|
for (const polygon3 of polygonList) {
|
|
264
|
-
rotatePoints(polygon3, rotationCenter, -
|
|
264
|
+
rotatePoints(polygon3, rotationCenter, -angle2);
|
|
265
265
|
}
|
|
266
|
-
rotateLines(lines, rotationCenter, -
|
|
266
|
+
rotateLines(lines, rotationCenter, -angle2);
|
|
267
267
|
}
|
|
268
268
|
return lines;
|
|
269
269
|
}
|
|
@@ -374,7 +374,7 @@ function straightHachureLines(polygons, gap, hachureStepOffset) {
|
|
|
374
374
|
// ../../node_modules/roughjs/bin/fillers/scan-line-hachure.js
|
|
375
375
|
function polygonHachureLines(polygonList, o) {
|
|
376
376
|
var _a;
|
|
377
|
-
const
|
|
377
|
+
const angle2 = o.hachureAngle + 90;
|
|
378
378
|
let gap = o.hachureGap;
|
|
379
379
|
if (gap < 0) {
|
|
380
380
|
gap = o.strokeWidth * 4;
|
|
@@ -386,7 +386,7 @@ function polygonHachureLines(polygonList, o) {
|
|
|
386
386
|
skipOffset = gap;
|
|
387
387
|
}
|
|
388
388
|
}
|
|
389
|
-
return hachureLines(polygonList, gap,
|
|
389
|
+
return hachureLines(polygonList, gap, angle2, skipOffset || 1);
|
|
390
390
|
}
|
|
391
391
|
|
|
392
392
|
// ../../node_modules/roughjs/bin/fillers/hachure-filler.js
|
|
@@ -924,7 +924,7 @@ function normalize(segments) {
|
|
|
924
924
|
case "A": {
|
|
925
925
|
const r1 = Math.abs(data[0]);
|
|
926
926
|
const r2 = Math.abs(data[1]);
|
|
927
|
-
const
|
|
927
|
+
const angle2 = data[2];
|
|
928
928
|
const largeArcFlag = data[3];
|
|
929
929
|
const sweepFlag = data[4];
|
|
930
930
|
const x = data[5];
|
|
@@ -935,7 +935,7 @@ function normalize(segments) {
|
|
|
935
935
|
cy = y;
|
|
936
936
|
} else {
|
|
937
937
|
if (cx !== x || cy !== y) {
|
|
938
|
-
const curves = arcToCubicCurves(cx, cy, x, y, r1, r2,
|
|
938
|
+
const curves = arcToCubicCurves(cx, cy, x, y, r1, r2, angle2, largeArcFlag, sweepFlag);
|
|
939
939
|
curves.forEach(function(curve4) {
|
|
940
940
|
out.push({ key: "C", data: curve4 });
|
|
941
941
|
});
|
|
@@ -963,8 +963,8 @@ function rotate(x, y, angleRad) {
|
|
|
963
963
|
const Y = x * Math.sin(angleRad) + y * Math.cos(angleRad);
|
|
964
964
|
return [X, Y];
|
|
965
965
|
}
|
|
966
|
-
function arcToCubicCurves(x1, y1, x2, y2, r1, r2,
|
|
967
|
-
const angleRad = degToRad(
|
|
966
|
+
function arcToCubicCurves(x1, y1, x2, y2, r1, r2, angle2, largeArcFlag, sweepFlag, recursive) {
|
|
967
|
+
const angleRad = degToRad(angle2);
|
|
968
968
|
let params = [];
|
|
969
969
|
let f1 = 0, f2 = 0, cx = 0, cy = 0;
|
|
970
970
|
if (recursive) {
|
|
@@ -1021,7 +1021,7 @@ function arcToCubicCurves(x1, y1, x2, y2, r1, r2, angle, largeArcFlag, sweepFlag
|
|
|
1021
1021
|
}
|
|
1022
1022
|
x2 = cx + r1 * Math.cos(f2);
|
|
1023
1023
|
y2 = cy + r2 * Math.sin(f2);
|
|
1024
|
-
params = arcToCubicCurves(x2, y2, x2old, y2old, r1, r2,
|
|
1024
|
+
params = arcToCubicCurves(x2, y2, x2old, y2old, r1, r2, angle2, 0, sweepFlag, [f2, f2old, cx, cy]);
|
|
1025
1025
|
}
|
|
1026
1026
|
df = f2 - f1;
|
|
1027
1027
|
const c1 = Math.cos(f1);
|
|
@@ -1227,8 +1227,8 @@ function patternFillArc(x, y, width, height, start, stop, o) {
|
|
|
1227
1227
|
}
|
|
1228
1228
|
const increment = (stp - strt) / o.curveStepCount;
|
|
1229
1229
|
const points = [];
|
|
1230
|
-
for (let
|
|
1231
|
-
points.push([cx + rx * Math.cos(
|
|
1230
|
+
for (let angle2 = strt; angle2 <= stp; angle2 = angle2 + increment) {
|
|
1231
|
+
points.push([cx + rx * Math.cos(angle2), cy + ry * Math.sin(angle2)]);
|
|
1232
1232
|
}
|
|
1233
1233
|
points.push([cx + rx * Math.cos(stp), cy + ry * Math.sin(stp)]);
|
|
1234
1234
|
points.push([cx, cy]);
|
|
@@ -1414,10 +1414,10 @@ function _computeEllipsePoints(increment, cx, cy, rx, ry, offset, overlap, o) {
|
|
|
1414
1414
|
cx + rx * Math.cos(-increment),
|
|
1415
1415
|
cy + ry * Math.sin(-increment)
|
|
1416
1416
|
]);
|
|
1417
|
-
for (let
|
|
1417
|
+
for (let angle2 = 0; angle2 <= Math.PI * 2; angle2 = angle2 + increment) {
|
|
1418
1418
|
const p = [
|
|
1419
|
-
cx + rx * Math.cos(
|
|
1420
|
-
cy + ry * Math.sin(
|
|
1419
|
+
cx + rx * Math.cos(angle2),
|
|
1420
|
+
cy + ry * Math.sin(angle2)
|
|
1421
1421
|
];
|
|
1422
1422
|
corePoints.push(p);
|
|
1423
1423
|
allPoints.push(p);
|
|
@@ -1437,10 +1437,10 @@ function _computeEllipsePoints(increment, cx, cy, rx, ry, offset, overlap, o) {
|
|
|
1437
1437
|
_offsetOpt(offset, o) + cy + 0.9 * ry * Math.sin(radOffset - increment)
|
|
1438
1438
|
]);
|
|
1439
1439
|
const endAngle = Math.PI * 2 + radOffset - 0.01;
|
|
1440
|
-
for (let
|
|
1440
|
+
for (let angle2 = radOffset; angle2 < endAngle; angle2 = angle2 + increment) {
|
|
1441
1441
|
const p = [
|
|
1442
|
-
_offsetOpt(offset, o) + cx + rx * Math.cos(
|
|
1443
|
-
_offsetOpt(offset, o) + cy + ry * Math.sin(
|
|
1442
|
+
_offsetOpt(offset, o) + cx + rx * Math.cos(angle2),
|
|
1443
|
+
_offsetOpt(offset, o) + cy + ry * Math.sin(angle2)
|
|
1444
1444
|
];
|
|
1445
1445
|
corePoints.push(p);
|
|
1446
1446
|
allPoints.push(p);
|
|
@@ -1467,10 +1467,10 @@ function _arc(increment, cx, cy, rx, ry, strt, stp, offset, o) {
|
|
|
1467
1467
|
_offsetOpt(offset, o) + cx + 0.9 * rx * Math.cos(radOffset - increment),
|
|
1468
1468
|
_offsetOpt(offset, o) + cy + 0.9 * ry * Math.sin(radOffset - increment)
|
|
1469
1469
|
]);
|
|
1470
|
-
for (let
|
|
1470
|
+
for (let angle2 = radOffset; angle2 <= stp; angle2 = angle2 + increment) {
|
|
1471
1471
|
points.push([
|
|
1472
|
-
_offsetOpt(offset, o) + cx + rx * Math.cos(
|
|
1473
|
-
_offsetOpt(offset, o) + cy + ry * Math.sin(
|
|
1472
|
+
_offsetOpt(offset, o) + cx + rx * Math.cos(angle2),
|
|
1473
|
+
_offsetOpt(offset, o) + cy + ry * Math.sin(angle2)
|
|
1474
1474
|
]);
|
|
1475
1475
|
}
|
|
1476
1476
|
points.push([
|
|
@@ -2267,11 +2267,10 @@ import {
|
|
|
2267
2267
|
} from "@excalidraw/common";
|
|
2268
2268
|
import {
|
|
2269
2269
|
degreesToRadians,
|
|
2270
|
-
lineSegment as
|
|
2271
|
-
|
|
2272
|
-
pointFrom as pointFrom14,
|
|
2270
|
+
lineSegment as lineSegment6,
|
|
2271
|
+
pointFrom as pointFrom13,
|
|
2273
2272
|
pointFromArray as pointFromArray3,
|
|
2274
|
-
pointRotateRads as
|
|
2273
|
+
pointRotateRads as pointRotateRads12
|
|
2275
2274
|
} from "@excalidraw/math";
|
|
2276
2275
|
|
|
2277
2276
|
// ../utils/src/shape.ts
|
|
@@ -2296,24 +2295,24 @@ import {
|
|
|
2296
2295
|
} from "@excalidraw/math";
|
|
2297
2296
|
import { getElementAbsoluteCoords } from "@excalidraw/element";
|
|
2298
2297
|
var getPolygonShape = (element) => {
|
|
2299
|
-
const { angle, width, height, x, y } = element;
|
|
2298
|
+
const { angle: angle2, width, height, x, y } = element;
|
|
2300
2299
|
const cx = x + width / 2;
|
|
2301
2300
|
const cy = y + height / 2;
|
|
2302
2301
|
const center = pointFrom(cx, cy);
|
|
2303
2302
|
let data;
|
|
2304
2303
|
if (element.type === "diamond") {
|
|
2305
2304
|
data = polygon2(
|
|
2306
|
-
pointRotateRads(pointFrom(cx, y), center,
|
|
2307
|
-
pointRotateRads(pointFrom(x + width, cy), center,
|
|
2308
|
-
pointRotateRads(pointFrom(cx, y + height), center,
|
|
2309
|
-
pointRotateRads(pointFrom(x, cy), center,
|
|
2305
|
+
pointRotateRads(pointFrom(cx, y), center, angle2),
|
|
2306
|
+
pointRotateRads(pointFrom(x + width, cy), center, angle2),
|
|
2307
|
+
pointRotateRads(pointFrom(cx, y + height), center, angle2),
|
|
2308
|
+
pointRotateRads(pointFrom(x, cy), center, angle2)
|
|
2310
2309
|
);
|
|
2311
2310
|
} else {
|
|
2312
2311
|
data = polygon2(
|
|
2313
|
-
pointRotateRads(pointFrom(x, y), center,
|
|
2314
|
-
pointRotateRads(pointFrom(x + width, y), center,
|
|
2315
|
-
pointRotateRads(pointFrom(x + width, y + height), center,
|
|
2316
|
-
pointRotateRads(pointFrom(x, y + height), center,
|
|
2312
|
+
pointRotateRads(pointFrom(x, y), center, angle2),
|
|
2313
|
+
pointRotateRads(pointFrom(x + width, y), center, angle2),
|
|
2314
|
+
pointRotateRads(pointFrom(x + width, y + height), center, angle2),
|
|
2315
|
+
pointRotateRads(pointFrom(x, y + height), center, angle2)
|
|
2317
2316
|
);
|
|
2318
2317
|
}
|
|
2319
2318
|
return {
|
|
@@ -2322,12 +2321,12 @@ var getPolygonShape = (element) => {
|
|
|
2322
2321
|
};
|
|
2323
2322
|
};
|
|
2324
2323
|
var getEllipseShape = (element) => {
|
|
2325
|
-
const { width, height, angle, x, y } = element;
|
|
2324
|
+
const { width, height, angle: angle2, x, y } = element;
|
|
2326
2325
|
return {
|
|
2327
2326
|
type: "ellipse",
|
|
2328
2327
|
data: {
|
|
2329
2328
|
center: pointFrom(x + width / 2, y + height / 2),
|
|
2330
|
-
angle,
|
|
2329
|
+
angle: angle2,
|
|
2331
2330
|
halfWidth: width / 2,
|
|
2332
2331
|
halfHeight: height / 2
|
|
2333
2332
|
}
|
|
@@ -2611,11 +2610,367 @@ function ae(e, t = {}) {
|
|
|
2611
2610
|
return ce(me(e, t), t);
|
|
2612
2611
|
}
|
|
2613
2612
|
|
|
2613
|
+
// ../laser-pointer/src/index.ts
|
|
2614
|
+
init_define_import_meta_env();
|
|
2615
|
+
|
|
2616
|
+
// ../laser-pointer/src/state.ts
|
|
2617
|
+
init_define_import_meta_env();
|
|
2618
|
+
|
|
2619
|
+
// ../laser-pointer/src/math.ts
|
|
2620
|
+
init_define_import_meta_env();
|
|
2621
|
+
function add([ax, ay, ar], [bx, by, br]) {
|
|
2622
|
+
return [ax + bx, ay + by, ar + br];
|
|
2623
|
+
}
|
|
2624
|
+
function sub([ax, ay, ar], [bx, by, br]) {
|
|
2625
|
+
return [ax - bx, ay - by, ar - br];
|
|
2626
|
+
}
|
|
2627
|
+
function smul([x, y, r], s) {
|
|
2628
|
+
return [x * s, y * s, r * s];
|
|
2629
|
+
}
|
|
2630
|
+
function norm([x, y, r]) {
|
|
2631
|
+
return [x / Math.sqrt(x ** 2 + y ** 2), y / Math.sqrt(x ** 2 + y ** 2), r];
|
|
2632
|
+
}
|
|
2633
|
+
function rot([x, y, r], rad) {
|
|
2634
|
+
return [
|
|
2635
|
+
Math.cos(rad) * x - Math.sin(rad) * y,
|
|
2636
|
+
Math.sin(rad) * x + Math.cos(rad) * y,
|
|
2637
|
+
r
|
|
2638
|
+
];
|
|
2639
|
+
}
|
|
2640
|
+
function plerp(a2, b2, t) {
|
|
2641
|
+
return add(a2, smul(sub(b2, a2), t));
|
|
2642
|
+
}
|
|
2643
|
+
function angle(p, p1, p2) {
|
|
2644
|
+
return Math.atan2(p2[1] - p[1], p2[0] - p[0]) - Math.atan2(p1[1] - p[1], p1[0] - p[0]);
|
|
2645
|
+
}
|
|
2646
|
+
function normAngle(a2) {
|
|
2647
|
+
return Math.atan2(Math.sin(a2), Math.cos(a2));
|
|
2648
|
+
}
|
|
2649
|
+
function mag([x, y]) {
|
|
2650
|
+
return Math.sqrt(x ** 2 + y ** 2);
|
|
2651
|
+
}
|
|
2652
|
+
function dist([ax, ay], [bx, by]) {
|
|
2653
|
+
return Math.sqrt((bx - ax) ** 2 + (by - ay) ** 2);
|
|
2654
|
+
}
|
|
2655
|
+
function runLength(ps) {
|
|
2656
|
+
if (ps.length < 2) {
|
|
2657
|
+
return 0;
|
|
2658
|
+
}
|
|
2659
|
+
let len = 0;
|
|
2660
|
+
for (let i = 1; i <= ps.length - 1; i++) {
|
|
2661
|
+
len += dist(ps[i - 1], ps[i]);
|
|
2662
|
+
}
|
|
2663
|
+
len += dist(ps[ps.length - 2], ps[ps.length - 1]);
|
|
2664
|
+
return len;
|
|
2665
|
+
}
|
|
2666
|
+
var clamp = (v, min, max) => Math.max(min, Math.min(max, v));
|
|
2667
|
+
function distancePointToSegment(p3, p1, p2) {
|
|
2668
|
+
const sMag = dist(p1, p2);
|
|
2669
|
+
if (sMag === 0) {
|
|
2670
|
+
return dist(p3, p1);
|
|
2671
|
+
}
|
|
2672
|
+
const u = clamp(
|
|
2673
|
+
((p3[0] - p1[0]) * (p2[0] - p1[0]) + (p3[1] - p1[1]) * (p2[1] - p1[1])) / sMag ** 2,
|
|
2674
|
+
0,
|
|
2675
|
+
1
|
|
2676
|
+
);
|
|
2677
|
+
const pi = [
|
|
2678
|
+
p1[0] + u * (p2[0] - p1[0]),
|
|
2679
|
+
p1[1] + u * (p2[1] - p1[1]),
|
|
2680
|
+
p3[2]
|
|
2681
|
+
];
|
|
2682
|
+
return dist(pi, p3);
|
|
2683
|
+
}
|
|
2684
|
+
|
|
2685
|
+
// ../laser-pointer/src/simplify.ts
|
|
2686
|
+
init_define_import_meta_env();
|
|
2687
|
+
function douglasPeucker(points, epsilon) {
|
|
2688
|
+
if (epsilon === 0) {
|
|
2689
|
+
return points;
|
|
2690
|
+
}
|
|
2691
|
+
if (points.length <= 2) {
|
|
2692
|
+
return points;
|
|
2693
|
+
}
|
|
2694
|
+
const first = points[0];
|
|
2695
|
+
const last = points[points.length - 1];
|
|
2696
|
+
const [maxDistance, maxIndex] = points.reduce(
|
|
2697
|
+
([maxDistance2, maxIndex2], point, index) => {
|
|
2698
|
+
const distance3 = distancePointToSegment(point, first, last);
|
|
2699
|
+
return distance3 > maxDistance2 ? [distance3, index] : [maxDistance2, maxIndex2];
|
|
2700
|
+
},
|
|
2701
|
+
[0, -1]
|
|
2702
|
+
);
|
|
2703
|
+
if (maxDistance >= epsilon) {
|
|
2704
|
+
const maxIndexPoint = points[maxIndex];
|
|
2705
|
+
return [
|
|
2706
|
+
...douglasPeucker(
|
|
2707
|
+
[first, ...points.slice(1, maxIndex), maxIndexPoint],
|
|
2708
|
+
epsilon
|
|
2709
|
+
).slice(0, -1),
|
|
2710
|
+
maxIndexPoint,
|
|
2711
|
+
...douglasPeucker(
|
|
2712
|
+
[maxIndexPoint, ...points.slice(maxIndex, -1), last],
|
|
2713
|
+
epsilon
|
|
2714
|
+
).slice(1)
|
|
2715
|
+
];
|
|
2716
|
+
}
|
|
2717
|
+
return [first, last];
|
|
2718
|
+
}
|
|
2719
|
+
|
|
2720
|
+
// ../laser-pointer/src/state.ts
|
|
2721
|
+
var LaserPointer = class _LaserPointer {
|
|
2722
|
+
static defaults = {
|
|
2723
|
+
size: 2,
|
|
2724
|
+
streamline: 0.45,
|
|
2725
|
+
simplify: 0.1,
|
|
2726
|
+
simplifyPhase: "output",
|
|
2727
|
+
keepHead: false,
|
|
2728
|
+
sizeMapping: () => 1
|
|
2729
|
+
};
|
|
2730
|
+
static constants = {
|
|
2731
|
+
cornerDetectionMaxAngle: 75,
|
|
2732
|
+
cornerDetectionVariance: (s) => s > 35 ? 0.5 : 1,
|
|
2733
|
+
maxTailLength: 50
|
|
2734
|
+
};
|
|
2735
|
+
options;
|
|
2736
|
+
constructor(options) {
|
|
2737
|
+
this.options = Object.assign({}, _LaserPointer.defaults, options);
|
|
2738
|
+
}
|
|
2739
|
+
originalPoints = [];
|
|
2740
|
+
stablePoints = [];
|
|
2741
|
+
tailPoints = [];
|
|
2742
|
+
isFresh = true;
|
|
2743
|
+
get lastPoint() {
|
|
2744
|
+
return this.tailPoints[this.tailPoints.length - 1] ?? this.stablePoints[this.stablePoints.length - 1];
|
|
2745
|
+
}
|
|
2746
|
+
addPoint(point) {
|
|
2747
|
+
const lastPoint = this.originalPoints[this.originalPoints.length - 1];
|
|
2748
|
+
if (lastPoint && lastPoint[0] === point[0] && lastPoint[1] === point[1]) {
|
|
2749
|
+
return;
|
|
2750
|
+
}
|
|
2751
|
+
this.originalPoints.push(point);
|
|
2752
|
+
if (this.isFresh) {
|
|
2753
|
+
this.isFresh = false;
|
|
2754
|
+
this.stablePoints.push(point);
|
|
2755
|
+
return;
|
|
2756
|
+
}
|
|
2757
|
+
if (this.options.streamline > 0) {
|
|
2758
|
+
point = plerp(this.lastPoint, point, 1 - this.options.streamline);
|
|
2759
|
+
}
|
|
2760
|
+
this.tailPoints.push(point);
|
|
2761
|
+
if (runLength(this.tailPoints) > _LaserPointer.constants.maxTailLength) {
|
|
2762
|
+
this.stabilizeTail();
|
|
2763
|
+
}
|
|
2764
|
+
}
|
|
2765
|
+
close() {
|
|
2766
|
+
this.stabilizeTail();
|
|
2767
|
+
}
|
|
2768
|
+
stabilizeTail() {
|
|
2769
|
+
if (this.options.simplify > 0 && this.options.simplifyPhase === "tail") {
|
|
2770
|
+
throw new Error("Not implemented yet");
|
|
2771
|
+
} else {
|
|
2772
|
+
this.stablePoints.push(...this.tailPoints);
|
|
2773
|
+
this.tailPoints = [];
|
|
2774
|
+
}
|
|
2775
|
+
}
|
|
2776
|
+
getSize(sizeOverride, pressure, index, totalLength, runningLength) {
|
|
2777
|
+
return (sizeOverride ?? this.options.size) * this.options.sizeMapping({
|
|
2778
|
+
pressure,
|
|
2779
|
+
runningLength,
|
|
2780
|
+
currentIndex: index,
|
|
2781
|
+
totalLength
|
|
2782
|
+
});
|
|
2783
|
+
}
|
|
2784
|
+
getStrokeOutline(sizeOverride) {
|
|
2785
|
+
if (this.isFresh) {
|
|
2786
|
+
return [];
|
|
2787
|
+
}
|
|
2788
|
+
let points = [...this.stablePoints, ...this.tailPoints];
|
|
2789
|
+
if (this.options.simplify > 0 && this.options.simplifyPhase === "input") {
|
|
2790
|
+
points = douglasPeucker(points, this.options.simplify);
|
|
2791
|
+
}
|
|
2792
|
+
const len = points.length;
|
|
2793
|
+
if (len === 0) {
|
|
2794
|
+
return [];
|
|
2795
|
+
}
|
|
2796
|
+
if (len === 1) {
|
|
2797
|
+
const c = points[0];
|
|
2798
|
+
const size = this.getSize(sizeOverride, c[2], 0, len, 0);
|
|
2799
|
+
if (size < 0.5) {
|
|
2800
|
+
return [];
|
|
2801
|
+
}
|
|
2802
|
+
const ps = [];
|
|
2803
|
+
for (let theta = 0; theta <= Math.PI * 2; theta += Math.PI / 16) {
|
|
2804
|
+
ps.push(add(c, smul(rot([1, 0, 0], theta), size)));
|
|
2805
|
+
}
|
|
2806
|
+
ps.push(
|
|
2807
|
+
add(
|
|
2808
|
+
c,
|
|
2809
|
+
smul(
|
|
2810
|
+
[1, 0, 0],
|
|
2811
|
+
this.getSize(sizeOverride, c[2], 0, len, 0)
|
|
2812
|
+
)
|
|
2813
|
+
)
|
|
2814
|
+
);
|
|
2815
|
+
return ps;
|
|
2816
|
+
}
|
|
2817
|
+
if (len === 2) {
|
|
2818
|
+
const c = points[0];
|
|
2819
|
+
const n = points[1];
|
|
2820
|
+
const cSize = this.getSize(sizeOverride, c[2], 0, len, 0);
|
|
2821
|
+
const nSize = this.getSize(sizeOverride, n[2], 0, len, 0);
|
|
2822
|
+
if (cSize < 0.5 || nSize < 0.5) {
|
|
2823
|
+
return [];
|
|
2824
|
+
}
|
|
2825
|
+
const ps = [];
|
|
2826
|
+
const pAngle = angle(c, [c[0], c[1] - 100, c[2]], n);
|
|
2827
|
+
for (let theta = pAngle; theta <= Math.PI + pAngle; theta += Math.PI / 16) {
|
|
2828
|
+
ps.push(add(c, smul(rot([1, 0, 0], theta), cSize)));
|
|
2829
|
+
}
|
|
2830
|
+
for (let theta = Math.PI + pAngle; theta <= Math.PI * 2 + pAngle; theta += Math.PI / 16) {
|
|
2831
|
+
ps.push(add(n, smul(rot([1, 0, 0], theta), nSize)));
|
|
2832
|
+
}
|
|
2833
|
+
ps.push(ps[0]);
|
|
2834
|
+
return ps;
|
|
2835
|
+
}
|
|
2836
|
+
const forwardPoints = [];
|
|
2837
|
+
const backwardPoints = [];
|
|
2838
|
+
let speed = 0;
|
|
2839
|
+
let prevSpeed = 0;
|
|
2840
|
+
let visibleStartIndex = 0;
|
|
2841
|
+
let runningLength = 0;
|
|
2842
|
+
for (let i = 1; i < len - 1; i++) {
|
|
2843
|
+
const p = points[i - 1];
|
|
2844
|
+
const c = points[i];
|
|
2845
|
+
const n = points[i + 1];
|
|
2846
|
+
const pressure = c[2];
|
|
2847
|
+
const d = dist(p, c);
|
|
2848
|
+
runningLength += d;
|
|
2849
|
+
speed = prevSpeed + (d - prevSpeed) * 0.2;
|
|
2850
|
+
const cSize = this.getSize(sizeOverride, pressure, i, len, runningLength);
|
|
2851
|
+
if (cSize === 0) {
|
|
2852
|
+
visibleStartIndex = i + 1;
|
|
2853
|
+
continue;
|
|
2854
|
+
}
|
|
2855
|
+
const dirPC = norm(sub(p, c));
|
|
2856
|
+
const dirNC = norm(sub(n, c));
|
|
2857
|
+
const p1dirPC = rot(dirPC, Math.PI / 2);
|
|
2858
|
+
const p2dirPC = rot(dirPC, -Math.PI / 2);
|
|
2859
|
+
const p1dirNC = rot(dirNC, Math.PI / 2);
|
|
2860
|
+
const p2dirNC = rot(dirNC, -Math.PI / 2);
|
|
2861
|
+
const p1PC = add(c, smul(p1dirPC, cSize));
|
|
2862
|
+
const p2PC = add(c, smul(p2dirPC, cSize));
|
|
2863
|
+
const p1NC = add(c, smul(p1dirNC, cSize));
|
|
2864
|
+
const p2NC = add(c, smul(p2dirNC, cSize));
|
|
2865
|
+
const ftdir = add(p1dirPC, p2dirNC);
|
|
2866
|
+
const btdir = add(p2dirPC, p1dirNC);
|
|
2867
|
+
const paPC = add(
|
|
2868
|
+
c,
|
|
2869
|
+
smul(mag(ftdir) === 0 ? dirPC : norm(ftdir), cSize)
|
|
2870
|
+
);
|
|
2871
|
+
const paNC = add(
|
|
2872
|
+
c,
|
|
2873
|
+
smul(mag(btdir) === 0 ? dirNC : norm(btdir), cSize)
|
|
2874
|
+
);
|
|
2875
|
+
const cAngle = normAngle(angle(c, p, n));
|
|
2876
|
+
const D_ANGLE = _LaserPointer.constants.cornerDetectionMaxAngle / 180 * Math.PI * _LaserPointer.constants.cornerDetectionVariance(speed);
|
|
2877
|
+
if (Math.abs(cAngle) < D_ANGLE) {
|
|
2878
|
+
const tAngle = Math.abs(normAngle(Math.PI - cAngle));
|
|
2879
|
+
if (tAngle === 0) {
|
|
2880
|
+
continue;
|
|
2881
|
+
}
|
|
2882
|
+
if (cAngle < 0) {
|
|
2883
|
+
backwardPoints.push(p2PC, paNC);
|
|
2884
|
+
for (let theta = 0; theta <= tAngle; theta += tAngle / 4) {
|
|
2885
|
+
forwardPoints.push(add(c, rot(smul(p1dirPC, cSize), theta)));
|
|
2886
|
+
}
|
|
2887
|
+
for (let theta = tAngle; theta >= 0; theta -= tAngle / 4) {
|
|
2888
|
+
backwardPoints.push(add(c, rot(smul(p1dirPC, cSize), theta)));
|
|
2889
|
+
}
|
|
2890
|
+
backwardPoints.push(paNC, p1NC);
|
|
2891
|
+
} else {
|
|
2892
|
+
forwardPoints.push(p1PC, paPC);
|
|
2893
|
+
for (let theta = 0; theta <= tAngle; theta += tAngle / 4) {
|
|
2894
|
+
backwardPoints.push(
|
|
2895
|
+
add(c, rot(smul(p1dirPC, -cSize), -theta))
|
|
2896
|
+
);
|
|
2897
|
+
}
|
|
2898
|
+
for (let theta = tAngle; theta >= 0; theta -= tAngle / 4) {
|
|
2899
|
+
forwardPoints.push(
|
|
2900
|
+
add(c, rot(smul(p1dirPC, -cSize), -theta))
|
|
2901
|
+
);
|
|
2902
|
+
}
|
|
2903
|
+
forwardPoints.push(paPC, p2NC);
|
|
2904
|
+
}
|
|
2905
|
+
} else {
|
|
2906
|
+
forwardPoints.push(paPC);
|
|
2907
|
+
backwardPoints.push(paNC);
|
|
2908
|
+
}
|
|
2909
|
+
prevSpeed = speed;
|
|
2910
|
+
}
|
|
2911
|
+
if (visibleStartIndex >= len - 2) {
|
|
2912
|
+
if (this.options.keepHead) {
|
|
2913
|
+
const c = points[len - 1];
|
|
2914
|
+
const ps = [];
|
|
2915
|
+
for (let theta = 0; theta <= Math.PI * 2; theta += Math.PI / 16) {
|
|
2916
|
+
ps.push(
|
|
2917
|
+
add(
|
|
2918
|
+
c,
|
|
2919
|
+
smul(rot([1, 0, 0], theta), this.options.size)
|
|
2920
|
+
)
|
|
2921
|
+
);
|
|
2922
|
+
}
|
|
2923
|
+
ps.push(add(c, smul([1, 0, 0], this.options.size)));
|
|
2924
|
+
return ps;
|
|
2925
|
+
}
|
|
2926
|
+
return [];
|
|
2927
|
+
}
|
|
2928
|
+
const first = points[visibleStartIndex];
|
|
2929
|
+
const second = points[visibleStartIndex + 1];
|
|
2930
|
+
const penultimate = points[len - 2];
|
|
2931
|
+
const ultimate = points[len - 1];
|
|
2932
|
+
const dirFS = norm(sub(second, first));
|
|
2933
|
+
const dirPU = norm(sub(penultimate, ultimate));
|
|
2934
|
+
const ppdirFS = rot(dirFS, -Math.PI / 2);
|
|
2935
|
+
const ppdirPU = rot(dirPU, Math.PI / 2);
|
|
2936
|
+
const startCapSize = this.getSize(sizeOverride, first[2], 0, len, 0);
|
|
2937
|
+
const startCap = [];
|
|
2938
|
+
const endCapSize = this.options.keepHead ? this.options.size : this.getSize(sizeOverride, penultimate[2], len - 2, len, runningLength);
|
|
2939
|
+
const endCap = [];
|
|
2940
|
+
if (startCapSize > 0.1) {
|
|
2941
|
+
for (let theta = 0; theta <= Math.PI; theta += Math.PI / 16) {
|
|
2942
|
+
startCap.unshift(
|
|
2943
|
+
add(first, rot(smul(ppdirFS, startCapSize), -theta))
|
|
2944
|
+
);
|
|
2945
|
+
}
|
|
2946
|
+
startCap.unshift(add(first, smul(ppdirFS, -startCapSize)));
|
|
2947
|
+
} else {
|
|
2948
|
+
startCap.push(first);
|
|
2949
|
+
}
|
|
2950
|
+
for (let theta = 0; theta <= Math.PI * 3; theta += Math.PI / 16) {
|
|
2951
|
+
endCap.push(add(ultimate, rot(smul(ppdirPU, -endCapSize), -theta)));
|
|
2952
|
+
}
|
|
2953
|
+
const strokeOutline = [
|
|
2954
|
+
...startCap,
|
|
2955
|
+
...forwardPoints,
|
|
2956
|
+
...endCap.reverse(),
|
|
2957
|
+
...backwardPoints.reverse()
|
|
2958
|
+
];
|
|
2959
|
+
if (startCap.length > 0) {
|
|
2960
|
+
strokeOutline.push(startCap[0]);
|
|
2961
|
+
}
|
|
2962
|
+
if (this.options.simplify > 0 && this.options.simplifyPhase === "output") {
|
|
2963
|
+
return douglasPeucker(strokeOutline, this.options.simplify);
|
|
2964
|
+
}
|
|
2965
|
+
return strokeOutline;
|
|
2966
|
+
}
|
|
2967
|
+
};
|
|
2968
|
+
|
|
2614
2969
|
// src/shape.ts
|
|
2615
2970
|
import {
|
|
2616
|
-
pointFrom as
|
|
2971
|
+
pointFrom as pointFrom12,
|
|
2617
2972
|
pointDistance as pointDistance6,
|
|
2618
|
-
pointRotateRads as
|
|
2973
|
+
pointRotateRads as pointRotateRads11
|
|
2619
2974
|
} from "@excalidraw/math";
|
|
2620
2975
|
import {
|
|
2621
2976
|
ROUGHNESS,
|
|
@@ -2624,16 +2979,17 @@ import {
|
|
|
2624
2979
|
assertNever as assertNever2,
|
|
2625
2980
|
COLOR_PALETTE,
|
|
2626
2981
|
LINE_POLYGON_POINT_MERGE_DISTANCE,
|
|
2627
|
-
applyDarkModeFilter as applyDarkModeFilter2
|
|
2982
|
+
applyDarkModeFilter as applyDarkModeFilter2,
|
|
2983
|
+
DEFAULT_STROKE_STREAMLINE
|
|
2628
2984
|
} from "@excalidraw/common";
|
|
2629
2985
|
|
|
2630
2986
|
// src/renderElement.ts
|
|
2631
2987
|
init_define_import_meta_env();
|
|
2632
2988
|
import {
|
|
2633
2989
|
isRightAngleRads,
|
|
2634
|
-
lineSegment as
|
|
2635
|
-
pointFrom as
|
|
2636
|
-
pointRotateRads as
|
|
2990
|
+
lineSegment as lineSegment5,
|
|
2991
|
+
pointFrom as pointFrom11,
|
|
2992
|
+
pointRotateRads as pointRotateRads10
|
|
2637
2993
|
} from "@excalidraw/math";
|
|
2638
2994
|
import {
|
|
2639
2995
|
BOUND_TEXT_PADDING as BOUND_TEXT_PADDING3,
|
|
@@ -2664,7 +3020,7 @@ import {
|
|
|
2664
3020
|
vectorAdd as vectorAdd2,
|
|
2665
3021
|
vectorScale as vectorScale2,
|
|
2666
3022
|
pointFromVector as pointFromVector2,
|
|
2667
|
-
clamp,
|
|
3023
|
+
clamp as clamp2,
|
|
2668
3024
|
isCloseTo
|
|
2669
3025
|
} from "@excalidraw/math";
|
|
2670
3026
|
var MINIMAL_CROP_SIZE = 10;
|
|
@@ -2698,7 +3054,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
2698
3054
|
let changeInHeight = pointerY - element.y;
|
|
2699
3055
|
let changeInWidth = pointerX - element.x;
|
|
2700
3056
|
if (transformHandle.includes("n")) {
|
|
2701
|
-
nextHeight =
|
|
3057
|
+
nextHeight = clamp2(
|
|
2702
3058
|
element.height - changeInHeight,
|
|
2703
3059
|
MINIMAL_CROP_SIZE,
|
|
2704
3060
|
isFlippedByY ? uncroppedHeight - croppedTop : element.height + croppedTop
|
|
@@ -2706,7 +3062,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
2706
3062
|
}
|
|
2707
3063
|
if (transformHandle.includes("s")) {
|
|
2708
3064
|
changeInHeight = pointerY - element.y - element.height;
|
|
2709
|
-
nextHeight =
|
|
3065
|
+
nextHeight = clamp2(
|
|
2710
3066
|
element.height + changeInHeight,
|
|
2711
3067
|
MINIMAL_CROP_SIZE,
|
|
2712
3068
|
isFlippedByY ? element.height + croppedTop : uncroppedHeight - croppedTop
|
|
@@ -2714,14 +3070,14 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
2714
3070
|
}
|
|
2715
3071
|
if (transformHandle.includes("e")) {
|
|
2716
3072
|
changeInWidth = pointerX - element.x - element.width;
|
|
2717
|
-
nextWidth =
|
|
3073
|
+
nextWidth = clamp2(
|
|
2718
3074
|
element.width + changeInWidth,
|
|
2719
3075
|
MINIMAL_CROP_SIZE,
|
|
2720
3076
|
isFlippedByX ? element.width + croppedLeft : uncroppedWidth - croppedLeft
|
|
2721
3077
|
);
|
|
2722
3078
|
}
|
|
2723
3079
|
if (transformHandle.includes("w")) {
|
|
2724
|
-
nextWidth =
|
|
3080
|
+
nextWidth = clamp2(
|
|
2725
3081
|
element.width - changeInWidth,
|
|
2726
3082
|
MINIMAL_CROP_SIZE,
|
|
2727
3083
|
isFlippedByX ? uncroppedWidth - croppedLeft : element.width + croppedLeft
|
|
@@ -2761,7 +3117,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
2761
3117
|
const distanceToLeft = croppedLeft + element.width / 2;
|
|
2762
3118
|
const distanceToRight = uncroppedWidth - croppedLeft - element.width / 2;
|
|
2763
3119
|
const MAX_WIDTH = Math.min(distanceToLeft, distanceToRight) * 2;
|
|
2764
|
-
nextWidth =
|
|
3120
|
+
nextWidth = clamp2(
|
|
2765
3121
|
nextHeight * widthAspectRatio,
|
|
2766
3122
|
MINIMAL_CROP_SIZE,
|
|
2767
3123
|
MAX_WIDTH
|
|
@@ -2779,7 +3135,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
2779
3135
|
const distanceToLeft = croppedLeft + element.width / 2;
|
|
2780
3136
|
const distanceToRight = uncroppedWidth - croppedLeft - element.width / 2;
|
|
2781
3137
|
const MAX_WIDTH = Math.min(distanceToLeft, distanceToRight) * 2;
|
|
2782
|
-
nextWidth =
|
|
3138
|
+
nextWidth = clamp2(
|
|
2783
3139
|
nextHeight * widthAspectRatio,
|
|
2784
3140
|
MINIMAL_CROP_SIZE,
|
|
2785
3141
|
MAX_WIDTH
|
|
@@ -2797,7 +3153,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
2797
3153
|
const distanceToTop = croppedTop + element.height / 2;
|
|
2798
3154
|
const distanceToBottom = uncroppedHeight - croppedTop - element.height / 2;
|
|
2799
3155
|
const MAX_HEIGHT = Math.min(distanceToTop, distanceToBottom) * 2;
|
|
2800
|
-
nextHeight =
|
|
3156
|
+
nextHeight = clamp2(
|
|
2801
3157
|
nextWidth / widthAspectRatio,
|
|
2802
3158
|
MINIMAL_CROP_SIZE,
|
|
2803
3159
|
MAX_HEIGHT
|
|
@@ -2815,7 +3171,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
2815
3171
|
const distanceToTop = croppedTop + element.height / 2;
|
|
2816
3172
|
const distanceToBottom = uncroppedHeight - croppedTop - element.height / 2;
|
|
2817
3173
|
const MAX_HEIGHT = Math.min(distanceToTop, distanceToBottom) * 2;
|
|
2818
|
-
nextHeight =
|
|
3174
|
+
nextHeight = clamp2(
|
|
2819
3175
|
nextWidth / widthAspectRatio,
|
|
2820
3176
|
MINIMAL_CROP_SIZE,
|
|
2821
3177
|
MAX_HEIGHT
|
|
@@ -2832,7 +3188,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
2832
3188
|
if (widthAspectRatio) {
|
|
2833
3189
|
if (changeInWidth > -changeInHeight) {
|
|
2834
3190
|
const MAX_HEIGHT = isFlippedByY ? uncroppedHeight - croppedTop : croppedTop + element.height;
|
|
2835
|
-
nextHeight =
|
|
3191
|
+
nextHeight = clamp2(
|
|
2836
3192
|
nextWidth / widthAspectRatio,
|
|
2837
3193
|
MINIMAL_CROP_SIZE,
|
|
2838
3194
|
MAX_HEIGHT
|
|
@@ -2840,7 +3196,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
2840
3196
|
nextWidth = nextHeight * widthAspectRatio;
|
|
2841
3197
|
} else {
|
|
2842
3198
|
const MAX_WIDTH = isFlippedByX ? croppedLeft + element.width : uncroppedWidth - croppedLeft;
|
|
2843
|
-
nextWidth =
|
|
3199
|
+
nextWidth = clamp2(
|
|
2844
3200
|
nextHeight * widthAspectRatio,
|
|
2845
3201
|
MINIMAL_CROP_SIZE,
|
|
2846
3202
|
MAX_WIDTH
|
|
@@ -2855,7 +3211,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
2855
3211
|
if (widthAspectRatio) {
|
|
2856
3212
|
if (changeInWidth < changeInHeight) {
|
|
2857
3213
|
const MAX_HEIGHT = isFlippedByY ? uncroppedHeight - croppedTop : croppedTop + element.height;
|
|
2858
|
-
nextHeight =
|
|
3214
|
+
nextHeight = clamp2(
|
|
2859
3215
|
nextWidth / widthAspectRatio,
|
|
2860
3216
|
MINIMAL_CROP_SIZE,
|
|
2861
3217
|
MAX_HEIGHT
|
|
@@ -2863,7 +3219,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
2863
3219
|
nextWidth = nextHeight * widthAspectRatio;
|
|
2864
3220
|
} else {
|
|
2865
3221
|
const MAX_WIDTH = isFlippedByX ? uncroppedWidth - croppedLeft : croppedLeft + element.width;
|
|
2866
|
-
nextWidth =
|
|
3222
|
+
nextWidth = clamp2(
|
|
2867
3223
|
nextHeight * widthAspectRatio,
|
|
2868
3224
|
MINIMAL_CROP_SIZE,
|
|
2869
3225
|
MAX_WIDTH
|
|
@@ -2878,7 +3234,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
2878
3234
|
if (widthAspectRatio) {
|
|
2879
3235
|
if (changeInWidth > changeInHeight) {
|
|
2880
3236
|
const MAX_HEIGHT = isFlippedByY ? croppedTop + element.height : uncroppedHeight - croppedTop;
|
|
2881
|
-
nextHeight =
|
|
3237
|
+
nextHeight = clamp2(
|
|
2882
3238
|
nextWidth / widthAspectRatio,
|
|
2883
3239
|
MINIMAL_CROP_SIZE,
|
|
2884
3240
|
MAX_HEIGHT
|
|
@@ -2886,7 +3242,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
2886
3242
|
nextWidth = nextHeight * widthAspectRatio;
|
|
2887
3243
|
} else {
|
|
2888
3244
|
const MAX_WIDTH = isFlippedByX ? croppedLeft + element.width : uncroppedWidth - croppedLeft;
|
|
2889
|
-
nextWidth =
|
|
3245
|
+
nextWidth = clamp2(
|
|
2890
3246
|
nextHeight * widthAspectRatio,
|
|
2891
3247
|
MINIMAL_CROP_SIZE,
|
|
2892
3248
|
MAX_WIDTH
|
|
@@ -2901,7 +3257,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
2901
3257
|
if (widthAspectRatio) {
|
|
2902
3258
|
if (-changeInWidth > changeInHeight) {
|
|
2903
3259
|
const MAX_HEIGHT = isFlippedByY ? croppedTop + element.height : uncroppedHeight - croppedTop;
|
|
2904
|
-
nextHeight =
|
|
3260
|
+
nextHeight = clamp2(
|
|
2905
3261
|
nextWidth / widthAspectRatio,
|
|
2906
3262
|
MINIMAL_CROP_SIZE,
|
|
2907
3263
|
MAX_HEIGHT
|
|
@@ -2909,7 +3265,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
2909
3265
|
nextWidth = nextHeight * widthAspectRatio;
|
|
2910
3266
|
} else {
|
|
2911
3267
|
const MAX_WIDTH = isFlippedByX ? uncroppedWidth - croppedLeft : croppedLeft + element.width;
|
|
2912
|
-
nextWidth =
|
|
3268
|
+
nextWidth = clamp2(
|
|
2913
3269
|
nextHeight * widthAspectRatio,
|
|
2914
3270
|
MINIMAL_CROP_SIZE,
|
|
2915
3271
|
MAX_WIDTH
|
|
@@ -2977,17 +3333,17 @@ var recomputeOrigin = (stateAtCropStart, transformHandle, width, height, shouldM
|
|
|
2977
3333
|
newTopLeft[1] = startCenter[1] - newBoundsHeight / 2;
|
|
2978
3334
|
}
|
|
2979
3335
|
}
|
|
2980
|
-
const
|
|
2981
|
-
const rotatedTopLeft = pointRotateRads2(newTopLeft, startCenter,
|
|
3336
|
+
const angle2 = stateAtCropStart.angle;
|
|
3337
|
+
const rotatedTopLeft = pointRotateRads2(newTopLeft, startCenter, angle2);
|
|
2982
3338
|
const newCenter = [
|
|
2983
3339
|
newTopLeft[0] + Math.abs(newBoundsWidth) / 2,
|
|
2984
3340
|
newTopLeft[1] + Math.abs(newBoundsHeight) / 2
|
|
2985
3341
|
];
|
|
2986
|
-
const rotatedNewCenter = pointRotateRads2(newCenter, startCenter,
|
|
3342
|
+
const rotatedNewCenter = pointRotateRads2(newCenter, startCenter, angle2);
|
|
2987
3343
|
newTopLeft = pointRotateRads2(
|
|
2988
3344
|
rotatedTopLeft,
|
|
2989
3345
|
rotatedNewCenter,
|
|
2990
|
-
-
|
|
3346
|
+
-angle2
|
|
2991
3347
|
);
|
|
2992
3348
|
const newOrigin = [...newTopLeft];
|
|
2993
3349
|
newOrigin[0] += stateAtCropStart.x - newBoundsX1;
|
|
@@ -3149,7 +3505,7 @@ import {
|
|
|
3149
3505
|
} from "@excalidraw/common";
|
|
3150
3506
|
import {
|
|
3151
3507
|
PRECISION as PRECISION2,
|
|
3152
|
-
clamp as
|
|
3508
|
+
clamp as clamp4,
|
|
3153
3509
|
lineSegment as lineSegment4,
|
|
3154
3510
|
pointDistance as pointDistance4,
|
|
3155
3511
|
pointDistanceSq,
|
|
@@ -4695,8 +5051,8 @@ var computeBoundTextPosition = (container, boundTextElement, elementsMap) => {
|
|
|
4695
5051
|
} else {
|
|
4696
5052
|
x = containerCoords.x + (maxContainerWidth / 2 - boundTextElement.width / 2);
|
|
4697
5053
|
}
|
|
4698
|
-
const
|
|
4699
|
-
if (
|
|
5054
|
+
const angle2 = container.angle ?? 0;
|
|
5055
|
+
if (angle2 !== 0) {
|
|
4700
5056
|
const contentCenter = pointFrom4(
|
|
4701
5057
|
containerCoords.x + maxContainerWidth / 2,
|
|
4702
5058
|
containerCoords.y + maxContainerHeight / 2
|
|
@@ -4705,7 +5061,7 @@ var computeBoundTextPosition = (container, boundTextElement, elementsMap) => {
|
|
|
4705
5061
|
x + boundTextElement.width / 2,
|
|
4706
5062
|
y + boundTextElement.height / 2
|
|
4707
5063
|
);
|
|
4708
|
-
const [rx, ry] = pointRotateRads4(textCenter, contentCenter,
|
|
5064
|
+
const [rx, ry] = pointRotateRads4(textCenter, contentCenter, angle2);
|
|
4709
5065
|
return {
|
|
4710
5066
|
x: rx - boundTextElement.width / 2,
|
|
4711
5067
|
y: ry - boundTextElement.height / 2
|
|
@@ -4722,7 +5078,13 @@ var getBoundTextElement = (element, elementsMap) => {
|
|
|
4722
5078
|
}
|
|
4723
5079
|
const boundTextElementId = getBoundTextElementId(element);
|
|
4724
5080
|
if (boundTextElementId) {
|
|
4725
|
-
|
|
5081
|
+
const boundTextElement = elementsMap.get(boundTextElementId) || null;
|
|
5082
|
+
if (boundTextElement && !isNonDeletedElement(boundTextElement)) {
|
|
5083
|
+
console.error(
|
|
5084
|
+
"[NONDELETED][INVARIANT] Bound text element `isDeleted: true` which is not expected."
|
|
5085
|
+
);
|
|
5086
|
+
}
|
|
5087
|
+
return boundTextElement;
|
|
4726
5088
|
}
|
|
4727
5089
|
return null;
|
|
4728
5090
|
};
|
|
@@ -4962,6 +5324,7 @@ var hasBackground = (type) => type === "rectangle" || type === "iframe" || type
|
|
|
4962
5324
|
var hasStrokeColor = (type) => type === "rectangle" || type === "ellipse" || type === "diamond" || type === "freedraw" || type === "arrow" || type === "line" || type === "text" || type === "embeddable";
|
|
4963
5325
|
var hasStrokeWidth = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "freedraw" || type === "arrow" || type === "line";
|
|
4964
5326
|
var hasStrokeStyle = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "arrow" || type === "line";
|
|
5327
|
+
var hasFreedrawMode = (type) => type === "freedraw";
|
|
4965
5328
|
var canChangeRoundness = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "line" || type === "diamond" || type === "image";
|
|
4966
5329
|
var toolIsArrow = (type) => type === "arrow";
|
|
4967
5330
|
var canHaveArrowheads = (type) => type === "arrow";
|
|
@@ -5030,8 +5393,8 @@ var hitElementItself = ({
|
|
|
5030
5393
|
cachedHit = result;
|
|
5031
5394
|
return result;
|
|
5032
5395
|
};
|
|
5033
|
-
var isPointInRotatedBounds = (point, bounds,
|
|
5034
|
-
const adjustedPoint =
|
|
5396
|
+
var isPointInRotatedBounds = (point, bounds, angle2, tolerance = 0) => {
|
|
5397
|
+
const adjustedPoint = angle2 === 0 ? point : pointRotateRads6(point, getCenterForBounds(bounds), -angle2);
|
|
5035
5398
|
return isPointWithinBounds(
|
|
5036
5399
|
pointFrom5(bounds[0] - tolerance, bounds[1] - tolerance),
|
|
5037
5400
|
adjustedPoint,
|
|
@@ -5207,7 +5570,7 @@ var intersectElementWithLineSegment = (element, elementsMap, line2, offset = 0,
|
|
|
5207
5570
|
);
|
|
5208
5571
|
}
|
|
5209
5572
|
};
|
|
5210
|
-
var curveIntersections = (curves, segment, intersections, center,
|
|
5573
|
+
var curveIntersections = (curves, segment, intersections, center, angle2, onlyFirst = false) => {
|
|
5211
5574
|
for (const c of curves) {
|
|
5212
5575
|
const b1 = getCubicBezierCurveBound(c[0], c[1], c[2], c[3]);
|
|
5213
5576
|
const b2 = [
|
|
@@ -5222,7 +5585,7 @@ var curveIntersections = (curves, segment, intersections, center, angle, onlyFir
|
|
|
5222
5585
|
const hits = curveIntersectLineSegment(c, segment);
|
|
5223
5586
|
if (hits.length > 0) {
|
|
5224
5587
|
for (const j of hits) {
|
|
5225
|
-
intersections.push(pointRotateRads6(j, center,
|
|
5588
|
+
intersections.push(pointRotateRads6(j, center, angle2));
|
|
5226
5589
|
}
|
|
5227
5590
|
if (onlyFirst) {
|
|
5228
5591
|
return intersections;
|
|
@@ -5231,11 +5594,11 @@ var curveIntersections = (curves, segment, intersections, center, angle, onlyFir
|
|
|
5231
5594
|
}
|
|
5232
5595
|
return intersections;
|
|
5233
5596
|
};
|
|
5234
|
-
var lineIntersections = (lines, segment, intersections, center,
|
|
5597
|
+
var lineIntersections = (lines, segment, intersections, center, angle2, onlyFirst = false) => {
|
|
5235
5598
|
for (const l2 of lines) {
|
|
5236
5599
|
const intersection = lineSegmentIntersectionPoints2(l2, segment);
|
|
5237
5600
|
if (intersection) {
|
|
5238
|
-
intersections.push(pointRotateRads6(intersection, center,
|
|
5601
|
+
intersections.push(pointRotateRads6(intersection, center, angle2));
|
|
5239
5602
|
if (onlyFirst) {
|
|
5240
5603
|
return intersections;
|
|
5241
5604
|
}
|
|
@@ -5381,7 +5744,7 @@ var isPointInElement = (point, element, elementsMap) => {
|
|
|
5381
5744
|
};
|
|
5382
5745
|
var isBindableElementInsideOtherBindable = (innerElement, outerElement, elementsMap) => {
|
|
5383
5746
|
const getCornerPoints = (element, offset2) => {
|
|
5384
|
-
const { x, y, width, height, angle } = element;
|
|
5747
|
+
const { x, y, width, height, angle: angle2 } = element;
|
|
5385
5748
|
const center = elementCenterPoint(element, elementsMap);
|
|
5386
5749
|
if (element.type === "diamond") {
|
|
5387
5750
|
const [topX, topY, rightX, rightY, bottomX, bottomY, leftX, leftY] = getDiamondPoints(element);
|
|
@@ -5395,7 +5758,7 @@ var isBindableElementInsideOtherBindable = (innerElement, outerElement, elements
|
|
|
5395
5758
|
pointFrom5(x + leftX - offset2, y + leftY)
|
|
5396
5759
|
// left
|
|
5397
5760
|
];
|
|
5398
|
-
return corners2.map((corner) => pointRotateRads6(corner, center,
|
|
5761
|
+
return corners2.map((corner) => pointRotateRads6(corner, center, angle2));
|
|
5399
5762
|
}
|
|
5400
5763
|
if (element.type === "ellipse") {
|
|
5401
5764
|
const cx = x + width / 2;
|
|
@@ -5412,7 +5775,7 @@ var isBindableElementInsideOtherBindable = (innerElement, outerElement, elements
|
|
|
5412
5775
|
pointFrom5(cx - rx - offset2, cy)
|
|
5413
5776
|
// left
|
|
5414
5777
|
];
|
|
5415
|
-
return corners2.map((corner) => pointRotateRads6(corner, center,
|
|
5778
|
+
return corners2.map((corner) => pointRotateRads6(corner, center, angle2));
|
|
5416
5779
|
}
|
|
5417
5780
|
const corners = [
|
|
5418
5781
|
pointFrom5(x - offset2, y - offset2),
|
|
@@ -5424,7 +5787,7 @@ var isBindableElementInsideOtherBindable = (innerElement, outerElement, elements
|
|
|
5424
5787
|
pointFrom5(x - offset2, y + height + offset2)
|
|
5425
5788
|
// bottom-left
|
|
5426
5789
|
];
|
|
5427
|
-
return corners.map((corner) => pointRotateRads6(corner, center,
|
|
5790
|
+
return corners.map((corner) => pointRotateRads6(corner, center, angle2));
|
|
5428
5791
|
};
|
|
5429
5792
|
const offset = -1 * Math.max(innerElement.width, innerElement.height) / 20;
|
|
5430
5793
|
const innerCorners = getCornerPoints(innerElement, offset);
|
|
@@ -5650,7 +6013,7 @@ import {
|
|
|
5650
6013
|
// src/elbowArrow.ts
|
|
5651
6014
|
init_define_import_meta_env();
|
|
5652
6015
|
import {
|
|
5653
|
-
clamp as
|
|
6016
|
+
clamp as clamp3,
|
|
5654
6017
|
pointDistance as pointDistance3,
|
|
5655
6018
|
pointFrom as pointFrom7,
|
|
5656
6019
|
pointScaleFromOrigin as pointScaleFromOrigin2,
|
|
@@ -6994,12 +7357,12 @@ var normalizeArrowElementUpdate = (global2, nextFixedSegments, startIsSpecial, e
|
|
|
6994
7357
|
);
|
|
6995
7358
|
}
|
|
6996
7359
|
points = points.map(
|
|
6997
|
-
([x, y]) => pointFrom7(
|
|
7360
|
+
([x, y]) => pointFrom7(clamp3(x, -1e6, 1e6), clamp3(y, -1e6, 1e6))
|
|
6998
7361
|
);
|
|
6999
7362
|
return {
|
|
7000
7363
|
points,
|
|
7001
|
-
x:
|
|
7002
|
-
y:
|
|
7364
|
+
x: clamp3(offsetX, -1e6, 1e6),
|
|
7365
|
+
y: clamp3(offsetY, -1e6, 1e6),
|
|
7003
7366
|
fixedSegments: (nextFixedSegments?.length ?? 0) > 0 ? nextFixedSegments : null,
|
|
7004
7367
|
...getSizeFromPoints(points),
|
|
7005
7368
|
startIsSpecial,
|
|
@@ -7205,13 +7568,14 @@ var BASE_BINDING_GAP = 5;
|
|
|
7205
7568
|
var BASE_BINDING_GAP_ELBOW = 5;
|
|
7206
7569
|
var BASE_ARROW_MIN_LENGTH = 10;
|
|
7207
7570
|
var FOCUS_POINT_SIZE = 10 / 1.5;
|
|
7571
|
+
var MIN_BINDABLE_SIZE = 1;
|
|
7208
7572
|
var getBindingGap = (bindTarget, opts) => {
|
|
7209
7573
|
return (opts.elbowed ? BASE_BINDING_GAP_ELBOW : BASE_BINDING_GAP) + bindTarget.strokeWidth / 2;
|
|
7210
7574
|
};
|
|
7211
7575
|
var maxBindingDistance_simple = (zoom) => {
|
|
7212
7576
|
const BASE_BINDING_DISTANCE = Math.max(BASE_BINDING_GAP, 15);
|
|
7213
7577
|
const zoomValue = zoom?.value && zoom.value < 1 ? zoom.value : 1;
|
|
7214
|
-
return
|
|
7578
|
+
return clamp4(
|
|
7215
7579
|
// reducing zoom impact so that the diff between binding distance and
|
|
7216
7580
|
// binding gap is kept to minimum when possible
|
|
7217
7581
|
BASE_BINDING_DISTANCE / (zoomValue * 1.5),
|
|
@@ -7438,7 +7802,9 @@ var bindingStrategyForSimpleArrowEndpointDragging_complex = (point, currentBindi
|
|
|
7438
7802
|
const isOverlapping = oppositeBinding ? getAllHoveredElementAtPoint(point, elements, elementsMap).some(
|
|
7439
7803
|
(el) => el.id === oppositeBinding.elementId
|
|
7440
7804
|
) : false;
|
|
7441
|
-
const oppositeElement = oppositeBinding ? elementsMap.get(
|
|
7805
|
+
const oppositeElement = oppositeBinding ? elementsMap.get(
|
|
7806
|
+
oppositeBinding.elementId
|
|
7807
|
+
) : null;
|
|
7442
7808
|
const otherIsTransparent = isOverlapping && oppositeElement ? isTransparent2(oppositeElement.backgroundColor) : false;
|
|
7443
7809
|
const isNested = hit && oppositeElement && isBindableElementInsideOtherBindable(oppositeElement, hit, elementsMap);
|
|
7444
7810
|
if (globalBindMode === "inside" || globalBindMode === "skip") {
|
|
@@ -7523,10 +7889,12 @@ var getBindingStrategyForDraggingBindingElementEndpoints_simple = (arrow, draggi
|
|
|
7523
7889
|
const endDragged = draggingPoints.has(endIdx);
|
|
7524
7890
|
let start = { mode: void 0 };
|
|
7525
7891
|
let end = { mode: void 0 };
|
|
7526
|
-
|
|
7527
|
-
|
|
7528
|
-
|
|
7529
|
-
|
|
7892
|
+
if (arrow.points.length < 2) {
|
|
7893
|
+
console.error(
|
|
7894
|
+
"Attempting to bind a linear element with less than 2 points"
|
|
7895
|
+
);
|
|
7896
|
+
return { start: { mode: void 0 }, end: { mode: void 0 } };
|
|
7897
|
+
}
|
|
7530
7898
|
if (!startDragged && !endDragged) {
|
|
7531
7899
|
return { start, end };
|
|
7532
7900
|
}
|
|
@@ -7687,10 +8055,12 @@ var getBindingStrategyForDraggingBindingElementEndpoints_complex = (arrow, dragg
|
|
|
7687
8055
|
const endDragged = draggingPoints.has(endIdx);
|
|
7688
8056
|
let start = { mode: void 0 };
|
|
7689
8057
|
let end = { mode: void 0 };
|
|
7690
|
-
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
|
-
|
|
8058
|
+
if (arrow.points.length < 2) {
|
|
8059
|
+
console.error(
|
|
8060
|
+
"Attempting to bind a linear element with less than 2 points"
|
|
8061
|
+
);
|
|
8062
|
+
return { start: { mode: void 0 }, end: { mode: void 0 } };
|
|
8063
|
+
}
|
|
7694
8064
|
if (!startDragged && !endDragged) {
|
|
7695
8065
|
return { start, end };
|
|
7696
8066
|
}
|
|
@@ -7856,7 +8226,12 @@ var updateBoundElements = (changedElement, scene, options) => {
|
|
|
7856
8226
|
});
|
|
7857
8227
|
}
|
|
7858
8228
|
const visitor = (element) => {
|
|
7859
|
-
if (
|
|
8229
|
+
if (element && !isNonDeletedElement(element)) {
|
|
8230
|
+
console.error(
|
|
8231
|
+
"[NONDELETED][INVARIANT] updateBoundElements(): `isDeleted: true` in visitor"
|
|
8232
|
+
);
|
|
8233
|
+
}
|
|
8234
|
+
if (!isArrowElement(element) || !isNonDeletedElement(element)) {
|
|
7860
8235
|
return;
|
|
7861
8236
|
}
|
|
7862
8237
|
if (!doesNeedUpdate(element, changedElement)) {
|
|
@@ -7910,7 +8285,9 @@ var updateArrowBindings = (latestElement, startOrEnd, elementsMap, scene, appSta
|
|
|
7910
8285
|
"Elbow arrows not supported for indirect updates"
|
|
7911
8286
|
);
|
|
7912
8287
|
const binding = latestElement[startOrEnd];
|
|
7913
|
-
const bindableElement = binding && elementsMap.get(
|
|
8288
|
+
const bindableElement = binding && elementsMap.get(
|
|
8289
|
+
binding.elementId
|
|
8290
|
+
);
|
|
7914
8291
|
const point = LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
|
7915
8292
|
latestElement,
|
|
7916
8293
|
startOrEnd === "startBinding" ? 0 : -1,
|
|
@@ -8175,12 +8552,12 @@ var avoidRectangularCorner = (arrowElement, bindTarget, elementsMap, p) => {
|
|
|
8175
8552
|
return p;
|
|
8176
8553
|
};
|
|
8177
8554
|
var snapToMid = (bindTarget, elementsMap, p, tolerance = 0.05, arrowElement) => {
|
|
8178
|
-
const { x, y, width, height, angle } = bindTarget;
|
|
8555
|
+
const { x, y, width, height, angle: angle2 } = bindTarget;
|
|
8179
8556
|
const center = elementCenterPoint(bindTarget, elementsMap, -0.1, -0.1);
|
|
8180
|
-
const nonRotated = pointRotateRads8(p, center, -
|
|
8557
|
+
const nonRotated = pointRotateRads8(p, center, -angle2);
|
|
8181
8558
|
const bindingGap = arrowElement ? getBindingGap(bindTarget, arrowElement) : 0;
|
|
8182
|
-
const verticalThreshold =
|
|
8183
|
-
const horizontalThreshold =
|
|
8559
|
+
const verticalThreshold = clamp4(tolerance * height, 5, 80);
|
|
8560
|
+
const horizontalThreshold = clamp4(tolerance * width, 5, 80);
|
|
8184
8561
|
if (pointDistance4(center, nonRotated) < bindingGap) {
|
|
8185
8562
|
return void 0;
|
|
8186
8563
|
}
|
|
@@ -8188,25 +8565,25 @@ var snapToMid = (bindTarget, elementsMap, p, tolerance = 0.05, arrowElement) =>
|
|
|
8188
8565
|
return pointRotateRads8(
|
|
8189
8566
|
pointFrom8(x - bindingGap, center[1]),
|
|
8190
8567
|
center,
|
|
8191
|
-
|
|
8568
|
+
angle2
|
|
8192
8569
|
);
|
|
8193
8570
|
} else if (nonRotated[1] <= y + height / 2 && nonRotated[0] > center[0] - horizontalThreshold && nonRotated[0] < center[0] + horizontalThreshold) {
|
|
8194
8571
|
return pointRotateRads8(
|
|
8195
8572
|
pointFrom8(center[0], y - bindingGap),
|
|
8196
8573
|
center,
|
|
8197
|
-
|
|
8574
|
+
angle2
|
|
8198
8575
|
);
|
|
8199
8576
|
} else if (nonRotated[0] >= x + width / 2 && nonRotated[1] > center[1] - verticalThreshold && nonRotated[1] < center[1] + verticalThreshold) {
|
|
8200
8577
|
return pointRotateRads8(
|
|
8201
8578
|
pointFrom8(x + width + bindingGap, center[1]),
|
|
8202
8579
|
center,
|
|
8203
|
-
|
|
8580
|
+
angle2
|
|
8204
8581
|
);
|
|
8205
8582
|
} else if (nonRotated[1] >= y + height / 2 && nonRotated[0] > center[0] - horizontalThreshold && nonRotated[0] < center[0] + horizontalThreshold) {
|
|
8206
8583
|
return pointRotateRads8(
|
|
8207
8584
|
pointFrom8(center[0], y + height + bindingGap),
|
|
8208
8585
|
center,
|
|
8209
|
-
|
|
8586
|
+
angle2
|
|
8210
8587
|
);
|
|
8211
8588
|
} else if (bindTarget.type === "diamond") {
|
|
8212
8589
|
const distance3 = bindingGap;
|
|
@@ -8227,16 +8604,16 @@ var snapToMid = (bindTarget, elementsMap, p, tolerance = 0.05, arrowElement) =>
|
|
|
8227
8604
|
y + 3 * height / 4 + distance3
|
|
8228
8605
|
);
|
|
8229
8606
|
if (pointDistance4(topLeft, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {
|
|
8230
|
-
return pointRotateRads8(topLeft, center,
|
|
8607
|
+
return pointRotateRads8(topLeft, center, angle2);
|
|
8231
8608
|
}
|
|
8232
8609
|
if (pointDistance4(topRight, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {
|
|
8233
|
-
return pointRotateRads8(topRight, center,
|
|
8610
|
+
return pointRotateRads8(topRight, center, angle2);
|
|
8234
8611
|
}
|
|
8235
8612
|
if (pointDistance4(bottomLeft, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {
|
|
8236
|
-
return pointRotateRads8(bottomLeft, center,
|
|
8613
|
+
return pointRotateRads8(bottomLeft, center, angle2);
|
|
8237
8614
|
}
|
|
8238
8615
|
if (pointDistance4(bottomRight, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {
|
|
8239
|
-
return pointRotateRads8(bottomRight, center,
|
|
8616
|
+
return pointRotateRads8(bottomRight, center, angle2);
|
|
8240
8617
|
}
|
|
8241
8618
|
}
|
|
8242
8619
|
return void 0;
|
|
@@ -8394,10 +8771,14 @@ var calculateFixedPointForElbowArrowBinding = (linearElement, hoveredElement, st
|
|
|
8394
8771
|
globalMidPoint,
|
|
8395
8772
|
-hoveredElement.angle
|
|
8396
8773
|
);
|
|
8774
|
+
if (hoveredElement.width < MIN_BINDABLE_SIZE || hoveredElement.height < MIN_BINDABLE_SIZE) {
|
|
8775
|
+
return { fixedPoint: normalizeFixedPoint([0.5, 0.5]) };
|
|
8776
|
+
}
|
|
8777
|
+
const sizeFloor = getBindingGap(hoveredElement, linearElement);
|
|
8397
8778
|
return {
|
|
8398
8779
|
fixedPoint: normalizeFixedPoint([
|
|
8399
|
-
(nonRotatedSnappedGlobalPoint[0] - hoveredElement.x) / Math.max(hoveredElement.width,
|
|
8400
|
-
(nonRotatedSnappedGlobalPoint[1] - hoveredElement.y) / Math.max(hoveredElement.height,
|
|
8780
|
+
(nonRotatedSnappedGlobalPoint[0] - hoveredElement.x) / Math.max(hoveredElement.width, sizeFloor),
|
|
8781
|
+
(nonRotatedSnappedGlobalPoint[1] - hoveredElement.y) / Math.max(hoveredElement.height, sizeFloor)
|
|
8401
8782
|
])
|
|
8402
8783
|
};
|
|
8403
8784
|
};
|
|
@@ -8413,8 +8794,12 @@ var calculateFixedPointForNonElbowArrowBinding = (linearElement, hoveredElement,
|
|
|
8413
8794
|
elementCenter,
|
|
8414
8795
|
-hoveredElement.angle
|
|
8415
8796
|
);
|
|
8416
|
-
|
|
8417
|
-
|
|
8797
|
+
if (hoveredElement.width < MIN_BINDABLE_SIZE || hoveredElement.height < MIN_BINDABLE_SIZE) {
|
|
8798
|
+
return { fixedPoint: normalizeFixedPoint([0.5, 0.5]) };
|
|
8799
|
+
}
|
|
8800
|
+
const sizeFloor = getBindingGap(hoveredElement, linearElement);
|
|
8801
|
+
const fixedPointX = (nonRotatedPoint[0] - hoveredElement.x) / Math.max(hoveredElement.width, sizeFloor);
|
|
8802
|
+
const fixedPointY = (nonRotatedPoint[1] - hoveredElement.y) / Math.max(hoveredElement.height, sizeFloor);
|
|
8418
8803
|
return {
|
|
8419
8804
|
fixedPoint: normalizeFixedPoint([fixedPointX, fixedPointY])
|
|
8420
8805
|
};
|
|
@@ -8739,17 +9124,21 @@ var getArrowLocalFixedPoints = (arrow, elementsMap) => {
|
|
|
8739
9124
|
var isFixedPoint = (fixedPoint) => {
|
|
8740
9125
|
return Array.isArray(fixedPoint) && fixedPoint.length === 2 && fixedPoint.every((coord) => Number.isFinite(coord));
|
|
8741
9126
|
};
|
|
9127
|
+
var FIXED_POINT_BOUND = 10;
|
|
8742
9128
|
var normalizeFixedPoint = (fixedPoint) => {
|
|
8743
9129
|
if (!isFixedPoint(fixedPoint)) {
|
|
8744
9130
|
return [0.5001, 0.5001];
|
|
8745
9131
|
}
|
|
8746
|
-
const
|
|
8747
|
-
|
|
8748
|
-
|
|
8749
|
-
|
|
9132
|
+
const EPSILON = 1e-4;
|
|
9133
|
+
const clamped = fixedPoint.map(
|
|
9134
|
+
(ratio) => clamp4(ratio, -FIXED_POINT_BOUND, FIXED_POINT_BOUND)
|
|
9135
|
+
);
|
|
9136
|
+
if (Math.abs(clamped[0] - 0.5) < EPSILON || Math.abs(clamped[1] - 0.5) < EPSILON) {
|
|
9137
|
+
return clamped.map(
|
|
9138
|
+
(ratio) => Math.abs(ratio - 0.5) < EPSILON ? 0.5001 : ratio
|
|
8750
9139
|
);
|
|
8751
9140
|
}
|
|
8752
|
-
return
|
|
9141
|
+
return clamped;
|
|
8753
9142
|
};
|
|
8754
9143
|
var getShapeType = (element) => {
|
|
8755
9144
|
if (element.type === "ellipse" || element.type === "diamond") {
|
|
@@ -8806,11 +9195,11 @@ var getShapeSideAdaptive = (fixedPoint, shapeType) => {
|
|
|
8806
9195
|
const [x, y] = fixedPoint;
|
|
8807
9196
|
const centerX = x - 0.5;
|
|
8808
9197
|
const centerY = y - 0.5;
|
|
8809
|
-
let
|
|
8810
|
-
if (
|
|
8811
|
-
|
|
9198
|
+
let angle2 = Math.atan2(centerY, centerX);
|
|
9199
|
+
if (angle2 < 0) {
|
|
9200
|
+
angle2 += 2 * Math.PI;
|
|
8812
9201
|
}
|
|
8813
|
-
const degrees =
|
|
9202
|
+
const degrees = angle2 * 180 / Math.PI;
|
|
8814
9203
|
const config = SHAPE_CONFIGS[shapeType];
|
|
8815
9204
|
const boundaries = getSectorBoundaries(config);
|
|
8816
9205
|
for (const boundary of boundaries) {
|
|
@@ -8965,33 +9354,33 @@ var getBindingSideMidPoint = (binding, elementsMap) => {
|
|
|
8965
9354
|
break;
|
|
8966
9355
|
}
|
|
8967
9356
|
case "top-right": {
|
|
8968
|
-
const
|
|
8969
|
-
const ellipseX = radiusX * Math.cos(
|
|
8970
|
-
const ellipseY = radiusY * Math.sin(
|
|
9357
|
+
const angle2 = -Math.PI / 4;
|
|
9358
|
+
const ellipseX = radiusX * Math.cos(angle2);
|
|
9359
|
+
const ellipseY = radiusY * Math.sin(angle2);
|
|
8971
9360
|
x = ellipseCenterX + ellipseX + OFFSET * 0.707;
|
|
8972
9361
|
y = ellipseCenterY + ellipseY - OFFSET * 0.707;
|
|
8973
9362
|
break;
|
|
8974
9363
|
}
|
|
8975
9364
|
case "bottom-right": {
|
|
8976
|
-
const
|
|
8977
|
-
const ellipseX = radiusX * Math.cos(
|
|
8978
|
-
const ellipseY = radiusY * Math.sin(
|
|
9365
|
+
const angle2 = Math.PI / 4;
|
|
9366
|
+
const ellipseX = radiusX * Math.cos(angle2);
|
|
9367
|
+
const ellipseY = radiusY * Math.sin(angle2);
|
|
8979
9368
|
x = ellipseCenterX + ellipseX + OFFSET * 0.707;
|
|
8980
9369
|
y = ellipseCenterY + ellipseY + OFFSET * 0.707;
|
|
8981
9370
|
break;
|
|
8982
9371
|
}
|
|
8983
9372
|
case "bottom-left": {
|
|
8984
|
-
const
|
|
8985
|
-
const ellipseX = radiusX * Math.cos(
|
|
8986
|
-
const ellipseY = radiusY * Math.sin(
|
|
9373
|
+
const angle2 = 3 * Math.PI / 4;
|
|
9374
|
+
const ellipseX = radiusX * Math.cos(angle2);
|
|
9375
|
+
const ellipseY = radiusY * Math.sin(angle2);
|
|
8987
9376
|
x = ellipseCenterX + ellipseX - OFFSET * 0.707;
|
|
8988
9377
|
y = ellipseCenterY + ellipseY + OFFSET * 0.707;
|
|
8989
9378
|
break;
|
|
8990
9379
|
}
|
|
8991
9380
|
case "top-left": {
|
|
8992
|
-
const
|
|
8993
|
-
const ellipseX = radiusX * Math.cos(
|
|
8994
|
-
const ellipseY = radiusY * Math.sin(
|
|
9381
|
+
const angle2 = -3 * Math.PI / 4;
|
|
9382
|
+
const ellipseX = radiusX * Math.cos(angle2);
|
|
9383
|
+
const ellipseY = radiusY * Math.sin(angle2);
|
|
8995
9384
|
x = ellipseCenterX + ellipseX - OFFSET * 0.707;
|
|
8996
9385
|
y = ellipseCenterY + ellipseY - OFFSET * 0.707;
|
|
8997
9386
|
break;
|
|
@@ -10187,11 +10576,11 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
10187
10576
|
return false;
|
|
10188
10577
|
}
|
|
10189
10578
|
const origin = linearElementEditor.initialState.origin;
|
|
10190
|
-
const
|
|
10579
|
+
const dist2 = pointDistance5(
|
|
10191
10580
|
origin,
|
|
10192
10581
|
pointFrom9(pointerCoords.x, pointerCoords.y)
|
|
10193
10582
|
);
|
|
10194
|
-
if (!appState.selectedLinearElement?.isEditing &&
|
|
10583
|
+
if (!appState.selectedLinearElement?.isEditing && dist2 < DRAGGING_THRESHOLD / appState.zoom.value) {
|
|
10195
10584
|
return false;
|
|
10196
10585
|
}
|
|
10197
10586
|
return true;
|
|
@@ -10757,52 +11146,15 @@ var determineCustomLinearAngle = (pivotPoint, draggedPoint) => Math.atan2(dragge
|
|
|
10757
11146
|
// src/frame.ts
|
|
10758
11147
|
init_define_import_meta_env();
|
|
10759
11148
|
import { arrayToMap as arrayToMap5 } from "@excalidraw/common";
|
|
10760
|
-
import { isPointWithinBounds as isPointWithinBounds2, pointFrom as pointFrom11 } from "@excalidraw/math";
|
|
10761
|
-
|
|
10762
|
-
// ../utils/src/bbox.ts
|
|
10763
|
-
init_define_import_meta_env();
|
|
10764
11149
|
import {
|
|
10765
|
-
|
|
10766
|
-
|
|
11150
|
+
isPointWithinBounds as isPointWithinBounds2,
|
|
11151
|
+
pointFrom as pointFrom10,
|
|
11152
|
+
segmentsIntersectAt as segmentsIntersectAt2
|
|
10767
11153
|
} from "@excalidraw/math";
|
|
10768
|
-
function getBBox(line2) {
|
|
10769
|
-
return [
|
|
10770
|
-
Math.min(line2[0][0], line2[1][0]),
|
|
10771
|
-
Math.min(line2[0][1], line2[1][1]),
|
|
10772
|
-
Math.max(line2[0][0], line2[1][0]),
|
|
10773
|
-
Math.max(line2[0][1], line2[1][1])
|
|
10774
|
-
];
|
|
10775
|
-
}
|
|
10776
|
-
function doBBoxesIntersect(a2, b2) {
|
|
10777
|
-
return a2[0] <= b2[2] && a2[2] >= b2[0] && a2[1] <= b2[3] && a2[3] >= b2[1];
|
|
10778
|
-
}
|
|
10779
|
-
var EPSILON = 1e-6;
|
|
10780
|
-
function isPointOnLine(l2, p) {
|
|
10781
|
-
const p1 = vectorFromPoint9(l2[1], l2[0]);
|
|
10782
|
-
const p2 = vectorFromPoint9(p, l2[0]);
|
|
10783
|
-
const r = vectorCross3(p1, p2);
|
|
10784
|
-
return Math.abs(r) < EPSILON;
|
|
10785
|
-
}
|
|
10786
|
-
function isPointRightOfLine(l2, p) {
|
|
10787
|
-
const p1 = vectorFromPoint9(l2[1], l2[0]);
|
|
10788
|
-
const p2 = vectorFromPoint9(p, l2[0]);
|
|
10789
|
-
return vectorCross3(p1, p2) < 0;
|
|
10790
|
-
}
|
|
10791
|
-
function isLineSegmentTouchingOrCrossingLine(a2, b2) {
|
|
10792
|
-
return isPointOnLine(a2, b2[0]) || isPointOnLine(a2, b2[1]) || (isPointRightOfLine(a2, b2[0]) ? !isPointRightOfLine(a2, b2[1]) : isPointRightOfLine(a2, b2[1]));
|
|
10793
|
-
}
|
|
10794
|
-
function doLineSegmentsIntersect(a2, b2) {
|
|
10795
|
-
return doBBoxesIntersect(getBBox(a2), getBBox(b2)) && isLineSegmentTouchingOrCrossingLine(a2, b2) && isLineSegmentTouchingOrCrossingLine(b2, a2);
|
|
10796
|
-
}
|
|
10797
11154
|
|
|
10798
11155
|
// src/selection.ts
|
|
10799
11156
|
init_define_import_meta_env();
|
|
10800
11157
|
import { arrayToMap as arrayToMap3, isShallowEqual as isShallowEqual2 } from "@excalidraw/common";
|
|
10801
|
-
import {
|
|
10802
|
-
lineSegment as lineSegment5,
|
|
10803
|
-
pointFrom as pointFrom10,
|
|
10804
|
-
pointRotateRads as pointRotateRads10
|
|
10805
|
-
} from "@excalidraw/math";
|
|
10806
11158
|
|
|
10807
11159
|
// src/groups.ts
|
|
10808
11160
|
init_define_import_meta_env();
|
|
@@ -11074,7 +11426,9 @@ var getSelectedElementsByGroup = (selectedElements, elementsMap, appState) => {
|
|
|
11074
11426
|
addToGroupsMap(element, selectedGroupId);
|
|
11075
11427
|
}
|
|
11076
11428
|
});
|
|
11077
|
-
return Array.from(groups.values()).concat(
|
|
11429
|
+
return Array.from(groups.values()).concat(
|
|
11430
|
+
Array.from(elements.values())
|
|
11431
|
+
);
|
|
11078
11432
|
};
|
|
11079
11433
|
|
|
11080
11434
|
// src/selection.ts
|
|
@@ -11108,248 +11462,71 @@ var getElementsWithinSelection = (elements, selection, elementsMap, excludeEleme
|
|
|
11108
11462
|
selectionX2,
|
|
11109
11463
|
selectionY2
|
|
11110
11464
|
];
|
|
11111
|
-
|
|
11112
|
-
|
|
11113
|
-
|
|
11114
|
-
|
|
11115
|
-
|
|
11116
|
-
|
|
11117
|
-
|
|
11118
|
-
|
|
11119
|
-
|
|
11120
|
-
|
|
11121
|
-
|
|
11122
|
-
|
|
11123
|
-
|
|
11124
|
-
|
|
11125
|
-
|
|
11126
|
-
|
|
11127
|
-
|
|
11128
|
-
|
|
11129
|
-
|
|
11130
|
-
|
|
11131
|
-
|
|
11132
|
-
|
|
11133
|
-
|
|
11134
|
-
|
|
11465
|
+
return elementsOverlappingBBox({
|
|
11466
|
+
elements,
|
|
11467
|
+
bounds: selectionBounds,
|
|
11468
|
+
elementsMap,
|
|
11469
|
+
type: boxSelectionMode,
|
|
11470
|
+
shouldIgnoreElementFromSelection,
|
|
11471
|
+
excludeElementsInFrames
|
|
11472
|
+
});
|
|
11473
|
+
};
|
|
11474
|
+
var getVisibleAndNonSelectedElements = (elements, selectedElements, appState, elementsMap) => {
|
|
11475
|
+
const selectedElementsSet = new Set(
|
|
11476
|
+
selectedElements.map((element) => element.id)
|
|
11477
|
+
);
|
|
11478
|
+
return elements.filter((element) => {
|
|
11479
|
+
const isVisible = isElementInViewport(
|
|
11480
|
+
element,
|
|
11481
|
+
appState.width,
|
|
11482
|
+
appState.height,
|
|
11483
|
+
appState,
|
|
11484
|
+
elementsMap
|
|
11485
|
+
);
|
|
11486
|
+
return !selectedElementsSet.has(element.id) && isVisible;
|
|
11487
|
+
});
|
|
11488
|
+
};
|
|
11489
|
+
var isSomeElementSelected = function() {
|
|
11490
|
+
let lastElements = null;
|
|
11491
|
+
let lastSelectedElementIds = null;
|
|
11492
|
+
let isSelected = null;
|
|
11493
|
+
const ret = (elements, appState) => {
|
|
11494
|
+
if (isSelected != null && elements === lastElements && appState.selectedElementIds === lastSelectedElementIds) {
|
|
11495
|
+
return isSelected;
|
|
11135
11496
|
}
|
|
11136
|
-
|
|
11137
|
-
|
|
11138
|
-
|
|
11139
|
-
|
|
11497
|
+
isSelected = elements.some(
|
|
11498
|
+
(element) => appState.selectedElementIds[element.id]
|
|
11499
|
+
);
|
|
11500
|
+
lastElements = elements;
|
|
11501
|
+
lastSelectedElementIds = appState.selectedElementIds;
|
|
11502
|
+
return isSelected;
|
|
11503
|
+
};
|
|
11504
|
+
ret.clearCache = () => {
|
|
11505
|
+
lastElements = null;
|
|
11506
|
+
lastSelectedElementIds = null;
|
|
11507
|
+
isSelected = null;
|
|
11508
|
+
};
|
|
11509
|
+
return ret;
|
|
11510
|
+
}();
|
|
11511
|
+
var getSelectedElements = (elements, appState, opts) => {
|
|
11512
|
+
const addedElements = /* @__PURE__ */ new Set();
|
|
11513
|
+
const selectedElements = [];
|
|
11514
|
+
for (const element of elements.values()) {
|
|
11515
|
+
if (appState.selectedElementIds[element.id]) {
|
|
11516
|
+
if (isNonDeletedElement(element)) {
|
|
11517
|
+
selectedElements.push(element);
|
|
11518
|
+
addedElements.add(element.id);
|
|
11519
|
+
} else {
|
|
11520
|
+
console.error(
|
|
11521
|
+
"[NONDELETED][INVARIANT] getSelectedElements skipping deleted selected element which should not be in the selection"
|
|
11522
|
+
);
|
|
11140
11523
|
}
|
|
11141
|
-
|
|
11524
|
+
continue;
|
|
11142
11525
|
}
|
|
11143
|
-
|
|
11144
|
-
|
|
11145
|
-
|
|
11146
|
-
|
|
11147
|
-
elementAABB[0] - strokeWidth / 2,
|
|
11148
|
-
elementAABB[1] - strokeWidth / 2,
|
|
11149
|
-
elementAABB[2] + strokeWidth / 2,
|
|
11150
|
-
elementAABB[3] + strokeWidth / 2
|
|
11151
|
-
];
|
|
11152
|
-
const boundTextElement = isArrowElement(element) && getBoundTextElement(element, elementsMap);
|
|
11153
|
-
if (boundTextElement) {
|
|
11154
|
-
const { x, y } = LinearElementEditor.getBoundTextElementPosition(
|
|
11155
|
-
element,
|
|
11156
|
-
boundTextElement,
|
|
11157
|
-
elementsMap
|
|
11158
|
-
);
|
|
11159
|
-
labelAABB = [
|
|
11160
|
-
x,
|
|
11161
|
-
y,
|
|
11162
|
-
x + boundTextElement.width,
|
|
11163
|
-
y + boundTextElement.height
|
|
11164
|
-
];
|
|
11165
|
-
}
|
|
11166
|
-
const associatedFrame = getContainingFrame(element, elementsMap);
|
|
11167
|
-
if (associatedFrame && elementOverlapsWithFrame(element, associatedFrame, elementsMap)) {
|
|
11168
|
-
const frameAABB = getElementBounds(associatedFrame, elementsMap);
|
|
11169
|
-
elementAABB = [
|
|
11170
|
-
Math.max(elementAABB[0], frameAABB[0]),
|
|
11171
|
-
Math.max(elementAABB[1], frameAABB[1]),
|
|
11172
|
-
Math.min(elementAABB[2], frameAABB[2]),
|
|
11173
|
-
Math.min(elementAABB[3], frameAABB[3])
|
|
11174
|
-
];
|
|
11175
|
-
labelAABB = labelAABB ? [
|
|
11176
|
-
Math.max(labelAABB[0], frameAABB[0]),
|
|
11177
|
-
Math.max(labelAABB[1], frameAABB[1]),
|
|
11178
|
-
Math.min(labelAABB[2], frameAABB[2]),
|
|
11179
|
-
Math.min(labelAABB[3], frameAABB[3])
|
|
11180
|
-
] : null;
|
|
11181
|
-
}
|
|
11182
|
-
const commonAABB2 = labelAABB ? [
|
|
11183
|
-
Math.min(labelAABB[0], elementAABB[0]),
|
|
11184
|
-
Math.min(labelAABB[1], elementAABB[1]),
|
|
11185
|
-
Math.max(labelAABB[2], elementAABB[2]),
|
|
11186
|
-
Math.max(labelAABB[3], elementAABB[3])
|
|
11187
|
-
] : elementAABB;
|
|
11188
|
-
if (boundsContainBounds(selectionBounds, commonAABB2)) {
|
|
11189
|
-
if (framesInSelection && isFrameLikeElement(element)) {
|
|
11190
|
-
framesInSelection.add(element.id);
|
|
11191
|
-
}
|
|
11192
|
-
elementsInSelection.add(element);
|
|
11193
|
-
continue;
|
|
11194
|
-
}
|
|
11195
|
-
if (boxSelectionMode === "overlap" && labelAABB && doBoundsIntersect(selectionBounds, labelAABB)) {
|
|
11196
|
-
elementsInSelection.add(element);
|
|
11197
|
-
continue;
|
|
11198
|
-
}
|
|
11199
|
-
if (boxSelectionMode === "overlap" && doBoundsIntersect(selectionBounds, elementAABB)) {
|
|
11200
|
-
let hasIntersection = false;
|
|
11201
|
-
if (isLinearElement(element) || isFreeDrawElement(element)) {
|
|
11202
|
-
const center = elementCenterPoint(element, elementsMap);
|
|
11203
|
-
hasIntersection = element.points.some((point) => {
|
|
11204
|
-
const rotatedPoint = pointRotateRads10(
|
|
11205
|
-
pointFrom10(element.x + point[0], element.y + point[1]),
|
|
11206
|
-
center,
|
|
11207
|
-
element.angle
|
|
11208
|
-
);
|
|
11209
|
-
return pointInsideBounds(rotatedPoint, selectionBounds);
|
|
11210
|
-
});
|
|
11211
|
-
} else {
|
|
11212
|
-
const nonRotatedElementBounds = getElementBounds(
|
|
11213
|
-
element,
|
|
11214
|
-
elementsMap,
|
|
11215
|
-
true
|
|
11216
|
-
);
|
|
11217
|
-
const center = elementCenterPoint(element, elementsMap);
|
|
11218
|
-
hasIntersection = [
|
|
11219
|
-
pointRotateRads10(
|
|
11220
|
-
pointFrom10(
|
|
11221
|
-
(nonRotatedElementBounds[0] + nonRotatedElementBounds[2]) / 2,
|
|
11222
|
-
nonRotatedElementBounds[1]
|
|
11223
|
-
),
|
|
11224
|
-
center,
|
|
11225
|
-
element.angle
|
|
11226
|
-
),
|
|
11227
|
-
pointRotateRads10(
|
|
11228
|
-
pointFrom10(
|
|
11229
|
-
nonRotatedElementBounds[2],
|
|
11230
|
-
(nonRotatedElementBounds[1] + nonRotatedElementBounds[3]) / 2
|
|
11231
|
-
),
|
|
11232
|
-
center,
|
|
11233
|
-
element.angle
|
|
11234
|
-
),
|
|
11235
|
-
pointRotateRads10(
|
|
11236
|
-
pointFrom10(
|
|
11237
|
-
(nonRotatedElementBounds[0] + nonRotatedElementBounds[2]) / 2,
|
|
11238
|
-
nonRotatedElementBounds[3]
|
|
11239
|
-
),
|
|
11240
|
-
center,
|
|
11241
|
-
element.angle
|
|
11242
|
-
),
|
|
11243
|
-
pointRotateRads10(
|
|
11244
|
-
pointFrom10(
|
|
11245
|
-
nonRotatedElementBounds[0],
|
|
11246
|
-
(nonRotatedElementBounds[1] + nonRotatedElementBounds[3]) / 2
|
|
11247
|
-
),
|
|
11248
|
-
center,
|
|
11249
|
-
element.angle
|
|
11250
|
-
)
|
|
11251
|
-
].some((point) => {
|
|
11252
|
-
return pointInsideBounds(
|
|
11253
|
-
pointRotateRads10(point, center, element.angle),
|
|
11254
|
-
selectionBounds
|
|
11255
|
-
);
|
|
11256
|
-
});
|
|
11257
|
-
}
|
|
11258
|
-
if (!hasIntersection) {
|
|
11259
|
-
hasIntersection = selectionEdges.some(
|
|
11260
|
-
(selectionEdge) => intersectElementWithLineSegment(
|
|
11261
|
-
element,
|
|
11262
|
-
elementsMap,
|
|
11263
|
-
selectionEdge,
|
|
11264
|
-
strokeWidth / 2,
|
|
11265
|
-
true
|
|
11266
|
-
// Stop at first hit for better performance
|
|
11267
|
-
).length > 0
|
|
11268
|
-
);
|
|
11269
|
-
}
|
|
11270
|
-
if (hasIntersection) {
|
|
11271
|
-
if (framesInSelection && isFrameLikeElement(element)) {
|
|
11272
|
-
framesInSelection.add(element.id);
|
|
11273
|
-
}
|
|
11274
|
-
elementsInSelection.add(element);
|
|
11275
|
-
continue;
|
|
11276
|
-
}
|
|
11277
|
-
}
|
|
11278
|
-
}
|
|
11279
|
-
if (framesInSelection) {
|
|
11280
|
-
elementsInSelection.forEach((element) => {
|
|
11281
|
-
if (element.frameId && framesInSelection.has(element.frameId)) {
|
|
11282
|
-
elementsInSelection.delete(element);
|
|
11283
|
-
}
|
|
11284
|
-
});
|
|
11285
|
-
}
|
|
11286
|
-
if (boxSelectionMode === "overlap") {
|
|
11287
|
-
Array.from(elementsInSelection).forEach((element) => {
|
|
11288
|
-
const groupId = element.groupIds.at(-1);
|
|
11289
|
-
const group = groupId ? groups[groupId] : null;
|
|
11290
|
-
group?.forEach((groupElement) => elementsInSelection.add(groupElement));
|
|
11291
|
-
});
|
|
11292
|
-
} else if (boxSelectionMode === "contain") {
|
|
11293
|
-
elementsInSelection.forEach((element) => {
|
|
11294
|
-
const groupId = element.groupIds.at(-1);
|
|
11295
|
-
const group = groupId ? groups[groupId] : null;
|
|
11296
|
-
if (group && !group.every((groupElement) => elementsInSelection.has(groupElement))) {
|
|
11297
|
-
elementsInSelection.delete(element);
|
|
11298
|
-
}
|
|
11299
|
-
});
|
|
11300
|
-
}
|
|
11301
|
-
return elements.filter((element) => elementsInSelection.has(element));
|
|
11302
|
-
};
|
|
11303
|
-
var getVisibleAndNonSelectedElements = (elements, selectedElements, appState, elementsMap) => {
|
|
11304
|
-
const selectedElementsSet = new Set(
|
|
11305
|
-
selectedElements.map((element) => element.id)
|
|
11306
|
-
);
|
|
11307
|
-
return elements.filter((element) => {
|
|
11308
|
-
const isVisible = isElementInViewport(
|
|
11309
|
-
element,
|
|
11310
|
-
appState.width,
|
|
11311
|
-
appState.height,
|
|
11312
|
-
appState,
|
|
11313
|
-
elementsMap
|
|
11314
|
-
);
|
|
11315
|
-
return !selectedElementsSet.has(element.id) && isVisible;
|
|
11316
|
-
});
|
|
11317
|
-
};
|
|
11318
|
-
var isSomeElementSelected = function() {
|
|
11319
|
-
let lastElements = null;
|
|
11320
|
-
let lastSelectedElementIds = null;
|
|
11321
|
-
let isSelected = null;
|
|
11322
|
-
const ret = (elements, appState) => {
|
|
11323
|
-
if (isSelected != null && elements === lastElements && appState.selectedElementIds === lastSelectedElementIds) {
|
|
11324
|
-
return isSelected;
|
|
11325
|
-
}
|
|
11326
|
-
isSelected = elements.some(
|
|
11327
|
-
(element) => appState.selectedElementIds[element.id]
|
|
11328
|
-
);
|
|
11329
|
-
lastElements = elements;
|
|
11330
|
-
lastSelectedElementIds = appState.selectedElementIds;
|
|
11331
|
-
return isSelected;
|
|
11332
|
-
};
|
|
11333
|
-
ret.clearCache = () => {
|
|
11334
|
-
lastElements = null;
|
|
11335
|
-
lastSelectedElementIds = null;
|
|
11336
|
-
isSelected = null;
|
|
11337
|
-
};
|
|
11338
|
-
return ret;
|
|
11339
|
-
}();
|
|
11340
|
-
var getSelectedElements = (elements, appState, opts) => {
|
|
11341
|
-
const addedElements = /* @__PURE__ */ new Set();
|
|
11342
|
-
const selectedElements = [];
|
|
11343
|
-
for (const element of elements.values()) {
|
|
11344
|
-
if (appState.selectedElementIds[element.id]) {
|
|
11345
|
-
selectedElements.push(element);
|
|
11346
|
-
addedElements.add(element.id);
|
|
11347
|
-
continue;
|
|
11348
|
-
}
|
|
11349
|
-
if (opts?.includeBoundTextElement && isBoundToContainer(element) && appState.selectedElementIds[element?.containerId]) {
|
|
11350
|
-
selectedElements.push(element);
|
|
11351
|
-
addedElements.add(element.id);
|
|
11352
|
-
continue;
|
|
11526
|
+
if (opts?.includeBoundTextElement && isBoundToContainer(element) && appState.selectedElementIds[element?.containerId]) {
|
|
11527
|
+
selectedElements.push(element);
|
|
11528
|
+
addedElements.add(element.id);
|
|
11529
|
+
continue;
|
|
11353
11530
|
}
|
|
11354
11531
|
}
|
|
11355
11532
|
if (opts?.includeElementsInFrames) {
|
|
@@ -11686,7 +11863,7 @@ function isElementIntersectingFrame(element, frame, elementsMap) {
|
|
|
11686
11863
|
const elementLineSegments = getElementLineSegments(element, elementsMap);
|
|
11687
11864
|
const intersecting = frameLineSegments.some(
|
|
11688
11865
|
(frameLineSegment) => elementLineSegments.some(
|
|
11689
|
-
(elementLineSegment) =>
|
|
11866
|
+
(elementLineSegment) => segmentsIntersectAt2(frameLineSegment, elementLineSegment)
|
|
11690
11867
|
)
|
|
11691
11868
|
);
|
|
11692
11869
|
return intersecting;
|
|
@@ -11722,9 +11899,9 @@ var elementOverlapsWithFrame = (element, frame, elementsMap) => {
|
|
|
11722
11899
|
var isCursorInFrame = (cursorCoords, frame, elementsMap) => {
|
|
11723
11900
|
const [fx1, fy1, fx2, fy2] = getElementAbsoluteCoords2(frame, elementsMap);
|
|
11724
11901
|
return isPointWithinBounds2(
|
|
11725
|
-
|
|
11726
|
-
|
|
11727
|
-
|
|
11902
|
+
pointFrom10(fx1, fy1),
|
|
11903
|
+
pointFrom10(cursorCoords.x, cursorCoords.y),
|
|
11904
|
+
pointFrom10(fx2, fy2)
|
|
11728
11905
|
);
|
|
11729
11906
|
};
|
|
11730
11907
|
var groupsAreAtLeastIntersectingTheFrame = (elements, groupIds, frame) => {
|
|
@@ -11831,8 +12008,11 @@ var getElementsInResizingFrame = (allElements, frame, appState, elementsMap) =>
|
|
|
11831
12008
|
const newGroupElementsCompletelyInFrame = Array.from(
|
|
11832
12009
|
elementsCompletelyInFrame
|
|
11833
12010
|
).filter((element) => element.groupIds.length > 0);
|
|
12011
|
+
const nonDeletedNewGroupElementsCompletelyInFrame = getNonDeletedElements(
|
|
12012
|
+
newGroupElementsCompletelyInFrame
|
|
12013
|
+
);
|
|
11834
12014
|
const groupIds = selectGroupsFromGivenElements(
|
|
11835
|
-
|
|
12015
|
+
nonDeletedNewGroupElementsCompletelyInFrame,
|
|
11836
12016
|
appState
|
|
11837
12017
|
);
|
|
11838
12018
|
for (const [id, isSelected] of Object.entries(groupIds)) {
|
|
@@ -11974,9 +12154,6 @@ var addElementsToFrame = (allElements, elementsToAdd, frame) => {
|
|
|
11974
12154
|
if (isFrameLikeElement(element) || element.frameId && otherFrames.has(element.frameId)) {
|
|
11975
12155
|
continue;
|
|
11976
12156
|
}
|
|
11977
|
-
if (element.frameId && element.frameId !== frame.id) {
|
|
11978
|
-
continue;
|
|
11979
|
-
}
|
|
11980
12157
|
finalElementsToAdd.add(element);
|
|
11981
12158
|
const boundTextElement = getBoundTextElement(element, elementsMap);
|
|
11982
12159
|
if (boundTextElement && !finalElementsToAdd.has(boundTextElement)) {
|
|
@@ -12303,43 +12480,6 @@ var generateElementCanvas = (element, elementsMap, zoom, renderConfig, appState)
|
|
|
12303
12480
|
const rc = rough_default.canvas(canvas);
|
|
12304
12481
|
drawElementOnCanvas(element, rc, context, renderConfig);
|
|
12305
12482
|
context.restore();
|
|
12306
|
-
const boundTextElement = getBoundTextElement(element, elementsMap);
|
|
12307
|
-
const boundTextCanvas = document.createElement("canvas");
|
|
12308
|
-
const boundTextCanvasContext = boundTextCanvas.getContext("2d");
|
|
12309
|
-
if (isArrowElement(element) && boundTextElement) {
|
|
12310
|
-
const [x1, y1, x2, y2] = getElementAbsoluteCoords2(element, elementsMap);
|
|
12311
|
-
const maxDim = Math.max(distance2(x1, x2), distance2(y1, y2));
|
|
12312
|
-
boundTextCanvas.width = maxDim * window.devicePixelRatio * scale + padding * scale * 10;
|
|
12313
|
-
boundTextCanvas.height = maxDim * window.devicePixelRatio * scale + padding * scale * 10;
|
|
12314
|
-
boundTextCanvasContext.translate(
|
|
12315
|
-
boundTextCanvas.width / 2,
|
|
12316
|
-
boundTextCanvas.height / 2
|
|
12317
|
-
);
|
|
12318
|
-
boundTextCanvasContext.rotate(element.angle);
|
|
12319
|
-
boundTextCanvasContext.drawImage(
|
|
12320
|
-
canvas,
|
|
12321
|
-
-canvas.width / 2,
|
|
12322
|
-
-canvas.height / 2,
|
|
12323
|
-
canvas.width,
|
|
12324
|
-
canvas.height
|
|
12325
|
-
);
|
|
12326
|
-
const [, , , , boundTextCx, boundTextCy] = getElementAbsoluteCoords2(
|
|
12327
|
-
boundTextElement,
|
|
12328
|
-
elementsMap
|
|
12329
|
-
);
|
|
12330
|
-
boundTextCanvasContext.rotate(-element.angle);
|
|
12331
|
-
const offsetX = (boundTextCanvas.width - canvas.width) / 2;
|
|
12332
|
-
const offsetY = (boundTextCanvas.height - canvas.height) / 2;
|
|
12333
|
-
const shiftX = boundTextCanvas.width / 2 - (boundTextCx - x1) * window.devicePixelRatio * scale - offsetX - padding * scale;
|
|
12334
|
-
const shiftY = boundTextCanvas.height / 2 - (boundTextCy - y1) * window.devicePixelRatio * scale - offsetY - padding * scale;
|
|
12335
|
-
boundTextCanvasContext.translate(-shiftX, -shiftY);
|
|
12336
|
-
boundTextCanvasContext.clearRect(
|
|
12337
|
-
-(boundTextElement.width / 2 + BOUND_TEXT_PADDING3) * window.devicePixelRatio * scale,
|
|
12338
|
-
-(boundTextElement.height / 2 + BOUND_TEXT_PADDING3) * window.devicePixelRatio * scale,
|
|
12339
|
-
(boundTextElement.width + BOUND_TEXT_PADDING3 * 2) * window.devicePixelRatio * scale,
|
|
12340
|
-
(boundTextElement.height + BOUND_TEXT_PADDING3 * 2) * window.devicePixelRatio * scale
|
|
12341
|
-
);
|
|
12342
|
-
}
|
|
12343
12483
|
return {
|
|
12344
12484
|
element,
|
|
12345
12485
|
canvas,
|
|
@@ -12348,10 +12488,7 @@ var generateElementCanvas = (element, elementsMap, zoom, renderConfig, appState)
|
|
|
12348
12488
|
zoomValue: zoom.value,
|
|
12349
12489
|
canvasOffsetX,
|
|
12350
12490
|
canvasOffsetY,
|
|
12351
|
-
boundTextElementVersion: getBoundTextElement(element, elementsMap)?.version || null,
|
|
12352
12491
|
containingFrameOpacity: getContainingFrame(element, elementsMap)?.opacity || 100,
|
|
12353
|
-
boundTextCanvas,
|
|
12354
|
-
angle: element.angle,
|
|
12355
12492
|
imageCrop: isImageElement(element) ? element.crop : null
|
|
12356
12493
|
};
|
|
12357
12494
|
};
|
|
@@ -12408,7 +12545,10 @@ var drawElementOnCanvas = (element, rc, context, renderConfig) => {
|
|
|
12408
12545
|
const shapes = ShapeCache.generateElementShape(element, renderConfig);
|
|
12409
12546
|
for (const shape of shapes) {
|
|
12410
12547
|
if (typeof shape === "string") {
|
|
12411
|
-
context.fillStyle =
|
|
12548
|
+
context.fillStyle = applyDarkModeFilter(
|
|
12549
|
+
element.strokeColor,
|
|
12550
|
+
renderConfig.theme === THEME.DARK
|
|
12551
|
+
);
|
|
12412
12552
|
context.fill(new Path2D(shape));
|
|
12413
12553
|
} else {
|
|
12414
12554
|
rc.draw(shape);
|
|
@@ -12516,7 +12656,10 @@ var drawElementOnCanvas = (element, rc, context, renderConfig) => {
|
|
|
12516
12656
|
context.canvas.setAttribute("dir", rtl ? "rtl" : "ltr");
|
|
12517
12657
|
context.save();
|
|
12518
12658
|
context.font = getFontString3(element);
|
|
12519
|
-
context.fillStyle =
|
|
12659
|
+
context.fillStyle = applyDarkModeFilter(
|
|
12660
|
+
element.strokeColor,
|
|
12661
|
+
renderConfig.theme === THEME.DARK
|
|
12662
|
+
);
|
|
12520
12663
|
context.textAlign = element.textAlign;
|
|
12521
12664
|
const lines = element.text.replace(/\r\n?/g, "\n").split("\n");
|
|
12522
12665
|
const horizontalOffset = element.textAlign === "center" ? element.width / 2 : element.textAlign === "right" ? element.width : 0;
|
|
@@ -12553,15 +12696,9 @@ var generateElementWithCanvas = (element, elementsMap, renderConfig, appState) =
|
|
|
12553
12696
|
};
|
|
12554
12697
|
const prevElementWithCanvas = elementWithCanvasCache.get(element);
|
|
12555
12698
|
const shouldRegenerateBecauseZoom = prevElementWithCanvas && prevElementWithCanvas.zoomValue !== zoom.value && !appState?.shouldCacheIgnoreZoom;
|
|
12556
|
-
const boundTextElement = getBoundTextElement(element, elementsMap);
|
|
12557
|
-
const boundTextElementVersion = boundTextElement?.version || null;
|
|
12558
12699
|
const imageCrop = isImageElement(element) ? element.crop : null;
|
|
12559
12700
|
const containingFrameOpacity = getContainingFrame(element, elementsMap)?.opacity || 100;
|
|
12560
|
-
if (!prevElementWithCanvas || shouldRegenerateBecauseZoom || prevElementWithCanvas.theme !== appState.theme || prevElementWithCanvas.
|
|
12561
|
-
// regenerate the cached canvas. But we need to in case of labels which are
|
|
12562
|
-
// cached alongside the arrow, and we want the labels to remain unrotated
|
|
12563
|
-
// with respect to the arrow.
|
|
12564
|
-
isArrowElement(element) && boundTextElement && element.angle !== prevElementWithCanvas.angle) {
|
|
12701
|
+
if (!prevElementWithCanvas || shouldRegenerateBecauseZoom || prevElementWithCanvas.theme !== appState.theme || prevElementWithCanvas.imageCrop !== imageCrop || prevElementWithCanvas.containingFrameOpacity !== containingFrameOpacity) {
|
|
12565
12702
|
const elementWithCanvas = generateElementCanvas(
|
|
12566
12703
|
element,
|
|
12567
12704
|
elementsMap,
|
|
@@ -12580,7 +12717,6 @@ var generateElementWithCanvas = (element, elementsMap, renderConfig, appState) =
|
|
|
12580
12717
|
var drawElementFromCanvas = (elementWithCanvas, context, renderConfig, appState, allElementsMap) => {
|
|
12581
12718
|
const element = elementWithCanvas.element;
|
|
12582
12719
|
const padding = getCanvasPadding(element);
|
|
12583
|
-
const zoom = elementWithCanvas.scale;
|
|
12584
12720
|
const [x1, y1, x2, y2] = getElementAbsoluteCoords2(element, allElementsMap);
|
|
12585
12721
|
const cx = ((x1 + x2) / 2 + appState.scrollX) * window.devicePixelRatio;
|
|
12586
12722
|
const cy = ((y1 + y2) / 2 + appState.scrollY) * window.devicePixelRatio;
|
|
@@ -12588,48 +12724,51 @@ var drawElementFromCanvas = (elementWithCanvas, context, renderConfig, appState,
|
|
|
12588
12724
|
context.scale(1 / window.devicePixelRatio, 1 / window.devicePixelRatio);
|
|
12589
12725
|
const boundTextElement = getBoundTextElement(element, allElementsMap);
|
|
12590
12726
|
if (isArrowElement(element) && boundTextElement) {
|
|
12591
|
-
const
|
|
12592
|
-
|
|
12593
|
-
|
|
12594
|
-
context.drawImage(
|
|
12595
|
-
elementWithCanvas.boundTextCanvas,
|
|
12596
|
-
-(x2 - x1) / 2 * window.devicePixelRatio - offsetX / zoom - padding,
|
|
12597
|
-
-(y2 - y1) / 2 * window.devicePixelRatio - offsetY / zoom - padding,
|
|
12598
|
-
elementWithCanvas.boundTextCanvas.width / zoom,
|
|
12599
|
-
elementWithCanvas.boundTextCanvas.height / zoom
|
|
12727
|
+
const [, , , , boundTextCx, boundTextCy] = getElementAbsoluteCoords2(
|
|
12728
|
+
boundTextElement,
|
|
12729
|
+
allElementsMap
|
|
12600
12730
|
);
|
|
12601
|
-
|
|
12602
|
-
context.
|
|
12603
|
-
context.
|
|
12604
|
-
|
|
12605
|
-
|
|
12606
|
-
|
|
12607
|
-
|
|
12608
|
-
)
|
|
12609
|
-
|
|
12610
|
-
context.
|
|
12611
|
-
|
|
12612
|
-
|
|
12613
|
-
|
|
12614
|
-
|
|
12615
|
-
|
|
12616
|
-
elementWithCanvas.
|
|
12731
|
+
const outerHalf = Math.max(distance2(x1, x2), distance2(y1, y2)) * window.devicePixelRatio + padding * 10;
|
|
12732
|
+
context.beginPath();
|
|
12733
|
+
context.rect(cx - outerHalf, cy - outerHalf, outerHalf * 2, outerHalf * 2);
|
|
12734
|
+
context.rect(
|
|
12735
|
+
(boundTextCx - boundTextElement.width / 2 - BOUND_TEXT_PADDING3 + appState.scrollX) * window.devicePixelRatio,
|
|
12736
|
+
(boundTextCy - boundTextElement.height / 2 - BOUND_TEXT_PADDING3 + appState.scrollY) * window.devicePixelRatio,
|
|
12737
|
+
(boundTextElement.width + BOUND_TEXT_PADDING3 * 2) * window.devicePixelRatio,
|
|
12738
|
+
(boundTextElement.height + BOUND_TEXT_PADDING3 * 2) * window.devicePixelRatio
|
|
12739
|
+
);
|
|
12740
|
+
context.clip("evenodd");
|
|
12741
|
+
}
|
|
12742
|
+
context.translate(cx, cy);
|
|
12743
|
+
context.rotate(element.angle);
|
|
12744
|
+
if ("scale" in elementWithCanvas.element && !isPendingImageElement(element, renderConfig)) {
|
|
12745
|
+
context.scale(
|
|
12746
|
+
elementWithCanvas.element.scale[0],
|
|
12747
|
+
elementWithCanvas.element.scale[1]
|
|
12748
|
+
);
|
|
12749
|
+
}
|
|
12750
|
+
context.translate(-cx, -cy);
|
|
12751
|
+
context.drawImage(
|
|
12752
|
+
elementWithCanvas.canvas,
|
|
12753
|
+
(x1 + appState.scrollX) * window.devicePixelRatio - padding * elementWithCanvas.scale / elementWithCanvas.scale,
|
|
12754
|
+
(y1 + appState.scrollY) * window.devicePixelRatio - padding * elementWithCanvas.scale / elementWithCanvas.scale,
|
|
12755
|
+
elementWithCanvas.canvas.width / elementWithCanvas.scale,
|
|
12756
|
+
elementWithCanvas.canvas.height / elementWithCanvas.scale
|
|
12757
|
+
);
|
|
12758
|
+
if (define_import_meta_env_default.VITE_APP_DEBUG_ENABLE_TEXT_CONTAINER_BOUNDING_BOX === "true" && hasBoundTextElement(element)) {
|
|
12759
|
+
const textElement = getBoundTextElement(
|
|
12760
|
+
element,
|
|
12761
|
+
allElementsMap
|
|
12762
|
+
);
|
|
12763
|
+
const coords = getContainerCoords(element);
|
|
12764
|
+
context.strokeStyle = "#c92a2a";
|
|
12765
|
+
context.lineWidth = 3;
|
|
12766
|
+
context.strokeRect(
|
|
12767
|
+
(coords.x + appState.scrollX) * window.devicePixelRatio,
|
|
12768
|
+
(coords.y + appState.scrollY) * window.devicePixelRatio,
|
|
12769
|
+
getBoundTextMaxWidth(element, textElement) * window.devicePixelRatio,
|
|
12770
|
+
getBoundTextMaxHeight(element, textElement) * window.devicePixelRatio
|
|
12617
12771
|
);
|
|
12618
|
-
if (define_import_meta_env_default.VITE_APP_DEBUG_ENABLE_TEXT_CONTAINER_BOUNDING_BOX === "true" && hasBoundTextElement(element)) {
|
|
12619
|
-
const textElement = getBoundTextElement(
|
|
12620
|
-
element,
|
|
12621
|
-
allElementsMap
|
|
12622
|
-
);
|
|
12623
|
-
const coords = getContainerCoords(element);
|
|
12624
|
-
context.strokeStyle = "#c92a2a";
|
|
12625
|
-
context.lineWidth = 3;
|
|
12626
|
-
context.strokeRect(
|
|
12627
|
-
(coords.x + appState.scrollX) * window.devicePixelRatio,
|
|
12628
|
-
(coords.y + appState.scrollY) * window.devicePixelRatio,
|
|
12629
|
-
getBoundTextMaxWidth(element, textElement) * window.devicePixelRatio,
|
|
12630
|
-
getBoundTextMaxHeight(element, textElement) * window.devicePixelRatio
|
|
12631
|
-
);
|
|
12632
|
-
}
|
|
12633
12772
|
}
|
|
12634
12773
|
context.restore();
|
|
12635
12774
|
};
|
|
@@ -12664,7 +12803,10 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
|
|
|
12664
12803
|
);
|
|
12665
12804
|
context.fillStyle = "rgba(0, 0, 200, 0.04)";
|
|
12666
12805
|
context.lineWidth = FRAME_STYLE.strokeWidth / appState.zoom.value;
|
|
12667
|
-
context.strokeStyle =
|
|
12806
|
+
context.strokeStyle = applyDarkModeFilter(
|
|
12807
|
+
FRAME_STYLE.strokeColor,
|
|
12808
|
+
appState.theme === THEME.DARK
|
|
12809
|
+
);
|
|
12668
12810
|
if (isMagicFrameElement(element)) {
|
|
12669
12811
|
context.strokeStyle = appState.theme === THEME.LIGHT ? "#7affd7" : applyDarkModeFilter("#1d8264");
|
|
12670
12812
|
}
|
|
@@ -12730,8 +12872,10 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
|
|
|
12730
12872
|
case "embeddable": {
|
|
12731
12873
|
if (renderConfig.isExporting) {
|
|
12732
12874
|
const [x1, y1, x2, y2] = getElementAbsoluteCoords2(element, elementsMap);
|
|
12733
|
-
const
|
|
12734
|
-
const
|
|
12875
|
+
const centerX = (x1 + x2) / 2;
|
|
12876
|
+
const centerY = (y1 + y2) / 2;
|
|
12877
|
+
const cx = centerX + appState.scrollX;
|
|
12878
|
+
const cy = centerY + appState.scrollY;
|
|
12735
12879
|
let shiftX = (x2 - x1) / 2 - (element.x - x1);
|
|
12736
12880
|
let shiftY = (y2 - y1) / 2 - (element.y - y1);
|
|
12737
12881
|
if (isTextElement(element)) {
|
|
@@ -12750,46 +12894,26 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
|
|
|
12750
12894
|
context.translate(cx, cy);
|
|
12751
12895
|
const boundTextElement = getBoundTextElement(element, elementsMap);
|
|
12752
12896
|
if (isArrowElement(element) && boundTextElement) {
|
|
12753
|
-
const tempCanvas = document.createElement("canvas");
|
|
12754
|
-
const tempCanvasContext = tempCanvas.getContext("2d");
|
|
12755
|
-
const maxDim = Math.max(distance2(x1, x2), distance2(y1, y2));
|
|
12756
|
-
const padding = getCanvasPadding(element);
|
|
12757
|
-
tempCanvas.width = maxDim * appState.exportScale + padding * 10 * appState.exportScale;
|
|
12758
|
-
tempCanvas.height = maxDim * appState.exportScale + padding * 10 * appState.exportScale;
|
|
12759
|
-
tempCanvasContext.translate(
|
|
12760
|
-
tempCanvas.width / 2,
|
|
12761
|
-
tempCanvas.height / 2
|
|
12762
|
-
);
|
|
12763
|
-
tempCanvasContext.scale(appState.exportScale, appState.exportScale);
|
|
12764
12897
|
shiftX = element.width / 2 - (element.x - x1);
|
|
12765
12898
|
shiftY = element.height / 2 - (element.y - y1);
|
|
12766
|
-
tempCanvasContext.rotate(element.angle);
|
|
12767
|
-
const tempRc = rough_default.canvas(tempCanvas);
|
|
12768
|
-
tempCanvasContext.translate(-shiftX, -shiftY);
|
|
12769
|
-
drawElementOnCanvas(element, tempRc, tempCanvasContext, renderConfig);
|
|
12770
|
-
tempCanvasContext.translate(shiftX, shiftY);
|
|
12771
|
-
tempCanvasContext.rotate(-element.angle);
|
|
12772
12899
|
const [, , , , boundTextCx, boundTextCy] = getElementAbsoluteCoords2(
|
|
12773
12900
|
boundTextElement,
|
|
12774
12901
|
elementsMap
|
|
12775
12902
|
);
|
|
12776
|
-
const
|
|
12777
|
-
const
|
|
12778
|
-
|
|
12779
|
-
|
|
12780
|
-
|
|
12781
|
-
|
|
12782
|
-
|
|
12783
|
-
|
|
12784
|
-
);
|
|
12785
|
-
context.
|
|
12786
|
-
context.
|
|
12787
|
-
|
|
12788
|
-
|
|
12789
|
-
|
|
12790
|
-
tempCanvas.width,
|
|
12791
|
-
tempCanvas.height
|
|
12792
|
-
);
|
|
12903
|
+
const holeX = boundTextCx - centerX - boundTextElement.width / 2 - BOUND_TEXT_PADDING3;
|
|
12904
|
+
const holeY = boundTextCy - centerY - boundTextElement.height / 2 - BOUND_TEXT_PADDING3;
|
|
12905
|
+
const holeWidth = boundTextElement.width + BOUND_TEXT_PADDING3 * 2;
|
|
12906
|
+
const holeHeight = boundTextElement.height + BOUND_TEXT_PADDING3 * 2;
|
|
12907
|
+
const outerHalf = Math.max(distance2(x1, x2), distance2(y1, y2)) + getCanvasPadding(element) * 10;
|
|
12908
|
+
context.save();
|
|
12909
|
+
context.beginPath();
|
|
12910
|
+
context.rect(-outerHalf, -outerHalf, outerHalf * 2, outerHalf * 2);
|
|
12911
|
+
context.rect(holeX, holeY, holeWidth, holeHeight);
|
|
12912
|
+
context.clip("evenodd");
|
|
12913
|
+
context.rotate(element.angle);
|
|
12914
|
+
context.translate(-shiftX, -shiftY);
|
|
12915
|
+
drawElementOnCanvas(element, rc, context, renderConfig);
|
|
12916
|
+
context.restore();
|
|
12793
12917
|
} else {
|
|
12794
12918
|
context.rotate(element.angle);
|
|
12795
12919
|
if (element.type === "image") {
|
|
@@ -12825,7 +12949,10 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
|
|
|
12825
12949
|
context.save();
|
|
12826
12950
|
context.globalAlpha = 0.1;
|
|
12827
12951
|
const uncroppedElementCanvas = generateElementCanvas(
|
|
12828
|
-
getUncroppedImageElement(
|
|
12952
|
+
getUncroppedImageElement(
|
|
12953
|
+
elementWithCanvas.element,
|
|
12954
|
+
elementsMap
|
|
12955
|
+
),
|
|
12829
12956
|
allElementsMap,
|
|
12830
12957
|
appState.zoom,
|
|
12831
12958
|
renderConfig,
|
|
@@ -12867,7 +12994,7 @@ function getFreedrawOutlineAsSegments(element, points, elementsMap) {
|
|
|
12867
12994
|
},
|
|
12868
12995
|
elementsMap
|
|
12869
12996
|
);
|
|
12870
|
-
const center =
|
|
12997
|
+
const center = pointFrom11(
|
|
12871
12998
|
(bounds[0] + bounds[2]) / 2,
|
|
12872
12999
|
(bounds[1] + bounds[3]) / 2
|
|
12873
13000
|
);
|
|
@@ -12875,10 +13002,10 @@ function getFreedrawOutlineAsSegments(element, points, elementsMap) {
|
|
|
12875
13002
|
return points.slice(2).reduce(
|
|
12876
13003
|
(acc, curr) => {
|
|
12877
13004
|
acc.push(
|
|
12878
|
-
|
|
13005
|
+
lineSegment5(
|
|
12879
13006
|
acc[acc.length - 1][1],
|
|
12880
|
-
|
|
12881
|
-
|
|
13007
|
+
pointRotateRads10(
|
|
13008
|
+
pointFrom11(curr[0] + element.x, curr[1] + element.y),
|
|
12882
13009
|
center,
|
|
12883
13010
|
element.angle
|
|
12884
13011
|
)
|
|
@@ -12887,17 +13014,17 @@ function getFreedrawOutlineAsSegments(element, points, elementsMap) {
|
|
|
12887
13014
|
return acc;
|
|
12888
13015
|
},
|
|
12889
13016
|
[
|
|
12890
|
-
|
|
12891
|
-
|
|
12892
|
-
|
|
13017
|
+
lineSegment5(
|
|
13018
|
+
pointRotateRads10(
|
|
13019
|
+
pointFrom11(
|
|
12893
13020
|
points[0][0] + element.x,
|
|
12894
13021
|
points[0][1] + element.y
|
|
12895
13022
|
),
|
|
12896
13023
|
center,
|
|
12897
13024
|
element.angle
|
|
12898
13025
|
),
|
|
12899
|
-
|
|
12900
|
-
|
|
13026
|
+
pointRotateRads10(
|
|
13027
|
+
pointFrom11(
|
|
12901
13028
|
points[1][0] + element.x,
|
|
12902
13029
|
points[1][1] + element.y
|
|
12903
13030
|
),
|
|
@@ -12992,7 +13119,7 @@ var generateRoughOptions = (element, continuousPath = false, isDarkMode = false)
|
|
|
12992
13119
|
fillWeight: element.strokeWidth / 2,
|
|
12993
13120
|
hachureGap: element.strokeWidth * 4,
|
|
12994
13121
|
roughness: adjustRoughness(element),
|
|
12995
|
-
stroke:
|
|
13122
|
+
stroke: applyDarkModeFilter2(element.strokeColor, isDarkMode),
|
|
12996
13123
|
preserveVertices: continuousPath || element.roughness < ROUGHNESS.cartoonist
|
|
12997
13124
|
};
|
|
12998
13125
|
switch (element.type) {
|
|
@@ -13002,7 +13129,7 @@ var generateRoughOptions = (element, continuousPath = false, isDarkMode = false)
|
|
|
13002
13129
|
case "diamond":
|
|
13003
13130
|
case "ellipse": {
|
|
13004
13131
|
options.fillStyle = element.fillStyle;
|
|
13005
|
-
options.fill = isTransparent3(element.backgroundColor) ? void 0 :
|
|
13132
|
+
options.fill = isTransparent3(element.backgroundColor) ? void 0 : applyDarkModeFilter2(element.backgroundColor, isDarkMode);
|
|
13006
13133
|
if (element.type === "ellipse") {
|
|
13007
13134
|
options.curveFitting = 1;
|
|
13008
13135
|
}
|
|
@@ -13012,7 +13139,7 @@ var generateRoughOptions = (element, continuousPath = false, isDarkMode = false)
|
|
|
13012
13139
|
case "freedraw": {
|
|
13013
13140
|
if (isPathALoop(element.points)) {
|
|
13014
13141
|
options.fillStyle = element.fillStyle;
|
|
13015
|
-
options.fill = element.backgroundColor === "transparent" ? void 0 :
|
|
13142
|
+
options.fill = element.backgroundColor === "transparent" ? void 0 : applyDarkModeFilter2(element.backgroundColor, isDarkMode);
|
|
13016
13143
|
}
|
|
13017
13144
|
return options;
|
|
13018
13145
|
}
|
|
@@ -13087,8 +13214,11 @@ var getArrowheadShapes = (element, shape, position, arrowhead, generator, option
|
|
|
13087
13214
|
if (arrowhead === null) {
|
|
13088
13215
|
return [];
|
|
13089
13216
|
}
|
|
13090
|
-
const strokeColor =
|
|
13091
|
-
const backgroundFillColor =
|
|
13217
|
+
const strokeColor = applyDarkModeFilter2(element.strokeColor, isDarkMode);
|
|
13218
|
+
const backgroundFillColor = applyDarkModeFilter2(
|
|
13219
|
+
canvasBackgroundColor,
|
|
13220
|
+
isDarkMode
|
|
13221
|
+
);
|
|
13092
13222
|
const cardinalityOneOrManyOffset = -0.25;
|
|
13093
13223
|
const cardinalityZeroCircleScale = 0.8;
|
|
13094
13224
|
switch (arrowhead) {
|
|
@@ -13273,26 +13403,26 @@ var generateLinearCollisionShape = (element, elementsMap) => {
|
|
|
13273
13403
|
switch (element.type) {
|
|
13274
13404
|
case "line":
|
|
13275
13405
|
case "arrow": {
|
|
13276
|
-
const points = element.points.length ? element.points : [
|
|
13406
|
+
const points = element.points.length ? element.points : [pointFrom12(0, 0)];
|
|
13277
13407
|
if (isElbowArrow(element)) {
|
|
13278
13408
|
return generator.path(generateElbowArrowShape(points, 16), options).sets[0].ops;
|
|
13279
13409
|
} else if (!element.roundness) {
|
|
13280
13410
|
return points.map((point, idx) => {
|
|
13281
|
-
const p =
|
|
13282
|
-
|
|
13411
|
+
const p = pointRotateRads11(
|
|
13412
|
+
pointFrom12(element.x + point[0], element.y + point[1]),
|
|
13283
13413
|
center,
|
|
13284
13414
|
element.angle
|
|
13285
13415
|
);
|
|
13286
13416
|
return {
|
|
13287
13417
|
op: idx === 0 ? "move" : "lineTo",
|
|
13288
|
-
data:
|
|
13418
|
+
data: pointFrom12(p[0] - element.x, p[1] - element.y)
|
|
13289
13419
|
};
|
|
13290
13420
|
});
|
|
13291
13421
|
}
|
|
13292
13422
|
return generator.curve(points, options).sets[0].ops.slice(0, element.points.length).map((op, i) => {
|
|
13293
13423
|
if (i === 0) {
|
|
13294
|
-
const p =
|
|
13295
|
-
|
|
13424
|
+
const p = pointRotateRads11(
|
|
13425
|
+
pointFrom12(
|
|
13296
13426
|
element.x + op.data[0],
|
|
13297
13427
|
element.y + op.data[1]
|
|
13298
13428
|
),
|
|
@@ -13301,30 +13431,30 @@ var generateLinearCollisionShape = (element, elementsMap) => {
|
|
|
13301
13431
|
);
|
|
13302
13432
|
return {
|
|
13303
13433
|
op: "move",
|
|
13304
|
-
data:
|
|
13434
|
+
data: pointFrom12(p[0] - element.x, p[1] - element.y)
|
|
13305
13435
|
};
|
|
13306
13436
|
}
|
|
13307
13437
|
return {
|
|
13308
13438
|
op: "bcurveTo",
|
|
13309
13439
|
data: [
|
|
13310
|
-
|
|
13311
|
-
|
|
13440
|
+
pointRotateRads11(
|
|
13441
|
+
pointFrom12(
|
|
13312
13442
|
element.x + op.data[0],
|
|
13313
13443
|
element.y + op.data[1]
|
|
13314
13444
|
),
|
|
13315
13445
|
center,
|
|
13316
13446
|
element.angle
|
|
13317
13447
|
),
|
|
13318
|
-
|
|
13319
|
-
|
|
13448
|
+
pointRotateRads11(
|
|
13449
|
+
pointFrom12(
|
|
13320
13450
|
element.x + op.data[2],
|
|
13321
13451
|
element.y + op.data[3]
|
|
13322
13452
|
),
|
|
13323
13453
|
center,
|
|
13324
13454
|
element.angle
|
|
13325
13455
|
),
|
|
13326
|
-
|
|
13327
|
-
|
|
13456
|
+
pointRotateRads11(
|
|
13457
|
+
pointFrom12(
|
|
13328
13458
|
element.x + op.data[4],
|
|
13329
13459
|
element.y + op.data[5]
|
|
13330
13460
|
),
|
|
@@ -13332,7 +13462,7 @@ var generateLinearCollisionShape = (element, elementsMap) => {
|
|
|
13332
13462
|
element.angle
|
|
13333
13463
|
)
|
|
13334
13464
|
].map(
|
|
13335
|
-
(p) =>
|
|
13465
|
+
(p) => pointFrom12(p[0] - element.x, p[1] - element.y)
|
|
13336
13466
|
).flat()
|
|
13337
13467
|
};
|
|
13338
13468
|
});
|
|
@@ -13347,8 +13477,8 @@ var generateLinearCollisionShape = (element, elementsMap) => {
|
|
|
13347
13477
|
);
|
|
13348
13478
|
return generator.curve(simplifiedPoints, options).sets[0].ops.slice(0, element.points.length).map((op, i) => {
|
|
13349
13479
|
if (i === 0) {
|
|
13350
|
-
const p =
|
|
13351
|
-
|
|
13480
|
+
const p = pointRotateRads11(
|
|
13481
|
+
pointFrom12(
|
|
13352
13482
|
element.x + op.data[0],
|
|
13353
13483
|
element.y + op.data[1]
|
|
13354
13484
|
),
|
|
@@ -13357,30 +13487,30 @@ var generateLinearCollisionShape = (element, elementsMap) => {
|
|
|
13357
13487
|
);
|
|
13358
13488
|
return {
|
|
13359
13489
|
op: "move",
|
|
13360
|
-
data:
|
|
13490
|
+
data: pointFrom12(p[0] - element.x, p[1] - element.y)
|
|
13361
13491
|
};
|
|
13362
13492
|
}
|
|
13363
13493
|
return {
|
|
13364
13494
|
op: "bcurveTo",
|
|
13365
13495
|
data: [
|
|
13366
|
-
|
|
13367
|
-
|
|
13496
|
+
pointRotateRads11(
|
|
13497
|
+
pointFrom12(
|
|
13368
13498
|
element.x + op.data[0],
|
|
13369
13499
|
element.y + op.data[1]
|
|
13370
13500
|
),
|
|
13371
13501
|
center,
|
|
13372
13502
|
element.angle
|
|
13373
13503
|
),
|
|
13374
|
-
|
|
13375
|
-
|
|
13504
|
+
pointRotateRads11(
|
|
13505
|
+
pointFrom12(
|
|
13376
13506
|
element.x + op.data[2],
|
|
13377
13507
|
element.y + op.data[3]
|
|
13378
13508
|
),
|
|
13379
13509
|
center,
|
|
13380
13510
|
element.angle
|
|
13381
13511
|
),
|
|
13382
|
-
|
|
13383
|
-
|
|
13512
|
+
pointRotateRads11(
|
|
13513
|
+
pointFrom12(
|
|
13384
13514
|
element.x + op.data[4],
|
|
13385
13515
|
element.y + op.data[5]
|
|
13386
13516
|
),
|
|
@@ -13388,7 +13518,7 @@ var generateLinearCollisionShape = (element, elementsMap) => {
|
|
|
13388
13518
|
element.angle
|
|
13389
13519
|
)
|
|
13390
13520
|
].map(
|
|
13391
|
-
(p) =>
|
|
13521
|
+
(p) => pointFrom12(p[0] - element.x, p[1] - element.y)
|
|
13392
13522
|
).flat()
|
|
13393
13523
|
};
|
|
13394
13524
|
});
|
|
@@ -13489,7 +13619,7 @@ var _generateElementShape = (element, generator, {
|
|
|
13489
13619
|
case "arrow": {
|
|
13490
13620
|
let shape;
|
|
13491
13621
|
const options = generateRoughOptions(element, false, isDarkMode);
|
|
13492
|
-
const points = element.points.length ? element.points : [
|
|
13622
|
+
const points = element.points.length ? element.points : [pointFrom12(0, 0)];
|
|
13493
13623
|
if (isElbowArrow(element)) {
|
|
13494
13624
|
if (!points.every(
|
|
13495
13625
|
(point) => Math.abs(point[0]) <= 1e6 && Math.abs(point[1]) <= 1e6
|
|
@@ -13653,14 +13783,14 @@ var getElementShape = (element, elementsMap) => {
|
|
|
13653
13783
|
return shouldTestInside(element) ? getClosedCurveShape(
|
|
13654
13784
|
element,
|
|
13655
13785
|
roughShape,
|
|
13656
|
-
|
|
13786
|
+
pointFrom12(element.x, element.y),
|
|
13657
13787
|
element.angle,
|
|
13658
|
-
|
|
13788
|
+
pointFrom12(cx, cy)
|
|
13659
13789
|
) : getCurveShape(
|
|
13660
13790
|
roughShape,
|
|
13661
|
-
|
|
13791
|
+
pointFrom12(element.x, element.y),
|
|
13662
13792
|
element.angle,
|
|
13663
|
-
|
|
13793
|
+
pointFrom12(cx, cy)
|
|
13664
13794
|
);
|
|
13665
13795
|
}
|
|
13666
13796
|
case "ellipse":
|
|
@@ -13669,7 +13799,7 @@ var getElementShape = (element, elementsMap) => {
|
|
|
13669
13799
|
const [, , , , cx, cy] = getElementAbsoluteCoords2(element, elementsMap);
|
|
13670
13800
|
return getFreedrawShape(
|
|
13671
13801
|
element,
|
|
13672
|
-
|
|
13802
|
+
pointFrom12(cx, cy),
|
|
13673
13803
|
shouldTestInside(element)
|
|
13674
13804
|
);
|
|
13675
13805
|
}
|
|
@@ -13688,9 +13818,9 @@ var toggleLinePolygonState = (element, nextPolygonState) => {
|
|
|
13688
13818
|
firstPoint[1] - lastPoint[1]
|
|
13689
13819
|
);
|
|
13690
13820
|
if (distance3 > LINE_POLYGON_POINT_MERGE_DISTANCE || updatedPoints.length < 4) {
|
|
13691
|
-
updatedPoints.push(
|
|
13821
|
+
updatedPoints.push(pointFrom12(firstPoint[0], firstPoint[1]));
|
|
13692
13822
|
} else {
|
|
13693
|
-
updatedPoints[updatedPoints.length - 1] =
|
|
13823
|
+
updatedPoints[updatedPoints.length - 1] = pointFrom12(
|
|
13694
13824
|
firstPoint[0],
|
|
13695
13825
|
firstPoint[1]
|
|
13696
13826
|
);
|
|
@@ -13707,19 +13837,46 @@ var getFreeDrawSvgPath = (element) => {
|
|
|
13707
13837
|
getFreedrawOutlinePoints(element)
|
|
13708
13838
|
);
|
|
13709
13839
|
};
|
|
13710
|
-
var
|
|
13711
|
-
|
|
13840
|
+
var VARIABLE_WIDTH_FREEDRAW = {
|
|
13841
|
+
/** Stroke size relative to `strokeWidth` for pressure-sensitive strokes. */
|
|
13842
|
+
SIZE_FACTOR: 4.25,
|
|
13843
|
+
THINNING: 0.6,
|
|
13844
|
+
SMOOTHING: 0.5
|
|
13845
|
+
};
|
|
13846
|
+
var CONSTANT_WIDTH_FREEDRAW = {
|
|
13847
|
+
/** Stroke size relative to `strokeWidth` for uniform (laser) strokes. */
|
|
13848
|
+
SIZE_FACTOR: 1.4
|
|
13849
|
+
};
|
|
13850
|
+
var getFreedrawStreamline = (element) => element.strokeOptions?.streamline ?? DEFAULT_STROKE_STREAMLINE;
|
|
13851
|
+
var getVariableWidthFreedrawOutline = (element) => {
|
|
13852
|
+
const inputPoints = element.simulatePressure ? element.points : element.points.length ? element.points.map(
|
|
13853
|
+
([x, y], i) => [x, y, element.pressures[i]]
|
|
13854
|
+
) : [[0, 0, 0.5]];
|
|
13712
13855
|
return ae(inputPoints, {
|
|
13713
13856
|
simulatePressure: element.simulatePressure,
|
|
13714
|
-
size: element.strokeWidth *
|
|
13715
|
-
thinning:
|
|
13716
|
-
smoothing:
|
|
13717
|
-
streamline:
|
|
13857
|
+
size: element.strokeWidth * VARIABLE_WIDTH_FREEDRAW.SIZE_FACTOR,
|
|
13858
|
+
thinning: VARIABLE_WIDTH_FREEDRAW.THINNING,
|
|
13859
|
+
smoothing: VARIABLE_WIDTH_FREEDRAW.SMOOTHING,
|
|
13860
|
+
streamline: getFreedrawStreamline(element),
|
|
13718
13861
|
easing: (t) => Math.sin(t * Math.PI / 2),
|
|
13719
13862
|
// https://easings.net/#easeOutSine
|
|
13720
13863
|
last: true
|
|
13721
13864
|
});
|
|
13722
13865
|
};
|
|
13866
|
+
var createLaserPointer = (element) => new LaserPointer({
|
|
13867
|
+
size: element.strokeWidth * CONSTANT_WIDTH_FREEDRAW.SIZE_FACTOR,
|
|
13868
|
+
streamline: getFreedrawStreamline(element),
|
|
13869
|
+
simplify: 0,
|
|
13870
|
+
sizeMapping: (details) => Math.max(0.1, details.pressure)
|
|
13871
|
+
});
|
|
13872
|
+
var getConstantWidthFreedrawOutline = (element) => {
|
|
13873
|
+
const laserPointer = createLaserPointer(element);
|
|
13874
|
+
element.points.map(([x, y]) => laserPointer.addPoint([x, y, 1]));
|
|
13875
|
+
return laserPointer.getStrokeOutline().map(([x, y]) => [x, y]);
|
|
13876
|
+
};
|
|
13877
|
+
var getFreedrawOutlinePoints = (element) => {
|
|
13878
|
+
return element.strokeOptions?.variability === "constant" ? getConstantWidthFreedrawOutline(element) : getVariableWidthFreedrawOutline(element);
|
|
13879
|
+
};
|
|
13723
13880
|
var med = (A2, B2) => {
|
|
13724
13881
|
return [(A2[0] + B2[0]) / 2, (A2[1] + B2[1]) / 2];
|
|
13725
13882
|
};
|
|
@@ -13783,9 +13940,9 @@ var ElementBounds = class _ElementBounds {
|
|
|
13783
13940
|
if (isFreeDrawElement(element)) {
|
|
13784
13941
|
const [minX, minY, maxX, maxY] = getBoundsFromPoints(
|
|
13785
13942
|
element.points.map(
|
|
13786
|
-
([x, y]) =>
|
|
13787
|
-
|
|
13788
|
-
|
|
13943
|
+
([x, y]) => pointRotateRads12(
|
|
13944
|
+
pointFrom13(x, y),
|
|
13945
|
+
pointFrom13(cx - element.x, cy - element.y),
|
|
13789
13946
|
element.angle
|
|
13790
13947
|
)
|
|
13791
13948
|
)
|
|
@@ -13799,24 +13956,24 @@ var ElementBounds = class _ElementBounds {
|
|
|
13799
13956
|
} else if (isLinearElement(element)) {
|
|
13800
13957
|
bounds = getLinearElementRotatedBounds(element, cx, cy, elementsMap);
|
|
13801
13958
|
} else if (element.type === "diamond") {
|
|
13802
|
-
const [x11, y11] =
|
|
13803
|
-
|
|
13804
|
-
|
|
13959
|
+
const [x11, y11] = pointRotateRads12(
|
|
13960
|
+
pointFrom13(cx, y1),
|
|
13961
|
+
pointFrom13(cx, cy),
|
|
13805
13962
|
element.angle
|
|
13806
13963
|
);
|
|
13807
|
-
const [x12, y12] =
|
|
13808
|
-
|
|
13809
|
-
|
|
13964
|
+
const [x12, y12] = pointRotateRads12(
|
|
13965
|
+
pointFrom13(cx, y2),
|
|
13966
|
+
pointFrom13(cx, cy),
|
|
13810
13967
|
element.angle
|
|
13811
13968
|
);
|
|
13812
|
-
const [x22, y22] =
|
|
13813
|
-
|
|
13814
|
-
|
|
13969
|
+
const [x22, y22] = pointRotateRads12(
|
|
13970
|
+
pointFrom13(x1, cy),
|
|
13971
|
+
pointFrom13(cx, cy),
|
|
13815
13972
|
element.angle
|
|
13816
13973
|
);
|
|
13817
|
-
const [x21, y21] =
|
|
13818
|
-
|
|
13819
|
-
|
|
13974
|
+
const [x21, y21] = pointRotateRads12(
|
|
13975
|
+
pointFrom13(x2, cy),
|
|
13976
|
+
pointFrom13(cx, cy),
|
|
13820
13977
|
element.angle
|
|
13821
13978
|
);
|
|
13822
13979
|
const minX = Math.min(x11, x12, x22, x21);
|
|
@@ -13833,24 +13990,24 @@ var ElementBounds = class _ElementBounds {
|
|
|
13833
13990
|
const hh = Math.hypot(h * cos, w * sin);
|
|
13834
13991
|
bounds = [cx - ww, cy - hh, cx + ww, cy + hh];
|
|
13835
13992
|
} else {
|
|
13836
|
-
const [x11, y11] =
|
|
13837
|
-
|
|
13838
|
-
|
|
13993
|
+
const [x11, y11] = pointRotateRads12(
|
|
13994
|
+
pointFrom13(x1, y1),
|
|
13995
|
+
pointFrom13(cx, cy),
|
|
13839
13996
|
element.angle
|
|
13840
13997
|
);
|
|
13841
|
-
const [x12, y12] =
|
|
13842
|
-
|
|
13843
|
-
|
|
13998
|
+
const [x12, y12] = pointRotateRads12(
|
|
13999
|
+
pointFrom13(x1, y2),
|
|
14000
|
+
pointFrom13(cx, cy),
|
|
13844
14001
|
element.angle
|
|
13845
14002
|
);
|
|
13846
|
-
const [x22, y22] =
|
|
13847
|
-
|
|
13848
|
-
|
|
14003
|
+
const [x22, y22] = pointRotateRads12(
|
|
14004
|
+
pointFrom13(x2, y2),
|
|
14005
|
+
pointFrom13(cx, cy),
|
|
13849
14006
|
element.angle
|
|
13850
14007
|
);
|
|
13851
|
-
const [x21, y21] =
|
|
13852
|
-
|
|
13853
|
-
|
|
14008
|
+
const [x21, y21] = pointRotateRads12(
|
|
14009
|
+
pointFrom13(x2, y1),
|
|
14010
|
+
pointFrom13(cx, cy),
|
|
13854
14011
|
element.angle
|
|
13855
14012
|
);
|
|
13856
14013
|
const minX = Math.min(x11, x12, x22, x21);
|
|
@@ -13904,7 +14061,7 @@ var getElementLineSegments = (element, elementsMap) => {
|
|
|
13904
14061
|
element,
|
|
13905
14062
|
elementsMap
|
|
13906
14063
|
);
|
|
13907
|
-
const center =
|
|
14064
|
+
const center = pointFrom13(cx, cy);
|
|
13908
14065
|
if (shape.type === "polycurve") {
|
|
13909
14066
|
const curves = shape.data;
|
|
13910
14067
|
const pointsOnCurves = curves.map(
|
|
@@ -13916,9 +14073,9 @@ var getElementLineSegments = (element, elementsMap) => {
|
|
|
13916
14073
|
let i = 0;
|
|
13917
14074
|
while (i < points.length - 1) {
|
|
13918
14075
|
segments.push(
|
|
13919
|
-
|
|
13920
|
-
|
|
13921
|
-
|
|
14076
|
+
lineSegment6(
|
|
14077
|
+
pointFrom13(points[i][0], points[i][1]),
|
|
14078
|
+
pointFrom13(points[i + 1][0], points[i + 1][1])
|
|
13922
14079
|
)
|
|
13923
14080
|
);
|
|
13924
14081
|
i++;
|
|
@@ -13929,9 +14086,9 @@ var getElementLineSegments = (element, elementsMap) => {
|
|
|
13929
14086
|
let i = 0;
|
|
13930
14087
|
while (i < points.length - 1) {
|
|
13931
14088
|
segments.push(
|
|
13932
|
-
|
|
13933
|
-
|
|
13934
|
-
|
|
14089
|
+
lineSegment6(
|
|
14090
|
+
pointFrom13(points[i][0], points[i][1]),
|
|
14091
|
+
pointFrom13(points[i + 1][0], points[i + 1][1])
|
|
13935
14092
|
)
|
|
13936
14093
|
);
|
|
13937
14094
|
i++;
|
|
@@ -13955,10 +14112,10 @@ var getElementLineSegments = (element, elementsMap) => {
|
|
|
13955
14112
|
const container = getContainerElement(element, elementsMap);
|
|
13956
14113
|
if (container && isLinearElement(container)) {
|
|
13957
14114
|
const segments2 = [
|
|
13958
|
-
|
|
13959
|
-
|
|
13960
|
-
|
|
13961
|
-
|
|
14115
|
+
lineSegment6(pointFrom13(x1, y1), pointFrom13(x2, y1)),
|
|
14116
|
+
lineSegment6(pointFrom13(x2, y1), pointFrom13(x2, y2)),
|
|
14117
|
+
lineSegment6(pointFrom13(x2, y2), pointFrom13(x1, y2)),
|
|
14118
|
+
lineSegment6(pointFrom13(x1, y2), pointFrom13(x1, y1))
|
|
13962
14119
|
];
|
|
13963
14120
|
return segments2;
|
|
13964
14121
|
}
|
|
@@ -13966,7 +14123,7 @@ var getElementLineSegments = (element, elementsMap) => {
|
|
|
13966
14123
|
const points = shape.data;
|
|
13967
14124
|
const segments = [];
|
|
13968
14125
|
for (let i = 0; i < points.length - 1; i++) {
|
|
13969
|
-
segments.push(
|
|
14126
|
+
segments.push(lineSegment6(points[i], points[i + 1]));
|
|
13970
14127
|
}
|
|
13971
14128
|
return segments;
|
|
13972
14129
|
} else if (shape.type === "ellipse") {
|
|
@@ -13981,45 +14138,45 @@ var getElementLineSegments = (element, elementsMap) => {
|
|
|
13981
14138
|
[cx, y2],
|
|
13982
14139
|
[x1, cy],
|
|
13983
14140
|
[x2, cy]
|
|
13984
|
-
].map((point) =>
|
|
14141
|
+
].map((point) => pointRotateRads12(point, center, element.angle));
|
|
13985
14142
|
return [
|
|
13986
|
-
|
|
13987
|
-
|
|
13988
|
-
|
|
13989
|
-
|
|
13990
|
-
|
|
13991
|
-
|
|
13992
|
-
|
|
13993
|
-
|
|
14143
|
+
lineSegment6(nw, ne),
|
|
14144
|
+
lineSegment6(sw, se2),
|
|
14145
|
+
lineSegment6(nw, sw),
|
|
14146
|
+
lineSegment6(ne, se2),
|
|
14147
|
+
lineSegment6(nw, e),
|
|
14148
|
+
lineSegment6(sw, e),
|
|
14149
|
+
lineSegment6(ne, w),
|
|
14150
|
+
lineSegment6(se2, w)
|
|
13994
14151
|
];
|
|
13995
14152
|
};
|
|
13996
14153
|
var _isRectanguloidElement = (element) => {
|
|
13997
14154
|
return element != null && (element.type === "rectangle" || element.type === "image" || element.type === "iframe" || element.type === "embeddable" || element.type === "frame" || element.type === "magicframe" || element.type === "text" && !element.containerId);
|
|
13998
14155
|
};
|
|
13999
|
-
var getRotatedSides = (sides, center,
|
|
14156
|
+
var getRotatedSides = (sides, center, angle2) => {
|
|
14000
14157
|
return sides.map((side) => {
|
|
14001
|
-
return
|
|
14002
|
-
|
|
14003
|
-
|
|
14158
|
+
return lineSegment6(
|
|
14159
|
+
pointRotateRads12(side[0], center, angle2),
|
|
14160
|
+
pointRotateRads12(side[1], center, angle2)
|
|
14004
14161
|
);
|
|
14005
14162
|
});
|
|
14006
14163
|
};
|
|
14007
|
-
var getSegmentsOnCurve = (curve4, center,
|
|
14164
|
+
var getSegmentsOnCurve = (curve4, center, angle2) => {
|
|
14008
14165
|
const points = pointsOnBezierCurves(curve4, 10);
|
|
14009
14166
|
let i = 0;
|
|
14010
14167
|
const segments = [];
|
|
14011
14168
|
while (i < points.length - 1) {
|
|
14012
14169
|
segments.push(
|
|
14013
|
-
|
|
14014
|
-
|
|
14015
|
-
|
|
14170
|
+
lineSegment6(
|
|
14171
|
+
pointRotateRads12(
|
|
14172
|
+
pointFrom13(points[i][0], points[i][1]),
|
|
14016
14173
|
center,
|
|
14017
|
-
|
|
14174
|
+
angle2
|
|
14018
14175
|
),
|
|
14019
|
-
|
|
14020
|
-
|
|
14176
|
+
pointRotateRads12(
|
|
14177
|
+
pointFrom13(points[i + 1][0], points[i + 1][1]),
|
|
14021
14178
|
center,
|
|
14022
|
-
|
|
14179
|
+
angle2
|
|
14023
14180
|
)
|
|
14024
14181
|
)
|
|
14025
14182
|
);
|
|
@@ -14028,7 +14185,7 @@ var getSegmentsOnCurve = (curve4, center, angle) => {
|
|
|
14028
14185
|
return segments;
|
|
14029
14186
|
};
|
|
14030
14187
|
var getSegmentsOnEllipse = (ellipse4) => {
|
|
14031
|
-
const center =
|
|
14188
|
+
const center = pointFrom13(
|
|
14032
14189
|
ellipse4.x + ellipse4.width / 2,
|
|
14033
14190
|
ellipse4.y + ellipse4.height / 2
|
|
14034
14191
|
);
|
|
@@ -14042,12 +14199,12 @@ var getSegmentsOnEllipse = (ellipse4) => {
|
|
|
14042
14199
|
const t = i * deltaT;
|
|
14043
14200
|
const x = center[0] + a2 * Math.cos(t);
|
|
14044
14201
|
const y = center[1] + b2 * Math.sin(t);
|
|
14045
|
-
points.push(
|
|
14202
|
+
points.push(pointRotateRads12(pointFrom13(x, y), center, ellipse4.angle));
|
|
14046
14203
|
}
|
|
14047
14204
|
for (let i = 0; i < points.length - 1; i++) {
|
|
14048
|
-
segments.push(
|
|
14205
|
+
segments.push(lineSegment6(points[i], points[i + 1]));
|
|
14049
14206
|
}
|
|
14050
|
-
segments.push(
|
|
14207
|
+
segments.push(lineSegment6(points[points.length - 1], points[0]));
|
|
14051
14208
|
return segments;
|
|
14052
14209
|
};
|
|
14053
14210
|
var getRectangleBoxAbsoluteCoords = (boxSceneCoords) => {
|
|
@@ -14125,7 +14282,7 @@ var getCubicBezierCurveBound = (p0, p1, p2, p3) => {
|
|
|
14125
14282
|
return [minX, minY, maxX, maxY];
|
|
14126
14283
|
};
|
|
14127
14284
|
var getMinMaxXYFromCurvePathOps = (ops, transformXY) => {
|
|
14128
|
-
let currentP =
|
|
14285
|
+
let currentP = pointFrom13(0, 0);
|
|
14129
14286
|
const { minX, minY, maxX, maxY } = ops.reduce(
|
|
14130
14287
|
(limits, { op, data }) => {
|
|
14131
14288
|
if (op === "move") {
|
|
@@ -14133,9 +14290,9 @@ var getMinMaxXYFromCurvePathOps = (ops, transformXY) => {
|
|
|
14133
14290
|
invariant10(p != null, "Op data is not a point");
|
|
14134
14291
|
currentP = p;
|
|
14135
14292
|
} else if (op === "bcurveTo") {
|
|
14136
|
-
const _p1 =
|
|
14137
|
-
const _p2 =
|
|
14138
|
-
const _p3 =
|
|
14293
|
+
const _p1 = pointFrom13(data[0], data[1]);
|
|
14294
|
+
const _p2 = pointFrom13(data[2], data[3]);
|
|
14295
|
+
const _p3 = pointFrom13(data[4], data[5]);
|
|
14139
14296
|
const p1 = transformXY ? transformXY(_p1) : _p1;
|
|
14140
14297
|
const p2 = transformXY ? transformXY(_p2) : _p2;
|
|
14141
14298
|
const p3 = transformXY ? transformXY(_p3) : _p3;
|
|
@@ -14226,17 +14383,17 @@ var getArrowheadPoints = (element, shape, position, arrowhead, offsetMultiplier
|
|
|
14226
14383
|
const index = position === "start" ? 1 : ops.length - 1;
|
|
14227
14384
|
const data = ops[index].data;
|
|
14228
14385
|
invariant10(data.length === 6, "Op data length is not 6");
|
|
14229
|
-
const p3 =
|
|
14230
|
-
const p2 =
|
|
14231
|
-
const p1 =
|
|
14386
|
+
const p3 = pointFrom13(data[4], data[5]);
|
|
14387
|
+
const p2 = pointFrom13(data[2], data[3]);
|
|
14388
|
+
const p1 = pointFrom13(data[0], data[1]);
|
|
14232
14389
|
const prevOp = ops[index - 1];
|
|
14233
|
-
let p0 =
|
|
14390
|
+
let p0 = pointFrom13(0, 0);
|
|
14234
14391
|
if (prevOp.op === "move") {
|
|
14235
14392
|
const p = pointFromArray3(prevOp.data);
|
|
14236
14393
|
invariant10(p != null, "Op data is not a point");
|
|
14237
14394
|
p0 = p;
|
|
14238
14395
|
} else if (prevOp.op === "bcurveTo") {
|
|
14239
|
-
p0 =
|
|
14396
|
+
p0 = pointFrom13(prevOp.data[4], prevOp.data[5]);
|
|
14240
14397
|
}
|
|
14241
14398
|
const equation = (t, idx) => Math.pow(1 - t, 3) * p3[idx] + 3 * t * Math.pow(1 - t, 2) * p2[idx] + 3 * Math.pow(t, 2) * (1 - t) * p1[idx] + p0[idx] * Math.pow(t, 3);
|
|
14242
14399
|
const [x2, y2] = position === "start" ? p0 : p3;
|
|
@@ -14261,45 +14418,45 @@ var getArrowheadPoints = (element, shape, position, arrowhead, offsetMultiplier
|
|
|
14261
14418
|
const diameter = Math.hypot(ys - ty, xs - tx) + element.strokeWidth - 2;
|
|
14262
14419
|
return [tx, ty, diameter];
|
|
14263
14420
|
}
|
|
14264
|
-
const
|
|
14421
|
+
const angle2 = getArrowheadAngle(arrowhead);
|
|
14265
14422
|
if (arrowhead === "cardinality_many" || arrowhead === "cardinality_one_or_many") {
|
|
14266
|
-
const [x32, y32] =
|
|
14267
|
-
|
|
14268
|
-
|
|
14269
|
-
degreesToRadians(-
|
|
14423
|
+
const [x32, y32] = pointRotateRads12(
|
|
14424
|
+
pointFrom13(tx, ty),
|
|
14425
|
+
pointFrom13(xs, ys),
|
|
14426
|
+
degreesToRadians(-angle2)
|
|
14270
14427
|
);
|
|
14271
|
-
const [x42, y42] =
|
|
14272
|
-
|
|
14273
|
-
|
|
14274
|
-
degreesToRadians(
|
|
14428
|
+
const [x42, y42] = pointRotateRads12(
|
|
14429
|
+
pointFrom13(tx, ty),
|
|
14430
|
+
pointFrom13(xs, ys),
|
|
14431
|
+
degreesToRadians(angle2)
|
|
14275
14432
|
);
|
|
14276
14433
|
return [xs, ys, x32, y32, x42, y42];
|
|
14277
14434
|
}
|
|
14278
|
-
const [x3, y3] =
|
|
14279
|
-
|
|
14280
|
-
|
|
14281
|
-
-
|
|
14435
|
+
const [x3, y3] = pointRotateRads12(
|
|
14436
|
+
pointFrom13(xs, ys),
|
|
14437
|
+
pointFrom13(tx, ty),
|
|
14438
|
+
-angle2 * Math.PI / 180
|
|
14282
14439
|
);
|
|
14283
|
-
const [x4, y4] =
|
|
14284
|
-
|
|
14285
|
-
|
|
14286
|
-
degreesToRadians(
|
|
14440
|
+
const [x4, y4] = pointRotateRads12(
|
|
14441
|
+
pointFrom13(xs, ys),
|
|
14442
|
+
pointFrom13(tx, ty),
|
|
14443
|
+
degreesToRadians(angle2)
|
|
14287
14444
|
);
|
|
14288
14445
|
if (arrowhead === "diamond" || arrowhead === "diamond_outline") {
|
|
14289
14446
|
let ox;
|
|
14290
14447
|
let oy;
|
|
14291
14448
|
if (position === "start") {
|
|
14292
14449
|
const [px, py] = element.points.length > 1 ? element.points[1] : [0, 0];
|
|
14293
|
-
[ox, oy] =
|
|
14294
|
-
|
|
14295
|
-
|
|
14450
|
+
[ox, oy] = pointRotateRads12(
|
|
14451
|
+
pointFrom13(tx + minSize * 2, ty),
|
|
14452
|
+
pointFrom13(tx, ty),
|
|
14296
14453
|
Math.atan2(py - ty, px - tx)
|
|
14297
14454
|
);
|
|
14298
14455
|
} else {
|
|
14299
14456
|
const [px, py] = element.points.length > 1 ? element.points[element.points.length - 2] : [0, 0];
|
|
14300
|
-
[ox, oy] =
|
|
14301
|
-
|
|
14302
|
-
|
|
14457
|
+
[ox, oy] = pointRotateRads12(
|
|
14458
|
+
pointFrom13(tx - minSize * 2, ty),
|
|
14459
|
+
pointFrom13(tx, ty),
|
|
14303
14460
|
Math.atan2(ty - py, tx - px)
|
|
14304
14461
|
);
|
|
14305
14462
|
}
|
|
@@ -14328,9 +14485,9 @@ var getLinearElementRotatedBounds = (element, cx, cy, elementsMap) => {
|
|
|
14328
14485
|
const boundTextElement = getBoundTextElement(element, elementsMap);
|
|
14329
14486
|
if (element.points.length < 2) {
|
|
14330
14487
|
const [pointX, pointY] = element.points[0];
|
|
14331
|
-
const [x, y] =
|
|
14332
|
-
|
|
14333
|
-
|
|
14488
|
+
const [x, y] = pointRotateRads12(
|
|
14489
|
+
pointFrom13(element.x + pointX, element.y + pointY),
|
|
14490
|
+
pointFrom13(cx, cy),
|
|
14334
14491
|
element.angle
|
|
14335
14492
|
);
|
|
14336
14493
|
let coords2 = [x, y, x, y];
|
|
@@ -14353,9 +14510,9 @@ var getLinearElementRotatedBounds = (element, cx, cy, elementsMap) => {
|
|
|
14353
14510
|
const cachedShape = ShapeCache.get(element, null)?.[0];
|
|
14354
14511
|
const shape = cachedShape ?? generateLinearElementShape(element);
|
|
14355
14512
|
const ops = getCurvePathOps(shape);
|
|
14356
|
-
const transformXY = ([x, y]) =>
|
|
14357
|
-
|
|
14358
|
-
|
|
14513
|
+
const transformXY = ([x, y]) => pointRotateRads12(
|
|
14514
|
+
pointFrom13(element.x + x, element.y + y),
|
|
14515
|
+
pointFrom13(cx, cy),
|
|
14359
14516
|
element.angle
|
|
14360
14517
|
);
|
|
14361
14518
|
const res = getMinMaxXYFromCurvePathOps(ops, transformXY);
|
|
@@ -14456,26 +14613,6 @@ var getElementPointsCoords = (element, points) => {
|
|
|
14456
14613
|
maxY + element.y
|
|
14457
14614
|
];
|
|
14458
14615
|
};
|
|
14459
|
-
var getClosestElementBounds = (elements, from) => {
|
|
14460
|
-
if (!elements.length) {
|
|
14461
|
-
return [0, 0, 0, 0];
|
|
14462
|
-
}
|
|
14463
|
-
let minDistance = Infinity;
|
|
14464
|
-
let closestElement = elements[0];
|
|
14465
|
-
const elementsMap = arrayToMap6(elements);
|
|
14466
|
-
elements.forEach((element) => {
|
|
14467
|
-
const [x1, y1, x2, y2] = getElementBounds(element, elementsMap);
|
|
14468
|
-
const distance3 = pointDistance7(
|
|
14469
|
-
pointFrom14((x1 + x2) / 2, (y1 + y2) / 2),
|
|
14470
|
-
pointFrom14(from.x, from.y)
|
|
14471
|
-
);
|
|
14472
|
-
if (distance3 < minDistance) {
|
|
14473
|
-
minDistance = distance3;
|
|
14474
|
-
closestElement = element;
|
|
14475
|
-
}
|
|
14476
|
-
});
|
|
14477
|
-
return getElementBounds(closestElement, elementsMap);
|
|
14478
|
-
};
|
|
14479
14616
|
var getCommonBoundingBox = (elements) => {
|
|
14480
14617
|
const [minX, minY, maxX, maxY] = getCommonBounds(elements);
|
|
14481
14618
|
return {
|
|
@@ -14503,7 +14640,7 @@ var getVisibleSceneBounds = ({
|
|
|
14503
14640
|
-scrollY + height / zoom.value
|
|
14504
14641
|
];
|
|
14505
14642
|
};
|
|
14506
|
-
var getCenterForBounds = (bounds) =>
|
|
14643
|
+
var getCenterForBounds = (bounds) => pointFrom13(
|
|
14507
14644
|
bounds[0] + (bounds[2] - bounds[0]) / 2,
|
|
14508
14645
|
bounds[1] + (bounds[3] - bounds[1]) / 2
|
|
14509
14646
|
);
|
|
@@ -14517,23 +14654,23 @@ var aabbForElement = (element, elementsMap, offset) => {
|
|
|
14517
14654
|
midY: element.y + element.height / 2
|
|
14518
14655
|
};
|
|
14519
14656
|
const center = elementCenterPoint(element, elementsMap);
|
|
14520
|
-
const [topLeftX, topLeftY] =
|
|
14521
|
-
|
|
14657
|
+
const [topLeftX, topLeftY] = pointRotateRads12(
|
|
14658
|
+
pointFrom13(bbox.minX, bbox.minY),
|
|
14522
14659
|
center,
|
|
14523
14660
|
element.angle
|
|
14524
14661
|
);
|
|
14525
|
-
const [topRightX, topRightY] =
|
|
14526
|
-
|
|
14662
|
+
const [topRightX, topRightY] = pointRotateRads12(
|
|
14663
|
+
pointFrom13(bbox.maxX, bbox.minY),
|
|
14527
14664
|
center,
|
|
14528
14665
|
element.angle
|
|
14529
14666
|
);
|
|
14530
|
-
const [bottomRightX, bottomRightY] =
|
|
14531
|
-
|
|
14667
|
+
const [bottomRightX, bottomRightY] = pointRotateRads12(
|
|
14668
|
+
pointFrom13(bbox.maxX, bbox.maxY),
|
|
14532
14669
|
center,
|
|
14533
14670
|
element.angle
|
|
14534
14671
|
);
|
|
14535
|
-
const [bottomLeftX, bottomLeftY] =
|
|
14536
|
-
|
|
14672
|
+
const [bottomLeftX, bottomLeftY] = pointRotateRads12(
|
|
14673
|
+
pointFrom13(bbox.minX, bbox.maxY),
|
|
14537
14674
|
center,
|
|
14538
14675
|
element.angle
|
|
14539
14676
|
);
|
|
@@ -14565,19 +14702,224 @@ var doBoundsIntersect = (bounds1, bounds2) => {
|
|
|
14565
14702
|
return minX1 < maxX2 && maxX1 > minX2 && minY1 < maxY2 && maxY1 > minY2;
|
|
14566
14703
|
};
|
|
14567
14704
|
var boundsContainBounds = (outerBounds, innerBounds) => [
|
|
14568
|
-
|
|
14569
|
-
|
|
14570
|
-
|
|
14571
|
-
|
|
14705
|
+
pointFrom13(innerBounds[0], innerBounds[1]),
|
|
14706
|
+
pointFrom13(innerBounds[0], innerBounds[3]),
|
|
14707
|
+
pointFrom13(innerBounds[2], innerBounds[1]),
|
|
14708
|
+
pointFrom13(innerBounds[2], innerBounds[3])
|
|
14572
14709
|
].every((point) => pointInsideBoundsInclusive(point, outerBounds));
|
|
14710
|
+
var elementsOverlappingBBox = ({
|
|
14711
|
+
elements,
|
|
14712
|
+
elementsMap,
|
|
14713
|
+
bounds,
|
|
14714
|
+
type,
|
|
14715
|
+
excludeElementsInFrames,
|
|
14716
|
+
shouldIgnoreElementFromSelection: shouldIgnoreElementFromSelection2
|
|
14717
|
+
}) => {
|
|
14718
|
+
if (!elementsMap) {
|
|
14719
|
+
elementsMap = arrayToMap6(elements);
|
|
14720
|
+
}
|
|
14721
|
+
const selectionBounds = isExcalidrawElement(bounds) ? getElementBounds(bounds, elementsMap) : bounds;
|
|
14722
|
+
const [selectionX1, selectionY1, selectionX2, selectionY2] = selectionBounds;
|
|
14723
|
+
const selectionEdges = [
|
|
14724
|
+
lineSegment6(
|
|
14725
|
+
pointFrom13(selectionX1, selectionY1),
|
|
14726
|
+
pointFrom13(selectionX2, selectionY1)
|
|
14727
|
+
),
|
|
14728
|
+
lineSegment6(
|
|
14729
|
+
pointFrom13(selectionX2, selectionY1),
|
|
14730
|
+
pointFrom13(selectionX2, selectionY2)
|
|
14731
|
+
),
|
|
14732
|
+
lineSegment6(
|
|
14733
|
+
pointFrom13(selectionX2, selectionY2),
|
|
14734
|
+
pointFrom13(selectionX1, selectionY2)
|
|
14735
|
+
),
|
|
14736
|
+
lineSegment6(
|
|
14737
|
+
pointFrom13(selectionX1, selectionY2),
|
|
14738
|
+
pointFrom13(selectionX1, selectionY1)
|
|
14739
|
+
)
|
|
14740
|
+
];
|
|
14741
|
+
const framesInSelection = excludeElementsInFrames ? /* @__PURE__ */ new Set() : null;
|
|
14742
|
+
const groups = {};
|
|
14743
|
+
const elementsInSelection = /* @__PURE__ */ new Set();
|
|
14744
|
+
for (const element of elements) {
|
|
14745
|
+
if (shouldIgnoreElementFromSelection2?.(element)) {
|
|
14746
|
+
continue;
|
|
14747
|
+
}
|
|
14748
|
+
const groupId = element.groupIds.at(-1);
|
|
14749
|
+
if (groupId) {
|
|
14750
|
+
if (!groups[groupId]) {
|
|
14751
|
+
groups[groupId] = [];
|
|
14752
|
+
}
|
|
14753
|
+
groups[groupId].push(element);
|
|
14754
|
+
}
|
|
14755
|
+
const strokeWidth = element.strokeWidth;
|
|
14756
|
+
let labelAABB = null;
|
|
14757
|
+
let elementAABB = getElementBounds(element, elementsMap);
|
|
14758
|
+
elementAABB = [
|
|
14759
|
+
elementAABB[0] - strokeWidth / 2,
|
|
14760
|
+
elementAABB[1] - strokeWidth / 2,
|
|
14761
|
+
elementAABB[2] + strokeWidth / 2,
|
|
14762
|
+
elementAABB[3] + strokeWidth / 2
|
|
14763
|
+
];
|
|
14764
|
+
const boundTextElement = isArrowElement(element) && getBoundTextElement(element, elementsMap);
|
|
14765
|
+
if (boundTextElement) {
|
|
14766
|
+
const { x, y } = LinearElementEditor.getBoundTextElementPosition(
|
|
14767
|
+
element,
|
|
14768
|
+
boundTextElement,
|
|
14769
|
+
elementsMap
|
|
14770
|
+
);
|
|
14771
|
+
labelAABB = [
|
|
14772
|
+
x,
|
|
14773
|
+
y,
|
|
14774
|
+
x + boundTextElement.width,
|
|
14775
|
+
y + boundTextElement.height
|
|
14776
|
+
];
|
|
14777
|
+
}
|
|
14778
|
+
const associatedFrame = getContainingFrame(element, elementsMap);
|
|
14779
|
+
if (associatedFrame && elementOverlapsWithFrame(element, associatedFrame, elementsMap)) {
|
|
14780
|
+
const frameAABB = getElementBounds(associatedFrame, elementsMap);
|
|
14781
|
+
elementAABB = [
|
|
14782
|
+
Math.max(elementAABB[0], frameAABB[0]),
|
|
14783
|
+
Math.max(elementAABB[1], frameAABB[1]),
|
|
14784
|
+
Math.min(elementAABB[2], frameAABB[2]),
|
|
14785
|
+
Math.min(elementAABB[3], frameAABB[3])
|
|
14786
|
+
];
|
|
14787
|
+
labelAABB = labelAABB ? [
|
|
14788
|
+
Math.max(labelAABB[0], frameAABB[0]),
|
|
14789
|
+
Math.max(labelAABB[1], frameAABB[1]),
|
|
14790
|
+
Math.min(labelAABB[2], frameAABB[2]),
|
|
14791
|
+
Math.min(labelAABB[3], frameAABB[3])
|
|
14792
|
+
] : null;
|
|
14793
|
+
}
|
|
14794
|
+
const commonAABB2 = labelAABB ? [
|
|
14795
|
+
Math.min(labelAABB[0], elementAABB[0]),
|
|
14796
|
+
Math.min(labelAABB[1], elementAABB[1]),
|
|
14797
|
+
Math.max(labelAABB[2], elementAABB[2]),
|
|
14798
|
+
Math.max(labelAABB[3], elementAABB[3])
|
|
14799
|
+
] : elementAABB;
|
|
14800
|
+
if (boundsContainBounds(selectionBounds, commonAABB2)) {
|
|
14801
|
+
if (framesInSelection && isFrameLikeElement(element)) {
|
|
14802
|
+
framesInSelection.add(element.id);
|
|
14803
|
+
}
|
|
14804
|
+
elementsInSelection.add(element);
|
|
14805
|
+
continue;
|
|
14806
|
+
}
|
|
14807
|
+
if (type === "overlap" && labelAABB && doBoundsIntersect(selectionBounds, labelAABB)) {
|
|
14808
|
+
elementsInSelection.add(element);
|
|
14809
|
+
continue;
|
|
14810
|
+
}
|
|
14811
|
+
if (type === "overlap" && doBoundsIntersect(selectionBounds, elementAABB)) {
|
|
14812
|
+
let hasIntersection = false;
|
|
14813
|
+
if (isLinearElement(element) || isFreeDrawElement(element)) {
|
|
14814
|
+
const center = elementCenterPoint(element, elementsMap);
|
|
14815
|
+
hasIntersection = element.points.some((point) => {
|
|
14816
|
+
const rotatedPoint = pointRotateRads12(
|
|
14817
|
+
pointFrom13(element.x + point[0], element.y + point[1]),
|
|
14818
|
+
center,
|
|
14819
|
+
element.angle
|
|
14820
|
+
);
|
|
14821
|
+
return pointInsideBounds(rotatedPoint, selectionBounds);
|
|
14822
|
+
});
|
|
14823
|
+
} else {
|
|
14824
|
+
const nonRotatedElementBounds = getElementBounds(
|
|
14825
|
+
element,
|
|
14826
|
+
elementsMap,
|
|
14827
|
+
true
|
|
14828
|
+
);
|
|
14829
|
+
const center = elementCenterPoint(element, elementsMap);
|
|
14830
|
+
hasIntersection = [
|
|
14831
|
+
pointRotateRads12(
|
|
14832
|
+
pointFrom13(
|
|
14833
|
+
(nonRotatedElementBounds[0] + nonRotatedElementBounds[2]) / 2,
|
|
14834
|
+
nonRotatedElementBounds[1]
|
|
14835
|
+
),
|
|
14836
|
+
center,
|
|
14837
|
+
element.angle
|
|
14838
|
+
),
|
|
14839
|
+
pointRotateRads12(
|
|
14840
|
+
pointFrom13(
|
|
14841
|
+
nonRotatedElementBounds[2],
|
|
14842
|
+
(nonRotatedElementBounds[1] + nonRotatedElementBounds[3]) / 2
|
|
14843
|
+
),
|
|
14844
|
+
center,
|
|
14845
|
+
element.angle
|
|
14846
|
+
),
|
|
14847
|
+
pointRotateRads12(
|
|
14848
|
+
pointFrom13(
|
|
14849
|
+
(nonRotatedElementBounds[0] + nonRotatedElementBounds[2]) / 2,
|
|
14850
|
+
nonRotatedElementBounds[3]
|
|
14851
|
+
),
|
|
14852
|
+
center,
|
|
14853
|
+
element.angle
|
|
14854
|
+
),
|
|
14855
|
+
pointRotateRads12(
|
|
14856
|
+
pointFrom13(
|
|
14857
|
+
nonRotatedElementBounds[0],
|
|
14858
|
+
(nonRotatedElementBounds[1] + nonRotatedElementBounds[3]) / 2
|
|
14859
|
+
),
|
|
14860
|
+
center,
|
|
14861
|
+
element.angle
|
|
14862
|
+
)
|
|
14863
|
+
].some((point) => {
|
|
14864
|
+
return pointInsideBounds(
|
|
14865
|
+
pointRotateRads12(point, center, element.angle),
|
|
14866
|
+
selectionBounds
|
|
14867
|
+
);
|
|
14868
|
+
});
|
|
14869
|
+
}
|
|
14870
|
+
if (!hasIntersection) {
|
|
14871
|
+
hasIntersection = selectionEdges.some(
|
|
14872
|
+
(selectionEdge) => intersectElementWithLineSegment(
|
|
14873
|
+
element,
|
|
14874
|
+
elementsMap,
|
|
14875
|
+
selectionEdge,
|
|
14876
|
+
strokeWidth / 2,
|
|
14877
|
+
true
|
|
14878
|
+
// Stop at first hit for better performance
|
|
14879
|
+
).length > 0
|
|
14880
|
+
);
|
|
14881
|
+
}
|
|
14882
|
+
if (hasIntersection) {
|
|
14883
|
+
if (framesInSelection && isFrameLikeElement(element)) {
|
|
14884
|
+
framesInSelection.add(element.id);
|
|
14885
|
+
}
|
|
14886
|
+
elementsInSelection.add(element);
|
|
14887
|
+
continue;
|
|
14888
|
+
}
|
|
14889
|
+
}
|
|
14890
|
+
}
|
|
14891
|
+
if (framesInSelection) {
|
|
14892
|
+
elementsInSelection.forEach((element) => {
|
|
14893
|
+
if (element.frameId && framesInSelection.has(element.frameId)) {
|
|
14894
|
+
elementsInSelection.delete(element);
|
|
14895
|
+
}
|
|
14896
|
+
});
|
|
14897
|
+
}
|
|
14898
|
+
if (type === "overlap") {
|
|
14899
|
+
Array.from(elementsInSelection).forEach((element) => {
|
|
14900
|
+
const groupId = element.groupIds.at(-1);
|
|
14901
|
+
const group = groupId ? groups[groupId] : null;
|
|
14902
|
+
group?.forEach((groupElement) => elementsInSelection.add(groupElement));
|
|
14903
|
+
});
|
|
14904
|
+
} else if (type === "contain") {
|
|
14905
|
+
elementsInSelection.forEach((element) => {
|
|
14906
|
+
const groupId = element.groupIds.at(-1);
|
|
14907
|
+
const group = groupId ? groups[groupId] : null;
|
|
14908
|
+
if (group && !group.every((groupElement) => elementsInSelection.has(groupElement))) {
|
|
14909
|
+
elementsInSelection.delete(element);
|
|
14910
|
+
}
|
|
14911
|
+
});
|
|
14912
|
+
}
|
|
14913
|
+
return elements.filter((element) => elementsInSelection.has(element));
|
|
14914
|
+
};
|
|
14573
14915
|
var elementCenterPoint = (element, elementsMap, xOffset = 0, yOffset = 0) => {
|
|
14574
14916
|
if (isLinearElement(element) || isFreeDrawElement(element)) {
|
|
14575
14917
|
const [x1, y1, x2, y2] = getElementAbsoluteCoords2(element, elementsMap);
|
|
14576
|
-
const [x3, y3] =
|
|
14577
|
-
return
|
|
14918
|
+
const [x3, y3] = pointFrom13((x1 + x2) / 2, (y1 + y2) / 2);
|
|
14919
|
+
return pointFrom13(x3 + xOffset, y3 + yOffset);
|
|
14578
14920
|
}
|
|
14579
14921
|
const [x, y] = getCenterForBounds(getElementBounds(element, elementsMap));
|
|
14580
|
-
return
|
|
14922
|
+
return pointFrom13(x + xOffset, y + yOffset);
|
|
14581
14923
|
};
|
|
14582
14924
|
|
|
14583
14925
|
// src/sizeHelpers.ts
|
|
@@ -14648,18 +14990,18 @@ var getPerfectElementSize = (elementType, width, height) => {
|
|
|
14648
14990
|
var getLockedLinearCursorAlignSize = (originX, originY, x, y, customAngle) => {
|
|
14649
14991
|
let width = x - originX;
|
|
14650
14992
|
let height = y - originY;
|
|
14651
|
-
const
|
|
14652
|
-
let lockedAngle = Math.round(
|
|
14993
|
+
const angle2 = Math.atan2(height, width);
|
|
14994
|
+
let lockedAngle = Math.round(angle2 / SHIFT_LOCKING_ANGLE) * SHIFT_LOCKING_ANGLE;
|
|
14653
14995
|
if (customAngle) {
|
|
14654
14996
|
const lower = Math.floor(customAngle / SHIFT_LOCKING_ANGLE) * SHIFT_LOCKING_ANGLE;
|
|
14655
14997
|
if (radiansBetweenAngles(
|
|
14656
|
-
|
|
14998
|
+
angle2,
|
|
14657
14999
|
lower,
|
|
14658
15000
|
lower + SHIFT_LOCKING_ANGLE
|
|
14659
15001
|
)) {
|
|
14660
|
-
if (radiansDifference(
|
|
15002
|
+
if (radiansDifference(angle2, customAngle) < SHIFT_LOCKING_ANGLE / 6) {
|
|
14661
15003
|
lockedAngle = customAngle;
|
|
14662
|
-
} else if (normalizeRadians(
|
|
15004
|
+
} else if (normalizeRadians(angle2) > normalizeRadians(customAngle)) {
|
|
14663
15005
|
lockedAngle = lower + SHIFT_LOCKING_ANGLE;
|
|
14664
15006
|
} else {
|
|
14665
15007
|
lockedAngle = lower;
|
|
@@ -14711,7 +15053,7 @@ var alignElements = (selectedElements, alignment, scene, appState) => {
|
|
|
14711
15053
|
selectedElements,
|
|
14712
15054
|
scene.getNonDeletedElementsMap(),
|
|
14713
15055
|
appState
|
|
14714
|
-
);
|
|
15056
|
+
).map(getNonDeletedElements);
|
|
14715
15057
|
const selectionBoundingBox = getCommonBoundingBox(selectedElements);
|
|
14716
15058
|
return groups.flatMap((group) => {
|
|
14717
15059
|
const translation = calculateTranslation(
|
|
@@ -14913,6 +15255,11 @@ var duplicateElements = (opts) => {
|
|
|
14913
15255
|
return acc;
|
|
14914
15256
|
}
|
|
14915
15257
|
processedIds.set(element2.id, true);
|
|
15258
|
+
if (!isNonDeletedElement(element2)) {
|
|
15259
|
+
console.error(
|
|
15260
|
+
"[NONDELETED][INVARIANT] Element to duplicate should be non-deleted"
|
|
15261
|
+
);
|
|
15262
|
+
}
|
|
14916
15263
|
const newElement2 = duplicateElement(
|
|
14917
15264
|
appState.editingGroupId,
|
|
14918
15265
|
groupIdMap,
|
|
@@ -15768,7 +16115,7 @@ import {
|
|
|
15768
16115
|
isTestEnv as isTestEnv6,
|
|
15769
16116
|
toArray
|
|
15770
16117
|
} from "@excalidraw/common";
|
|
15771
|
-
import { isNonDeletedElement } from "@excalidraw/element";
|
|
16118
|
+
import { isNonDeletedElement as isNonDeletedElement2 } from "@excalidraw/element";
|
|
15772
16119
|
import { isFrameLikeElement as isFrameLikeElement2 } from "@excalidraw/element";
|
|
15773
16120
|
import { getElementsInGroup as getElementsInGroup2 } from "@excalidraw/element";
|
|
15774
16121
|
import {
|
|
@@ -15778,7 +16125,7 @@ import {
|
|
|
15778
16125
|
} from "@excalidraw/element";
|
|
15779
16126
|
import { getSelectedElements as getSelectedElements2 } from "@excalidraw/element";
|
|
15780
16127
|
import { mutateElement as mutateElement2 } from "@excalidraw/element";
|
|
15781
|
-
var
|
|
16128
|
+
var getNonDeletedElements2 = (allElements) => {
|
|
15782
16129
|
const elementsMap = /* @__PURE__ */ new Map();
|
|
15783
16130
|
const elements = [];
|
|
15784
16131
|
for (const element of allElements) {
|
|
@@ -15893,7 +16240,7 @@ var Scene = class {
|
|
|
15893
16240
|
}
|
|
15894
16241
|
getNonDeletedElement(id) {
|
|
15895
16242
|
const element = this.getElement(id);
|
|
15896
|
-
if (element &&
|
|
16243
|
+
if (element && isNonDeletedElement2(element)) {
|
|
15897
16244
|
return element;
|
|
15898
16245
|
}
|
|
15899
16246
|
return null;
|
|
@@ -15938,11 +16285,11 @@ var Scene = class {
|
|
|
15938
16285
|
}
|
|
15939
16286
|
this.elementsMap.set(element.id, element);
|
|
15940
16287
|
});
|
|
15941
|
-
const nonDeletedElements =
|
|
16288
|
+
const nonDeletedElements = getNonDeletedElements2(this.elements);
|
|
15942
16289
|
this.nonDeletedElements = nonDeletedElements.elements;
|
|
15943
16290
|
this.nonDeletedElementsMap = nonDeletedElements.elementsMap;
|
|
15944
16291
|
this.frames = nextFrameLikes;
|
|
15945
|
-
this.nonDeletedFramesLikes =
|
|
16292
|
+
this.nonDeletedFramesLikes = getNonDeletedElements2(this.frames).elements;
|
|
15946
16293
|
this.triggerUpdate();
|
|
15947
16294
|
}
|
|
15948
16295
|
triggerUpdate() {
|
|
@@ -17271,9 +17618,14 @@ var ElementsDelta = class _ElementsDelta {
|
|
|
17271
17618
|
static redrawBoundArrows(scene, changed) {
|
|
17272
17619
|
for (const element of changed.values()) {
|
|
17273
17620
|
if (!element.isDeleted && isBindableElement(element)) {
|
|
17274
|
-
updateBoundElements(
|
|
17275
|
-
|
|
17276
|
-
|
|
17621
|
+
updateBoundElements(
|
|
17622
|
+
element,
|
|
17623
|
+
// NOTE: Assumed correct, no runtime check for isDeleted due to performance reasons
|
|
17624
|
+
scene,
|
|
17625
|
+
{
|
|
17626
|
+
changedElements: changed
|
|
17627
|
+
}
|
|
17628
|
+
);
|
|
17277
17629
|
}
|
|
17278
17630
|
}
|
|
17279
17631
|
}
|
|
@@ -17335,7 +17687,7 @@ var distributeElements = (selectedElements, elementsMap, distribution, appState,
|
|
|
17335
17687
|
selectedElements,
|
|
17336
17688
|
elementsMap,
|
|
17337
17689
|
appState
|
|
17338
|
-
).map((group) => [group, getCommonBoundingBox(group)]).sort((a2, b2) => a2[1][mid] - b2[1][mid]);
|
|
17690
|
+
).map(getNonDeletedElements).map((group) => [group, getCommonBoundingBox(group)]).sort((a2, b2) => a2[1][mid] - b2[1][mid]);
|
|
17339
17691
|
let span = 0;
|
|
17340
17692
|
for (const group of groups) {
|
|
17341
17693
|
span += group[1][extent];
|
|
@@ -17692,6 +18044,7 @@ import {
|
|
|
17692
18044
|
DEFAULT_FONT_SIZE as DEFAULT_FONT_SIZE3,
|
|
17693
18045
|
DEFAULT_TEXT_ALIGN,
|
|
17694
18046
|
DEFAULT_VERTICAL_ALIGN,
|
|
18047
|
+
DEFAULT_STROKE_STREAMLINE as DEFAULT_STROKE_STREAMLINE2,
|
|
17695
18048
|
VERTICAL_ALIGN as VERTICAL_ALIGN2,
|
|
17696
18049
|
randomInteger as randomInteger5,
|
|
17697
18050
|
randomId as randomId3,
|
|
@@ -17711,7 +18064,7 @@ var _newElementBase = (type, {
|
|
|
17711
18064
|
opacity = DEFAULT_ELEMENT_PROPS.opacity,
|
|
17712
18065
|
width = 0,
|
|
17713
18066
|
height = 0,
|
|
17714
|
-
angle = 0,
|
|
18067
|
+
angle: angle2 = 0,
|
|
17715
18068
|
groupIds = [],
|
|
17716
18069
|
frameId = null,
|
|
17717
18070
|
index = null,
|
|
@@ -17738,7 +18091,7 @@ var _newElementBase = (type, {
|
|
|
17738
18091
|
y,
|
|
17739
18092
|
width,
|
|
17740
18093
|
height,
|
|
17741
|
-
angle,
|
|
18094
|
+
angle: angle2,
|
|
17742
18095
|
strokeColor,
|
|
17743
18096
|
backgroundColor,
|
|
17744
18097
|
fillStyle,
|
|
@@ -17895,9 +18248,9 @@ var getAdjustedDimensions = (element, elementsMap, nextText) => {
|
|
|
17895
18248
|
y: Number.isFinite(y) ? y : element.y
|
|
17896
18249
|
};
|
|
17897
18250
|
};
|
|
17898
|
-
var adjustXYWithRotation = (sides, x, y,
|
|
17899
|
-
const cos = Math.cos(
|
|
17900
|
-
const sin = Math.sin(
|
|
18251
|
+
var adjustXYWithRotation = (sides, x, y, angle2, deltaX1, deltaY1, deltaX2, deltaY2) => {
|
|
18252
|
+
const cos = Math.cos(angle2);
|
|
18253
|
+
const sin = Math.sin(angle2);
|
|
17901
18254
|
if (sides.e && sides.w) {
|
|
17902
18255
|
x += deltaX1 + deltaX2;
|
|
17903
18256
|
} else if (sides.e) {
|
|
@@ -17945,7 +18298,11 @@ var newFreeDrawElement = (opts) => {
|
|
|
17945
18298
|
..._newElementBase(opts.type, opts),
|
|
17946
18299
|
points: opts.points || [],
|
|
17947
18300
|
pressures: opts.pressures || [],
|
|
17948
|
-
simulatePressure: opts.simulatePressure
|
|
18301
|
+
simulatePressure: opts.simulatePressure,
|
|
18302
|
+
strokeOptions: opts.strokeOptions ?? {
|
|
18303
|
+
variability: "variable",
|
|
18304
|
+
streamline: DEFAULT_STROKE_STREAMLINE2
|
|
18305
|
+
}
|
|
17949
18306
|
};
|
|
17950
18307
|
};
|
|
17951
18308
|
var newLinearElement = (opts) => {
|
|
@@ -18414,7 +18771,7 @@ var embeddableURLValidator = (url, validateEmbeddable) => {
|
|
|
18414
18771
|
// src/flowchart.ts
|
|
18415
18772
|
init_define_import_meta_env();
|
|
18416
18773
|
import { KEYS as KEYS2, invariant as invariant11, toBrandedType as toBrandedType2 } from "@excalidraw/common";
|
|
18417
|
-
import { pointFrom as
|
|
18774
|
+
import { pointFrom as pointFrom14 } from "@excalidraw/math";
|
|
18418
18775
|
var VERTICAL_OFFSET = 100;
|
|
18419
18776
|
var HORIZONTAL_OFFSET = 100;
|
|
18420
18777
|
var getLinkDirectionFromKey = (key) => {
|
|
@@ -18694,7 +19051,7 @@ var createBindingArrow = (startBindingElement, endBindingElement, direction, app
|
|
|
18694
19051
|
strokeWidth: startBindingElement.strokeWidth,
|
|
18695
19052
|
opacity: startBindingElement.opacity,
|
|
18696
19053
|
roughness: startBindingElement.roughness,
|
|
18697
|
-
points: [
|
|
19054
|
+
points: [pointFrom14(0, 0), pointFrom14(endX, endY)],
|
|
18698
19055
|
elbowed: true
|
|
18699
19056
|
});
|
|
18700
19057
|
const elementsMap = scene.getNonDeletedElementsMap();
|
|
@@ -18745,7 +19102,8 @@ var createBindingArrow = (startBindingElement, endBindingElement, direction, app
|
|
|
18745
19102
|
);
|
|
18746
19103
|
return {
|
|
18747
19104
|
...bindingArrow,
|
|
18748
|
-
...update
|
|
19105
|
+
...update,
|
|
19106
|
+
isDeleted: bindingArrow.isDeleted
|
|
18749
19107
|
};
|
|
18750
19108
|
};
|
|
18751
19109
|
var FlowChartNavigator = class {
|
|
@@ -18882,12 +19240,13 @@ var isNodeInFlowchart = (element, elementsMap) => {
|
|
|
18882
19240
|
|
|
18883
19241
|
// src/arrows/focus.ts
|
|
18884
19242
|
init_define_import_meta_env();
|
|
18885
|
-
import { pointDistance as
|
|
19243
|
+
import { pointDistance as pointDistance7, pointFrom as pointFrom15 } from "@excalidraw/math";
|
|
18886
19244
|
import { invariant as invariant12 } from "@excalidraw/common";
|
|
18887
19245
|
|
|
18888
19246
|
// src/zindex.ts
|
|
18889
19247
|
init_define_import_meta_env();
|
|
18890
19248
|
import { arrayToMap as arrayToMap11, findIndex, findLastIndex as findLastIndex2 } from "@excalidraw/common";
|
|
19249
|
+
import { isFiniteNumber } from "@excalidraw/math";
|
|
18891
19250
|
var isOfTargetFrame = (element, frameId) => {
|
|
18892
19251
|
return element.frameId === frameId || element.id === frameId;
|
|
18893
19252
|
};
|
|
@@ -18977,7 +19336,12 @@ var getContiguousFrameRangeElements = (allElements, frameId) => {
|
|
|
18977
19336
|
return allElements.slice(rangeStart, rangeEnd + 1);
|
|
18978
19337
|
};
|
|
18979
19338
|
var moveArrowAboveBindable2 = (point, arrow, elements, elementsMap, scene, hit) => {
|
|
18980
|
-
const hoveredElement = hit ? hit : getHoveredElementForBinding(
|
|
19339
|
+
const hoveredElement = hit ? hit : getHoveredElementForBinding(
|
|
19340
|
+
point,
|
|
19341
|
+
// SAFETY: callers that omit `hit` pass non-deleted elements
|
|
19342
|
+
getNonDeletedElements(elements),
|
|
19343
|
+
elementsMap
|
|
19344
|
+
);
|
|
18981
19345
|
if (!hoveredElement) {
|
|
18982
19346
|
return elements;
|
|
18983
19347
|
}
|
|
@@ -19067,7 +19431,34 @@ var getTargetElementsMap = (elements, indices) => {
|
|
|
19067
19431
|
return acc;
|
|
19068
19432
|
}, /* @__PURE__ */ new Map());
|
|
19069
19433
|
};
|
|
19434
|
+
var hasSameElementIds = (prevElements, nextElements) => {
|
|
19435
|
+
if (prevElements.length !== nextElements.length) {
|
|
19436
|
+
console.error(
|
|
19437
|
+
"z-index reordering failed: resulting array have different lengths"
|
|
19438
|
+
);
|
|
19439
|
+
return false;
|
|
19440
|
+
}
|
|
19441
|
+
const prevElementIdCounts = /* @__PURE__ */ new Map();
|
|
19442
|
+
for (const element of prevElements) {
|
|
19443
|
+
prevElementIdCounts.set(
|
|
19444
|
+
element.id,
|
|
19445
|
+
(prevElementIdCounts.get(element.id) || 0) + 1
|
|
19446
|
+
);
|
|
19447
|
+
}
|
|
19448
|
+
for (const element of nextElements) {
|
|
19449
|
+
const count = prevElementIdCounts.get(element.id);
|
|
19450
|
+
if (!count) {
|
|
19451
|
+
console.error(
|
|
19452
|
+
"z-index reordering failed: element id mismatch / duplicate ids"
|
|
19453
|
+
);
|
|
19454
|
+
return false;
|
|
19455
|
+
}
|
|
19456
|
+
prevElementIdCounts.set(element.id, count - 1);
|
|
19457
|
+
}
|
|
19458
|
+
return true;
|
|
19459
|
+
};
|
|
19070
19460
|
var shiftElementsByOne = (elements, appState, direction, scene) => {
|
|
19461
|
+
const originalElements = elements;
|
|
19071
19462
|
const indicesToMove = getIndicesToMove(elements, appState);
|
|
19072
19463
|
const targetElementsMap = getTargetElementsMap(elements, indicesToMove);
|
|
19073
19464
|
let groupedIndices = toContiguousGroups(indicesToMove);
|
|
@@ -19112,11 +19503,17 @@ var shiftElementsByOne = (elements, appState, direction, scene) => {
|
|
|
19112
19503
|
...trailingElements
|
|
19113
19504
|
];
|
|
19114
19505
|
});
|
|
19506
|
+
if (!hasSameElementIds(originalElements, elements)) {
|
|
19507
|
+
return originalElements;
|
|
19508
|
+
}
|
|
19115
19509
|
syncMovedIndices(elements, targetElementsMap);
|
|
19116
19510
|
return elements;
|
|
19117
19511
|
};
|
|
19118
19512
|
var shiftElementsToEnd = (elements, appState, direction, containingFrame, elementsToBeMoved) => {
|
|
19119
19513
|
const indicesToMove = getIndicesToMove(elements, appState, elementsToBeMoved);
|
|
19514
|
+
if (indicesToMove.length === 0) {
|
|
19515
|
+
return elements;
|
|
19516
|
+
}
|
|
19120
19517
|
const targetElementsMap = getTargetElementsMap(elements, indicesToMove);
|
|
19121
19518
|
const displacedElements = [];
|
|
19122
19519
|
let leadingIndex;
|
|
@@ -19163,6 +19560,12 @@ var shiftElementsToEnd = (elements, appState, direction, containingFrame, elemen
|
|
|
19163
19560
|
if (leadingIndex === -1) {
|
|
19164
19561
|
leadingIndex = 0;
|
|
19165
19562
|
}
|
|
19563
|
+
const isValidIndex = (index) => {
|
|
19564
|
+
return isFiniteNumber(index) && index >= 0;
|
|
19565
|
+
};
|
|
19566
|
+
if (!isValidIndex(leadingIndex) || !isValidIndex(trailingIndex) || leadingIndex > trailingIndex || indicesToMove.some((index) => index < leadingIndex || index > trailingIndex)) {
|
|
19567
|
+
return elements;
|
|
19568
|
+
}
|
|
19166
19569
|
for (let index = leadingIndex; index < trailingIndex + 1; index++) {
|
|
19167
19570
|
if (!indicesToMove.includes(index)) {
|
|
19168
19571
|
displacedElements.push(elements[index]);
|
|
@@ -19182,6 +19585,9 @@ var shiftElementsToEnd = (elements, appState, direction, containingFrame, elemen
|
|
|
19182
19585
|
...targetElements,
|
|
19183
19586
|
...trailingElements
|
|
19184
19587
|
];
|
|
19588
|
+
if (!hasSameElementIds(elements, nextElements)) {
|
|
19589
|
+
return elements;
|
|
19590
|
+
}
|
|
19185
19591
|
syncMovedIndices(nextElements, targetElementsMap);
|
|
19186
19592
|
return nextElements;
|
|
19187
19593
|
};
|
|
@@ -19223,7 +19629,7 @@ function shiftElementsAccountingForFrames(allElements, appState, direction, shif
|
|
|
19223
19629
|
);
|
|
19224
19630
|
for (const [frameId, children] of frameChildrenSets) {
|
|
19225
19631
|
nextElements = shiftFunction(
|
|
19226
|
-
|
|
19632
|
+
nextElements,
|
|
19227
19633
|
appState,
|
|
19228
19634
|
direction,
|
|
19229
19635
|
frameId,
|
|
@@ -19273,7 +19679,7 @@ var isFocusPointVisible = (focusPoint, arrow, bindableElement, elementsMap, appS
|
|
|
19273
19679
|
associatedPointIdx,
|
|
19274
19680
|
elementsMap
|
|
19275
19681
|
);
|
|
19276
|
-
if (
|
|
19682
|
+
if (pointDistance7(focusPoint, associatedArrowPoint) < FOCUS_POINT_SIZE * 1.5 / appState.zoom.value) {
|
|
19277
19683
|
return false;
|
|
19278
19684
|
}
|
|
19279
19685
|
}
|
|
@@ -19282,7 +19688,7 @@ var isFocusPointVisible = (focusPoint, arrow, bindableElement, elementsMap, appS
|
|
|
19282
19688
|
startOrEnd === "end" ? arrow.points.length - 1 : 0,
|
|
19283
19689
|
elementsMap
|
|
19284
19690
|
);
|
|
19285
|
-
return
|
|
19691
|
+
return pointDistance7(focusPoint, arrowPoint) >= FOCUS_POINT_SIZE * 1.5 / appState.zoom.value && hitElementItself({
|
|
19286
19692
|
element: bindableElement,
|
|
19287
19693
|
elementsMap,
|
|
19288
19694
|
point: focusPoint,
|
|
@@ -19372,7 +19778,7 @@ var handleFocusPointDrag = (linearElementEditor, elementsMap, pointerCoords, sce
|
|
|
19372
19778
|
const isStartBinding = linearElementEditor.draggedFocusPointBinding === "start";
|
|
19373
19779
|
const binding = isStartBinding ? arrow.startBinding : arrow.endBinding;
|
|
19374
19780
|
const { x: offsetX, y: offsetY } = linearElementEditor.pointerOffset;
|
|
19375
|
-
const point =
|
|
19781
|
+
const point = pointFrom15(
|
|
19376
19782
|
pointerCoords.x - offsetX,
|
|
19377
19783
|
pointerCoords.y - offsetY
|
|
19378
19784
|
);
|
|
@@ -19455,7 +19861,7 @@ var handleFocusPointDrag = (linearElementEditor, elementsMap, pointerCoords, sce
|
|
|
19455
19861
|
}
|
|
19456
19862
|
};
|
|
19457
19863
|
var handleFocusPointPointerDown = (arrow, pointerDownState, elementsMap, appState) => {
|
|
19458
|
-
const pointerPos =
|
|
19864
|
+
const pointerPos = pointFrom15(
|
|
19459
19865
|
pointerDownState.origin.x,
|
|
19460
19866
|
pointerDownState.origin.y
|
|
19461
19867
|
);
|
|
@@ -19475,7 +19881,7 @@ var handleFocusPointPointerDown = (arrow, pointerDownState, elementsMap, appStat
|
|
|
19475
19881
|
elementsMap,
|
|
19476
19882
|
appState,
|
|
19477
19883
|
"start"
|
|
19478
|
-
) &&
|
|
19884
|
+
) && pointDistance7(pointerPos, focusPoint) <= hitThreshold) {
|
|
19479
19885
|
return {
|
|
19480
19886
|
hitFocusPoint: "start",
|
|
19481
19887
|
pointerOffset: {
|
|
@@ -19501,7 +19907,7 @@ var handleFocusPointPointerDown = (arrow, pointerDownState, elementsMap, appStat
|
|
|
19501
19907
|
elementsMap,
|
|
19502
19908
|
appState,
|
|
19503
19909
|
"end"
|
|
19504
|
-
) &&
|
|
19910
|
+
) && pointDistance7(pointerPos, focusPoint) <= hitThreshold) {
|
|
19505
19911
|
return {
|
|
19506
19912
|
hitFocusPoint: "end",
|
|
19507
19913
|
pointerOffset: {
|
|
@@ -19558,7 +19964,7 @@ var handleFocusPointPointerUp = (linearElementEditor, scene) => {
|
|
|
19558
19964
|
};
|
|
19559
19965
|
var handleFocusPointHover = (arrow, scenePointerX, scenePointerY, scene, appState) => {
|
|
19560
19966
|
const elementsMap = scene.getNonDeletedElementsMap();
|
|
19561
|
-
const pointerPos =
|
|
19967
|
+
const pointerPos = pointFrom15(scenePointerX, scenePointerY);
|
|
19562
19968
|
const hitThreshold = FOCUS_POINT_SIZE * 1.5 / appState.zoom.value;
|
|
19563
19969
|
if (arrow.startBinding?.elementId) {
|
|
19564
19970
|
const bindableElement = elementsMap.get(arrow.startBinding.elementId);
|
|
@@ -19575,7 +19981,7 @@ var handleFocusPointHover = (arrow, scenePointerX, scenePointerY, scene, appStat
|
|
|
19575
19981
|
elementsMap,
|
|
19576
19982
|
appState,
|
|
19577
19983
|
"start"
|
|
19578
|
-
) &&
|
|
19984
|
+
) && pointDistance7(pointerPos, focusPoint) <= hitThreshold) {
|
|
19579
19985
|
return "start";
|
|
19580
19986
|
}
|
|
19581
19987
|
}
|
|
@@ -19595,7 +20001,7 @@ var handleFocusPointHover = (arrow, scenePointerX, scenePointerY, scene, appStat
|
|
|
19595
20001
|
elementsMap,
|
|
19596
20002
|
appState,
|
|
19597
20003
|
"end"
|
|
19598
|
-
) &&
|
|
20004
|
+
) && pointDistance7(pointerPos, focusPoint) <= hitThreshold) {
|
|
19599
20005
|
return "end";
|
|
19600
20006
|
}
|
|
19601
20007
|
}
|
|
@@ -19779,8 +20185,8 @@ init_define_import_meta_env();
|
|
|
19779
20185
|
import {
|
|
19780
20186
|
pointCenter as pointCenter3,
|
|
19781
20187
|
normalizeRadians as normalizeRadians2,
|
|
19782
|
-
pointFrom as
|
|
19783
|
-
pointRotateRads as
|
|
20188
|
+
pointFrom as pointFrom16,
|
|
20189
|
+
pointRotateRads as pointRotateRads13
|
|
19784
20190
|
} from "@excalidraw/math";
|
|
19785
20191
|
import {
|
|
19786
20192
|
MIN_FONT_SIZE,
|
|
@@ -19892,20 +20298,20 @@ var rotateSingleElement = (element, scene, pointerX, pointerY, shouldRotateWithD
|
|
|
19892
20298
|
);
|
|
19893
20299
|
const cx = (x1 + x2) / 2;
|
|
19894
20300
|
const cy = (y1 + y2) / 2;
|
|
19895
|
-
let
|
|
20301
|
+
let angle2;
|
|
19896
20302
|
if (isFrameLikeElement(element)) {
|
|
19897
|
-
|
|
20303
|
+
angle2 = 0;
|
|
19898
20304
|
} else {
|
|
19899
|
-
|
|
20305
|
+
angle2 = 5 * Math.PI / 2 + Math.atan2(pointerY - cy, pointerX - cx);
|
|
19900
20306
|
if (shouldRotateWithDiscreteAngle2) {
|
|
19901
|
-
|
|
19902
|
-
|
|
20307
|
+
angle2 = angle2 + SHIFT_LOCKING_ANGLE2 / 2;
|
|
20308
|
+
angle2 = angle2 - angle2 % SHIFT_LOCKING_ANGLE2;
|
|
19903
20309
|
}
|
|
19904
|
-
|
|
20310
|
+
angle2 = normalizeRadians2(angle2);
|
|
19905
20311
|
}
|
|
19906
20312
|
const boundTextElementId = getBoundTextElementId(element);
|
|
19907
20313
|
let update = {
|
|
19908
|
-
angle
|
|
20314
|
+
angle: angle2
|
|
19909
20315
|
};
|
|
19910
20316
|
if (isBindingElement(element)) {
|
|
19911
20317
|
update = {
|
|
@@ -19928,7 +20334,7 @@ var rotateSingleElement = (element, scene, pointerX, pointerY, shouldRotateWithD
|
|
|
19928
20334
|
scene.getNonDeletedElementsMap()
|
|
19929
20335
|
);
|
|
19930
20336
|
scene.mutateElement(textElement, {
|
|
19931
|
-
angle,
|
|
20337
|
+
angle: angle2,
|
|
19932
20338
|
x,
|
|
19933
20339
|
y
|
|
19934
20340
|
});
|
|
@@ -19968,7 +20374,7 @@ var resizeSingleTextElement = (origElement, element, scene, transformHandleType,
|
|
|
19968
20374
|
return;
|
|
19969
20375
|
}
|
|
19970
20376
|
if (transformHandleType.includes("n") || transformHandleType.includes("s")) {
|
|
19971
|
-
const previousOrigin =
|
|
20377
|
+
const previousOrigin = pointFrom16(origElement.x, origElement.y);
|
|
19972
20378
|
const newOrigin = getResizedOrigin(
|
|
19973
20379
|
previousOrigin,
|
|
19974
20380
|
origElement.width,
|
|
@@ -20009,7 +20415,7 @@ var resizeSingleTextElement = (origElement, element, scene, transformHandleType,
|
|
|
20009
20415
|
element.lineHeight
|
|
20010
20416
|
);
|
|
20011
20417
|
const newHeight = metrics2.height;
|
|
20012
|
-
const previousOrigin =
|
|
20418
|
+
const previousOrigin = pointFrom16(origElement.x, origElement.y);
|
|
20013
20419
|
const newOrigin = getResizedOrigin(
|
|
20014
20420
|
previousOrigin,
|
|
20015
20421
|
origElement.width,
|
|
@@ -20046,9 +20452,9 @@ var rotateMultipleElements = (originalElements, elements, scene, pointerX, point
|
|
|
20046
20452
|
const cx = (x1 + x2) / 2;
|
|
20047
20453
|
const cy = (y1 + y2) / 2;
|
|
20048
20454
|
const origAngle = originalElements.get(element.id)?.angle ?? element.angle;
|
|
20049
|
-
const [rotatedCX, rotatedCY] =
|
|
20050
|
-
|
|
20051
|
-
|
|
20455
|
+
const [rotatedCX, rotatedCY] = pointRotateRads13(
|
|
20456
|
+
pointFrom16(cx, cy),
|
|
20457
|
+
pointFrom16(centerX, centerY),
|
|
20052
20458
|
centerAngle + origAngle - element.angle
|
|
20053
20459
|
);
|
|
20054
20460
|
const updates = isElbowArrow(element) ? {
|
|
@@ -20096,45 +20502,45 @@ var getResizeOffsetXY = (transformHandleType, selectedElements, elementsMap, x,
|
|
|
20096
20502
|
const [x1, y1, x2, y2] = selectedElements.length === 1 ? getElementAbsoluteCoords2(selectedElements[0], elementsMap) : getCommonBounds(selectedElements);
|
|
20097
20503
|
const cx = (x1 + x2) / 2;
|
|
20098
20504
|
const cy = (y1 + y2) / 2;
|
|
20099
|
-
const
|
|
20100
|
-
[x, y] =
|
|
20101
|
-
|
|
20102
|
-
|
|
20103
|
-
-
|
|
20505
|
+
const angle2 = selectedElements.length === 1 ? selectedElements[0].angle : 0;
|
|
20506
|
+
[x, y] = pointRotateRads13(
|
|
20507
|
+
pointFrom16(x, y),
|
|
20508
|
+
pointFrom16(cx, cy),
|
|
20509
|
+
-angle2
|
|
20104
20510
|
);
|
|
20105
20511
|
switch (transformHandleType) {
|
|
20106
20512
|
case "n":
|
|
20107
|
-
return
|
|
20108
|
-
|
|
20109
|
-
|
|
20110
|
-
|
|
20513
|
+
return pointRotateRads13(
|
|
20514
|
+
pointFrom16(x - (x1 + x2) / 2, y - y1),
|
|
20515
|
+
pointFrom16(0, 0),
|
|
20516
|
+
angle2
|
|
20111
20517
|
);
|
|
20112
20518
|
case "s":
|
|
20113
|
-
return
|
|
20114
|
-
|
|
20115
|
-
|
|
20116
|
-
|
|
20519
|
+
return pointRotateRads13(
|
|
20520
|
+
pointFrom16(x - (x1 + x2) / 2, y - y2),
|
|
20521
|
+
pointFrom16(0, 0),
|
|
20522
|
+
angle2
|
|
20117
20523
|
);
|
|
20118
20524
|
case "w":
|
|
20119
|
-
return
|
|
20120
|
-
|
|
20121
|
-
|
|
20122
|
-
|
|
20525
|
+
return pointRotateRads13(
|
|
20526
|
+
pointFrom16(x - x1, y - (y1 + y2) / 2),
|
|
20527
|
+
pointFrom16(0, 0),
|
|
20528
|
+
angle2
|
|
20123
20529
|
);
|
|
20124
20530
|
case "e":
|
|
20125
|
-
return
|
|
20126
|
-
|
|
20127
|
-
|
|
20128
|
-
|
|
20531
|
+
return pointRotateRads13(
|
|
20532
|
+
pointFrom16(x - x2, y - (y1 + y2) / 2),
|
|
20533
|
+
pointFrom16(0, 0),
|
|
20534
|
+
angle2
|
|
20129
20535
|
);
|
|
20130
20536
|
case "nw":
|
|
20131
|
-
return
|
|
20537
|
+
return pointRotateRads13(pointFrom16(x - x1, y - y1), pointFrom16(0, 0), angle2);
|
|
20132
20538
|
case "ne":
|
|
20133
|
-
return
|
|
20539
|
+
return pointRotateRads13(pointFrom16(x - x2, y - y1), pointFrom16(0, 0), angle2);
|
|
20134
20540
|
case "sw":
|
|
20135
|
-
return
|
|
20541
|
+
return pointRotateRads13(pointFrom16(x - x1, y - y2), pointFrom16(0, 0), angle2);
|
|
20136
20542
|
case "se":
|
|
20137
|
-
return
|
|
20543
|
+
return pointRotateRads13(pointFrom16(x - x2, y - y2), pointFrom16(0, 0), angle2);
|
|
20138
20544
|
default:
|
|
20139
20545
|
return [0, 0];
|
|
20140
20546
|
}
|
|
@@ -20178,7 +20584,7 @@ var getResizeAnchor = (handleDirection, shouldMaintainAspectRatio, shouldResizeF
|
|
|
20178
20584
|
}
|
|
20179
20585
|
return "top-right";
|
|
20180
20586
|
};
|
|
20181
|
-
var getResizedOrigin = (prevOrigin, prevWidth, prevHeight, newWidth, newHeight,
|
|
20587
|
+
var getResizedOrigin = (prevOrigin, prevWidth, prevHeight, newWidth, newHeight, angle2, handleDirection, shouldMaintainAspectRatio, shouldResizeFromCenter) => {
|
|
20182
20588
|
const anchor = getResizeAnchor(
|
|
20183
20589
|
handleDirection,
|
|
20184
20590
|
shouldMaintainAspectRatio,
|
|
@@ -20188,23 +20594,23 @@ var getResizedOrigin = (prevOrigin, prevWidth, prevHeight, newWidth, newHeight,
|
|
|
20188
20594
|
switch (anchor) {
|
|
20189
20595
|
case "top-left":
|
|
20190
20596
|
return {
|
|
20191
|
-
x: x + (prevWidth - newWidth) / 2 + (newWidth - prevWidth) / 2 * Math.cos(
|
|
20192
|
-
y: y + (prevHeight - newHeight) / 2 + (newWidth - prevWidth) / 2 * Math.sin(
|
|
20597
|
+
x: x + (prevWidth - newWidth) / 2 + (newWidth - prevWidth) / 2 * Math.cos(angle2) + (prevHeight - newHeight) / 2 * Math.sin(angle2),
|
|
20598
|
+
y: y + (prevHeight - newHeight) / 2 + (newWidth - prevWidth) / 2 * Math.sin(angle2) + (newHeight - prevHeight) / 2 * Math.cos(angle2)
|
|
20193
20599
|
};
|
|
20194
20600
|
case "top-right":
|
|
20195
20601
|
return {
|
|
20196
|
-
x: x + (prevWidth - newWidth) / 2 * (Math.cos(
|
|
20197
|
-
y: y + (prevHeight - newHeight) / 2 + (prevWidth - newWidth) / 2 * Math.sin(
|
|
20602
|
+
x: x + (prevWidth - newWidth) / 2 * (Math.cos(angle2) + 1) + (prevHeight - newHeight) / 2 * Math.sin(angle2),
|
|
20603
|
+
y: y + (prevHeight - newHeight) / 2 + (prevWidth - newWidth) / 2 * Math.sin(angle2) + (newHeight - prevHeight) / 2 * Math.cos(angle2)
|
|
20198
20604
|
};
|
|
20199
20605
|
case "bottom-left":
|
|
20200
20606
|
return {
|
|
20201
|
-
x: x + (prevWidth - newWidth) / 2 * (1 - Math.cos(
|
|
20202
|
-
y: y + (prevHeight - newHeight) / 2 * (Math.cos(
|
|
20607
|
+
x: x + (prevWidth - newWidth) / 2 * (1 - Math.cos(angle2)) + (newHeight - prevHeight) / 2 * Math.sin(angle2),
|
|
20608
|
+
y: y + (prevHeight - newHeight) / 2 * (Math.cos(angle2) + 1) + (newWidth - prevWidth) / 2 * Math.sin(angle2)
|
|
20203
20609
|
};
|
|
20204
20610
|
case "bottom-right":
|
|
20205
20611
|
return {
|
|
20206
|
-
x: x + (prevWidth - newWidth) / 2 * (Math.cos(
|
|
20207
|
-
y: y + (prevHeight - newHeight) / 2 * (Math.cos(
|
|
20612
|
+
x: x + (prevWidth - newWidth) / 2 * (Math.cos(angle2) + 1) + (newHeight - prevHeight) / 2 * Math.sin(angle2),
|
|
20613
|
+
y: y + (prevHeight - newHeight) / 2 * (Math.cos(angle2) + 1) + (prevWidth - newWidth) / 2 * Math.sin(angle2)
|
|
20208
20614
|
};
|
|
20209
20615
|
case "center":
|
|
20210
20616
|
return {
|
|
@@ -20213,23 +20619,23 @@ var getResizedOrigin = (prevOrigin, prevWidth, prevHeight, newWidth, newHeight,
|
|
|
20213
20619
|
};
|
|
20214
20620
|
case "east-side":
|
|
20215
20621
|
return {
|
|
20216
|
-
x: x + (prevWidth - newWidth) / 2 * (Math.cos(
|
|
20217
|
-
y: y + (prevWidth - newWidth) / 2 * Math.sin(
|
|
20622
|
+
x: x + (prevWidth - newWidth) / 2 * (Math.cos(angle2) + 1),
|
|
20623
|
+
y: y + (prevWidth - newWidth) / 2 * Math.sin(angle2) + (prevHeight - newHeight) / 2
|
|
20218
20624
|
};
|
|
20219
20625
|
case "west-side":
|
|
20220
20626
|
return {
|
|
20221
|
-
x: x + (prevWidth - newWidth) / 2 * (1 - Math.cos(
|
|
20222
|
-
y: y + (newWidth - prevWidth) / 2 * Math.sin(
|
|
20627
|
+
x: x + (prevWidth - newWidth) / 2 * (1 - Math.cos(angle2)),
|
|
20628
|
+
y: y + (newWidth - prevWidth) / 2 * Math.sin(angle2) + (prevHeight - newHeight) / 2
|
|
20223
20629
|
};
|
|
20224
20630
|
case "north-side":
|
|
20225
20631
|
return {
|
|
20226
|
-
x: x + (prevWidth - newWidth) / 2 + (prevHeight - newHeight) / 2 * Math.sin(
|
|
20227
|
-
y: y + (newHeight - prevHeight) / 2 * (Math.cos(
|
|
20632
|
+
x: x + (prevWidth - newWidth) / 2 + (prevHeight - newHeight) / 2 * Math.sin(angle2),
|
|
20633
|
+
y: y + (newHeight - prevHeight) / 2 * (Math.cos(angle2) - 1)
|
|
20228
20634
|
};
|
|
20229
20635
|
case "south-side":
|
|
20230
20636
|
return {
|
|
20231
|
-
x: x + (prevWidth - newWidth) / 2 + (newHeight - prevHeight) / 2 * Math.sin(
|
|
20232
|
-
y: y + (prevHeight - newHeight) / 2 * (Math.cos(
|
|
20637
|
+
x: x + (prevWidth - newWidth) / 2 + (newHeight - prevHeight) / 2 * Math.sin(angle2),
|
|
20638
|
+
y: y + (prevHeight - newHeight) / 2 * (Math.cos(angle2) + 1)
|
|
20233
20639
|
};
|
|
20234
20640
|
}
|
|
20235
20641
|
};
|
|
@@ -20297,10 +20703,10 @@ var resizeSingleElement = (nextWidth, nextHeight, latestElement, origElement, or
|
|
|
20297
20703
|
nextHeight,
|
|
20298
20704
|
true
|
|
20299
20705
|
);
|
|
20300
|
-
let previousOrigin =
|
|
20706
|
+
let previousOrigin = pointFrom16(origElement.x, origElement.y);
|
|
20301
20707
|
if (isLinearElement(origElement)) {
|
|
20302
20708
|
const [x1, y1] = getElementBounds(origElement, originalElementsMap);
|
|
20303
|
-
previousOrigin =
|
|
20709
|
+
previousOrigin = pointFrom16(x1, y1);
|
|
20304
20710
|
}
|
|
20305
20711
|
const newOrigin = getResizedOrigin(
|
|
20306
20712
|
previousOrigin,
|
|
@@ -20323,7 +20729,7 @@ var resizeSingleElement = (nextWidth, nextHeight, latestElement, origElement, or
|
|
|
20323
20729
|
newOrigin.x += scaledX;
|
|
20324
20730
|
newOrigin.y += scaledY;
|
|
20325
20731
|
rescaledPoints.points = rescaledPoints.points.map(
|
|
20326
|
-
(p) =>
|
|
20732
|
+
(p) => pointFrom16(p[0] - scaledX, p[1] - scaledY)
|
|
20327
20733
|
);
|
|
20328
20734
|
}
|
|
20329
20735
|
if (nextWidth < 0) {
|
|
@@ -20399,11 +20805,11 @@ var getNextSingleWidthAndHeightFromPointer = (latestElement, origElement, handle
|
|
|
20399
20805
|
origElement.height,
|
|
20400
20806
|
true
|
|
20401
20807
|
);
|
|
20402
|
-
const startTopLeft =
|
|
20403
|
-
const startBottomRight =
|
|
20808
|
+
const startTopLeft = pointFrom16(x1, y1);
|
|
20809
|
+
const startBottomRight = pointFrom16(x2, y2);
|
|
20404
20810
|
const startCenter = pointCenter3(startTopLeft, startBottomRight);
|
|
20405
|
-
const rotatedPointer =
|
|
20406
|
-
|
|
20811
|
+
const rotatedPointer = pointRotateRads13(
|
|
20812
|
+
pointFrom16(pointerX, pointerY),
|
|
20407
20813
|
startCenter,
|
|
20408
20814
|
-origElement.angle
|
|
20409
20815
|
);
|
|
@@ -20593,9 +20999,10 @@ var resizeMultipleElements = (selectedElements, elementsMap, handleDirection, sc
|
|
|
20593
20999
|
}
|
|
20594
21000
|
];
|
|
20595
21001
|
}, []);
|
|
20596
|
-
boundingBox = getCommonBoundingBox(
|
|
20597
|
-
targetElements.map(({ orig }) => orig)
|
|
20598
|
-
|
|
21002
|
+
boundingBox = getCommonBoundingBox([
|
|
21003
|
+
...targetElements.map(({ orig }) => orig),
|
|
21004
|
+
...boundTextElements
|
|
21005
|
+
]);
|
|
20599
21006
|
}
|
|
20600
21007
|
const { minX, minY, maxX, maxY, midX, midY } = boundingBox;
|
|
20601
21008
|
const width = maxX - minX;
|
|
@@ -20651,7 +21058,7 @@ var resizeMultipleElements = (selectedElements, elementsMap, handleDirection, sc
|
|
|
20651
21058
|
}
|
|
20652
21059
|
const width2 = orig.width * scaleX;
|
|
20653
21060
|
const height2 = orig.height * scaleY;
|
|
20654
|
-
const
|
|
21061
|
+
const angle2 = normalizeRadians2(
|
|
20655
21062
|
orig.angle * flipFactorX * flipFactorY
|
|
20656
21063
|
);
|
|
20657
21064
|
const isLinearOrFreeDraw = isLinearElement(orig) || isFreeDrawElement(orig);
|
|
@@ -20672,7 +21079,7 @@ var resizeMultipleElements = (selectedElements, elementsMap, handleDirection, sc
|
|
|
20672
21079
|
y,
|
|
20673
21080
|
width: width2,
|
|
20674
21081
|
height: height2,
|
|
20675
|
-
angle,
|
|
21082
|
+
angle: angle2,
|
|
20676
21083
|
...rescaledPoints
|
|
20677
21084
|
};
|
|
20678
21085
|
if (isElbowArrow(orig)) {
|
|
@@ -20740,7 +21147,7 @@ var resizeMultipleElements = (selectedElements, elementsMap, handleDirection, sc
|
|
|
20740
21147
|
element,
|
|
20741
21148
|
update: { boundTextFontSize, ...update }
|
|
20742
21149
|
} of elementsAndUpdates) {
|
|
20743
|
-
const { angle } = update;
|
|
21150
|
+
const { angle: angle2 } = update;
|
|
20744
21151
|
scene.mutateElement(element, update);
|
|
20745
21152
|
updateBoundElements(element, scene, {
|
|
20746
21153
|
simultaneouslyUpdated: elementsToUpdate
|
|
@@ -20761,7 +21168,7 @@ var resizeMultipleElements = (selectedElements, elementsMap, handleDirection, sc
|
|
|
20761
21168
|
if (boundTextElement && boundTextFontSize) {
|
|
20762
21169
|
scene.mutateElement(boundTextElement, {
|
|
20763
21170
|
fontSize: boundTextFontSize,
|
|
20764
|
-
angle: isLinearElement(element) ? void 0 :
|
|
21171
|
+
angle: isLinearElement(element) ? void 0 : angle2
|
|
20765
21172
|
});
|
|
20766
21173
|
handleBindTextResize(element, scene, handleDirection, true);
|
|
20767
21174
|
}
|
|
@@ -20773,9 +21180,9 @@ var resizeMultipleElements = (selectedElements, elementsMap, handleDirection, sc
|
|
|
20773
21180
|
// src/resizeTest.ts
|
|
20774
21181
|
init_define_import_meta_env();
|
|
20775
21182
|
import {
|
|
20776
|
-
pointFrom as
|
|
21183
|
+
pointFrom as pointFrom18,
|
|
20777
21184
|
pointOnLineSegment,
|
|
20778
|
-
pointRotateRads as
|
|
21185
|
+
pointRotateRads as pointRotateRads15
|
|
20779
21186
|
} from "@excalidraw/math";
|
|
20780
21187
|
import {
|
|
20781
21188
|
SIDE_RESIZING_THRESHOLD
|
|
@@ -20786,7 +21193,7 @@ init_define_import_meta_env();
|
|
|
20786
21193
|
import {
|
|
20787
21194
|
DEFAULT_TRANSFORM_HANDLE_SPACING
|
|
20788
21195
|
} from "@excalidraw/common";
|
|
20789
|
-
import { pointFrom as
|
|
21196
|
+
import { pointFrom as pointFrom17, pointRotateRads as pointRotateRads14 } from "@excalidraw/math";
|
|
20790
21197
|
var transformHandleSizes = {
|
|
20791
21198
|
mouse: 8,
|
|
20792
21199
|
pen: 16,
|
|
@@ -20826,11 +21233,11 @@ var OMIT_SIDES_FOR_LINE_BACKSLASH = {
|
|
|
20826
21233
|
n: true,
|
|
20827
21234
|
w: true
|
|
20828
21235
|
};
|
|
20829
|
-
var generateTransformHandle = (x, y, width, height, cx, cy,
|
|
20830
|
-
const [xx, yy] =
|
|
20831
|
-
|
|
20832
|
-
|
|
20833
|
-
|
|
21236
|
+
var generateTransformHandle = (x, y, width, height, cx, cy, angle2) => {
|
|
21237
|
+
const [xx, yy] = pointRotateRads14(
|
|
21238
|
+
pointFrom17(x + width / 2, y + height / 2),
|
|
21239
|
+
pointFrom17(cx, cy),
|
|
21240
|
+
angle2
|
|
20834
21241
|
);
|
|
20835
21242
|
return [xx - width / 2, yy - height / 2, width, height];
|
|
20836
21243
|
};
|
|
@@ -20846,7 +21253,7 @@ var getOmitSidesForEditorInterface = (editorInterface) => {
|
|
|
20846
21253
|
}
|
|
20847
21254
|
return {};
|
|
20848
21255
|
};
|
|
20849
|
-
var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy],
|
|
21256
|
+
var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle2, zoom, pointerType, omitSides = {}, margin = 4, spacing = DEFAULT_TRANSFORM_HANDLE_SPACING) => {
|
|
20850
21257
|
const size = transformHandleSizes[pointerType];
|
|
20851
21258
|
const handleWidth = size / zoom.value;
|
|
20852
21259
|
const handleHeight = size / zoom.value;
|
|
@@ -20864,7 +21271,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
|
|
|
20864
21271
|
handleHeight,
|
|
20865
21272
|
cx,
|
|
20866
21273
|
cy,
|
|
20867
|
-
|
|
21274
|
+
angle2
|
|
20868
21275
|
),
|
|
20869
21276
|
ne: omitSides.ne ? void 0 : generateTransformHandle(
|
|
20870
21277
|
x2 + dashedLineMargin - centeringOffset,
|
|
@@ -20873,7 +21280,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
|
|
|
20873
21280
|
handleHeight,
|
|
20874
21281
|
cx,
|
|
20875
21282
|
cy,
|
|
20876
|
-
|
|
21283
|
+
angle2
|
|
20877
21284
|
),
|
|
20878
21285
|
sw: omitSides.sw ? void 0 : generateTransformHandle(
|
|
20879
21286
|
x1 - dashedLineMargin - handleMarginX + centeringOffset,
|
|
@@ -20882,7 +21289,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
|
|
|
20882
21289
|
handleHeight,
|
|
20883
21290
|
cx,
|
|
20884
21291
|
cy,
|
|
20885
|
-
|
|
21292
|
+
angle2
|
|
20886
21293
|
),
|
|
20887
21294
|
se: omitSides.se ? void 0 : generateTransformHandle(
|
|
20888
21295
|
x2 + dashedLineMargin - centeringOffset,
|
|
@@ -20891,7 +21298,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
|
|
|
20891
21298
|
handleHeight,
|
|
20892
21299
|
cx,
|
|
20893
21300
|
cy,
|
|
20894
|
-
|
|
21301
|
+
angle2
|
|
20895
21302
|
),
|
|
20896
21303
|
rotation: omitSides.rotation ? void 0 : generateTransformHandle(
|
|
20897
21304
|
x1 + width / 2 - handleWidth / 2,
|
|
@@ -20900,7 +21307,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
|
|
|
20900
21307
|
handleHeight,
|
|
20901
21308
|
cx,
|
|
20902
21309
|
cy,
|
|
20903
|
-
|
|
21310
|
+
angle2
|
|
20904
21311
|
)
|
|
20905
21312
|
};
|
|
20906
21313
|
const minimumSizeForEightHandles = 5 * transformHandleSizes.mouse / zoom.value;
|
|
@@ -20913,7 +21320,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
|
|
|
20913
21320
|
handleHeight,
|
|
20914
21321
|
cx,
|
|
20915
21322
|
cy,
|
|
20916
|
-
|
|
21323
|
+
angle2
|
|
20917
21324
|
);
|
|
20918
21325
|
}
|
|
20919
21326
|
if (!omitSides.s) {
|
|
@@ -20924,7 +21331,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
|
|
|
20924
21331
|
handleHeight,
|
|
20925
21332
|
cx,
|
|
20926
21333
|
cy,
|
|
20927
|
-
|
|
21334
|
+
angle2
|
|
20928
21335
|
);
|
|
20929
21336
|
}
|
|
20930
21337
|
}
|
|
@@ -20937,7 +21344,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
|
|
|
20937
21344
|
handleHeight,
|
|
20938
21345
|
cx,
|
|
20939
21346
|
cy,
|
|
20940
|
-
|
|
21347
|
+
angle2
|
|
20941
21348
|
);
|
|
20942
21349
|
}
|
|
20943
21350
|
if (!omitSides.e) {
|
|
@@ -20948,7 +21355,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
|
|
|
20948
21355
|
handleHeight,
|
|
20949
21356
|
cx,
|
|
20950
21357
|
cy,
|
|
20951
|
-
|
|
21358
|
+
angle2
|
|
20952
21359
|
);
|
|
20953
21360
|
}
|
|
20954
21361
|
}
|
|
@@ -21043,14 +21450,14 @@ var resizeTest = (element, elementsMap, appState, x, y, zoom, pointerType, edito
|
|
|
21043
21450
|
const SPACING = isImageElement(element) ? 0 : SIDE_RESIZING_THRESHOLD / zoom.value;
|
|
21044
21451
|
const ZOOMED_SIDE_RESIZING_THRESHOLD = SIDE_RESIZING_THRESHOLD / zoom.value;
|
|
21045
21452
|
const sides = getSelectionBorders(
|
|
21046
|
-
|
|
21047
|
-
|
|
21048
|
-
|
|
21453
|
+
pointFrom18(x1 - SPACING, y1 - SPACING),
|
|
21454
|
+
pointFrom18(x2 + SPACING, y2 + SPACING),
|
|
21455
|
+
pointFrom18(cx, cy),
|
|
21049
21456
|
element.angle
|
|
21050
21457
|
);
|
|
21051
21458
|
for (const [dir, side] of Object.entries(sides)) {
|
|
21052
21459
|
if (pointOnLineSegment(
|
|
21053
|
-
|
|
21460
|
+
pointFrom18(x, y),
|
|
21054
21461
|
side,
|
|
21055
21462
|
ZOOMED_SIDE_RESIZING_THRESHOLD
|
|
21056
21463
|
)) {
|
|
@@ -21099,14 +21506,14 @@ var getTransformHandleTypeFromCoords = ([x1, y1, x2, y2], scenePointerX, scenePo
|
|
|
21099
21506
|
const cy = (y1 + y2) / 2;
|
|
21100
21507
|
const SPACING = SIDE_RESIZING_THRESHOLD / zoom.value;
|
|
21101
21508
|
const sides = getSelectionBorders(
|
|
21102
|
-
|
|
21103
|
-
|
|
21104
|
-
|
|
21509
|
+
pointFrom18(x1 - SPACING, y1 - SPACING),
|
|
21510
|
+
pointFrom18(x2 + SPACING, y2 + SPACING),
|
|
21511
|
+
pointFrom18(cx, cy),
|
|
21105
21512
|
0
|
|
21106
21513
|
);
|
|
21107
21514
|
for (const [dir, side] of Object.entries(sides)) {
|
|
21108
21515
|
if (pointOnLineSegment(
|
|
21109
|
-
|
|
21516
|
+
pointFrom18(scenePointerX, scenePointerY),
|
|
21110
21517
|
side,
|
|
21111
21518
|
SPACING
|
|
21112
21519
|
)) {
|
|
@@ -21117,10 +21524,10 @@ var getTransformHandleTypeFromCoords = ([x1, y1, x2, y2], scenePointerX, scenePo
|
|
|
21117
21524
|
return false;
|
|
21118
21525
|
};
|
|
21119
21526
|
var RESIZE_CURSORS = ["ns", "nesw", "ew", "nwse"];
|
|
21120
|
-
var rotateResizeCursor = (cursor,
|
|
21527
|
+
var rotateResizeCursor = (cursor, angle2) => {
|
|
21121
21528
|
const index = RESIZE_CURSORS.indexOf(cursor);
|
|
21122
21529
|
if (index >= 0) {
|
|
21123
|
-
const a2 = Math.round(
|
|
21530
|
+
const a2 = Math.round(angle2 / (Math.PI / 4));
|
|
21124
21531
|
cursor = RESIZE_CURSORS[(index + a2) % RESIZE_CURSORS.length];
|
|
21125
21532
|
}
|
|
21126
21533
|
return cursor;
|
|
@@ -21162,11 +21569,11 @@ var getCursorForResizingElement = (resizingElement) => {
|
|
|
21162
21569
|
}
|
|
21163
21570
|
return cursor ? `${cursor}-resize` : "";
|
|
21164
21571
|
};
|
|
21165
|
-
var getSelectionBorders = ([x1, y1], [x2, y2], center,
|
|
21166
|
-
const topLeft =
|
|
21167
|
-
const topRight =
|
|
21168
|
-
const bottomLeft =
|
|
21169
|
-
const bottomRight =
|
|
21572
|
+
var getSelectionBorders = ([x1, y1], [x2, y2], center, angle2) => {
|
|
21573
|
+
const topLeft = pointRotateRads15(pointFrom18(x1, y1), center, angle2);
|
|
21574
|
+
const topRight = pointRotateRads15(pointFrom18(x2, y1), center, angle2);
|
|
21575
|
+
const bottomLeft = pointRotateRads15(pointFrom18(x1, y2), center, angle2);
|
|
21576
|
+
const bottomRight = pointRotateRads15(pointFrom18(x2, y2), center, angle2);
|
|
21170
21577
|
return {
|
|
21171
21578
|
n: [topLeft, topRight],
|
|
21172
21579
|
e: [topRight, bottomRight],
|
|
@@ -21183,7 +21590,7 @@ var showSelectedShapeActions = (appState, elements) => Boolean(
|
|
|
21183
21590
|
|
|
21184
21591
|
// src/transform.ts
|
|
21185
21592
|
init_define_import_meta_env();
|
|
21186
|
-
import { pointFrom as
|
|
21593
|
+
import { pointFrom as pointFrom19 } from "@excalidraw/math";
|
|
21187
21594
|
import {
|
|
21188
21595
|
DEFAULT_FONT_FAMILY as DEFAULT_FONT_FAMILY3,
|
|
21189
21596
|
DEFAULT_FONT_SIZE as DEFAULT_FONT_SIZE4,
|
|
@@ -21421,7 +21828,9 @@ var ElementStore = class {
|
|
|
21421
21828
|
this.excalidrawElements.set(ele.id, ele);
|
|
21422
21829
|
};
|
|
21423
21830
|
getElements = () => {
|
|
21424
|
-
return syncInvalidIndices(
|
|
21831
|
+
return syncInvalidIndices(
|
|
21832
|
+
Array.from(this.excalidrawElements.values())
|
|
21833
|
+
);
|
|
21425
21834
|
};
|
|
21426
21835
|
getElementsMap = () => {
|
|
21427
21836
|
return toBrandedType3(
|
|
@@ -21465,7 +21874,7 @@ var convertToExcalidrawElements = (elementsSkeleton, opts) => {
|
|
|
21465
21874
|
excalidrawElement = newLinearElement({
|
|
21466
21875
|
width,
|
|
21467
21876
|
height,
|
|
21468
|
-
points: [
|
|
21877
|
+
points: [pointFrom19(0, 0), pointFrom19(width, height)],
|
|
21469
21878
|
...element
|
|
21470
21879
|
});
|
|
21471
21880
|
break;
|
|
@@ -21477,7 +21886,7 @@ var convertToExcalidrawElements = (elementsSkeleton, opts) => {
|
|
|
21477
21886
|
width,
|
|
21478
21887
|
height,
|
|
21479
21888
|
endArrowhead: "arrow",
|
|
21480
|
-
points: [
|
|
21889
|
+
points: [pointFrom19(0, 0), pointFrom19(width, height)],
|
|
21481
21890
|
...element,
|
|
21482
21891
|
type: "arrow"
|
|
21483
21892
|
});
|
|
@@ -21764,11 +22173,11 @@ var hashString = (s) => {
|
|
|
21764
22173
|
}
|
|
21765
22174
|
return hash >>> 0;
|
|
21766
22175
|
};
|
|
22176
|
+
var isNonDeletedElement = (element) => !element.isDeleted;
|
|
21767
22177
|
var getVisibleElements = (elements) => elements.filter(
|
|
21768
|
-
(el) =>
|
|
22178
|
+
(el) => isNonDeletedElement(el) && !isInvisiblySmallElement(el)
|
|
21769
22179
|
);
|
|
21770
|
-
var
|
|
21771
|
-
var isNonDeletedElement2 = (element) => !element.isDeleted;
|
|
22180
|
+
var getNonDeletedElements = (elements) => elements.filter(isNonDeletedElement);
|
|
21772
22181
|
export {
|
|
21773
22182
|
AppStateDelta,
|
|
21774
22183
|
BASE_ARROW_MIN_LENGTH,
|
|
@@ -21855,6 +22264,7 @@ export {
|
|
|
21855
22264
|
elementWithCanvasCache,
|
|
21856
22265
|
elementsAreInFrameBounds,
|
|
21857
22266
|
elementsAreInSameGroup,
|
|
22267
|
+
elementsOverlappingBBox,
|
|
21858
22268
|
embeddableURLValidator,
|
|
21859
22269
|
excludeElementsInFramesFromSelection,
|
|
21860
22270
|
filterElementsEligibleAsFrameChildren,
|
|
@@ -21883,7 +22293,6 @@ export {
|
|
|
21883
22293
|
getBoundTextMaxWidth,
|
|
21884
22294
|
getBoundsFromPoints,
|
|
21885
22295
|
getCenterForBounds,
|
|
21886
|
-
getClosestElementBounds,
|
|
21887
22296
|
getCommonBoundingBox,
|
|
21888
22297
|
getCommonBounds,
|
|
21889
22298
|
getCommonFrameId,
|
|
@@ -21939,7 +22348,7 @@ export {
|
|
|
21939
22348
|
getMinMaxXYFromCurvePathOps,
|
|
21940
22349
|
getMinTextElementWidth,
|
|
21941
22350
|
getNewGroupIdsForDuplication,
|
|
21942
|
-
|
|
22351
|
+
getNonDeletedElements,
|
|
21943
22352
|
getNonDeletedGroupIds,
|
|
21944
22353
|
getNormalizedDimensions,
|
|
21945
22354
|
getObservedAppState,
|
|
@@ -21987,6 +22396,7 @@ export {
|
|
|
21987
22396
|
hasBackground,
|
|
21988
22397
|
hasBoundTextElement,
|
|
21989
22398
|
hasBoundingBox,
|
|
22399
|
+
hasFreedrawMode,
|
|
21990
22400
|
hasStrokeColor,
|
|
21991
22401
|
hasStrokeStyle,
|
|
21992
22402
|
hasStrokeWidth,
|
|
@@ -22043,7 +22453,7 @@ export {
|
|
|
22043
22453
|
isMagicFrameElement,
|
|
22044
22454
|
isMeasureTextSupported,
|
|
22045
22455
|
isNodeInFlowchart,
|
|
22046
|
-
|
|
22456
|
+
isNonDeletedElement,
|
|
22047
22457
|
isPathALoop,
|
|
22048
22458
|
isPointInElement,
|
|
22049
22459
|
isRectangularElement,
|