@excalidraw/excalidraw 0.17.1-1d71f84 → 0.17.1-4689a6b
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/CHANGELOG.md +1 -0
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-AK7SWNLN.js → chunk-23CKV3WP.js} +4 -2
- package/dist/browser/dev/excalidraw-assets-dev/chunk-23CKV3WP.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-RWZVJAQU.js → chunk-7D5BMEAB.js} +2227 -1976
- package/dist/browser/dev/excalidraw-assets-dev/chunk-7D5BMEAB.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{en-5TCZHGGJ.js → en-W7TECCRB.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{image-EDKQZH7Z.js → image-JKT6GXZD.js} +2 -2
- package/dist/browser/dev/index.css +20 -0
- package/dist/browser/dev/index.css.map +2 -2
- package/dist/browser/dev/index.js +770 -585
- package/dist/browser/dev/index.js.map +4 -4
- package/dist/browser/prod/excalidraw-assets/chunk-DWOM5R6H.js +55 -0
- package/dist/browser/prod/excalidraw-assets/{chunk-CTYINSWT.js → chunk-SK23VHAR.js} +2 -2
- package/dist/browser/prod/excalidraw-assets/{en-LROPV2RN.js → en-SMMH575S.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/image-WDEQS5RL.js +1 -0
- package/dist/browser/prod/index.css +1 -1
- package/dist/browser/prod/index.js +22 -22
- package/dist/{prod/en-II4GK66F.json → dev/en-CVBEBUBY.json} +3 -1
- package/dist/dev/index.css +20 -0
- package/dist/dev/index.css.map +2 -2
- package/dist/dev/index.js +2383 -2074
- package/dist/dev/index.js.map +4 -4
- package/dist/excalidraw/actions/actionBoundText.js +4 -1
- package/dist/excalidraw/actions/actionCanvas.js +3 -1
- package/dist/excalidraw/actions/actionDuplicateSelection.js +4 -0
- package/dist/excalidraw/actions/actionExport.d.ts +1 -1
- package/dist/excalidraw/actions/actionFinalize.d.ts +1 -1
- package/dist/excalidraw/actions/actionFinalize.js +3 -3
- package/dist/excalidraw/actions/actionFlip.d.ts +3 -3
- package/dist/excalidraw/actions/actionFlip.js +6 -6
- package/dist/excalidraw/actions/actionGroup.js +4 -2
- package/dist/excalidraw/actions/actionHistory.js +3 -0
- package/dist/excalidraw/actions/actionZindex.d.ts +11 -11
- package/dist/excalidraw/actions/shortcuts.js +1 -1
- package/dist/excalidraw/analytics.js +1 -1
- package/dist/excalidraw/components/App.d.ts +13 -3
- package/dist/excalidraw/components/App.js +212 -83
- package/dist/excalidraw/components/CommandPalette/CommandPalette.js +24 -10
- package/dist/excalidraw/components/DarkModeToggle.js +3 -1
- package/dist/excalidraw/components/HelpDialog.js +8 -6
- package/dist/excalidraw/components/RadioGroup.d.ts +2 -1
- package/dist/excalidraw/components/RadioGroup.js +1 -1
- package/dist/excalidraw/components/TTDDialog/MermaidToExcalidraw.js +6 -2
- package/dist/excalidraw/components/dropdownMenu/DropdownMenuItemContentRadio.d.ts +18 -0
- package/dist/excalidraw/components/dropdownMenu/DropdownMenuItemContentRadio.js +9 -0
- package/dist/excalidraw/components/hyperlink/Hyperlink.js +3 -3
- package/dist/excalidraw/components/hyperlink/helpers.js +2 -3
- package/dist/excalidraw/components/icons.d.ts +3 -0
- package/dist/excalidraw/components/icons.js +5 -1
- package/dist/excalidraw/components/main-menu/DefaultItems.d.ts +12 -2
- package/dist/excalidraw/components/main-menu/DefaultItems.js +38 -7
- package/dist/excalidraw/constants.d.ts +0 -3
- package/dist/excalidraw/constants.js +0 -3
- package/dist/excalidraw/data/magic.js +2 -1
- package/dist/excalidraw/data/reconcile.d.ts +6 -0
- package/dist/excalidraw/data/reconcile.js +49 -0
- package/dist/excalidraw/data/restore.d.ts +3 -3
- package/dist/excalidraw/data/restore.js +5 -6
- package/dist/excalidraw/data/transform.d.ts +1 -1
- package/dist/excalidraw/data/transform.js +12 -3
- package/dist/excalidraw/element/binding.d.ts +22 -9
- package/dist/excalidraw/element/binding.js +403 -26
- package/dist/excalidraw/element/bounds.d.ts +0 -1
- package/dist/excalidraw/element/bounds.js +0 -3
- package/dist/excalidraw/element/collision.d.ts +14 -19
- package/dist/excalidraw/element/collision.js +36 -713
- package/dist/excalidraw/element/embeddable.js +18 -43
- package/dist/excalidraw/element/index.d.ts +0 -1
- package/dist/excalidraw/element/index.js +0 -1
- package/dist/excalidraw/element/linearElementEditor.d.ts +10 -10
- package/dist/excalidraw/element/linearElementEditor.js +6 -4
- package/dist/excalidraw/element/newElement.d.ts +1 -1
- package/dist/excalidraw/element/newElement.js +2 -1
- package/dist/excalidraw/element/textElement.d.ts +0 -1
- package/dist/excalidraw/element/textElement.js +0 -30
- package/dist/excalidraw/element/types.d.ts +17 -2
- package/dist/excalidraw/errors.d.ts +3 -0
- package/dist/excalidraw/errors.js +3 -0
- package/dist/excalidraw/fractionalIndex.d.ts +40 -0
- package/dist/excalidraw/fractionalIndex.js +241 -0
- package/dist/excalidraw/frame.d.ts +1 -1
- package/dist/excalidraw/hooks/useCreatePortalContainer.js +2 -1
- package/dist/excalidraw/locales/en.json +3 -1
- package/dist/excalidraw/renderer/helpers.js +2 -2
- package/dist/excalidraw/renderer/interactiveScene.js +1 -1
- package/dist/excalidraw/renderer/renderElement.js +3 -3
- package/dist/excalidraw/renderer/renderSnaps.js +2 -1
- package/dist/excalidraw/scene/Scene.d.ts +7 -6
- package/dist/excalidraw/scene/Scene.js +28 -13
- package/dist/excalidraw/scene/export.js +4 -3
- package/dist/excalidraw/types.d.ts +4 -3
- package/dist/excalidraw/utils.d.ts +1 -0
- package/dist/excalidraw/utils.js +1 -0
- package/dist/excalidraw/zindex.d.ts +2 -2
- package/dist/excalidraw/zindex.js +9 -13
- package/dist/{dev/en-II4GK66F.json → prod/en-CVBEBUBY.json} +3 -1
- package/dist/prod/index.css +1 -1
- package/dist/prod/index.js +36 -36
- package/dist/utils/collision.d.ts +4 -0
- package/dist/utils/collision.js +48 -0
- package/dist/utils/geometry/geometry.d.ts +71 -0
- package/dist/utils/geometry/geometry.js +674 -0
- package/dist/utils/geometry/shape.d.ts +55 -0
- package/dist/utils/geometry/shape.js +149 -0
- package/package.json +2 -1
- package/dist/browser/dev/excalidraw-assets-dev/chunk-AK7SWNLN.js.map +0 -7
- package/dist/browser/dev/excalidraw-assets-dev/chunk-RWZVJAQU.js.map +0 -7
- package/dist/browser/prod/excalidraw-assets/chunk-LL4GORAM.js +0 -55
- package/dist/browser/prod/excalidraw-assets/image-EFCJDJH3.js +0 -1
- /package/dist/browser/dev/excalidraw-assets-dev/{en-5TCZHGGJ.js.map → en-W7TECCRB.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{image-EDKQZH7Z.js.map → image-JKT6GXZD.js.map} +0 -0
|
@@ -5127,7 +5127,6 @@ var ROUNDNESS = {
|
|
|
5127
5127
|
// (see DEFAULT_ADAPTIVE_RADIUS constant)
|
|
5128
5128
|
ADAPTIVE_RADIUS: 3
|
|
5129
5129
|
};
|
|
5130
|
-
var PRECEDING_ELEMENT_KEY = "__precedingElement__";
|
|
5131
5130
|
var ROUGHNESS = {
|
|
5132
5131
|
architect: 0,
|
|
5133
5132
|
artist: 1,
|
|
@@ -5777,6 +5776,7 @@ var arrayToMapWithIndex = (elements) => elements.reduce((acc, element, idx) => {
|
|
|
5777
5776
|
return acc;
|
|
5778
5777
|
}, /* @__PURE__ */ new Map());
|
|
5779
5778
|
var isTestEnv = () => define_import_meta_env_default.MODE === "test";
|
|
5779
|
+
var isDevEnv = () => define_import_meta_env_default.MODE === "development";
|
|
5780
5780
|
var wrapEvent = (name, nativeEvent) => {
|
|
5781
5781
|
return new CustomEvent(name, {
|
|
5782
5782
|
detail: {
|
|
@@ -6967,14 +6967,14 @@ var helper = {
|
|
|
6967
6967
|
function line(x1, y1, x2, y2, o2) {
|
|
6968
6968
|
return { type: "path", ops: _doubleLine(x1, y1, x2, y2, o2) };
|
|
6969
6969
|
}
|
|
6970
|
-
function linearPath(points,
|
|
6970
|
+
function linearPath(points, close2, o2) {
|
|
6971
6971
|
const len = (points || []).length;
|
|
6972
6972
|
if (len > 2) {
|
|
6973
6973
|
const ops = [];
|
|
6974
6974
|
for (let i2 = 0; i2 < len - 1; i2++) {
|
|
6975
6975
|
ops.push(..._doubleLine(points[i2][0], points[i2][1], points[i2 + 1][0], points[i2 + 1][1], o2));
|
|
6976
6976
|
}
|
|
6977
|
-
if (
|
|
6977
|
+
if (close2) {
|
|
6978
6978
|
ops.push(..._doubleLine(points[len - 1][0], points[len - 1][1], points[0][0], points[0][1], o2));
|
|
6979
6979
|
}
|
|
6980
6980
|
return { type: "path", ops };
|
|
@@ -7527,8 +7527,8 @@ function getPointsOnBezierCurveWithSplitting(points, offset2, tolerance, newPoin
|
|
|
7527
7527
|
}
|
|
7528
7528
|
return outPoints;
|
|
7529
7529
|
}
|
|
7530
|
-
function simplify(points,
|
|
7531
|
-
return simplifyPoints(points, 0, points.length,
|
|
7530
|
+
function simplify(points, distance4) {
|
|
7531
|
+
return simplifyPoints(points, 0, points.length, distance4);
|
|
7532
7532
|
}
|
|
7533
7533
|
function simplifyPoints(points, start, end, epsilon, newPoints) {
|
|
7534
7534
|
const outPoints = newPoints || [];
|
|
@@ -7554,22 +7554,22 @@ function simplifyPoints(points, start, end, epsilon, newPoints) {
|
|
|
7554
7554
|
}
|
|
7555
7555
|
return outPoints;
|
|
7556
7556
|
}
|
|
7557
|
-
function pointsOnBezierCurves(points, tolerance = 0.15,
|
|
7557
|
+
function pointsOnBezierCurves(points, tolerance = 0.15, distance4) {
|
|
7558
7558
|
const newPoints = [];
|
|
7559
7559
|
const numSegments = (points.length - 1) / 3;
|
|
7560
7560
|
for (let i2 = 0; i2 < numSegments; i2++) {
|
|
7561
7561
|
const offset2 = i2 * 3;
|
|
7562
7562
|
getPointsOnBezierCurveWithSplitting(points, offset2, tolerance, newPoints);
|
|
7563
7563
|
}
|
|
7564
|
-
if (
|
|
7565
|
-
return simplifyPoints(newPoints, 0, newPoints.length,
|
|
7564
|
+
if (distance4 && distance4 > 0) {
|
|
7565
|
+
return simplifyPoints(newPoints, 0, newPoints.length, distance4);
|
|
7566
7566
|
}
|
|
7567
7567
|
return newPoints;
|
|
7568
7568
|
}
|
|
7569
7569
|
|
|
7570
7570
|
// ../../node_modules/points-on-path/lib/index.js
|
|
7571
7571
|
init_define_import_meta_env();
|
|
7572
|
-
function pointsOnPath(path, tolerance,
|
|
7572
|
+
function pointsOnPath(path, tolerance, distance4) {
|
|
7573
7573
|
const segments = parsePath(path);
|
|
7574
7574
|
const normalized2 = normalize(absolutize(segments));
|
|
7575
7575
|
const sets = [];
|
|
@@ -7616,12 +7616,12 @@ function pointsOnPath(path, tolerance, distance5) {
|
|
|
7616
7616
|
}
|
|
7617
7617
|
}
|
|
7618
7618
|
appendPendingPoints();
|
|
7619
|
-
if (!
|
|
7619
|
+
if (!distance4) {
|
|
7620
7620
|
return sets;
|
|
7621
7621
|
}
|
|
7622
7622
|
const out = [];
|
|
7623
7623
|
for (const set of sets) {
|
|
7624
|
-
const simplifiedSet = simplify(set,
|
|
7624
|
+
const simplifiedSet = simplify(set, distance4);
|
|
7625
7625
|
if (simplifiedSet.length) {
|
|
7626
7626
|
out.push(simplifiedSet);
|
|
7627
7627
|
}
|
|
@@ -7786,8 +7786,8 @@ var RoughGenerator = class {
|
|
|
7786
7786
|
const hasFill = o2.fill && o2.fill !== "transparent" && o2.fill !== NOS;
|
|
7787
7787
|
const hasStroke = o2.stroke !== NOS;
|
|
7788
7788
|
const simplified = !!(o2.simplification && o2.simplification < 1);
|
|
7789
|
-
const
|
|
7790
|
-
const sets = pointsOnPath(d, 1,
|
|
7789
|
+
const distance4 = simplified ? 4 - 4 * (o2.simplification || 1) : (1 + o2.roughness) / 2;
|
|
7790
|
+
const sets = pointsOnPath(d, 1, distance4);
|
|
7791
7791
|
const shape = svgPath(d, o2);
|
|
7792
7792
|
if (hasFill) {
|
|
7793
7793
|
if (o2.fillStyle === "solid") {
|
|
@@ -8341,127 +8341,6 @@ init_define_import_meta_env();
|
|
|
8341
8341
|
// element/binding.ts
|
|
8342
8342
|
init_define_import_meta_env();
|
|
8343
8343
|
|
|
8344
|
-
// scene/index.ts
|
|
8345
|
-
init_define_import_meta_env();
|
|
8346
|
-
|
|
8347
|
-
// scene/scroll.ts
|
|
8348
|
-
init_define_import_meta_env();
|
|
8349
|
-
var isOutsideViewPort = (appState, cords) => {
|
|
8350
|
-
const [x1, y1, x2, y2] = cords;
|
|
8351
|
-
const { x: viewportX1, y: viewportY1 } = sceneCoordsToViewportCoords(
|
|
8352
|
-
{ sceneX: x1, sceneY: y1 },
|
|
8353
|
-
appState
|
|
8354
|
-
);
|
|
8355
|
-
const { x: viewportX2, y: viewportY2 } = sceneCoordsToViewportCoords(
|
|
8356
|
-
{ sceneX: x2, sceneY: y2 },
|
|
8357
|
-
appState
|
|
8358
|
-
);
|
|
8359
|
-
return viewportX2 - viewportX1 > appState.width || viewportY2 - viewportY1 > appState.height;
|
|
8360
|
-
};
|
|
8361
|
-
var centerScrollOn = ({
|
|
8362
|
-
scenePoint,
|
|
8363
|
-
viewportDimensions,
|
|
8364
|
-
zoom
|
|
8365
|
-
}) => {
|
|
8366
|
-
return {
|
|
8367
|
-
scrollX: viewportDimensions.width / 2 / zoom.value - scenePoint.x,
|
|
8368
|
-
scrollY: viewportDimensions.height / 2 / zoom.value - scenePoint.y
|
|
8369
|
-
};
|
|
8370
|
-
};
|
|
8371
|
-
var calculateScrollCenter = (elements, appState) => {
|
|
8372
|
-
elements = getVisibleElements(elements);
|
|
8373
|
-
if (!elements.length) {
|
|
8374
|
-
return {
|
|
8375
|
-
scrollX: 0,
|
|
8376
|
-
scrollY: 0
|
|
8377
|
-
};
|
|
8378
|
-
}
|
|
8379
|
-
let [x1, y1, x2, y2] = getCommonBounds(elements);
|
|
8380
|
-
if (isOutsideViewPort(appState, [x1, y1, x2, y2])) {
|
|
8381
|
-
[x1, y1, x2, y2] = getClosestElementBounds(
|
|
8382
|
-
elements,
|
|
8383
|
-
viewportCoordsToSceneCoords(
|
|
8384
|
-
{ clientX: appState.scrollX, clientY: appState.scrollY },
|
|
8385
|
-
appState
|
|
8386
|
-
)
|
|
8387
|
-
);
|
|
8388
|
-
}
|
|
8389
|
-
const centerX = (x1 + x2) / 2;
|
|
8390
|
-
const centerY = (y1 + y2) / 2;
|
|
8391
|
-
return centerScrollOn({
|
|
8392
|
-
scenePoint: { x: centerX, y: centerY },
|
|
8393
|
-
viewportDimensions: { width: appState.width, height: appState.height },
|
|
8394
|
-
zoom: appState.zoom
|
|
8395
|
-
});
|
|
8396
|
-
};
|
|
8397
|
-
|
|
8398
|
-
// scene/comparisons.ts
|
|
8399
|
-
init_define_import_meta_env();
|
|
8400
|
-
var hasBackground = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "line" || type === "freedraw";
|
|
8401
|
-
var hasStrokeColor = (type) => type !== "image" && type !== "frame" && type !== "magicframe";
|
|
8402
|
-
var hasStrokeWidth = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "freedraw" || type === "arrow" || type === "line";
|
|
8403
|
-
var hasStrokeStyle = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "arrow" || type === "line";
|
|
8404
|
-
var canChangeRoundness = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "arrow" || type === "line" || type === "diamond" || type === "image";
|
|
8405
|
-
var canHaveArrowheads = (type) => type === "arrow";
|
|
8406
|
-
var getElementAtPosition = (elements, isAtPositionFn) => {
|
|
8407
|
-
let hitElement = null;
|
|
8408
|
-
for (let index = elements.length - 1; index >= 0; --index) {
|
|
8409
|
-
const element = elements[index];
|
|
8410
|
-
if (element.isDeleted) {
|
|
8411
|
-
continue;
|
|
8412
|
-
}
|
|
8413
|
-
if (isAtPositionFn(element)) {
|
|
8414
|
-
hitElement = element;
|
|
8415
|
-
break;
|
|
8416
|
-
}
|
|
8417
|
-
}
|
|
8418
|
-
return hitElement;
|
|
8419
|
-
};
|
|
8420
|
-
var getElementsAtPosition = (elements, isAtPositionFn) => {
|
|
8421
|
-
const iframeLikes = [];
|
|
8422
|
-
const elsAtPos = elements.filter((element) => {
|
|
8423
|
-
const hit = !element.isDeleted && isAtPositionFn(element);
|
|
8424
|
-
if (hit) {
|
|
8425
|
-
if (isIframeElement(element)) {
|
|
8426
|
-
iframeLikes.push(element);
|
|
8427
|
-
return false;
|
|
8428
|
-
}
|
|
8429
|
-
return true;
|
|
8430
|
-
}
|
|
8431
|
-
return false;
|
|
8432
|
-
});
|
|
8433
|
-
return elsAtPos.concat(iframeLikes);
|
|
8434
|
-
};
|
|
8435
|
-
|
|
8436
|
-
// scene/zoom.ts
|
|
8437
|
-
init_define_import_meta_env();
|
|
8438
|
-
var getNormalizedZoom = (zoom) => {
|
|
8439
|
-
return Math.max(MIN_ZOOM, Math.min(zoom, 30));
|
|
8440
|
-
};
|
|
8441
|
-
var getStateForZoom = ({
|
|
8442
|
-
viewportX,
|
|
8443
|
-
viewportY,
|
|
8444
|
-
nextZoom
|
|
8445
|
-
}, appState) => {
|
|
8446
|
-
const appLayerX = viewportX - appState.offsetLeft;
|
|
8447
|
-
const appLayerY = viewportY - appState.offsetTop;
|
|
8448
|
-
const currentZoom = appState.zoom.value;
|
|
8449
|
-
const baseScrollX = appState.scrollX + (appLayerX - appLayerX / currentZoom);
|
|
8450
|
-
const baseScrollY = appState.scrollY + (appLayerY - appLayerY / currentZoom);
|
|
8451
|
-
const zoomOffsetScrollX = -(appLayerX - appLayerX / nextZoom);
|
|
8452
|
-
const zoomOffsetScrollY = -(appLayerY - appLayerY / nextZoom);
|
|
8453
|
-
return {
|
|
8454
|
-
scrollX: baseScrollX + zoomOffsetScrollX,
|
|
8455
|
-
scrollY: baseScrollY + zoomOffsetScrollY,
|
|
8456
|
-
zoom: {
|
|
8457
|
-
value: nextZoom
|
|
8458
|
-
}
|
|
8459
|
-
};
|
|
8460
|
-
};
|
|
8461
|
-
|
|
8462
|
-
// element/collision.ts
|
|
8463
|
-
init_define_import_meta_env();
|
|
8464
|
-
|
|
8465
8344
|
// ga.ts
|
|
8466
8345
|
init_define_import_meta_env();
|
|
8467
8346
|
var point = (x, y) => [0, 0, 0, 0, y, x, 1, 0];
|
|
@@ -8671,1728 +8550,1373 @@ var translation = (direction) => [
|
|
|
8671
8550
|
0,
|
|
8672
8551
|
0
|
|
8673
8552
|
];
|
|
8674
|
-
var translationOrthogonal = (direction,
|
|
8675
|
-
const scale = 0.5 *
|
|
8553
|
+
var translationOrthogonal = (direction, distance4) => {
|
|
8554
|
+
const scale = 0.5 * distance4;
|
|
8676
8555
|
return [1, 0, 0, 0, scale * direction[4], scale * direction[5], 0, 0];
|
|
8677
8556
|
};
|
|
8678
8557
|
var compose = (motor1, motor2) => mul(motor2, motor1);
|
|
8679
8558
|
var apply = (motor, nvector2) => normalized(mul(mul(motor, nvector2), reverse(motor)));
|
|
8680
8559
|
|
|
8681
|
-
//
|
|
8560
|
+
// ../utils/collision.ts
|
|
8682
8561
|
init_define_import_meta_env();
|
|
8683
|
-
|
|
8684
|
-
|
|
8685
|
-
|
|
8686
|
-
|
|
8687
|
-
|
|
8688
|
-
|
|
8689
|
-
|
|
8690
|
-
|
|
8691
|
-
|
|
8692
|
-
|
|
8693
|
-
|
|
8694
|
-
|
|
8695
|
-
|
|
8696
|
-
return
|
|
8697
|
-
}
|
|
8698
|
-
|
|
8562
|
+
|
|
8563
|
+
// ../utils/geometry/geometry.ts
|
|
8564
|
+
init_define_import_meta_env();
|
|
8565
|
+
var DEFAULT_THRESHOLD = 1e-4;
|
|
8566
|
+
var isClosed = (polygon2) => {
|
|
8567
|
+
const first = polygon2[0];
|
|
8568
|
+
const last = polygon2[polygon2.length - 1];
|
|
8569
|
+
return first[0] === last[0] && first[1] === last[1];
|
|
8570
|
+
};
|
|
8571
|
+
var close = (polygon2) => {
|
|
8572
|
+
return isClosed(polygon2) ? polygon2 : [...polygon2, polygon2[0]];
|
|
8573
|
+
};
|
|
8574
|
+
var angleToDegrees = (angle) => {
|
|
8575
|
+
return angle * 180 / Math.PI;
|
|
8576
|
+
};
|
|
8577
|
+
var angleToRadians = (angle) => {
|
|
8578
|
+
return angle / 180 * Math.PI;
|
|
8579
|
+
};
|
|
8580
|
+
var rotate2 = (point2, angle) => {
|
|
8699
8581
|
return [
|
|
8700
|
-
|
|
8701
|
-
|
|
8582
|
+
point2[0] * Math.cos(angle) - point2[1] * Math.sin(angle),
|
|
8583
|
+
point2[0] * Math.sin(angle) + point2[1] * Math.cos(angle)
|
|
8702
8584
|
];
|
|
8703
|
-
}
|
|
8704
|
-
|
|
8705
|
-
|
|
8706
|
-
|
|
8707
|
-
|
|
8708
|
-
const
|
|
8709
|
-
|
|
8710
|
-
|
|
8711
|
-
let uy = 3 * p2[1] - 2 * p1[1] - p4[1];
|
|
8712
|
-
uy *= uy;
|
|
8713
|
-
let vx = 3 * p3[0] - 2 * p4[0] - p1[0];
|
|
8714
|
-
vx *= vx;
|
|
8715
|
-
let vy = 3 * p3[1] - 2 * p4[1] - p1[1];
|
|
8716
|
-
vy *= vy;
|
|
8717
|
-
if (ux < vx) {
|
|
8718
|
-
ux = vx;
|
|
8719
|
-
}
|
|
8720
|
-
if (uy < vy) {
|
|
8721
|
-
uy = vy;
|
|
8585
|
+
};
|
|
8586
|
+
var isOrigin = (point2) => {
|
|
8587
|
+
return point2[0] === 0 && point2[1] === 0;
|
|
8588
|
+
};
|
|
8589
|
+
var pointRotate = (point2, angle, origin) => {
|
|
8590
|
+
const r = angleToRadians(angle);
|
|
8591
|
+
if (!origin || isOrigin(origin)) {
|
|
8592
|
+
return rotate2(point2, r);
|
|
8722
8593
|
}
|
|
8723
|
-
return
|
|
8724
|
-
|
|
8725
|
-
|
|
8726
|
-
|
|
8727
|
-
|
|
8728
|
-
|
|
8729
|
-
|
|
8730
|
-
|
|
8731
|
-
|
|
8732
|
-
|
|
8733
|
-
|
|
8734
|
-
|
|
8735
|
-
|
|
8736
|
-
|
|
8737
|
-
|
|
8594
|
+
return rotate2(point2.map((c, i2) => c - origin[i2]), r).map(
|
|
8595
|
+
(c, i2) => c + origin[i2]
|
|
8596
|
+
);
|
|
8597
|
+
};
|
|
8598
|
+
var pointInverse = (point2) => {
|
|
8599
|
+
return [-point2[0], -point2[1]];
|
|
8600
|
+
};
|
|
8601
|
+
var pointAdd = (pointA, pointB) => {
|
|
8602
|
+
return [pointA[0] + pointB[0], pointA[1] + pointB[1]];
|
|
8603
|
+
};
|
|
8604
|
+
var distanceToPoint = (p1, p2) => {
|
|
8605
|
+
return distance2d(...p1, ...p2);
|
|
8606
|
+
};
|
|
8607
|
+
var pointRelativeToCenter = (point2, center, angle) => {
|
|
8608
|
+
const translated = pointAdd(point2, pointInverse(center));
|
|
8609
|
+
const rotated = pointRotate(translated, -angleToDegrees(angle));
|
|
8610
|
+
return rotated;
|
|
8611
|
+
};
|
|
8612
|
+
var distanceToSegment = (point2, line2) => {
|
|
8613
|
+
const [x, y] = point2;
|
|
8614
|
+
const [[x1, y1], [x2, y2]] = line2;
|
|
8615
|
+
const A2 = x - x1;
|
|
8616
|
+
const B2 = y - y1;
|
|
8617
|
+
const C2 = x2 - x1;
|
|
8618
|
+
const D = y2 - y1;
|
|
8619
|
+
const dot2 = A2 * C2 + B2 * D;
|
|
8620
|
+
const len_sq = C2 * C2 + D * D;
|
|
8621
|
+
let param = -1;
|
|
8622
|
+
if (len_sq !== 0) {
|
|
8623
|
+
param = dot2 / len_sq;
|
|
8624
|
+
}
|
|
8625
|
+
let xx;
|
|
8626
|
+
let yy;
|
|
8627
|
+
if (param < 0) {
|
|
8628
|
+
xx = x1;
|
|
8629
|
+
yy = y1;
|
|
8630
|
+
} else if (param > 1) {
|
|
8631
|
+
xx = x2;
|
|
8632
|
+
yy = y2;
|
|
8738
8633
|
} else {
|
|
8739
|
-
|
|
8740
|
-
|
|
8741
|
-
const p2 = points[offset2 + 1];
|
|
8742
|
-
const p3 = points[offset2 + 2];
|
|
8743
|
-
const p4 = points[offset2 + 3];
|
|
8744
|
-
const q1 = lerp2(p1, p2, t2);
|
|
8745
|
-
const q2 = lerp2(p2, p3, t2);
|
|
8746
|
-
const q3 = lerp2(p3, p4, t2);
|
|
8747
|
-
const r1 = lerp2(q1, q2, t2);
|
|
8748
|
-
const r2 = lerp2(q2, q3, t2);
|
|
8749
|
-
const red = lerp2(r1, r2, t2);
|
|
8750
|
-
getPointsOnBezierCurveWithSplitting2([p1, q1, r1, red], 0, tolerance, outPoints);
|
|
8751
|
-
getPointsOnBezierCurveWithSplitting2([red, r2, q3, p4], 0, tolerance, outPoints);
|
|
8634
|
+
xx = x1 + param * C2;
|
|
8635
|
+
yy = y1 + param * D;
|
|
8752
8636
|
}
|
|
8753
|
-
|
|
8754
|
-
|
|
8755
|
-
|
|
8756
|
-
|
|
8757
|
-
|
|
8758
|
-
|
|
8759
|
-
|
|
8760
|
-
|
|
8761
|
-
const e2 = points[end - 1];
|
|
8762
|
-
let maxDistSq = 0;
|
|
8763
|
-
let maxNdx = 1;
|
|
8764
|
-
for (let i2 = start + 1; i2 < end - 1; ++i2) {
|
|
8765
|
-
const distSq = distanceToSegmentSq2(points[i2], s2, e2);
|
|
8766
|
-
if (distSq > maxDistSq) {
|
|
8767
|
-
maxDistSq = distSq;
|
|
8768
|
-
maxNdx = i2;
|
|
8769
|
-
}
|
|
8637
|
+
const dx = x - xx;
|
|
8638
|
+
const dy = y - yy;
|
|
8639
|
+
return Math.sqrt(dx * dx + dy * dy);
|
|
8640
|
+
};
|
|
8641
|
+
var pointOnLine = (point2, line2, threshold = DEFAULT_THRESHOLD) => {
|
|
8642
|
+
const distance4 = distanceToSegment(point2, line2);
|
|
8643
|
+
if (distance4 === 0) {
|
|
8644
|
+
return true;
|
|
8770
8645
|
}
|
|
8771
|
-
|
|
8772
|
-
|
|
8773
|
-
|
|
8774
|
-
|
|
8775
|
-
|
|
8776
|
-
|
|
8646
|
+
return distance4 < threshold;
|
|
8647
|
+
};
|
|
8648
|
+
var pointOnPolyline = (point2, polyline, threshold = DEFAULT_THRESHOLD) => {
|
|
8649
|
+
return polyline.some((line2) => pointOnLine(point2, line2, threshold));
|
|
8650
|
+
};
|
|
8651
|
+
var cubicBezierEquation = (curve2) => {
|
|
8652
|
+
const [p0, p1, p2, p3] = curve2;
|
|
8653
|
+
return (t2, idx) => Math.pow(1 - t2, 3) * p3[idx] + 3 * t2 * Math.pow(1 - t2, 2) * p2[idx] + 3 * Math.pow(t2, 2) * (1 - t2) * p1[idx] + p0[idx] * Math.pow(t2, 3);
|
|
8654
|
+
};
|
|
8655
|
+
var polyLineFromCurve = (curve2, segments = 10) => {
|
|
8656
|
+
const equation2 = cubicBezierEquation(curve2);
|
|
8657
|
+
let startingPoint = [equation2(0, 0), equation2(0, 1)];
|
|
8658
|
+
const lineSegments = [];
|
|
8659
|
+
let t2 = 0;
|
|
8660
|
+
const increment = 1 / segments;
|
|
8661
|
+
for (let i2 = 0; i2 < segments; i2++) {
|
|
8662
|
+
t2 += increment;
|
|
8663
|
+
if (t2 <= 1) {
|
|
8664
|
+
const nextPoint = [equation2(t2, 0), equation2(t2, 1)];
|
|
8665
|
+
lineSegments.push([startingPoint, nextPoint]);
|
|
8666
|
+
startingPoint = nextPoint;
|
|
8667
|
+
}
|
|
8668
|
+
}
|
|
8669
|
+
return lineSegments;
|
|
8670
|
+
};
|
|
8671
|
+
var pointOnCurve = (point2, curve2, threshold = DEFAULT_THRESHOLD) => {
|
|
8672
|
+
return pointOnPolyline(point2, polyLineFromCurve(curve2), threshold);
|
|
8673
|
+
};
|
|
8674
|
+
var pointOnPolycurve = (point2, polycurve, threshold = DEFAULT_THRESHOLD) => {
|
|
8675
|
+
return polycurve.some((curve2) => pointOnCurve(point2, curve2, threshold));
|
|
8676
|
+
};
|
|
8677
|
+
var pointInPolygon = (point2, polygon2) => {
|
|
8678
|
+
const x = point2[0];
|
|
8679
|
+
const y = point2[1];
|
|
8680
|
+
let inside = false;
|
|
8681
|
+
for (let i2 = 0, j = polygon2.length - 1; i2 < polygon2.length; j = i2++) {
|
|
8682
|
+
const xi = polygon2[i2][0];
|
|
8683
|
+
const yi = polygon2[i2][1];
|
|
8684
|
+
const xj = polygon2[j][0];
|
|
8685
|
+
const yj = polygon2[j][1];
|
|
8686
|
+
if ((yi > y && yj <= y || yi <= y && yj > y) && x < (xj - xi) * (y - yi) / (yj - yi) + xi) {
|
|
8687
|
+
inside = !inside;
|
|
8688
|
+
}
|
|
8689
|
+
}
|
|
8690
|
+
return inside;
|
|
8691
|
+
};
|
|
8692
|
+
var pointOnPolygon = (point2, polygon2, threshold = DEFAULT_THRESHOLD) => {
|
|
8693
|
+
let on = false;
|
|
8694
|
+
const closed = close(polygon2);
|
|
8695
|
+
for (let i2 = 0, l2 = closed.length - 1; i2 < l2; i2++) {
|
|
8696
|
+
if (pointOnLine(point2, [closed[i2], closed[i2 + 1]], threshold)) {
|
|
8697
|
+
on = true;
|
|
8698
|
+
break;
|
|
8777
8699
|
}
|
|
8778
|
-
outPoints.push(e2);
|
|
8779
|
-
}
|
|
8780
|
-
return outPoints;
|
|
8781
|
-
}
|
|
8782
|
-
function pointsOnBezierCurves2(points, tolerance = 0.15, distance5) {
|
|
8783
|
-
const newPoints = [];
|
|
8784
|
-
const numSegments = (points.length - 1) / 3;
|
|
8785
|
-
for (let i2 = 0; i2 < numSegments; i2++) {
|
|
8786
|
-
const offset2 = i2 * 3;
|
|
8787
|
-
getPointsOnBezierCurveWithSplitting2(points, offset2, tolerance, newPoints);
|
|
8788
8700
|
}
|
|
8789
|
-
|
|
8790
|
-
|
|
8701
|
+
return on;
|
|
8702
|
+
};
|
|
8703
|
+
var distanceToEllipse = (point2, ellipse2) => {
|
|
8704
|
+
const { angle, halfWidth, halfHeight, center } = ellipse2;
|
|
8705
|
+
const a2 = halfWidth;
|
|
8706
|
+
const b2 = halfHeight;
|
|
8707
|
+
const [rotatedPointX, rotatedPointY] = pointRelativeToCenter(
|
|
8708
|
+
point2,
|
|
8709
|
+
center,
|
|
8710
|
+
angle
|
|
8711
|
+
);
|
|
8712
|
+
const px = Math.abs(rotatedPointX);
|
|
8713
|
+
const py = Math.abs(rotatedPointY);
|
|
8714
|
+
let tx = 0.707;
|
|
8715
|
+
let ty = 0.707;
|
|
8716
|
+
for (let i2 = 0; i2 < 3; i2++) {
|
|
8717
|
+
const x = a2 * tx;
|
|
8718
|
+
const y = b2 * ty;
|
|
8719
|
+
const ex = (a2 * a2 - b2 * b2) * tx ** 3 / a2;
|
|
8720
|
+
const ey = (b2 * b2 - a2 * a2) * ty ** 3 / b2;
|
|
8721
|
+
const rx = x - ex;
|
|
8722
|
+
const ry = y - ey;
|
|
8723
|
+
const qx = px - ex;
|
|
8724
|
+
const qy = py - ey;
|
|
8725
|
+
const r = Math.hypot(ry, rx);
|
|
8726
|
+
const q = Math.hypot(qy, qx);
|
|
8727
|
+
tx = Math.min(1, Math.max(0, (qx * r / q + ex) / a2));
|
|
8728
|
+
ty = Math.min(1, Math.max(0, (qy * r / q + ey) / b2));
|
|
8729
|
+
const t2 = Math.hypot(ty, tx);
|
|
8730
|
+
tx /= t2;
|
|
8731
|
+
ty /= t2;
|
|
8791
8732
|
}
|
|
8792
|
-
|
|
8793
|
-
|
|
8794
|
-
|
|
8795
|
-
|
|
8796
|
-
|
|
8797
|
-
var transformHandleSizes = {
|
|
8798
|
-
mouse: 8,
|
|
8799
|
-
pen: 16,
|
|
8800
|
-
touch: 28
|
|
8733
|
+
const [minX, minY] = [
|
|
8734
|
+
a2 * tx * Math.sign(rotatedPointX),
|
|
8735
|
+
b2 * ty * Math.sign(rotatedPointY)
|
|
8736
|
+
];
|
|
8737
|
+
return distanceToPoint([rotatedPointX, rotatedPointY], [minX, minY]);
|
|
8801
8738
|
};
|
|
8802
|
-
var
|
|
8803
|
-
|
|
8804
|
-
e: true,
|
|
8805
|
-
s: true,
|
|
8806
|
-
n: true,
|
|
8807
|
-
w: true
|
|
8739
|
+
var pointOnEllipse = (point2, ellipse2, threshold = DEFAULT_THRESHOLD) => {
|
|
8740
|
+
return distanceToEllipse(point2, ellipse2) <= threshold;
|
|
8808
8741
|
};
|
|
8809
|
-
var
|
|
8810
|
-
|
|
8811
|
-
|
|
8812
|
-
|
|
8813
|
-
|
|
8814
|
-
|
|
8742
|
+
var pointInEllipse = (point2, ellipse2) => {
|
|
8743
|
+
const { center, angle, halfWidth, halfHeight } = ellipse2;
|
|
8744
|
+
const [rotatedPointX, rotatedPointY] = pointRelativeToCenter(
|
|
8745
|
+
point2,
|
|
8746
|
+
center,
|
|
8747
|
+
angle
|
|
8748
|
+
);
|
|
8749
|
+
return rotatedPointX / halfWidth * (rotatedPointX / halfWidth) + rotatedPointY / halfHeight * (rotatedPointY / halfHeight) <= 1;
|
|
8815
8750
|
};
|
|
8816
|
-
|
|
8817
|
-
|
|
8818
|
-
|
|
8819
|
-
|
|
8820
|
-
|
|
8821
|
-
|
|
8822
|
-
|
|
8823
|
-
|
|
8824
|
-
|
|
8825
|
-
|
|
8826
|
-
|
|
8827
|
-
|
|
8828
|
-
|
|
8829
|
-
|
|
8830
|
-
|
|
8831
|
-
|
|
8832
|
-
|
|
8833
|
-
|
|
8834
|
-
w: true
|
|
8835
|
-
};
|
|
8836
|
-
var generateTransformHandle = (x, y, width, height, cx, cy, angle) => {
|
|
8837
|
-
const [xx, yy] = rotate2(x + width / 2, y + height / 2, cx, cy, angle);
|
|
8838
|
-
return [xx - width / 2, yy - height / 2, width, height];
|
|
8839
|
-
};
|
|
8840
|
-
var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, pointerType, omitSides = {}, margin = 4) => {
|
|
8841
|
-
const size = transformHandleSizes[pointerType];
|
|
8842
|
-
const handleWidth = size / zoom.value;
|
|
8843
|
-
const handleHeight = size / zoom.value;
|
|
8844
|
-
const handleMarginX = size / zoom.value;
|
|
8845
|
-
const handleMarginY = size / zoom.value;
|
|
8846
|
-
const width = x2 - x1;
|
|
8847
|
-
const height = y2 - y1;
|
|
8848
|
-
const dashedLineMargin = margin / zoom.value;
|
|
8849
|
-
const centeringOffset = (size - DEFAULT_TRANSFORM_HANDLE_SPACING * 2) / (2 * zoom.value);
|
|
8850
|
-
const transformHandles = {
|
|
8851
|
-
nw: omitSides.nw ? void 0 : generateTransformHandle(
|
|
8852
|
-
x1 - dashedLineMargin - handleMarginX + centeringOffset,
|
|
8853
|
-
y1 - dashedLineMargin - handleMarginY + centeringOffset,
|
|
8854
|
-
handleWidth,
|
|
8855
|
-
handleHeight,
|
|
8856
|
-
cx,
|
|
8857
|
-
cy,
|
|
8858
|
-
angle
|
|
8859
|
-
),
|
|
8860
|
-
ne: omitSides.ne ? void 0 : generateTransformHandle(
|
|
8861
|
-
x2 + dashedLineMargin - centeringOffset,
|
|
8862
|
-
y1 - dashedLineMargin - handleMarginY + centeringOffset,
|
|
8863
|
-
handleWidth,
|
|
8864
|
-
handleHeight,
|
|
8865
|
-
cx,
|
|
8866
|
-
cy,
|
|
8867
|
-
angle
|
|
8868
|
-
),
|
|
8869
|
-
sw: omitSides.sw ? void 0 : generateTransformHandle(
|
|
8870
|
-
x1 - dashedLineMargin - handleMarginX + centeringOffset,
|
|
8871
|
-
y2 + dashedLineMargin - centeringOffset,
|
|
8872
|
-
handleWidth,
|
|
8873
|
-
handleHeight,
|
|
8874
|
-
cx,
|
|
8875
|
-
cy,
|
|
8876
|
-
angle
|
|
8877
|
-
),
|
|
8878
|
-
se: omitSides.se ? void 0 : generateTransformHandle(
|
|
8879
|
-
x2 + dashedLineMargin - centeringOffset,
|
|
8880
|
-
y2 + dashedLineMargin - centeringOffset,
|
|
8881
|
-
handleWidth,
|
|
8882
|
-
handleHeight,
|
|
8883
|
-
cx,
|
|
8884
|
-
cy,
|
|
8885
|
-
angle
|
|
8886
|
-
),
|
|
8887
|
-
rotation: omitSides.rotation ? void 0 : generateTransformHandle(
|
|
8888
|
-
x1 + width / 2 - handleWidth / 2,
|
|
8889
|
-
y1 - dashedLineMargin - handleMarginY + centeringOffset - ROTATION_RESIZE_HANDLE_GAP / zoom.value,
|
|
8890
|
-
handleWidth,
|
|
8891
|
-
handleHeight,
|
|
8892
|
-
cx,
|
|
8893
|
-
cy,
|
|
8894
|
-
angle
|
|
8895
|
-
)
|
|
8896
|
-
};
|
|
8897
|
-
const minimumSizeForEightHandles = 5 * transformHandleSizes.mouse / zoom.value;
|
|
8898
|
-
if (Math.abs(width) > minimumSizeForEightHandles) {
|
|
8899
|
-
if (!omitSides.n) {
|
|
8900
|
-
transformHandles.n = generateTransformHandle(
|
|
8901
|
-
x1 + width / 2 - handleWidth / 2,
|
|
8902
|
-
y1 - dashedLineMargin - handleMarginY + centeringOffset,
|
|
8903
|
-
handleWidth,
|
|
8904
|
-
handleHeight,
|
|
8905
|
-
cx,
|
|
8906
|
-
cy,
|
|
8907
|
-
angle
|
|
8908
|
-
);
|
|
8909
|
-
}
|
|
8910
|
-
if (!omitSides.s) {
|
|
8911
|
-
transformHandles.s = generateTransformHandle(
|
|
8912
|
-
x1 + width / 2 - handleWidth / 2,
|
|
8913
|
-
y2 + dashedLineMargin - centeringOffset,
|
|
8914
|
-
handleWidth,
|
|
8915
|
-
handleHeight,
|
|
8916
|
-
cx,
|
|
8917
|
-
cy,
|
|
8918
|
-
angle
|
|
8919
|
-
);
|
|
8920
|
-
}
|
|
8751
|
+
|
|
8752
|
+
// ../utils/collision.ts
|
|
8753
|
+
var isPointOnShape = (point2, shape, tolerance = 0) => {
|
|
8754
|
+
switch (shape.type) {
|
|
8755
|
+
case "polygon":
|
|
8756
|
+
return pointOnPolygon(point2, shape.data, tolerance);
|
|
8757
|
+
case "ellipse":
|
|
8758
|
+
return pointOnEllipse(point2, shape.data, tolerance);
|
|
8759
|
+
case "line":
|
|
8760
|
+
return pointOnLine(point2, shape.data, tolerance);
|
|
8761
|
+
case "polyline":
|
|
8762
|
+
return pointOnPolyline(point2, shape.data, tolerance);
|
|
8763
|
+
case "curve":
|
|
8764
|
+
return pointOnCurve(point2, shape.data, tolerance);
|
|
8765
|
+
case "polycurve":
|
|
8766
|
+
return pointOnPolycurve(point2, shape.data, tolerance);
|
|
8767
|
+
default:
|
|
8768
|
+
throw Error(`shape ${shape} is not implemented`);
|
|
8921
8769
|
}
|
|
8922
|
-
|
|
8923
|
-
|
|
8924
|
-
|
|
8925
|
-
|
|
8926
|
-
|
|
8927
|
-
|
|
8928
|
-
|
|
8929
|
-
|
|
8930
|
-
|
|
8931
|
-
|
|
8932
|
-
);
|
|
8770
|
+
};
|
|
8771
|
+
var isPointInShape = (point2, shape) => {
|
|
8772
|
+
switch (shape.type) {
|
|
8773
|
+
case "polygon":
|
|
8774
|
+
return pointInPolygon(point2, shape.data);
|
|
8775
|
+
case "line":
|
|
8776
|
+
return false;
|
|
8777
|
+
case "curve":
|
|
8778
|
+
return false;
|
|
8779
|
+
case "ellipse":
|
|
8780
|
+
return pointInEllipse(point2, shape.data);
|
|
8781
|
+
case "polyline": {
|
|
8782
|
+
const polygon2 = close(shape.data.flat());
|
|
8783
|
+
return pointInPolygon(point2, polygon2);
|
|
8933
8784
|
}
|
|
8934
|
-
|
|
8935
|
-
|
|
8936
|
-
x2 + dashedLineMargin - centeringOffset,
|
|
8937
|
-
y1 + height / 2 - handleHeight / 2,
|
|
8938
|
-
handleWidth,
|
|
8939
|
-
handleHeight,
|
|
8940
|
-
cx,
|
|
8941
|
-
cy,
|
|
8942
|
-
angle
|
|
8943
|
-
);
|
|
8785
|
+
case "polycurve": {
|
|
8786
|
+
return false;
|
|
8944
8787
|
}
|
|
8788
|
+
default:
|
|
8789
|
+
throw Error(`shape ${shape} is not implemented`);
|
|
8945
8790
|
}
|
|
8946
|
-
return transformHandles;
|
|
8947
8791
|
};
|
|
8948
|
-
|
|
8949
|
-
|
|
8950
|
-
|
|
8951
|
-
|
|
8952
|
-
|
|
8953
|
-
|
|
8954
|
-
|
|
8955
|
-
|
|
8956
|
-
|
|
8957
|
-
|
|
8958
|
-
|
|
8959
|
-
|
|
8960
|
-
|
|
8961
|
-
|
|
8962
|
-
|
|
8963
|
-
omitSides = OMIT_SIDES_FOR_LINE_SLASH;
|
|
8964
|
-
} else if (p1[0] < 0 && p1[1] < 0) {
|
|
8965
|
-
omitSides = OMIT_SIDES_FOR_LINE_BACKSLASH;
|
|
8966
|
-
}
|
|
8967
|
-
}
|
|
8968
|
-
} else if (isTextElement(element)) {
|
|
8969
|
-
omitSides = OMIT_SIDES_FOR_TEXT_ELEMENT;
|
|
8970
|
-
} else if (isFrameLikeElement(element)) {
|
|
8971
|
-
omitSides = {
|
|
8972
|
-
rotation: true
|
|
8973
|
-
};
|
|
8974
|
-
}
|
|
8975
|
-
const dashedLineMargin = isLinearElement(element) ? DEFAULT_TRANSFORM_HANDLE_SPACING + 8 : DEFAULT_TRANSFORM_HANDLE_SPACING;
|
|
8976
|
-
return getTransformHandlesFromCoords(
|
|
8977
|
-
getElementAbsoluteCoords(element, elementsMap, true),
|
|
8978
|
-
element.angle,
|
|
8979
|
-
zoom,
|
|
8980
|
-
pointerType,
|
|
8981
|
-
omitSides,
|
|
8982
|
-
dashedLineMargin
|
|
8792
|
+
|
|
8793
|
+
// scene/index.ts
|
|
8794
|
+
init_define_import_meta_env();
|
|
8795
|
+
|
|
8796
|
+
// scene/scroll.ts
|
|
8797
|
+
init_define_import_meta_env();
|
|
8798
|
+
var isOutsideViewPort = (appState, cords) => {
|
|
8799
|
+
const [x1, y1, x2, y2] = cords;
|
|
8800
|
+
const { x: viewportX1, y: viewportY1 } = sceneCoordsToViewportCoords(
|
|
8801
|
+
{ sceneX: x1, sceneY: y1 },
|
|
8802
|
+
appState
|
|
8803
|
+
);
|
|
8804
|
+
const { x: viewportX2, y: viewportY2 } = sceneCoordsToViewportCoords(
|
|
8805
|
+
{ sceneX: x2, sceneY: y2 },
|
|
8806
|
+
appState
|
|
8983
8807
|
);
|
|
8808
|
+
return viewportX2 - viewportX1 > appState.width || viewportY2 - viewportY1 > appState.height;
|
|
8984
8809
|
};
|
|
8985
|
-
var
|
|
8986
|
-
|
|
8987
|
-
|
|
8810
|
+
var centerScrollOn = ({
|
|
8811
|
+
scenePoint,
|
|
8812
|
+
viewportDimensions,
|
|
8813
|
+
zoom
|
|
8814
|
+
}) => {
|
|
8815
|
+
return {
|
|
8816
|
+
scrollX: viewportDimensions.width / 2 / zoom.value - scenePoint.x,
|
|
8817
|
+
scrollY: viewportDimensions.height / 2 / zoom.value - scenePoint.y
|
|
8818
|
+
};
|
|
8819
|
+
};
|
|
8820
|
+
var calculateScrollCenter = (elements, appState) => {
|
|
8821
|
+
elements = getVisibleElements(elements);
|
|
8822
|
+
if (!elements.length) {
|
|
8823
|
+
return {
|
|
8824
|
+
scrollX: 0,
|
|
8825
|
+
scrollY: 0
|
|
8826
|
+
};
|
|
8988
8827
|
}
|
|
8989
|
-
|
|
8990
|
-
|
|
8828
|
+
let [x1, y1, x2, y2] = getCommonBounds(elements);
|
|
8829
|
+
if (isOutsideViewPort(appState, [x1, y1, x2, y2])) {
|
|
8830
|
+
[x1, y1, x2, y2] = getClosestElementBounds(
|
|
8831
|
+
elements,
|
|
8832
|
+
viewportCoordsToSceneCoords(
|
|
8833
|
+
{ clientX: appState.scrollX, clientY: appState.scrollY },
|
|
8834
|
+
appState
|
|
8835
|
+
)
|
|
8836
|
+
);
|
|
8991
8837
|
}
|
|
8992
|
-
const
|
|
8993
|
-
|
|
8994
|
-
|
|
8838
|
+
const centerX = (x1 + x2) / 2;
|
|
8839
|
+
const centerY = (y1 + y2) / 2;
|
|
8840
|
+
return centerScrollOn({
|
|
8841
|
+
scenePoint: { x: centerX, y: centerY },
|
|
8842
|
+
viewportDimensions: { width: appState.width, height: appState.height },
|
|
8843
|
+
zoom: appState.zoom
|
|
8844
|
+
});
|
|
8845
|
+
};
|
|
8846
|
+
|
|
8847
|
+
// scene/comparisons.ts
|
|
8848
|
+
init_define_import_meta_env();
|
|
8849
|
+
var hasBackground = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "line" || type === "freedraw";
|
|
8850
|
+
var hasStrokeColor = (type) => type !== "image" && type !== "frame" && type !== "magicframe";
|
|
8851
|
+
var hasStrokeWidth = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "freedraw" || type === "arrow" || type === "line";
|
|
8852
|
+
var hasStrokeStyle = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "arrow" || type === "line";
|
|
8853
|
+
var canChangeRoundness = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "arrow" || type === "line" || type === "diamond" || type === "image";
|
|
8854
|
+
var canHaveArrowheads = (type) => type === "arrow";
|
|
8855
|
+
var getElementAtPosition = (elements, isAtPositionFn) => {
|
|
8856
|
+
let hitElement = null;
|
|
8857
|
+
for (let index = elements.length - 1; index >= 0; --index) {
|
|
8858
|
+
const element = elements[index];
|
|
8859
|
+
if (element.isDeleted) {
|
|
8860
|
+
continue;
|
|
8861
|
+
}
|
|
8862
|
+
if (isAtPositionFn(element)) {
|
|
8863
|
+
hitElement = element;
|
|
8864
|
+
break;
|
|
8865
|
+
}
|
|
8995
8866
|
}
|
|
8996
|
-
return
|
|
8867
|
+
return hitElement;
|
|
8997
8868
|
};
|
|
8998
8869
|
|
|
8999
|
-
// scene/
|
|
8870
|
+
// scene/zoom.ts
|
|
9000
8871
|
init_define_import_meta_env();
|
|
9001
|
-
var
|
|
9002
|
-
|
|
9003
|
-
|
|
9004
|
-
|
|
9005
|
-
|
|
9006
|
-
|
|
9007
|
-
|
|
9008
|
-
|
|
9009
|
-
|
|
9010
|
-
|
|
9011
|
-
|
|
9012
|
-
|
|
9013
|
-
|
|
9014
|
-
|
|
9015
|
-
|
|
9016
|
-
|
|
9017
|
-
|
|
9018
|
-
|
|
9019
|
-
|
|
9020
|
-
|
|
9021
|
-
*/
|
|
9022
|
-
static generateElementShape = (element, renderConfig) => {
|
|
9023
|
-
const cachedShape = renderConfig?.isExporting ? void 0 : _ShapeCache.get(element);
|
|
9024
|
-
if (cachedShape !== void 0) {
|
|
9025
|
-
return cachedShape;
|
|
8872
|
+
var getNormalizedZoom = (zoom) => {
|
|
8873
|
+
return Math.max(MIN_ZOOM, Math.min(zoom, 30));
|
|
8874
|
+
};
|
|
8875
|
+
var getStateForZoom = ({
|
|
8876
|
+
viewportX,
|
|
8877
|
+
viewportY,
|
|
8878
|
+
nextZoom
|
|
8879
|
+
}, appState) => {
|
|
8880
|
+
const appLayerX = viewportX - appState.offsetLeft;
|
|
8881
|
+
const appLayerY = viewportY - appState.offsetTop;
|
|
8882
|
+
const currentZoom = appState.zoom.value;
|
|
8883
|
+
const baseScrollX = appState.scrollX + (appLayerX - appLayerX / currentZoom);
|
|
8884
|
+
const baseScrollY = appState.scrollY + (appLayerY - appLayerY / currentZoom);
|
|
8885
|
+
const zoomOffsetScrollX = -(appLayerX - appLayerX / nextZoom);
|
|
8886
|
+
const zoomOffsetScrollY = -(appLayerY - appLayerY / nextZoom);
|
|
8887
|
+
return {
|
|
8888
|
+
scrollX: baseScrollX + zoomOffsetScrollX,
|
|
8889
|
+
scrollY: baseScrollY + zoomOffsetScrollY,
|
|
8890
|
+
zoom: {
|
|
8891
|
+
value: nextZoom
|
|
9026
8892
|
}
|
|
9027
|
-
elementWithCanvasCache.delete(element);
|
|
9028
|
-
const shape = _generateElementShape(
|
|
9029
|
-
element,
|
|
9030
|
-
_ShapeCache.rg,
|
|
9031
|
-
renderConfig || {
|
|
9032
|
-
isExporting: false,
|
|
9033
|
-
canvasBackgroundColor: COLOR_PALETTE.white,
|
|
9034
|
-
embedsValidationStatus: null
|
|
9035
|
-
}
|
|
9036
|
-
);
|
|
9037
|
-
_ShapeCache.cache.set(element, shape);
|
|
9038
|
-
return shape;
|
|
9039
8893
|
};
|
|
9040
8894
|
};
|
|
9041
8895
|
|
|
9042
|
-
//
|
|
9043
|
-
|
|
9044
|
-
|
|
9045
|
-
|
|
9046
|
-
|
|
9047
|
-
|
|
9048
|
-
|
|
9049
|
-
|
|
9050
|
-
|
|
9051
|
-
|
|
9052
|
-
|
|
9053
|
-
|
|
9054
|
-
|
|
8896
|
+
// keys.ts
|
|
8897
|
+
init_define_import_meta_env();
|
|
8898
|
+
var CODES = {
|
|
8899
|
+
EQUAL: "Equal",
|
|
8900
|
+
MINUS: "Minus",
|
|
8901
|
+
NUM_ADD: "NumpadAdd",
|
|
8902
|
+
NUM_SUBTRACT: "NumpadSubtract",
|
|
8903
|
+
NUM_ZERO: "Numpad0",
|
|
8904
|
+
BRACKET_RIGHT: "BracketRight",
|
|
8905
|
+
BRACKET_LEFT: "BracketLeft",
|
|
8906
|
+
ONE: "Digit1",
|
|
8907
|
+
TWO: "Digit2",
|
|
8908
|
+
THREE: "Digit3",
|
|
8909
|
+
NINE: "Digit9",
|
|
8910
|
+
QUOTE: "Quote",
|
|
8911
|
+
ZERO: "Digit0",
|
|
8912
|
+
SLASH: "Slash",
|
|
8913
|
+
C: "KeyC",
|
|
8914
|
+
D: "KeyD",
|
|
8915
|
+
H: "KeyH",
|
|
8916
|
+
V: "KeyV",
|
|
8917
|
+
Z: "KeyZ",
|
|
8918
|
+
R: "KeyR",
|
|
8919
|
+
S: "KeyS"
|
|
9055
8920
|
};
|
|
9056
|
-
var
|
|
9057
|
-
|
|
9058
|
-
|
|
9059
|
-
|
|
9060
|
-
|
|
9061
|
-
|
|
9062
|
-
|
|
9063
|
-
|
|
9064
|
-
|
|
9065
|
-
|
|
9066
|
-
|
|
9067
|
-
|
|
9068
|
-
|
|
9069
|
-
|
|
9070
|
-
|
|
9071
|
-
|
|
9072
|
-
|
|
9073
|
-
|
|
9074
|
-
|
|
9075
|
-
|
|
9076
|
-
|
|
9077
|
-
|
|
9078
|
-
|
|
9079
|
-
|
|
8921
|
+
var KEYS = {
|
|
8922
|
+
ARROW_DOWN: "ArrowDown",
|
|
8923
|
+
ARROW_LEFT: "ArrowLeft",
|
|
8924
|
+
ARROW_RIGHT: "ArrowRight",
|
|
8925
|
+
ARROW_UP: "ArrowUp",
|
|
8926
|
+
PAGE_UP: "PageUp",
|
|
8927
|
+
PAGE_DOWN: "PageDown",
|
|
8928
|
+
BACKSPACE: "Backspace",
|
|
8929
|
+
ALT: "Alt",
|
|
8930
|
+
CTRL_OR_CMD: isDarwin ? "metaKey" : "ctrlKey",
|
|
8931
|
+
DELETE: "Delete",
|
|
8932
|
+
ENTER: "Enter",
|
|
8933
|
+
ESCAPE: "Escape",
|
|
8934
|
+
QUESTION_MARK: "?",
|
|
8935
|
+
SPACE: " ",
|
|
8936
|
+
TAB: "Tab",
|
|
8937
|
+
CHEVRON_LEFT: "<",
|
|
8938
|
+
CHEVRON_RIGHT: ">",
|
|
8939
|
+
PERIOD: ".",
|
|
8940
|
+
COMMA: ",",
|
|
8941
|
+
SUBTRACT: "-",
|
|
8942
|
+
SLASH: "/",
|
|
8943
|
+
A: "a",
|
|
8944
|
+
C: "c",
|
|
8945
|
+
D: "d",
|
|
8946
|
+
E: "e",
|
|
8947
|
+
F: "f",
|
|
8948
|
+
G: "g",
|
|
8949
|
+
H: "h",
|
|
8950
|
+
I: "i",
|
|
8951
|
+
L: "l",
|
|
8952
|
+
O: "o",
|
|
8953
|
+
P: "p",
|
|
8954
|
+
Q: "q",
|
|
8955
|
+
R: "r",
|
|
8956
|
+
S: "s",
|
|
8957
|
+
T: "t",
|
|
8958
|
+
V: "v",
|
|
8959
|
+
X: "x",
|
|
8960
|
+
Y: "y",
|
|
8961
|
+
Z: "z",
|
|
8962
|
+
K: "k",
|
|
8963
|
+
W: "w",
|
|
8964
|
+
0: "0",
|
|
8965
|
+
1: "1",
|
|
8966
|
+
2: "2",
|
|
8967
|
+
3: "3",
|
|
8968
|
+
4: "4",
|
|
8969
|
+
5: "5",
|
|
8970
|
+
6: "6",
|
|
8971
|
+
7: "7",
|
|
8972
|
+
8: "8",
|
|
8973
|
+
9: "9"
|
|
8974
|
+
};
|
|
8975
|
+
var isArrowKey = (key) => key === KEYS.ARROW_LEFT || key === KEYS.ARROW_RIGHT || key === KEYS.ARROW_DOWN || key === KEYS.ARROW_UP;
|
|
8976
|
+
var shouldResizeFromCenter = (event) => event.altKey;
|
|
8977
|
+
var shouldMaintainAspectRatio = (event) => event.shiftKey;
|
|
8978
|
+
var shouldRotateWithDiscreteAngle = (event) => event.shiftKey;
|
|
8979
|
+
|
|
8980
|
+
// element/binding.ts
|
|
8981
|
+
var shouldEnableBindingForPointerEvent = (event) => {
|
|
8982
|
+
return !event[KEYS.CTRL_OR_CMD];
|
|
8983
|
+
};
|
|
8984
|
+
var isBindingEnabled = (appState) => {
|
|
8985
|
+
return appState.isBindingEnabled;
|
|
8986
|
+
};
|
|
8987
|
+
var getNonDeletedElements = (scene, ids) => {
|
|
8988
|
+
const result = [];
|
|
8989
|
+
ids.forEach((id) => {
|
|
8990
|
+
const element = scene.getNonDeletedElement(id);
|
|
8991
|
+
if (element != null) {
|
|
8992
|
+
result.push(element);
|
|
9080
8993
|
}
|
|
9081
|
-
}
|
|
9082
|
-
return
|
|
9083
|
-
|
|
9084
|
-
|
|
9085
|
-
|
|
9086
|
-
|
|
8994
|
+
});
|
|
8995
|
+
return result;
|
|
8996
|
+
};
|
|
8997
|
+
var bindOrUnbindLinearElement = (linearElement, startBindingElement, endBindingElement, elementsMap) => {
|
|
8998
|
+
const boundToElementIds = /* @__PURE__ */ new Set();
|
|
8999
|
+
const unboundFromElementIds = /* @__PURE__ */ new Set();
|
|
9000
|
+
bindOrUnbindLinearElementEdge(
|
|
9001
|
+
linearElement,
|
|
9002
|
+
startBindingElement,
|
|
9003
|
+
endBindingElement,
|
|
9004
|
+
"start",
|
|
9005
|
+
boundToElementIds,
|
|
9006
|
+
unboundFromElementIds,
|
|
9087
9007
|
elementsMap
|
|
9088
9008
|
);
|
|
9089
|
-
|
|
9090
|
-
|
|
9091
|
-
|
|
9092
|
-
|
|
9093
|
-
|
|
9094
|
-
|
|
9095
|
-
|
|
9096
|
-
return !isHittingElementNotConsideringBoundingBox(
|
|
9097
|
-
element,
|
|
9098
|
-
appState,
|
|
9099
|
-
frameNameBoundsCache,
|
|
9100
|
-
[x, y],
|
|
9009
|
+
bindOrUnbindLinearElementEdge(
|
|
9010
|
+
linearElement,
|
|
9011
|
+
endBindingElement,
|
|
9012
|
+
startBindingElement,
|
|
9013
|
+
"end",
|
|
9014
|
+
boundToElementIds,
|
|
9015
|
+
unboundFromElementIds,
|
|
9101
9016
|
elementsMap
|
|
9102
|
-
) && isPointHittingElementBoundingBox(
|
|
9103
|
-
element,
|
|
9104
|
-
elementsMap,
|
|
9105
|
-
[x, y],
|
|
9106
|
-
threshold,
|
|
9107
|
-
frameNameBoundsCache
|
|
9108
9017
|
);
|
|
9109
|
-
|
|
9110
|
-
|
|
9111
|
-
|
|
9112
|
-
|
|
9113
|
-
|
|
9114
|
-
|
|
9115
|
-
|
|
9116
|
-
|
|
9117
|
-
|
|
9118
|
-
|
|
9119
|
-
|
|
9120
|
-
});
|
|
9121
|
-
};
|
|
9122
|
-
var isElementSelected = (appState, element) => appState.selectedElementIds[element.id];
|
|
9123
|
-
var isPointHittingElementBoundingBox = (element, elementsMap, [x, y], threshold, frameNameBoundsCache) => {
|
|
9124
|
-
if (isFrameLikeElement(element)) {
|
|
9125
|
-
return hitTestPointAgainstElement({
|
|
9126
|
-
element,
|
|
9127
|
-
elementsMap,
|
|
9128
|
-
point: [x, y],
|
|
9129
|
-
threshold,
|
|
9130
|
-
check: isInsideCheck,
|
|
9131
|
-
frameNameBoundsCache
|
|
9132
|
-
});
|
|
9133
|
-
}
|
|
9134
|
-
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
|
|
9135
|
-
const elementCenterX = (x1 + x2) / 2;
|
|
9136
|
-
const elementCenterY = (y1 + y2) / 2;
|
|
9137
|
-
const [rotatedX, rotatedY] = rotate2(
|
|
9138
|
-
x,
|
|
9139
|
-
y,
|
|
9140
|
-
elementCenterX,
|
|
9141
|
-
elementCenterY,
|
|
9142
|
-
-element.angle
|
|
9018
|
+
const onlyUnbound = Array.from(unboundFromElementIds).filter(
|
|
9019
|
+
(id) => !boundToElementIds.has(id)
|
|
9020
|
+
);
|
|
9021
|
+
getNonDeletedElements(Scene_default.getScene(linearElement), onlyUnbound).forEach(
|
|
9022
|
+
(element) => {
|
|
9023
|
+
mutateElement(element, {
|
|
9024
|
+
boundElements: element.boundElements?.filter(
|
|
9025
|
+
(element2) => element2.type !== "arrow" || element2.id !== linearElement.id
|
|
9026
|
+
)
|
|
9027
|
+
});
|
|
9028
|
+
}
|
|
9143
9029
|
);
|
|
9144
|
-
return rotatedX > x1 - threshold && rotatedX < x2 + threshold && rotatedY > y1 - threshold && rotatedY < y2 + threshold;
|
|
9145
9030
|
};
|
|
9146
|
-
var
|
|
9147
|
-
|
|
9148
|
-
|
|
9149
|
-
|
|
9150
|
-
|
|
9151
|
-
|
|
9152
|
-
|
|
9153
|
-
|
|
9154
|
-
|
|
9155
|
-
|
|
9156
|
-
|
|
9157
|
-
|
|
9031
|
+
var bindOrUnbindLinearElementEdge = (linearElement, bindableElement, otherEdgeBindableElement, startOrEnd, boundToElementIds, unboundFromElementIds, elementsMap) => {
|
|
9032
|
+
if (bindableElement !== "keep") {
|
|
9033
|
+
if (bindableElement != null) {
|
|
9034
|
+
if (otherEdgeBindableElement == null || (otherEdgeBindableElement === "keep" ? !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(
|
|
9035
|
+
linearElement,
|
|
9036
|
+
bindableElement,
|
|
9037
|
+
startOrEnd
|
|
9038
|
+
) : startOrEnd === "start" || otherEdgeBindableElement.id !== bindableElement.id)) {
|
|
9039
|
+
bindLinearElement(
|
|
9040
|
+
linearElement,
|
|
9041
|
+
bindableElement,
|
|
9042
|
+
startOrEnd,
|
|
9043
|
+
elementsMap
|
|
9044
|
+
);
|
|
9045
|
+
boundToElementIds.add(bindableElement.id);
|
|
9046
|
+
}
|
|
9047
|
+
} else {
|
|
9048
|
+
const unbound = unbindLinearElement(linearElement, startOrEnd);
|
|
9049
|
+
if (unbound != null) {
|
|
9050
|
+
unboundFromElementIds.add(unbound);
|
|
9051
|
+
}
|
|
9052
|
+
}
|
|
9053
|
+
}
|
|
9158
9054
|
};
|
|
9159
|
-
var
|
|
9160
|
-
|
|
9161
|
-
|
|
9162
|
-
|
|
9163
|
-
|
|
9164
|
-
|
|
9165
|
-
|
|
9166
|
-
|
|
9167
|
-
case "iframe":
|
|
9168
|
-
case "embeddable":
|
|
9169
|
-
case "image":
|
|
9170
|
-
case "text":
|
|
9171
|
-
case "diamond":
|
|
9172
|
-
case "ellipse":
|
|
9173
|
-
const distance5 = distanceToBindableElement(
|
|
9174
|
-
args.element,
|
|
9175
|
-
args.point,
|
|
9176
|
-
args.elementsMap
|
|
9177
|
-
);
|
|
9178
|
-
return args.check(distance5, args.threshold);
|
|
9179
|
-
case "freedraw": {
|
|
9180
|
-
if (!args.check(
|
|
9181
|
-
distanceToRectangle(args.element, args.point, args.elementsMap),
|
|
9182
|
-
args.threshold
|
|
9183
|
-
)) {
|
|
9184
|
-
return false;
|
|
9185
|
-
}
|
|
9186
|
-
return hitTestFreeDrawElement(
|
|
9187
|
-
args.element,
|
|
9188
|
-
args.point,
|
|
9189
|
-
args.threshold,
|
|
9190
|
-
args.elementsMap
|
|
9055
|
+
var bindOrUnbindSelectedElements = (selectedElements, app) => {
|
|
9056
|
+
selectedElements.forEach((selectedElement) => {
|
|
9057
|
+
if (isBindingElement(selectedElement)) {
|
|
9058
|
+
bindOrUnbindLinearElement(
|
|
9059
|
+
selectedElement,
|
|
9060
|
+
getElligibleElementForBindingElement(selectedElement, "start", app),
|
|
9061
|
+
getElligibleElementForBindingElement(selectedElement, "end", app),
|
|
9062
|
+
app.scene.getNonDeletedElementsMap()
|
|
9191
9063
|
);
|
|
9192
|
-
}
|
|
9193
|
-
|
|
9194
|
-
|
|
9195
|
-
|
|
9196
|
-
|
|
9197
|
-
console.warn(
|
|
9198
|
-
"This should not happen, we need to investigate why it does."
|
|
9064
|
+
} else if (isBindableElement(selectedElement)) {
|
|
9065
|
+
maybeBindBindableElement(
|
|
9066
|
+
selectedElement,
|
|
9067
|
+
app.scene.getNonDeletedElementsMap(),
|
|
9068
|
+
app
|
|
9199
9069
|
);
|
|
9200
|
-
return false;
|
|
9201
|
-
case "frame":
|
|
9202
|
-
case "magicframe": {
|
|
9203
|
-
if (args.check(
|
|
9204
|
-
distanceToBindableElement(args.element, args.point, args.elementsMap),
|
|
9205
|
-
args.threshold
|
|
9206
|
-
)) {
|
|
9207
|
-
return true;
|
|
9208
|
-
}
|
|
9209
|
-
const frameNameBounds = args.frameNameBoundsCache?.get(args.element);
|
|
9210
|
-
if (frameNameBounds) {
|
|
9211
|
-
return args.check(
|
|
9212
|
-
distanceToRectangleBox(frameNameBounds, args.point),
|
|
9213
|
-
args.threshold
|
|
9214
|
-
);
|
|
9215
|
-
}
|
|
9216
|
-
return false;
|
|
9217
9070
|
}
|
|
9218
|
-
}
|
|
9071
|
+
});
|
|
9219
9072
|
};
|
|
9220
|
-
var
|
|
9221
|
-
|
|
9222
|
-
|
|
9223
|
-
|
|
9224
|
-
|
|
9225
|
-
|
|
9226
|
-
|
|
9227
|
-
|
|
9228
|
-
|
|
9229
|
-
|
|
9230
|
-
|
|
9231
|
-
|
|
9232
|
-
|
|
9233
|
-
|
|
9073
|
+
var maybeBindBindableElement = (bindableElement, elementsMap, app) => {
|
|
9074
|
+
getElligibleElementsForBindableElementAndWhere(bindableElement, app).forEach(
|
|
9075
|
+
([linearElement, where]) => bindOrUnbindLinearElement(
|
|
9076
|
+
linearElement,
|
|
9077
|
+
where === "end" ? "keep" : bindableElement,
|
|
9078
|
+
where === "start" ? "keep" : bindableElement,
|
|
9079
|
+
elementsMap
|
|
9080
|
+
)
|
|
9081
|
+
);
|
|
9082
|
+
};
|
|
9083
|
+
var maybeBindLinearElement = (linearElement, appState, pointerCoords, app) => {
|
|
9084
|
+
if (appState.startBoundElement != null) {
|
|
9085
|
+
bindLinearElement(
|
|
9086
|
+
linearElement,
|
|
9087
|
+
appState.startBoundElement,
|
|
9088
|
+
"start",
|
|
9089
|
+
app.scene.getNonDeletedElementsMap()
|
|
9090
|
+
);
|
|
9091
|
+
}
|
|
9092
|
+
const hoveredElement = getHoveredElementForBinding(pointerCoords, app);
|
|
9093
|
+
if (hoveredElement != null && !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(
|
|
9094
|
+
linearElement,
|
|
9095
|
+
hoveredElement,
|
|
9096
|
+
"end"
|
|
9097
|
+
)) {
|
|
9098
|
+
bindLinearElement(
|
|
9099
|
+
linearElement,
|
|
9100
|
+
hoveredElement,
|
|
9101
|
+
"end",
|
|
9102
|
+
app.scene.getNonDeletedElementsMap()
|
|
9103
|
+
);
|
|
9234
9104
|
}
|
|
9235
9105
|
};
|
|
9236
|
-
var
|
|
9237
|
-
|
|
9106
|
+
var bindLinearElement = (linearElement, hoveredElement, startOrEnd, elementsMap) => {
|
|
9107
|
+
mutateElement(linearElement, {
|
|
9108
|
+
[startOrEnd === "start" ? "startBinding" : "endBinding"]: {
|
|
9109
|
+
elementId: hoveredElement.id,
|
|
9110
|
+
...calculateFocusAndGap(
|
|
9111
|
+
linearElement,
|
|
9112
|
+
hoveredElement,
|
|
9113
|
+
startOrEnd,
|
|
9114
|
+
elementsMap
|
|
9115
|
+
)
|
|
9116
|
+
}
|
|
9117
|
+
});
|
|
9118
|
+
const boundElementsMap = arrayToMap(hoveredElement.boundElements || []);
|
|
9119
|
+
if (!boundElementsMap.has(linearElement.id)) {
|
|
9120
|
+
mutateElement(hoveredElement, {
|
|
9121
|
+
boundElements: (hoveredElement.boundElements || []).concat({
|
|
9122
|
+
id: linearElement.id,
|
|
9123
|
+
type: "arrow"
|
|
9124
|
+
})
|
|
9125
|
+
});
|
|
9126
|
+
}
|
|
9238
9127
|
};
|
|
9239
|
-
var
|
|
9240
|
-
|
|
9128
|
+
var isLinearElementSimpleAndAlreadyBoundOnOppositeEdge = (linearElement, bindableElement, startOrEnd) => {
|
|
9129
|
+
const otherBinding = linearElement[startOrEnd === "start" ? "endBinding" : "startBinding"];
|
|
9130
|
+
return isLinearElementSimpleAndAlreadyBound(
|
|
9131
|
+
linearElement,
|
|
9132
|
+
otherBinding?.elementId,
|
|
9133
|
+
bindableElement
|
|
9134
|
+
);
|
|
9241
9135
|
};
|
|
9242
|
-
var
|
|
9243
|
-
return
|
|
9136
|
+
var isLinearElementSimpleAndAlreadyBound = (linearElement, alreadyBoundToId, bindableElement) => {
|
|
9137
|
+
return alreadyBoundToId === bindableElement.id && linearElement.points.length < 3;
|
|
9244
9138
|
};
|
|
9245
|
-
var
|
|
9246
|
-
|
|
9139
|
+
var unbindLinearElements = (elements, elementsMap) => {
|
|
9140
|
+
elements.forEach((element) => {
|
|
9141
|
+
if (isBindingElement(element)) {
|
|
9142
|
+
bindOrUnbindLinearElement(element, null, null, elementsMap);
|
|
9143
|
+
}
|
|
9144
|
+
});
|
|
9247
9145
|
};
|
|
9248
|
-
var
|
|
9249
|
-
const
|
|
9250
|
-
|
|
9251
|
-
|
|
9252
|
-
|
|
9253
|
-
|
|
9254
|
-
|
|
9255
|
-
|
|
9256
|
-
distanceToLine(pointRel, equation(1, 0, -hwidth))
|
|
9257
|
-
);
|
|
9146
|
+
var unbindLinearElement = (linearElement, startOrEnd) => {
|
|
9147
|
+
const field = startOrEnd === "start" ? "startBinding" : "endBinding";
|
|
9148
|
+
const binding = linearElement[field];
|
|
9149
|
+
if (binding == null) {
|
|
9150
|
+
return null;
|
|
9151
|
+
}
|
|
9152
|
+
mutateElement(linearElement, { [field]: null });
|
|
9153
|
+
return binding.elementId;
|
|
9258
9154
|
};
|
|
9259
|
-
var
|
|
9260
|
-
const
|
|
9261
|
-
|
|
9262
|
-
|
|
9263
|
-
distanceToLine(pointRel, equation(1, 0, -hwidth))
|
|
9155
|
+
var getHoveredElementForBinding = (pointerCoords, app) => {
|
|
9156
|
+
const hoveredElement = getElementAtPosition(
|
|
9157
|
+
app.scene.getNonDeletedElements(),
|
|
9158
|
+
(element) => isBindableElement(element, false) && bindingBorderTest(element, pointerCoords, app)
|
|
9264
9159
|
);
|
|
9160
|
+
return hoveredElement;
|
|
9265
9161
|
};
|
|
9266
|
-
var
|
|
9267
|
-
const
|
|
9268
|
-
|
|
9269
|
-
|
|
9162
|
+
var calculateFocusAndGap = (linearElement, hoveredElement, startOrEnd, elementsMap) => {
|
|
9163
|
+
const direction = startOrEnd === "start" ? -1 : 1;
|
|
9164
|
+
const edgePointIndex = direction === -1 ? 0 : linearElement.points.length - 1;
|
|
9165
|
+
const adjacentPointIndex = edgePointIndex - direction;
|
|
9166
|
+
const edgePoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
|
9167
|
+
linearElement,
|
|
9168
|
+
edgePointIndex,
|
|
9270
9169
|
elementsMap
|
|
9271
9170
|
);
|
|
9272
|
-
const
|
|
9273
|
-
|
|
9274
|
-
|
|
9275
|
-
var distanceToEllipse = (element, point2, elementsMap) => {
|
|
9276
|
-
const [pointRel, tangent] = ellipseParamsForTest(element, point2, elementsMap);
|
|
9277
|
-
return -sign(tangent) * distanceToLine(pointRel, tangent);
|
|
9278
|
-
};
|
|
9279
|
-
var ellipseParamsForTest = (element, point2, elementsMap) => {
|
|
9280
|
-
const [, pointRel, hwidth, hheight] = pointRelativeToElement(
|
|
9281
|
-
element,
|
|
9282
|
-
point2,
|
|
9171
|
+
const adjacentPoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
|
9172
|
+
linearElement,
|
|
9173
|
+
adjacentPointIndex,
|
|
9283
9174
|
elementsMap
|
|
9284
9175
|
);
|
|
9285
|
-
|
|
9286
|
-
|
|
9287
|
-
|
|
9288
|
-
|
|
9289
|
-
|
|
9290
|
-
[0, 1, 2, 3].forEach((_) => {
|
|
9291
|
-
const xx = a2 * tx;
|
|
9292
|
-
const yy = b2 * ty;
|
|
9293
|
-
const ex = (a2 * a2 - b2 * b2) * tx ** 3 / a2;
|
|
9294
|
-
const ey = (b2 * b2 - a2 * a2) * ty ** 3 / b2;
|
|
9295
|
-
const rx = xx - ex;
|
|
9296
|
-
const ry = yy - ey;
|
|
9297
|
-
const qx = px - ex;
|
|
9298
|
-
const qy = py - ey;
|
|
9299
|
-
const r = Math.hypot(ry, rx);
|
|
9300
|
-
const q = Math.hypot(qy, qx);
|
|
9301
|
-
tx = Math.min(1, Math.max(0, (qx * r / q + ex) / a2));
|
|
9302
|
-
ty = Math.min(1, Math.max(0, (qy * r / q + ey) / b2));
|
|
9303
|
-
const t2 = Math.hypot(ty, tx);
|
|
9304
|
-
tx /= t2;
|
|
9305
|
-
ty /= t2;
|
|
9306
|
-
});
|
|
9307
|
-
const closestPoint = point(a2 * tx, b2 * ty);
|
|
9308
|
-
const tangent = orthogonalThrough(pointRel, closestPoint);
|
|
9309
|
-
return [pointRel, tangent];
|
|
9310
|
-
};
|
|
9311
|
-
var hitTestFreeDrawElement = (element, point2, threshold, elementsMap) => {
|
|
9312
|
-
let x;
|
|
9313
|
-
let y;
|
|
9314
|
-
if (element.angle === 0) {
|
|
9315
|
-
x = point2[0] - element.x;
|
|
9316
|
-
y = point2[1] - element.y;
|
|
9317
|
-
} else {
|
|
9318
|
-
const [minX, minY, maxX, maxY] = getElementAbsoluteCoords(
|
|
9319
|
-
element,
|
|
9176
|
+
return {
|
|
9177
|
+
focus: determineFocusDistance(
|
|
9178
|
+
hoveredElement,
|
|
9179
|
+
adjacentPoint,
|
|
9180
|
+
edgePoint,
|
|
9320
9181
|
elementsMap
|
|
9321
|
-
)
|
|
9322
|
-
|
|
9323
|
-
|
|
9324
|
-
|
|
9325
|
-
|
|
9326
|
-
|
|
9327
|
-
x = rotatedPoint[0] - element.x;
|
|
9328
|
-
y = rotatedPoint[1] - element.y;
|
|
9329
|
-
}
|
|
9330
|
-
let [A2, B2] = element.points;
|
|
9331
|
-
let P;
|
|
9332
|
-
if (distance2d(A2[0], A2[1], x, y) < threshold || distance2d(B2[0], B2[1], x, y) < threshold) {
|
|
9333
|
-
return true;
|
|
9334
|
-
}
|
|
9335
|
-
for (let i2 = 0; i2 < element.points.length; i2++) {
|
|
9336
|
-
const delta = [B2[0] - A2[0], B2[1] - A2[1]];
|
|
9337
|
-
const length = Math.hypot(delta[1], delta[0]);
|
|
9338
|
-
const U = [delta[0] / length, delta[1] / length];
|
|
9339
|
-
const C2 = [x - A2[0], y - A2[1]];
|
|
9340
|
-
const d = (C2[0] * U[0] + C2[1] * U[1]) / Math.hypot(U[1], U[0]);
|
|
9341
|
-
P = [A2[0] + U[0] * d, A2[1] + U[1] * d];
|
|
9342
|
-
const da = distance2d(P[0], P[1], A2[0], A2[1]);
|
|
9343
|
-
const db = distance2d(P[0], P[1], B2[0], B2[1]);
|
|
9344
|
-
P = db < da && da > length ? B2 : da < db && db > length ? A2 : P;
|
|
9345
|
-
if (Math.hypot(y - P[1], x - P[0]) < threshold) {
|
|
9346
|
-
return true;
|
|
9347
|
-
}
|
|
9348
|
-
A2 = B2;
|
|
9349
|
-
B2 = element.points[i2 + 1];
|
|
9350
|
-
}
|
|
9351
|
-
const shape = ShapeCache.get(element);
|
|
9352
|
-
if (shape && shape.sets.length) {
|
|
9353
|
-
return element.fillStyle === "solid" ? hitTestCurveInside(shape, x, y, "round") : hitTestRoughShape(shape, x, y, threshold);
|
|
9354
|
-
}
|
|
9355
|
-
return false;
|
|
9182
|
+
),
|
|
9183
|
+
gap: Math.max(
|
|
9184
|
+
1,
|
|
9185
|
+
distanceToBindableElement(hoveredElement, edgePoint, elementsMap)
|
|
9186
|
+
)
|
|
9187
|
+
};
|
|
9356
9188
|
};
|
|
9357
|
-
var
|
|
9358
|
-
const
|
|
9359
|
-
|
|
9360
|
-
return false;
|
|
9361
|
-
}
|
|
9362
|
-
const [point2, pointAbs, hwidth, hheight] = pointRelativeToElement(
|
|
9363
|
-
args.element,
|
|
9364
|
-
args.point,
|
|
9365
|
-
args.elementsMap
|
|
9189
|
+
var updateBoundElements = (changedElement, elementsMap, options) => {
|
|
9190
|
+
const boundLinearElements = (changedElement.boundElements ?? []).filter(
|
|
9191
|
+
(el) => el.type === "arrow"
|
|
9366
9192
|
);
|
|
9367
|
-
|
|
9368
|
-
|
|
9369
|
-
if (!isInsideCheck(distanceToLine(pointAbs, side1), threshold) || !isInsideCheck(distanceToLine(pointAbs, side2), threshold)) {
|
|
9370
|
-
return false;
|
|
9371
|
-
}
|
|
9372
|
-
const [relX, relY] = toTuple(point2);
|
|
9373
|
-
const shape = ShapeCache.get(element);
|
|
9374
|
-
if (!shape) {
|
|
9375
|
-
return false;
|
|
9193
|
+
if (boundLinearElements.length === 0) {
|
|
9194
|
+
return;
|
|
9376
9195
|
}
|
|
9377
|
-
|
|
9378
|
-
|
|
9379
|
-
|
|
9380
|
-
|
|
9381
|
-
|
|
9382
|
-
|
|
9383
|
-
|
|
9384
|
-
|
|
9196
|
+
const { newSize, simultaneouslyUpdated } = options ?? {};
|
|
9197
|
+
const simultaneouslyUpdatedElementIds = getSimultaneouslyUpdatedElementIds(
|
|
9198
|
+
simultaneouslyUpdated
|
|
9199
|
+
);
|
|
9200
|
+
const scene = Scene_default.getScene(changedElement);
|
|
9201
|
+
getNonDeletedElements(
|
|
9202
|
+
scene,
|
|
9203
|
+
boundLinearElements.map((el) => el.id)
|
|
9204
|
+
).forEach((element) => {
|
|
9205
|
+
if (!isLinearElement(element)) {
|
|
9206
|
+
return;
|
|
9207
|
+
}
|
|
9208
|
+
const bindableElement = changedElement;
|
|
9209
|
+
if (!doesNeedUpdate(element, bindableElement)) {
|
|
9210
|
+
return;
|
|
9211
|
+
}
|
|
9212
|
+
const startBinding = maybeCalculateNewGapWhenScaling(
|
|
9213
|
+
bindableElement,
|
|
9214
|
+
element.startBinding,
|
|
9215
|
+
newSize
|
|
9385
9216
|
);
|
|
9386
|
-
|
|
9387
|
-
|
|
9217
|
+
const endBinding = maybeCalculateNewGapWhenScaling(
|
|
9218
|
+
bindableElement,
|
|
9219
|
+
element.endBinding,
|
|
9220
|
+
newSize
|
|
9221
|
+
);
|
|
9222
|
+
if (simultaneouslyUpdatedElementIds.has(element.id)) {
|
|
9223
|
+
mutateElement(element, { startBinding, endBinding });
|
|
9224
|
+
return;
|
|
9388
9225
|
}
|
|
9389
|
-
|
|
9390
|
-
|
|
9391
|
-
|
|
9392
|
-
|
|
9393
|
-
|
|
9394
|
-
|
|
9395
|
-
|
|
9396
|
-
|
|
9397
|
-
|
|
9398
|
-
|
|
9399
|
-
|
|
9400
|
-
|
|
9401
|
-
|
|
9402
|
-
|
|
9403
|
-
|
|
9404
|
-
|
|
9405
|
-
|
|
9406
|
-
|
|
9407
|
-
|
|
9408
|
-
|
|
9409
|
-
|
|
9410
|
-
|
|
9411
|
-
const center = coordsCenter(x1, y1, x2, y2);
|
|
9412
|
-
const rotate3 = rotation(center, rectangle2.angle);
|
|
9413
|
-
const pointRotated = apply(rotate3, point2);
|
|
9414
|
-
const pointRelToCenter = sub(pointRotated, from2(center));
|
|
9415
|
-
const pointRelToCenterAbs = abs(pointRelToCenter);
|
|
9416
|
-
const elementPos = offset(rectangle2.x, rectangle2.y);
|
|
9417
|
-
const pointRelToPos = sub(pointRotated, elementPos);
|
|
9418
|
-
const halfWidth = (x2 - x1) / 2;
|
|
9419
|
-
const halfHeight = (y2 - y1) / 2;
|
|
9420
|
-
return [pointRelToPos, pointRelToCenterAbs, halfWidth, halfHeight];
|
|
9421
|
-
};
|
|
9422
|
-
var relativizationToElementCenter = (element, elementsMap) => {
|
|
9423
|
-
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
|
|
9424
|
-
const center = coordsCenter(x1, y1, x2, y2);
|
|
9425
|
-
const rotate3 = rotation(center, element.angle);
|
|
9426
|
-
const translate2 = reverse(
|
|
9427
|
-
translation(from2(center))
|
|
9428
|
-
);
|
|
9429
|
-
return compose(rotate3, translate2);
|
|
9226
|
+
updateBoundPoint(
|
|
9227
|
+
element,
|
|
9228
|
+
"start",
|
|
9229
|
+
startBinding,
|
|
9230
|
+
changedElement,
|
|
9231
|
+
elementsMap
|
|
9232
|
+
);
|
|
9233
|
+
updateBoundPoint(
|
|
9234
|
+
element,
|
|
9235
|
+
"end",
|
|
9236
|
+
endBinding,
|
|
9237
|
+
changedElement,
|
|
9238
|
+
elementsMap
|
|
9239
|
+
);
|
|
9240
|
+
const boundText = getBoundTextElement(
|
|
9241
|
+
element,
|
|
9242
|
+
scene.getNonDeletedElementsMap()
|
|
9243
|
+
);
|
|
9244
|
+
if (boundText) {
|
|
9245
|
+
handleBindTextResize(element, scene.getNonDeletedElementsMap(), false);
|
|
9246
|
+
}
|
|
9247
|
+
});
|
|
9430
9248
|
};
|
|
9431
|
-
var
|
|
9432
|
-
return
|
|
9249
|
+
var doesNeedUpdate = (boundElement, changedElement) => {
|
|
9250
|
+
return boundElement.startBinding?.elementId === changedElement.id || boundElement.endBinding?.elementId === changedElement.id;
|
|
9433
9251
|
};
|
|
9434
|
-
var
|
|
9435
|
-
|
|
9436
|
-
const aRel = apply(relateToCenter, from(a2));
|
|
9437
|
-
const bRel = apply(relateToCenter, from(b2));
|
|
9438
|
-
const line2 = through(aRel, bRel);
|
|
9439
|
-
const q = element.height / element.width;
|
|
9440
|
-
const hwidth = element.width / 2;
|
|
9441
|
-
const hheight = element.height / 2;
|
|
9442
|
-
const n2 = line2[2];
|
|
9443
|
-
const m = line2[3];
|
|
9444
|
-
const c = line2[1];
|
|
9445
|
-
const mabs = Math.abs(m);
|
|
9446
|
-
const nabs = Math.abs(n2);
|
|
9447
|
-
let ret;
|
|
9448
|
-
switch (element.type) {
|
|
9449
|
-
case "rectangle":
|
|
9450
|
-
case "image":
|
|
9451
|
-
case "text":
|
|
9452
|
-
case "iframe":
|
|
9453
|
-
case "embeddable":
|
|
9454
|
-
case "frame":
|
|
9455
|
-
case "magicframe":
|
|
9456
|
-
ret = c / (hwidth * (nabs + q * mabs));
|
|
9457
|
-
break;
|
|
9458
|
-
case "diamond":
|
|
9459
|
-
ret = mabs < nabs ? c / (nabs * hwidth) : c / (mabs * hheight);
|
|
9460
|
-
break;
|
|
9461
|
-
case "ellipse":
|
|
9462
|
-
ret = c / (hwidth * Math.sqrt(n2 ** 2 + q ** 2 * m ** 2));
|
|
9463
|
-
break;
|
|
9464
|
-
}
|
|
9465
|
-
return ret || 0;
|
|
9252
|
+
var getSimultaneouslyUpdatedElementIds = (simultaneouslyUpdated) => {
|
|
9253
|
+
return new Set((simultaneouslyUpdated || []).map((element) => element.id));
|
|
9466
9254
|
};
|
|
9467
|
-
var
|
|
9468
|
-
if (
|
|
9469
|
-
|
|
9470
|
-
|
|
9471
|
-
return toTuple(center);
|
|
9255
|
+
var updateBoundPoint = (linearElement, startOrEnd, binding, changedElement, elementsMap) => {
|
|
9256
|
+
if (binding == null || // We only need to update the other end if this is a 2 point line element
|
|
9257
|
+
binding.elementId !== changedElement.id && linearElement.points.length > 2) {
|
|
9258
|
+
return;
|
|
9472
9259
|
}
|
|
9473
|
-
const
|
|
9474
|
-
|
|
9475
|
-
relateToCenter,
|
|
9476
|
-
from(adjecentPoint)
|
|
9260
|
+
const bindingElement = Scene_default.getScene(linearElement).getElement(
|
|
9261
|
+
binding.elementId
|
|
9477
9262
|
);
|
|
9478
|
-
|
|
9479
|
-
|
|
9480
|
-
switch (element.type) {
|
|
9481
|
-
case "rectangle":
|
|
9482
|
-
case "image":
|
|
9483
|
-
case "text":
|
|
9484
|
-
case "diamond":
|
|
9485
|
-
case "iframe":
|
|
9486
|
-
case "embeddable":
|
|
9487
|
-
case "frame":
|
|
9488
|
-
case "magicframe":
|
|
9489
|
-
point2 = findFocusPointForRectangulars(element, focus, adjecentPointRel);
|
|
9490
|
-
break;
|
|
9491
|
-
case "ellipse":
|
|
9492
|
-
point2 = findFocusPointForEllipse(element, focus, adjecentPointRel);
|
|
9493
|
-
break;
|
|
9263
|
+
if (bindingElement == null) {
|
|
9264
|
+
return;
|
|
9494
9265
|
}
|
|
9495
|
-
|
|
9496
|
-
|
|
9497
|
-
|
|
9498
|
-
const
|
|
9499
|
-
|
|
9500
|
-
|
|
9501
|
-
|
|
9502
|
-
const reverseRelateToCenter = reverse(relateToCenter);
|
|
9503
|
-
const intersections = getSortedElementLineIntersections(
|
|
9504
|
-
element,
|
|
9505
|
-
line2,
|
|
9506
|
-
aRel,
|
|
9507
|
-
gap
|
|
9266
|
+
const direction = startOrEnd === "start" ? -1 : 1;
|
|
9267
|
+
const edgePointIndex = direction === -1 ? 0 : linearElement.points.length - 1;
|
|
9268
|
+
const adjacentPointIndex = edgePointIndex - direction;
|
|
9269
|
+
const adjacentPoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
|
9270
|
+
linearElement,
|
|
9271
|
+
adjacentPointIndex,
|
|
9272
|
+
elementsMap
|
|
9508
9273
|
);
|
|
9509
|
-
|
|
9510
|
-
|
|
9274
|
+
const focusPointAbsolute = determineFocusPoint(
|
|
9275
|
+
bindingElement,
|
|
9276
|
+
binding.focus,
|
|
9277
|
+
adjacentPoint,
|
|
9278
|
+
elementsMap
|
|
9511
9279
|
);
|
|
9512
|
-
|
|
9513
|
-
|
|
9514
|
-
|
|
9515
|
-
|
|
9516
|
-
|
|
9517
|
-
|
|
9518
|
-
|
|
9519
|
-
|
|
9520
|
-
|
|
9521
|
-
|
|
9522
|
-
|
|
9523
|
-
|
|
9524
|
-
|
|
9525
|
-
|
|
9526
|
-
|
|
9527
|
-
|
|
9528
|
-
}).concat(
|
|
9529
|
-
corners.flatMap((point2) => getCircleIntersections(point2, gap, line2))
|
|
9530
|
-
);
|
|
9531
|
-
break;
|
|
9532
|
-
case "ellipse":
|
|
9533
|
-
intersections = getEllipseIntersections(element, gap, line2);
|
|
9534
|
-
break;
|
|
9535
|
-
}
|
|
9536
|
-
if (intersections.length < 2) {
|
|
9537
|
-
return [];
|
|
9280
|
+
let newEdgePoint;
|
|
9281
|
+
if (binding.gap === 0) {
|
|
9282
|
+
newEdgePoint = focusPointAbsolute;
|
|
9283
|
+
} else {
|
|
9284
|
+
const intersections = intersectElementWithLine(
|
|
9285
|
+
bindingElement,
|
|
9286
|
+
adjacentPoint,
|
|
9287
|
+
focusPointAbsolute,
|
|
9288
|
+
binding.gap,
|
|
9289
|
+
elementsMap
|
|
9290
|
+
);
|
|
9291
|
+
if (intersections.length === 0) {
|
|
9292
|
+
newEdgePoint = focusPointAbsolute;
|
|
9293
|
+
} else {
|
|
9294
|
+
newEdgePoint = intersections[0];
|
|
9295
|
+
}
|
|
9538
9296
|
}
|
|
9539
|
-
|
|
9540
|
-
|
|
9297
|
+
LinearElementEditor.movePoints(
|
|
9298
|
+
linearElement,
|
|
9299
|
+
[
|
|
9300
|
+
{
|
|
9301
|
+
index: edgePointIndex,
|
|
9302
|
+
point: LinearElementEditor.pointFromAbsoluteCoords(
|
|
9303
|
+
linearElement,
|
|
9304
|
+
newEdgePoint,
|
|
9305
|
+
elementsMap
|
|
9306
|
+
)
|
|
9307
|
+
}
|
|
9308
|
+
],
|
|
9309
|
+
{ [startOrEnd === "start" ? "startBinding" : "endBinding"]: binding }
|
|
9541
9310
|
);
|
|
9542
|
-
return [
|
|
9543
|
-
sortedIntersections[0],
|
|
9544
|
-
sortedIntersections[sortedIntersections.length - 1]
|
|
9545
|
-
];
|
|
9546
|
-
};
|
|
9547
|
-
var getCorners = (element, scale = 1) => {
|
|
9548
|
-
const hx = scale * element.width / 2;
|
|
9549
|
-
const hy = scale * element.height / 2;
|
|
9550
|
-
switch (element.type) {
|
|
9551
|
-
case "rectangle":
|
|
9552
|
-
case "image":
|
|
9553
|
-
case "text":
|
|
9554
|
-
case "iframe":
|
|
9555
|
-
case "embeddable":
|
|
9556
|
-
case "frame":
|
|
9557
|
-
case "magicframe":
|
|
9558
|
-
return [
|
|
9559
|
-
point(hx, hy),
|
|
9560
|
-
point(hx, -hy),
|
|
9561
|
-
point(-hx, -hy),
|
|
9562
|
-
point(-hx, hy)
|
|
9563
|
-
];
|
|
9564
|
-
case "diamond":
|
|
9565
|
-
return [
|
|
9566
|
-
point(0, hy),
|
|
9567
|
-
point(hx, 0),
|
|
9568
|
-
point(0, -hy),
|
|
9569
|
-
point(-hx, 0)
|
|
9570
|
-
];
|
|
9571
|
-
}
|
|
9572
9311
|
};
|
|
9573
|
-
var
|
|
9574
|
-
|
|
9575
|
-
|
|
9576
|
-
const bDist = distanceToLine(b2, line2);
|
|
9577
|
-
if (aDist * bDist >= 0) {
|
|
9578
|
-
return [];
|
|
9312
|
+
var maybeCalculateNewGapWhenScaling = (changedElement, currentBinding, newSize) => {
|
|
9313
|
+
if (currentBinding == null || newSize == null) {
|
|
9314
|
+
return currentBinding;
|
|
9579
9315
|
}
|
|
9580
|
-
|
|
9581
|
-
};
|
|
9582
|
-
|
|
9583
|
-
const
|
|
9584
|
-
|
|
9585
|
-
|
|
9586
|
-
|
|
9316
|
+
const { gap, focus, elementId } = currentBinding;
|
|
9317
|
+
const { width: newWidth, height: newHeight } = newSize;
|
|
9318
|
+
const { width, height } = changedElement;
|
|
9319
|
+
const newGap = Math.max(
|
|
9320
|
+
1,
|
|
9321
|
+
Math.min(
|
|
9322
|
+
maxBindingGap(changedElement, newWidth, newHeight),
|
|
9323
|
+
gap * (newWidth < newHeight ? newWidth / width : newHeight / height)
|
|
9324
|
+
)
|
|
9587
9325
|
);
|
|
9588
|
-
return
|
|
9326
|
+
return { elementId, gap: newGap, focus };
|
|
9589
9327
|
};
|
|
9590
|
-
var
|
|
9591
|
-
const
|
|
9592
|
-
|
|
9593
|
-
|
|
9594
|
-
|
|
9595
|
-
|
|
9596
|
-
|
|
9597
|
-
|
|
9598
|
-
|
|
9599
|
-
|
|
9600
|
-
|
|
9601
|
-
|
|
9602
|
-
|
|
9603
|
-
const yn = -b2 * b2 * n2 * c;
|
|
9604
|
-
return [
|
|
9605
|
-
point(
|
|
9606
|
-
(xn + a2 * b2 * n2 * discrRoot) / squares,
|
|
9607
|
-
(yn - a2 * b2 * m * discrRoot) / squares
|
|
9608
|
-
),
|
|
9609
|
-
point(
|
|
9610
|
-
(xn - a2 * b2 * n2 * discrRoot) / squares,
|
|
9611
|
-
(yn + a2 * b2 * m * discrRoot) / squares
|
|
9612
|
-
)
|
|
9613
|
-
];
|
|
9328
|
+
var getEligibleElementsForBinding = (selectedElements, app) => {
|
|
9329
|
+
const includedElementIds = new Set(selectedElements.map(({ id }) => id));
|
|
9330
|
+
return selectedElements.flatMap(
|
|
9331
|
+
(selectedElement) => isBindingElement(selectedElement, false) ? getElligibleElementsForBindingElement(
|
|
9332
|
+
selectedElement,
|
|
9333
|
+
app
|
|
9334
|
+
).filter(
|
|
9335
|
+
(element) => !includedElementIds.has(element.id)
|
|
9336
|
+
) : isBindableElement(selectedElement, false) ? getElligibleElementsForBindableElementAndWhere(
|
|
9337
|
+
selectedElement,
|
|
9338
|
+
app
|
|
9339
|
+
).filter((binding) => !includedElementIds.has(binding[0].id)) : []
|
|
9340
|
+
);
|
|
9614
9341
|
};
|
|
9615
|
-
var
|
|
9616
|
-
if (radius === 0) {
|
|
9617
|
-
return distanceToLine(line2, center) === 0 ? [center] : [];
|
|
9618
|
-
}
|
|
9619
|
-
const m = line2[2];
|
|
9620
|
-
const n2 = line2[3];
|
|
9621
|
-
const c = line2[1];
|
|
9622
|
-
const [a2, b2] = toTuple(center);
|
|
9623
|
-
const r = radius;
|
|
9624
|
-
const squares = m * m + n2 * n2;
|
|
9625
|
-
const discr = r * r * squares - (m * a2 + n2 * b2 + c) ** 2;
|
|
9626
|
-
if (squares === 0 || discr <= 0) {
|
|
9627
|
-
return [];
|
|
9628
|
-
}
|
|
9629
|
-
const discrRoot = Math.sqrt(discr);
|
|
9630
|
-
const xn = a2 * n2 * n2 - b2 * m * n2 - m * c;
|
|
9631
|
-
const yn = b2 * m * m - a2 * m * n2 - n2 * c;
|
|
9342
|
+
var getElligibleElementsForBindingElement = (linearElement, app) => {
|
|
9632
9343
|
return [
|
|
9633
|
-
|
|
9634
|
-
|
|
9635
|
-
]
|
|
9344
|
+
getElligibleElementForBindingElement(linearElement, "start", app),
|
|
9345
|
+
getElligibleElementForBindingElement(linearElement, "end", app)
|
|
9346
|
+
].filter(
|
|
9347
|
+
(element) => element != null
|
|
9348
|
+
);
|
|
9636
9349
|
};
|
|
9637
|
-
var
|
|
9638
|
-
|
|
9639
|
-
|
|
9640
|
-
|
|
9641
|
-
|
|
9642
|
-
|
|
9643
|
-
|
|
9644
|
-
|
|
9645
|
-
|
|
9646
|
-
let n2 = (-m * px - 1) / py;
|
|
9647
|
-
if (n2 === 0) {
|
|
9648
|
-
n2 = (Object.is(n2, -0) ? -1 : 1) * 0.01;
|
|
9649
|
-
}
|
|
9650
|
-
const x = -(a2 ** 2 * m) / (n2 ** 2 * b2 ** 2 + m ** 2 * a2 ** 2);
|
|
9651
|
-
return point(x, (-m * x - 1) / n2);
|
|
9350
|
+
var getElligibleElementForBindingElement = (linearElement, startOrEnd, app) => {
|
|
9351
|
+
return getHoveredElementForBinding(
|
|
9352
|
+
getLinearElementEdgeCoors(
|
|
9353
|
+
linearElement,
|
|
9354
|
+
startOrEnd,
|
|
9355
|
+
app.scene.getNonDeletedElementsMap()
|
|
9356
|
+
),
|
|
9357
|
+
app
|
|
9358
|
+
);
|
|
9652
9359
|
};
|
|
9653
|
-
var
|
|
9654
|
-
const
|
|
9655
|
-
|
|
9656
|
-
|
|
9657
|
-
|
|
9658
|
-
|
|
9659
|
-
|
|
9660
|
-
|
|
9661
|
-
|
|
9662
|
-
maxDistance = distance5;
|
|
9663
|
-
tangentPoint = corner;
|
|
9664
|
-
}
|
|
9665
|
-
});
|
|
9666
|
-
return tangentPoint;
|
|
9360
|
+
var getLinearElementEdgeCoors = (linearElement, startOrEnd, elementsMap) => {
|
|
9361
|
+
const index = startOrEnd === "start" ? 0 : -1;
|
|
9362
|
+
return tupleToCoors(
|
|
9363
|
+
LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
|
9364
|
+
linearElement,
|
|
9365
|
+
index,
|
|
9366
|
+
elementsMap
|
|
9367
|
+
)
|
|
9368
|
+
);
|
|
9667
9369
|
};
|
|
9668
|
-
var
|
|
9669
|
-
const
|
|
9670
|
-
|
|
9671
|
-
|
|
9672
|
-
|
|
9673
|
-
const ty = equation2(t2, 1);
|
|
9674
|
-
const diff = Math.sqrt(Math.pow(tx - mx, 2) + Math.pow(ty - my, 2));
|
|
9675
|
-
if (diff < lineThreshold) {
|
|
9676
|
-
return true;
|
|
9370
|
+
var getElligibleElementsForBindableElementAndWhere = (bindableElement, app) => {
|
|
9371
|
+
const scene = Scene_default.getScene(bindableElement);
|
|
9372
|
+
return scene.getNonDeletedElements().map((element) => {
|
|
9373
|
+
if (!isBindingElement(element, false)) {
|
|
9374
|
+
return null;
|
|
9677
9375
|
}
|
|
9678
|
-
|
|
9679
|
-
|
|
9680
|
-
|
|
9376
|
+
const canBindStart = isLinearElementEligibleForNewBindingByBindable(
|
|
9377
|
+
element,
|
|
9378
|
+
"start",
|
|
9379
|
+
bindableElement,
|
|
9380
|
+
scene.getNonDeletedElementsMap(),
|
|
9381
|
+
app
|
|
9382
|
+
);
|
|
9383
|
+
const canBindEnd = isLinearElementEligibleForNewBindingByBindable(
|
|
9384
|
+
element,
|
|
9385
|
+
"end",
|
|
9386
|
+
bindableElement,
|
|
9387
|
+
scene.getNonDeletedElementsMap(),
|
|
9388
|
+
app
|
|
9389
|
+
);
|
|
9390
|
+
if (!canBindStart && !canBindEnd) {
|
|
9391
|
+
return null;
|
|
9392
|
+
}
|
|
9393
|
+
return [
|
|
9394
|
+
element,
|
|
9395
|
+
canBindStart && canBindEnd ? "both" : canBindStart ? "start" : "end",
|
|
9396
|
+
bindableElement
|
|
9397
|
+
];
|
|
9398
|
+
}).filter((maybeElement) => maybeElement != null);
|
|
9681
9399
|
};
|
|
9682
|
-
var
|
|
9683
|
-
const
|
|
9684
|
-
|
|
9685
|
-
|
|
9686
|
-
|
|
9687
|
-
|
|
9688
|
-
|
|
9689
|
-
|
|
9690
|
-
|
|
9400
|
+
var isLinearElementEligibleForNewBindingByBindable = (linearElement, startOrEnd, bindableElement, elementsMap, app) => {
|
|
9401
|
+
const existingBinding = linearElement[startOrEnd === "start" ? "startBinding" : "endBinding"];
|
|
9402
|
+
return existingBinding == null && !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(
|
|
9403
|
+
linearElement,
|
|
9404
|
+
bindableElement,
|
|
9405
|
+
startOrEnd
|
|
9406
|
+
) && bindingBorderTest(
|
|
9407
|
+
bindableElement,
|
|
9408
|
+
getLinearElementEdgeCoors(linearElement, startOrEnd, elementsMap),
|
|
9409
|
+
app
|
|
9410
|
+
);
|
|
9411
|
+
};
|
|
9412
|
+
var fixBindingsAfterDuplication = (sceneElements, oldElements, oldIdToDuplicatedId, duplicatesServeAsOld) => {
|
|
9413
|
+
const allBoundElementIds = /* @__PURE__ */ new Set();
|
|
9414
|
+
const allBindableElementIds = /* @__PURE__ */ new Set();
|
|
9415
|
+
const shouldReverseRoles = duplicatesServeAsOld === "duplicatesServeAsOld";
|
|
9416
|
+
oldElements.forEach((oldElement) => {
|
|
9417
|
+
const { boundElements } = oldElement;
|
|
9418
|
+
if (boundElements != null && boundElements.length > 0) {
|
|
9419
|
+
boundElements.forEach((boundElement) => {
|
|
9420
|
+
if (shouldReverseRoles && !oldIdToDuplicatedId.has(boundElement.id)) {
|
|
9421
|
+
allBoundElementIds.add(boundElement.id);
|
|
9422
|
+
}
|
|
9423
|
+
});
|
|
9424
|
+
allBindableElementIds.add(oldIdToDuplicatedId.get(oldElement.id));
|
|
9425
|
+
}
|
|
9426
|
+
if (isBindingElement(oldElement)) {
|
|
9427
|
+
if (oldElement.startBinding != null) {
|
|
9428
|
+
const { elementId } = oldElement.startBinding;
|
|
9429
|
+
if (shouldReverseRoles && !oldIdToDuplicatedId.has(elementId)) {
|
|
9430
|
+
allBindableElementIds.add(elementId);
|
|
9431
|
+
}
|
|
9691
9432
|
}
|
|
9692
|
-
|
|
9693
|
-
|
|
9694
|
-
|
|
9695
|
-
|
|
9696
|
-
|
|
9433
|
+
if (oldElement.endBinding != null) {
|
|
9434
|
+
const { elementId } = oldElement.endBinding;
|
|
9435
|
+
if (shouldReverseRoles && !oldIdToDuplicatedId.has(elementId)) {
|
|
9436
|
+
allBindableElementIds.add(elementId);
|
|
9437
|
+
}
|
|
9697
9438
|
}
|
|
9698
|
-
|
|
9699
|
-
|
|
9700
|
-
points.push([operation.data[0], operation.data[1]]);
|
|
9439
|
+
if (oldElement.startBinding != null || oldElement.endBinding != null) {
|
|
9440
|
+
allBoundElementIds.add(oldIdToDuplicatedId.get(oldElement.id));
|
|
9701
9441
|
}
|
|
9702
9442
|
}
|
|
9703
|
-
}
|
|
9704
|
-
|
|
9705
|
-
|
|
9706
|
-
|
|
9443
|
+
});
|
|
9444
|
+
sceneElements.filter(
|
|
9445
|
+
({ id }) => allBoundElementIds.has(id)
|
|
9446
|
+
).forEach((element) => {
|
|
9447
|
+
const { startBinding, endBinding } = element;
|
|
9448
|
+
mutateElement(element, {
|
|
9449
|
+
startBinding: newBindingAfterDuplication(
|
|
9450
|
+
startBinding,
|
|
9451
|
+
oldIdToDuplicatedId
|
|
9452
|
+
),
|
|
9453
|
+
endBinding: newBindingAfterDuplication(endBinding, oldIdToDuplicatedId)
|
|
9454
|
+
});
|
|
9455
|
+
});
|
|
9456
|
+
sceneElements.filter(({ id }) => allBindableElementIds.has(id)).forEach((bindableElement) => {
|
|
9457
|
+
const { boundElements } = bindableElement;
|
|
9458
|
+
if (boundElements != null && boundElements.length > 0) {
|
|
9459
|
+
mutateElement(bindableElement, {
|
|
9460
|
+
boundElements: boundElements.map(
|
|
9461
|
+
(boundElement) => oldIdToDuplicatedId.has(boundElement.id) ? {
|
|
9462
|
+
id: oldIdToDuplicatedId.get(boundElement.id),
|
|
9463
|
+
type: boundElement.type
|
|
9464
|
+
} : boundElement
|
|
9465
|
+
)
|
|
9466
|
+
});
|
|
9707
9467
|
}
|
|
9708
|
-
|
|
9709
|
-
|
|
9468
|
+
});
|
|
9469
|
+
};
|
|
9470
|
+
var newBindingAfterDuplication = (binding, oldIdToDuplicatedId) => {
|
|
9471
|
+
if (binding == null) {
|
|
9472
|
+
return null;
|
|
9710
9473
|
}
|
|
9711
|
-
|
|
9474
|
+
const { elementId, focus, gap } = binding;
|
|
9475
|
+
return {
|
|
9476
|
+
focus,
|
|
9477
|
+
gap,
|
|
9478
|
+
elementId: oldIdToDuplicatedId.get(elementId) ?? elementId
|
|
9479
|
+
};
|
|
9712
9480
|
};
|
|
9713
|
-
var
|
|
9714
|
-
const
|
|
9715
|
-
|
|
9716
|
-
|
|
9717
|
-
|
|
9718
|
-
|
|
9719
|
-
|
|
9720
|
-
|
|
9721
|
-
|
|
9722
|
-
|
|
9723
|
-
|
|
9724
|
-
|
|
9725
|
-
|
|
9726
|
-
|
|
9727
|
-
|
|
9728
|
-
|
|
9729
|
-
|
|
9730
|
-
|
|
9731
|
-
|
|
9732
|
-
);
|
|
9733
|
-
return retVal;
|
|
9734
|
-
} else if (op === "lineTo") {
|
|
9735
|
-
return hitTestCurveInside(drawable, x, y, "sharp");
|
|
9736
|
-
} else if (op === "qcurveTo") {
|
|
9737
|
-
console.warn("qcurveTo is not implemented yet");
|
|
9481
|
+
var fixBindingsAfterDeletion = (sceneElements, deletedElements) => {
|
|
9482
|
+
const deletedElementIds = new Set(
|
|
9483
|
+
deletedElements.map((element) => element.id)
|
|
9484
|
+
);
|
|
9485
|
+
const affectedElements = /* @__PURE__ */ new Set();
|
|
9486
|
+
deletedElements.forEach((deletedElement) => {
|
|
9487
|
+
if (isBindableElement(deletedElement)) {
|
|
9488
|
+
deletedElement.boundElements?.forEach((element) => {
|
|
9489
|
+
if (!deletedElementIds.has(element.id)) {
|
|
9490
|
+
affectedElements.add(element.id);
|
|
9491
|
+
}
|
|
9492
|
+
});
|
|
9493
|
+
} else if (isBindingElement(deletedElement)) {
|
|
9494
|
+
if (deletedElement.startBinding) {
|
|
9495
|
+
affectedElements.add(deletedElement.startBinding.elementId);
|
|
9496
|
+
}
|
|
9497
|
+
if (deletedElement.endBinding) {
|
|
9498
|
+
affectedElements.add(deletedElement.endBinding.elementId);
|
|
9499
|
+
}
|
|
9738
9500
|
}
|
|
9739
|
-
return false;
|
|
9740
9501
|
});
|
|
9741
|
-
}
|
|
9742
|
-
|
|
9743
|
-
// keys.ts
|
|
9744
|
-
init_define_import_meta_env();
|
|
9745
|
-
var CODES = {
|
|
9746
|
-
EQUAL: "Equal",
|
|
9747
|
-
MINUS: "Minus",
|
|
9748
|
-
NUM_ADD: "NumpadAdd",
|
|
9749
|
-
NUM_SUBTRACT: "NumpadSubtract",
|
|
9750
|
-
NUM_ZERO: "Numpad0",
|
|
9751
|
-
BRACKET_RIGHT: "BracketRight",
|
|
9752
|
-
BRACKET_LEFT: "BracketLeft",
|
|
9753
|
-
ONE: "Digit1",
|
|
9754
|
-
TWO: "Digit2",
|
|
9755
|
-
THREE: "Digit3",
|
|
9756
|
-
NINE: "Digit9",
|
|
9757
|
-
QUOTE: "Quote",
|
|
9758
|
-
ZERO: "Digit0",
|
|
9759
|
-
SLASH: "Slash",
|
|
9760
|
-
C: "KeyC",
|
|
9761
|
-
D: "KeyD",
|
|
9762
|
-
H: "KeyH",
|
|
9763
|
-
V: "KeyV",
|
|
9764
|
-
Z: "KeyZ",
|
|
9765
|
-
R: "KeyR",
|
|
9766
|
-
S: "KeyS"
|
|
9767
|
-
};
|
|
9768
|
-
var KEYS = {
|
|
9769
|
-
ARROW_DOWN: "ArrowDown",
|
|
9770
|
-
ARROW_LEFT: "ArrowLeft",
|
|
9771
|
-
ARROW_RIGHT: "ArrowRight",
|
|
9772
|
-
ARROW_UP: "ArrowUp",
|
|
9773
|
-
PAGE_UP: "PageUp",
|
|
9774
|
-
PAGE_DOWN: "PageDown",
|
|
9775
|
-
BACKSPACE: "Backspace",
|
|
9776
|
-
ALT: "Alt",
|
|
9777
|
-
CTRL_OR_CMD: isDarwin ? "metaKey" : "ctrlKey",
|
|
9778
|
-
DELETE: "Delete",
|
|
9779
|
-
ENTER: "Enter",
|
|
9780
|
-
ESCAPE: "Escape",
|
|
9781
|
-
QUESTION_MARK: "?",
|
|
9782
|
-
SPACE: " ",
|
|
9783
|
-
TAB: "Tab",
|
|
9784
|
-
CHEVRON_LEFT: "<",
|
|
9785
|
-
CHEVRON_RIGHT: ">",
|
|
9786
|
-
PERIOD: ".",
|
|
9787
|
-
COMMA: ",",
|
|
9788
|
-
SUBTRACT: "-",
|
|
9789
|
-
SLASH: "/",
|
|
9790
|
-
A: "a",
|
|
9791
|
-
C: "c",
|
|
9792
|
-
D: "d",
|
|
9793
|
-
E: "e",
|
|
9794
|
-
F: "f",
|
|
9795
|
-
G: "g",
|
|
9796
|
-
H: "h",
|
|
9797
|
-
I: "i",
|
|
9798
|
-
L: "l",
|
|
9799
|
-
O: "o",
|
|
9800
|
-
P: "p",
|
|
9801
|
-
Q: "q",
|
|
9802
|
-
R: "r",
|
|
9803
|
-
S: "s",
|
|
9804
|
-
T: "t",
|
|
9805
|
-
V: "v",
|
|
9806
|
-
X: "x",
|
|
9807
|
-
Y: "y",
|
|
9808
|
-
Z: "z",
|
|
9809
|
-
K: "k",
|
|
9810
|
-
W: "w",
|
|
9811
|
-
0: "0",
|
|
9812
|
-
1: "1",
|
|
9813
|
-
2: "2",
|
|
9814
|
-
3: "3",
|
|
9815
|
-
4: "4",
|
|
9816
|
-
5: "5",
|
|
9817
|
-
6: "6",
|
|
9818
|
-
7: "7",
|
|
9819
|
-
8: "8",
|
|
9820
|
-
9: "9"
|
|
9821
|
-
};
|
|
9822
|
-
var isArrowKey = (key) => key === KEYS.ARROW_LEFT || key === KEYS.ARROW_RIGHT || key === KEYS.ARROW_DOWN || key === KEYS.ARROW_UP;
|
|
9823
|
-
var shouldResizeFromCenter = (event) => event.altKey;
|
|
9824
|
-
var shouldMaintainAspectRatio = (event) => event.shiftKey;
|
|
9825
|
-
var shouldRotateWithDiscreteAngle = (event) => event.shiftKey;
|
|
9826
|
-
|
|
9827
|
-
// element/binding.ts
|
|
9828
|
-
var shouldEnableBindingForPointerEvent = (event) => {
|
|
9829
|
-
return !event[KEYS.CTRL_OR_CMD];
|
|
9830
|
-
};
|
|
9831
|
-
var isBindingEnabled = (appState) => {
|
|
9832
|
-
return appState.isBindingEnabled;
|
|
9833
|
-
};
|
|
9834
|
-
var getNonDeletedElements = (scene, ids) => {
|
|
9835
|
-
const result = [];
|
|
9836
|
-
ids.forEach((id) => {
|
|
9837
|
-
const element = scene.getNonDeletedElement(id);
|
|
9838
|
-
if (element != null) {
|
|
9839
|
-
result.push(element);
|
|
9840
|
-
}
|
|
9841
|
-
});
|
|
9842
|
-
return result;
|
|
9843
|
-
};
|
|
9844
|
-
var bindOrUnbindLinearElement = (linearElement, startBindingElement, endBindingElement, elementsMap) => {
|
|
9845
|
-
const boundToElementIds = /* @__PURE__ */ new Set();
|
|
9846
|
-
const unboundFromElementIds = /* @__PURE__ */ new Set();
|
|
9847
|
-
bindOrUnbindLinearElementEdge(
|
|
9848
|
-
linearElement,
|
|
9849
|
-
startBindingElement,
|
|
9850
|
-
endBindingElement,
|
|
9851
|
-
"start",
|
|
9852
|
-
boundToElementIds,
|
|
9853
|
-
unboundFromElementIds,
|
|
9854
|
-
elementsMap
|
|
9855
|
-
);
|
|
9856
|
-
bindOrUnbindLinearElementEdge(
|
|
9857
|
-
linearElement,
|
|
9858
|
-
endBindingElement,
|
|
9859
|
-
startBindingElement,
|
|
9860
|
-
"end",
|
|
9861
|
-
boundToElementIds,
|
|
9862
|
-
unboundFromElementIds,
|
|
9863
|
-
elementsMap
|
|
9864
|
-
);
|
|
9865
|
-
const onlyUnbound = Array.from(unboundFromElementIds).filter(
|
|
9866
|
-
(id) => !boundToElementIds.has(id)
|
|
9867
|
-
);
|
|
9868
|
-
getNonDeletedElements(Scene_default.getScene(linearElement), onlyUnbound).forEach(
|
|
9869
|
-
(element) => {
|
|
9502
|
+
sceneElements.filter(({ id }) => affectedElements.has(id)).forEach((element) => {
|
|
9503
|
+
if (isBindableElement(element)) {
|
|
9870
9504
|
mutateElement(element, {
|
|
9871
|
-
boundElements:
|
|
9872
|
-
|
|
9505
|
+
boundElements: newBoundElementsAfterDeletion(
|
|
9506
|
+
element.boundElements,
|
|
9507
|
+
deletedElementIds
|
|
9508
|
+
)
|
|
9509
|
+
});
|
|
9510
|
+
} else if (isBindingElement(element)) {
|
|
9511
|
+
mutateElement(element, {
|
|
9512
|
+
startBinding: newBindingAfterDeletion(
|
|
9513
|
+
element.startBinding,
|
|
9514
|
+
deletedElementIds
|
|
9515
|
+
),
|
|
9516
|
+
endBinding: newBindingAfterDeletion(
|
|
9517
|
+
element.endBinding,
|
|
9518
|
+
deletedElementIds
|
|
9873
9519
|
)
|
|
9874
9520
|
});
|
|
9875
9521
|
}
|
|
9876
|
-
);
|
|
9522
|
+
});
|
|
9877
9523
|
};
|
|
9878
|
-
var
|
|
9879
|
-
if (
|
|
9880
|
-
|
|
9881
|
-
if (otherEdgeBindableElement == null || (otherEdgeBindableElement === "keep" ? !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(
|
|
9882
|
-
linearElement,
|
|
9883
|
-
bindableElement,
|
|
9884
|
-
startOrEnd
|
|
9885
|
-
) : startOrEnd === "start" || otherEdgeBindableElement.id !== bindableElement.id)) {
|
|
9886
|
-
bindLinearElement(
|
|
9887
|
-
linearElement,
|
|
9888
|
-
bindableElement,
|
|
9889
|
-
startOrEnd,
|
|
9890
|
-
elementsMap
|
|
9891
|
-
);
|
|
9892
|
-
boundToElementIds.add(bindableElement.id);
|
|
9893
|
-
}
|
|
9894
|
-
} else {
|
|
9895
|
-
const unbound = unbindLinearElement(linearElement, startOrEnd);
|
|
9896
|
-
if (unbound != null) {
|
|
9897
|
-
unboundFromElementIds.add(unbound);
|
|
9898
|
-
}
|
|
9899
|
-
}
|
|
9524
|
+
var newBindingAfterDeletion = (binding, deletedElementIds) => {
|
|
9525
|
+
if (binding == null || deletedElementIds.has(binding.elementId)) {
|
|
9526
|
+
return null;
|
|
9900
9527
|
}
|
|
9528
|
+
return binding;
|
|
9901
9529
|
};
|
|
9902
|
-
var
|
|
9903
|
-
|
|
9904
|
-
|
|
9905
|
-
|
|
9906
|
-
|
|
9907
|
-
getElligibleElementForBindingElement(
|
|
9908
|
-
selectedElement,
|
|
9909
|
-
"start",
|
|
9910
|
-
elements,
|
|
9911
|
-
elementsMap
|
|
9912
|
-
),
|
|
9913
|
-
getElligibleElementForBindingElement(
|
|
9914
|
-
selectedElement,
|
|
9915
|
-
"end",
|
|
9916
|
-
elements,
|
|
9917
|
-
elementsMap
|
|
9918
|
-
),
|
|
9919
|
-
elementsMap
|
|
9920
|
-
);
|
|
9921
|
-
} else if (isBindableElement(selectedElement)) {
|
|
9922
|
-
maybeBindBindableElement(selectedElement, elementsMap);
|
|
9923
|
-
}
|
|
9924
|
-
});
|
|
9530
|
+
var newBoundElementsAfterDeletion = (boundElements, deletedElementIds) => {
|
|
9531
|
+
if (!boundElements) {
|
|
9532
|
+
return null;
|
|
9533
|
+
}
|
|
9534
|
+
return boundElements.filter((ele) => !deletedElementIds.has(ele.id));
|
|
9925
9535
|
};
|
|
9926
|
-
var
|
|
9927
|
-
|
|
9928
|
-
|
|
9536
|
+
var bindingBorderTest = (element, { x, y }, app) => {
|
|
9537
|
+
const threshold = maxBindingGap(element, element.width, element.height);
|
|
9538
|
+
const shape = app.getElementShape(element);
|
|
9539
|
+
return isPointOnShape([x, y], shape, threshold);
|
|
9540
|
+
};
|
|
9541
|
+
var maxBindingGap = (element, elementWidth, elementHeight) => {
|
|
9542
|
+
const shapeRatio = element.type === "diamond" ? 1 / Math.sqrt(2) : 1;
|
|
9543
|
+
const smallerDimension = shapeRatio * Math.min(elementWidth, elementHeight);
|
|
9544
|
+
return Math.max(16, Math.min(0.25 * smallerDimension, 32));
|
|
9545
|
+
};
|
|
9546
|
+
var distanceToBindableElement = (element, point2, elementsMap) => {
|
|
9547
|
+
switch (element.type) {
|
|
9548
|
+
case "rectangle":
|
|
9549
|
+
case "image":
|
|
9550
|
+
case "text":
|
|
9551
|
+
case "iframe":
|
|
9552
|
+
case "embeddable":
|
|
9553
|
+
case "frame":
|
|
9554
|
+
case "magicframe":
|
|
9555
|
+
return distanceToRectangle(element, point2, elementsMap);
|
|
9556
|
+
case "diamond":
|
|
9557
|
+
return distanceToDiamond(element, point2, elementsMap);
|
|
9558
|
+
case "ellipse":
|
|
9559
|
+
return distanceToEllipse2(element, point2, elementsMap);
|
|
9560
|
+
}
|
|
9561
|
+
};
|
|
9562
|
+
var distanceToRectangle = (element, point2, elementsMap) => {
|
|
9563
|
+
const [, pointRel, hwidth, hheight] = pointRelativeToElement(
|
|
9564
|
+
element,
|
|
9565
|
+
point2,
|
|
9929
9566
|
elementsMap
|
|
9930
|
-
)
|
|
9931
|
-
|
|
9932
|
-
|
|
9933
|
-
|
|
9934
|
-
where === "start" ? "keep" : bindableElement,
|
|
9935
|
-
elementsMap
|
|
9936
|
-
)
|
|
9567
|
+
);
|
|
9568
|
+
return Math.max(
|
|
9569
|
+
distanceToLine(pointRel, equation(0, 1, -hheight)),
|
|
9570
|
+
distanceToLine(pointRel, equation(1, 0, -hwidth))
|
|
9937
9571
|
);
|
|
9938
9572
|
};
|
|
9939
|
-
var
|
|
9940
|
-
|
|
9941
|
-
|
|
9942
|
-
|
|
9943
|
-
appState.startBoundElement,
|
|
9944
|
-
"start",
|
|
9945
|
-
elementsMap
|
|
9946
|
-
);
|
|
9947
|
-
}
|
|
9948
|
-
const hoveredElement = getHoveredElementForBinding(
|
|
9949
|
-
pointerCoords,
|
|
9950
|
-
scene.getNonDeletedElements(),
|
|
9573
|
+
var distanceToDiamond = (element, point2, elementsMap) => {
|
|
9574
|
+
const [, pointRel, hwidth, hheight] = pointRelativeToElement(
|
|
9575
|
+
element,
|
|
9576
|
+
point2,
|
|
9951
9577
|
elementsMap
|
|
9952
9578
|
);
|
|
9953
|
-
|
|
9954
|
-
|
|
9955
|
-
hoveredElement,
|
|
9956
|
-
"end"
|
|
9957
|
-
)) {
|
|
9958
|
-
bindLinearElement(linearElement, hoveredElement, "end", elementsMap);
|
|
9959
|
-
}
|
|
9579
|
+
const side = equation(hheight, hwidth, -hheight * hwidth);
|
|
9580
|
+
return distanceToLine(pointRel, side);
|
|
9960
9581
|
};
|
|
9961
|
-
var
|
|
9962
|
-
|
|
9963
|
-
|
|
9964
|
-
elementId: hoveredElement.id,
|
|
9965
|
-
...calculateFocusAndGap(
|
|
9966
|
-
linearElement,
|
|
9967
|
-
hoveredElement,
|
|
9968
|
-
startOrEnd,
|
|
9969
|
-
elementsMap
|
|
9970
|
-
)
|
|
9971
|
-
}
|
|
9972
|
-
});
|
|
9973
|
-
const boundElementsMap = arrayToMap(hoveredElement.boundElements || []);
|
|
9974
|
-
if (!boundElementsMap.has(linearElement.id)) {
|
|
9975
|
-
mutateElement(hoveredElement, {
|
|
9976
|
-
boundElements: (hoveredElement.boundElements || []).concat({
|
|
9977
|
-
id: linearElement.id,
|
|
9978
|
-
type: "arrow"
|
|
9979
|
-
})
|
|
9980
|
-
});
|
|
9981
|
-
}
|
|
9582
|
+
var distanceToEllipse2 = (element, point2, elementsMap) => {
|
|
9583
|
+
const [pointRel, tangent] = ellipseParamsForTest(element, point2, elementsMap);
|
|
9584
|
+
return -sign(tangent) * distanceToLine(pointRel, tangent);
|
|
9982
9585
|
};
|
|
9983
|
-
var
|
|
9984
|
-
const
|
|
9985
|
-
|
|
9986
|
-
|
|
9987
|
-
|
|
9988
|
-
bindableElement
|
|
9586
|
+
var ellipseParamsForTest = (element, point2, elementsMap) => {
|
|
9587
|
+
const [, pointRel, hwidth, hheight] = pointRelativeToElement(
|
|
9588
|
+
element,
|
|
9589
|
+
point2,
|
|
9590
|
+
elementsMap
|
|
9989
9591
|
);
|
|
9990
|
-
|
|
9991
|
-
|
|
9992
|
-
|
|
9993
|
-
|
|
9994
|
-
|
|
9995
|
-
|
|
9996
|
-
|
|
9997
|
-
|
|
9998
|
-
|
|
9592
|
+
const [px, py] = toTuple(pointRel);
|
|
9593
|
+
let tx = 0.707;
|
|
9594
|
+
let ty = 0.707;
|
|
9595
|
+
const a2 = hwidth;
|
|
9596
|
+
const b2 = hheight;
|
|
9597
|
+
[0, 1, 2, 3].forEach((_) => {
|
|
9598
|
+
const xx = a2 * tx;
|
|
9599
|
+
const yy = b2 * ty;
|
|
9600
|
+
const ex = (a2 * a2 - b2 * b2) * tx ** 3 / a2;
|
|
9601
|
+
const ey = (b2 * b2 - a2 * a2) * ty ** 3 / b2;
|
|
9602
|
+
const rx = xx - ex;
|
|
9603
|
+
const ry = yy - ey;
|
|
9604
|
+
const qx = px - ex;
|
|
9605
|
+
const qy = py - ey;
|
|
9606
|
+
const r = Math.hypot(ry, rx);
|
|
9607
|
+
const q = Math.hypot(qy, qx);
|
|
9608
|
+
tx = Math.min(1, Math.max(0, (qx * r / q + ex) / a2));
|
|
9609
|
+
ty = Math.min(1, Math.max(0, (qy * r / q + ey) / b2));
|
|
9610
|
+
const t2 = Math.hypot(ty, tx);
|
|
9611
|
+
tx /= t2;
|
|
9612
|
+
ty /= t2;
|
|
9999
9613
|
});
|
|
9614
|
+
const closestPoint = point(a2 * tx, b2 * ty);
|
|
9615
|
+
const tangent = orthogonalThrough(pointRel, closestPoint);
|
|
9616
|
+
return [pointRel, tangent];
|
|
10000
9617
|
};
|
|
10001
|
-
var
|
|
10002
|
-
const
|
|
10003
|
-
const
|
|
10004
|
-
|
|
10005
|
-
|
|
10006
|
-
|
|
10007
|
-
|
|
10008
|
-
|
|
9618
|
+
var pointRelativeToElement = (element, pointTuple, elementsMap) => {
|
|
9619
|
+
const point2 = from(pointTuple);
|
|
9620
|
+
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
|
|
9621
|
+
const center = coordsCenter(x1, y1, x2, y2);
|
|
9622
|
+
const rotate4 = rotation(center, element.angle);
|
|
9623
|
+
const pointRotated = apply(rotate4, point2);
|
|
9624
|
+
const pointRelToCenter = sub(pointRotated, from2(center));
|
|
9625
|
+
const pointRelToCenterAbs = abs(pointRelToCenter);
|
|
9626
|
+
const elementPos = offset(element.x, element.y);
|
|
9627
|
+
const pointRelToPos = sub(pointRotated, elementPos);
|
|
9628
|
+
const halfWidth = (x2 - x1) / 2;
|
|
9629
|
+
const halfHeight = (y2 - y1) / 2;
|
|
9630
|
+
return [pointRelToPos, pointRelToCenterAbs, halfWidth, halfHeight];
|
|
10009
9631
|
};
|
|
10010
|
-
var
|
|
10011
|
-
const
|
|
10012
|
-
|
|
10013
|
-
|
|
9632
|
+
var relativizationToElementCenter = (element, elementsMap) => {
|
|
9633
|
+
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
|
|
9634
|
+
const center = coordsCenter(x1, y1, x2, y2);
|
|
9635
|
+
const rotate4 = rotation(center, element.angle);
|
|
9636
|
+
const translate2 = reverse(
|
|
9637
|
+
translation(from2(center))
|
|
10014
9638
|
);
|
|
10015
|
-
return
|
|
9639
|
+
return compose(rotate4, translate2);
|
|
10016
9640
|
};
|
|
10017
|
-
var
|
|
10018
|
-
|
|
10019
|
-
const edgePointIndex = direction === -1 ? 0 : linearElement.points.length - 1;
|
|
10020
|
-
const adjacentPointIndex = edgePointIndex - direction;
|
|
10021
|
-
const edgePoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
|
10022
|
-
linearElement,
|
|
10023
|
-
edgePointIndex,
|
|
10024
|
-
elementsMap
|
|
10025
|
-
);
|
|
10026
|
-
const adjacentPoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
|
10027
|
-
linearElement,
|
|
10028
|
-
adjacentPointIndex,
|
|
10029
|
-
elementsMap
|
|
10030
|
-
);
|
|
10031
|
-
return {
|
|
10032
|
-
focus: determineFocusDistance(
|
|
10033
|
-
hoveredElement,
|
|
10034
|
-
adjacentPoint,
|
|
10035
|
-
edgePoint,
|
|
10036
|
-
elementsMap
|
|
10037
|
-
),
|
|
10038
|
-
gap: Math.max(
|
|
10039
|
-
1,
|
|
10040
|
-
distanceToBindableElement(hoveredElement, edgePoint, elementsMap)
|
|
10041
|
-
)
|
|
10042
|
-
};
|
|
9641
|
+
var coordsCenter = (x1, y1, x2, y2) => {
|
|
9642
|
+
return point((x1 + x2) / 2, (y1 + y2) / 2);
|
|
10043
9643
|
};
|
|
10044
|
-
var
|
|
10045
|
-
const
|
|
10046
|
-
|
|
10047
|
-
);
|
|
10048
|
-
|
|
10049
|
-
|
|
9644
|
+
var determineFocusDistance = (element, a2, b2, elementsMap) => {
|
|
9645
|
+
const relateToCenter = relativizationToElementCenter(element, elementsMap);
|
|
9646
|
+
const aRel = apply(relateToCenter, from(a2));
|
|
9647
|
+
const bRel = apply(relateToCenter, from(b2));
|
|
9648
|
+
const line2 = through(aRel, bRel);
|
|
9649
|
+
const q = element.height / element.width;
|
|
9650
|
+
const hwidth = element.width / 2;
|
|
9651
|
+
const hheight = element.height / 2;
|
|
9652
|
+
const n2 = line2[2];
|
|
9653
|
+
const m = line2[3];
|
|
9654
|
+
const c = line2[1];
|
|
9655
|
+
const mabs = Math.abs(m);
|
|
9656
|
+
const nabs = Math.abs(n2);
|
|
9657
|
+
let ret;
|
|
9658
|
+
switch (element.type) {
|
|
9659
|
+
case "rectangle":
|
|
9660
|
+
case "image":
|
|
9661
|
+
case "text":
|
|
9662
|
+
case "iframe":
|
|
9663
|
+
case "embeddable":
|
|
9664
|
+
case "frame":
|
|
9665
|
+
case "magicframe":
|
|
9666
|
+
ret = c / (hwidth * (nabs + q * mabs));
|
|
9667
|
+
break;
|
|
9668
|
+
case "diamond":
|
|
9669
|
+
ret = mabs < nabs ? c / (nabs * hwidth) : c / (mabs * hheight);
|
|
9670
|
+
break;
|
|
9671
|
+
case "ellipse":
|
|
9672
|
+
ret = c / (hwidth * Math.sqrt(n2 ** 2 + q ** 2 * m ** 2));
|
|
9673
|
+
break;
|
|
10050
9674
|
}
|
|
10051
|
-
|
|
10052
|
-
const simultaneouslyUpdatedElementIds = getSimultaneouslyUpdatedElementIds(
|
|
10053
|
-
simultaneouslyUpdated
|
|
10054
|
-
);
|
|
10055
|
-
const scene = Scene_default.getScene(changedElement);
|
|
10056
|
-
getNonDeletedElements(
|
|
10057
|
-
scene,
|
|
10058
|
-
boundLinearElements.map((el) => el.id)
|
|
10059
|
-
).forEach((element) => {
|
|
10060
|
-
if (!isLinearElement(element)) {
|
|
10061
|
-
return;
|
|
10062
|
-
}
|
|
10063
|
-
const bindableElement = changedElement;
|
|
10064
|
-
if (!doesNeedUpdate(element, bindableElement)) {
|
|
10065
|
-
return;
|
|
10066
|
-
}
|
|
10067
|
-
const startBinding = maybeCalculateNewGapWhenScaling(
|
|
10068
|
-
bindableElement,
|
|
10069
|
-
element.startBinding,
|
|
10070
|
-
newSize
|
|
10071
|
-
);
|
|
10072
|
-
const endBinding = maybeCalculateNewGapWhenScaling(
|
|
10073
|
-
bindableElement,
|
|
10074
|
-
element.endBinding,
|
|
10075
|
-
newSize
|
|
10076
|
-
);
|
|
10077
|
-
if (simultaneouslyUpdatedElementIds.has(element.id)) {
|
|
10078
|
-
mutateElement(element, { startBinding, endBinding });
|
|
10079
|
-
return;
|
|
10080
|
-
}
|
|
10081
|
-
updateBoundPoint(
|
|
10082
|
-
element,
|
|
10083
|
-
"start",
|
|
10084
|
-
startBinding,
|
|
10085
|
-
changedElement,
|
|
10086
|
-
elementsMap
|
|
10087
|
-
);
|
|
10088
|
-
updateBoundPoint(
|
|
10089
|
-
element,
|
|
10090
|
-
"end",
|
|
10091
|
-
endBinding,
|
|
10092
|
-
changedElement,
|
|
10093
|
-
elementsMap
|
|
10094
|
-
);
|
|
10095
|
-
const boundText = getBoundTextElement(
|
|
10096
|
-
element,
|
|
10097
|
-
scene.getNonDeletedElementsMap()
|
|
10098
|
-
);
|
|
10099
|
-
if (boundText) {
|
|
10100
|
-
handleBindTextResize(element, scene.getNonDeletedElementsMap(), false);
|
|
10101
|
-
}
|
|
10102
|
-
});
|
|
10103
|
-
};
|
|
10104
|
-
var doesNeedUpdate = (boundElement, changedElement) => {
|
|
10105
|
-
return boundElement.startBinding?.elementId === changedElement.id || boundElement.endBinding?.elementId === changedElement.id;
|
|
10106
|
-
};
|
|
10107
|
-
var getSimultaneouslyUpdatedElementIds = (simultaneouslyUpdated) => {
|
|
10108
|
-
return new Set((simultaneouslyUpdated || []).map((element) => element.id));
|
|
9675
|
+
return ret || 0;
|
|
10109
9676
|
};
|
|
10110
|
-
var
|
|
10111
|
-
if (
|
|
10112
|
-
|
|
10113
|
-
|
|
9677
|
+
var determineFocusPoint = (element, focus, adjecentPoint, elementsMap) => {
|
|
9678
|
+
if (focus === 0) {
|
|
9679
|
+
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
|
|
9680
|
+
const center = coordsCenter(x1, y1, x2, y2);
|
|
9681
|
+
return toTuple(center);
|
|
10114
9682
|
}
|
|
10115
|
-
const
|
|
10116
|
-
|
|
9683
|
+
const relateToCenter = relativizationToElementCenter(element, elementsMap);
|
|
9684
|
+
const adjecentPointRel = apply(
|
|
9685
|
+
relateToCenter,
|
|
9686
|
+
from(adjecentPoint)
|
|
10117
9687
|
);
|
|
10118
|
-
|
|
10119
|
-
|
|
9688
|
+
const reverseRelateToCenter = reverse(relateToCenter);
|
|
9689
|
+
let point2;
|
|
9690
|
+
switch (element.type) {
|
|
9691
|
+
case "rectangle":
|
|
9692
|
+
case "image":
|
|
9693
|
+
case "text":
|
|
9694
|
+
case "diamond":
|
|
9695
|
+
case "iframe":
|
|
9696
|
+
case "embeddable":
|
|
9697
|
+
case "frame":
|
|
9698
|
+
case "magicframe":
|
|
9699
|
+
point2 = findFocusPointForRectangulars(element, focus, adjecentPointRel);
|
|
9700
|
+
break;
|
|
9701
|
+
case "ellipse":
|
|
9702
|
+
point2 = findFocusPointForEllipse(element, focus, adjecentPointRel);
|
|
9703
|
+
break;
|
|
10120
9704
|
}
|
|
10121
|
-
|
|
10122
|
-
|
|
10123
|
-
|
|
10124
|
-
const
|
|
10125
|
-
|
|
10126
|
-
|
|
10127
|
-
|
|
10128
|
-
);
|
|
10129
|
-
const
|
|
10130
|
-
|
|
10131
|
-
|
|
10132
|
-
|
|
10133
|
-
|
|
9705
|
+
return toTuple(apply(reverseRelateToCenter, point2));
|
|
9706
|
+
};
|
|
9707
|
+
var intersectElementWithLine = (element, a2, b2, gap = 0, elementsMap) => {
|
|
9708
|
+
const relateToCenter = relativizationToElementCenter(element, elementsMap);
|
|
9709
|
+
const aRel = apply(relateToCenter, from(a2));
|
|
9710
|
+
const bRel = apply(relateToCenter, from(b2));
|
|
9711
|
+
const line2 = through(aRel, bRel);
|
|
9712
|
+
const reverseRelateToCenter = reverse(relateToCenter);
|
|
9713
|
+
const intersections = getSortedElementLineIntersections(
|
|
9714
|
+
element,
|
|
9715
|
+
line2,
|
|
9716
|
+
aRel,
|
|
9717
|
+
gap
|
|
10134
9718
|
);
|
|
10135
|
-
|
|
10136
|
-
|
|
10137
|
-
newEdgePoint = focusPointAbsolute;
|
|
10138
|
-
} else {
|
|
10139
|
-
const intersections = intersectElementWithLine(
|
|
10140
|
-
bindingElement,
|
|
10141
|
-
adjacentPoint,
|
|
10142
|
-
focusPointAbsolute,
|
|
10143
|
-
binding.gap,
|
|
10144
|
-
elementsMap
|
|
10145
|
-
);
|
|
10146
|
-
if (intersections.length === 0) {
|
|
10147
|
-
newEdgePoint = focusPointAbsolute;
|
|
10148
|
-
} else {
|
|
10149
|
-
newEdgePoint = intersections[0];
|
|
10150
|
-
}
|
|
10151
|
-
}
|
|
10152
|
-
LinearElementEditor.movePoints(
|
|
10153
|
-
linearElement,
|
|
10154
|
-
[
|
|
10155
|
-
{
|
|
10156
|
-
index: edgePointIndex,
|
|
10157
|
-
point: LinearElementEditor.pointFromAbsoluteCoords(
|
|
10158
|
-
linearElement,
|
|
10159
|
-
newEdgePoint,
|
|
10160
|
-
elementsMap
|
|
10161
|
-
)
|
|
10162
|
-
}
|
|
10163
|
-
],
|
|
10164
|
-
{ [startOrEnd === "start" ? "startBinding" : "endBinding"]: binding }
|
|
9719
|
+
return intersections.map(
|
|
9720
|
+
(point2) => toTuple(apply(reverseRelateToCenter, point2))
|
|
10165
9721
|
);
|
|
10166
9722
|
};
|
|
10167
|
-
var
|
|
10168
|
-
|
|
10169
|
-
|
|
9723
|
+
var getSortedElementLineIntersections = (element, line2, nearPoint, gap = 0) => {
|
|
9724
|
+
let intersections;
|
|
9725
|
+
switch (element.type) {
|
|
9726
|
+
case "rectangle":
|
|
9727
|
+
case "image":
|
|
9728
|
+
case "text":
|
|
9729
|
+
case "diamond":
|
|
9730
|
+
case "iframe":
|
|
9731
|
+
case "embeddable":
|
|
9732
|
+
case "frame":
|
|
9733
|
+
case "magicframe":
|
|
9734
|
+
const corners = getCorners(element);
|
|
9735
|
+
intersections = corners.flatMap((point2, i2) => {
|
|
9736
|
+
const edge = [point2, corners[(i2 + 1) % 4]];
|
|
9737
|
+
return intersectSegment(line2, offsetSegment(edge, gap));
|
|
9738
|
+
}).concat(
|
|
9739
|
+
corners.flatMap((point2) => getCircleIntersections(point2, gap, line2))
|
|
9740
|
+
);
|
|
9741
|
+
break;
|
|
9742
|
+
case "ellipse":
|
|
9743
|
+
intersections = getEllipseIntersections(element, gap, line2);
|
|
9744
|
+
break;
|
|
10170
9745
|
}
|
|
10171
|
-
|
|
10172
|
-
|
|
10173
|
-
|
|
10174
|
-
const
|
|
10175
|
-
|
|
10176
|
-
Math.min(
|
|
10177
|
-
maxBindingGap(changedElement, newWidth, newHeight),
|
|
10178
|
-
gap * (newWidth < newHeight ? newWidth / width : newHeight / height)
|
|
10179
|
-
)
|
|
10180
|
-
);
|
|
10181
|
-
return { elementId, gap: newGap, focus };
|
|
10182
|
-
};
|
|
10183
|
-
var getEligibleElementsForBinding = (selectedElements, elements, elementsMap) => {
|
|
10184
|
-
const includedElementIds = new Set(selectedElements.map(({ id }) => id));
|
|
10185
|
-
return selectedElements.flatMap(
|
|
10186
|
-
(selectedElement) => isBindingElement(selectedElement, false) ? getElligibleElementsForBindingElement(
|
|
10187
|
-
selectedElement,
|
|
10188
|
-
elements,
|
|
10189
|
-
elementsMap
|
|
10190
|
-
).filter(
|
|
10191
|
-
(element) => !includedElementIds.has(element.id)
|
|
10192
|
-
) : isBindableElement(selectedElement, false) ? getElligibleElementsForBindableElementAndWhere(
|
|
10193
|
-
selectedElement,
|
|
10194
|
-
elementsMap
|
|
10195
|
-
).filter((binding) => !includedElementIds.has(binding[0].id)) : []
|
|
9746
|
+
if (intersections.length < 2) {
|
|
9747
|
+
return [];
|
|
9748
|
+
}
|
|
9749
|
+
const sortedIntersections = intersections.sort(
|
|
9750
|
+
(i1, i2) => distance3(i1, nearPoint) - distance3(i2, nearPoint)
|
|
10196
9751
|
);
|
|
10197
|
-
};
|
|
10198
|
-
var getElligibleElementsForBindingElement = (linearElement, elements, elementsMap) => {
|
|
10199
9752
|
return [
|
|
10200
|
-
|
|
10201
|
-
|
|
10202
|
-
|
|
10203
|
-
elements,
|
|
10204
|
-
elementsMap
|
|
10205
|
-
),
|
|
10206
|
-
getElligibleElementForBindingElement(
|
|
10207
|
-
linearElement,
|
|
10208
|
-
"end",
|
|
10209
|
-
elements,
|
|
10210
|
-
elementsMap
|
|
10211
|
-
)
|
|
10212
|
-
].filter(
|
|
10213
|
-
(element) => element != null
|
|
10214
|
-
);
|
|
10215
|
-
};
|
|
10216
|
-
var getElligibleElementForBindingElement = (linearElement, startOrEnd, elements, elementsMap) => {
|
|
10217
|
-
return getHoveredElementForBinding(
|
|
10218
|
-
getLinearElementEdgeCoors(linearElement, startOrEnd, elementsMap),
|
|
10219
|
-
elements,
|
|
10220
|
-
elementsMap
|
|
10221
|
-
);
|
|
10222
|
-
};
|
|
10223
|
-
var getLinearElementEdgeCoors = (linearElement, startOrEnd, elementsMap) => {
|
|
10224
|
-
const index = startOrEnd === "start" ? 0 : -1;
|
|
10225
|
-
return tupleToCoors(
|
|
10226
|
-
LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
|
10227
|
-
linearElement,
|
|
10228
|
-
index,
|
|
10229
|
-
elementsMap
|
|
10230
|
-
)
|
|
10231
|
-
);
|
|
10232
|
-
};
|
|
10233
|
-
var getElligibleElementsForBindableElementAndWhere = (bindableElement, elementsMap) => {
|
|
10234
|
-
const scene = Scene_default.getScene(bindableElement);
|
|
10235
|
-
return scene.getNonDeletedElements().map((element) => {
|
|
10236
|
-
if (!isBindingElement(element, false)) {
|
|
10237
|
-
return null;
|
|
10238
|
-
}
|
|
10239
|
-
const canBindStart = isLinearElementEligibleForNewBindingByBindable(
|
|
10240
|
-
element,
|
|
10241
|
-
"start",
|
|
10242
|
-
bindableElement,
|
|
10243
|
-
elementsMap
|
|
10244
|
-
);
|
|
10245
|
-
const canBindEnd = isLinearElementEligibleForNewBindingByBindable(
|
|
10246
|
-
element,
|
|
10247
|
-
"end",
|
|
10248
|
-
bindableElement,
|
|
10249
|
-
elementsMap
|
|
10250
|
-
);
|
|
10251
|
-
if (!canBindStart && !canBindEnd) {
|
|
10252
|
-
return null;
|
|
10253
|
-
}
|
|
10254
|
-
return [
|
|
10255
|
-
element,
|
|
10256
|
-
canBindStart && canBindEnd ? "both" : canBindStart ? "start" : "end",
|
|
10257
|
-
bindableElement
|
|
10258
|
-
];
|
|
10259
|
-
}).filter((maybeElement) => maybeElement != null);
|
|
10260
|
-
};
|
|
10261
|
-
var isLinearElementEligibleForNewBindingByBindable = (linearElement, startOrEnd, bindableElement, elementsMap) => {
|
|
10262
|
-
const existingBinding = linearElement[startOrEnd === "start" ? "startBinding" : "endBinding"];
|
|
10263
|
-
return existingBinding == null && !isLinearElementSimpleAndAlreadyBoundOnOppositeEdge(
|
|
10264
|
-
linearElement,
|
|
10265
|
-
bindableElement,
|
|
10266
|
-
startOrEnd
|
|
10267
|
-
) && bindingBorderTest(
|
|
10268
|
-
bindableElement,
|
|
10269
|
-
getLinearElementEdgeCoors(linearElement, startOrEnd, elementsMap),
|
|
10270
|
-
elementsMap
|
|
10271
|
-
);
|
|
9753
|
+
sortedIntersections[0],
|
|
9754
|
+
sortedIntersections[sortedIntersections.length - 1]
|
|
9755
|
+
];
|
|
10272
9756
|
};
|
|
10273
|
-
var
|
|
10274
|
-
const
|
|
10275
|
-
const
|
|
10276
|
-
|
|
10277
|
-
|
|
10278
|
-
|
|
10279
|
-
|
|
10280
|
-
|
|
10281
|
-
|
|
10282
|
-
|
|
10283
|
-
|
|
10284
|
-
|
|
10285
|
-
|
|
10286
|
-
|
|
10287
|
-
|
|
10288
|
-
|
|
10289
|
-
|
|
10290
|
-
|
|
10291
|
-
|
|
10292
|
-
|
|
10293
|
-
|
|
10294
|
-
|
|
10295
|
-
|
|
10296
|
-
|
|
10297
|
-
|
|
10298
|
-
}
|
|
10299
|
-
}
|
|
10300
|
-
if (oldElement.startBinding != null || oldElement.endBinding != null) {
|
|
10301
|
-
allBoundElementIds.add(oldIdToDuplicatedId.get(oldElement.id));
|
|
10302
|
-
}
|
|
10303
|
-
}
|
|
10304
|
-
});
|
|
10305
|
-
sceneElements.filter(
|
|
10306
|
-
({ id }) => allBoundElementIds.has(id)
|
|
10307
|
-
).forEach((element) => {
|
|
10308
|
-
const { startBinding, endBinding } = element;
|
|
10309
|
-
mutateElement(element, {
|
|
10310
|
-
startBinding: newBindingAfterDuplication(
|
|
10311
|
-
startBinding,
|
|
10312
|
-
oldIdToDuplicatedId
|
|
10313
|
-
),
|
|
10314
|
-
endBinding: newBindingAfterDuplication(endBinding, oldIdToDuplicatedId)
|
|
10315
|
-
});
|
|
10316
|
-
});
|
|
10317
|
-
sceneElements.filter(({ id }) => allBindableElementIds.has(id)).forEach((bindableElement) => {
|
|
10318
|
-
const { boundElements } = bindableElement;
|
|
10319
|
-
if (boundElements != null && boundElements.length > 0) {
|
|
10320
|
-
mutateElement(bindableElement, {
|
|
10321
|
-
boundElements: boundElements.map(
|
|
10322
|
-
(boundElement) => oldIdToDuplicatedId.has(boundElement.id) ? {
|
|
10323
|
-
id: oldIdToDuplicatedId.get(boundElement.id),
|
|
10324
|
-
type: boundElement.type
|
|
10325
|
-
} : boundElement
|
|
10326
|
-
)
|
|
10327
|
-
});
|
|
10328
|
-
}
|
|
10329
|
-
});
|
|
9757
|
+
var getCorners = (element, scale = 1) => {
|
|
9758
|
+
const hx = scale * element.width / 2;
|
|
9759
|
+
const hy = scale * element.height / 2;
|
|
9760
|
+
switch (element.type) {
|
|
9761
|
+
case "rectangle":
|
|
9762
|
+
case "image":
|
|
9763
|
+
case "text":
|
|
9764
|
+
case "iframe":
|
|
9765
|
+
case "embeddable":
|
|
9766
|
+
case "frame":
|
|
9767
|
+
case "magicframe":
|
|
9768
|
+
return [
|
|
9769
|
+
point(hx, hy),
|
|
9770
|
+
point(hx, -hy),
|
|
9771
|
+
point(-hx, -hy),
|
|
9772
|
+
point(-hx, hy)
|
|
9773
|
+
];
|
|
9774
|
+
case "diamond":
|
|
9775
|
+
return [
|
|
9776
|
+
point(0, hy),
|
|
9777
|
+
point(hx, 0),
|
|
9778
|
+
point(0, -hy),
|
|
9779
|
+
point(-hx, 0)
|
|
9780
|
+
];
|
|
9781
|
+
}
|
|
10330
9782
|
};
|
|
10331
|
-
var
|
|
10332
|
-
|
|
10333
|
-
|
|
9783
|
+
var intersectSegment = (line2, segment) => {
|
|
9784
|
+
const [a2, b2] = segment;
|
|
9785
|
+
const aDist = distanceToLine(a2, line2);
|
|
9786
|
+
const bDist = distanceToLine(b2, line2);
|
|
9787
|
+
if (aDist * bDist >= 0) {
|
|
9788
|
+
return [];
|
|
10334
9789
|
}
|
|
10335
|
-
|
|
10336
|
-
return {
|
|
10337
|
-
focus,
|
|
10338
|
-
gap,
|
|
10339
|
-
elementId: oldIdToDuplicatedId.get(elementId) ?? elementId
|
|
10340
|
-
};
|
|
9790
|
+
return [intersect(line2, through(a2, b2))];
|
|
10341
9791
|
};
|
|
10342
|
-
var
|
|
10343
|
-
const
|
|
10344
|
-
|
|
9792
|
+
var offsetSegment = (segment, distance4) => {
|
|
9793
|
+
const [a2, b2] = segment;
|
|
9794
|
+
const offset2 = translationOrthogonal(
|
|
9795
|
+
fromTo(a2, b2),
|
|
9796
|
+
distance4
|
|
10345
9797
|
);
|
|
10346
|
-
|
|
10347
|
-
deletedElements.forEach((deletedElement) => {
|
|
10348
|
-
if (isBindableElement(deletedElement)) {
|
|
10349
|
-
deletedElement.boundElements?.forEach((element) => {
|
|
10350
|
-
if (!deletedElementIds.has(element.id)) {
|
|
10351
|
-
affectedElements.add(element.id);
|
|
10352
|
-
}
|
|
10353
|
-
});
|
|
10354
|
-
} else if (isBindingElement(deletedElement)) {
|
|
10355
|
-
if (deletedElement.startBinding) {
|
|
10356
|
-
affectedElements.add(deletedElement.startBinding.elementId);
|
|
10357
|
-
}
|
|
10358
|
-
if (deletedElement.endBinding) {
|
|
10359
|
-
affectedElements.add(deletedElement.endBinding.elementId);
|
|
10360
|
-
}
|
|
10361
|
-
}
|
|
10362
|
-
});
|
|
10363
|
-
sceneElements.filter(({ id }) => affectedElements.has(id)).forEach((element) => {
|
|
10364
|
-
if (isBindableElement(element)) {
|
|
10365
|
-
mutateElement(element, {
|
|
10366
|
-
boundElements: newBoundElementsAfterDeletion(
|
|
10367
|
-
element.boundElements,
|
|
10368
|
-
deletedElementIds
|
|
10369
|
-
)
|
|
10370
|
-
});
|
|
10371
|
-
} else if (isBindingElement(element)) {
|
|
10372
|
-
mutateElement(element, {
|
|
10373
|
-
startBinding: newBindingAfterDeletion(
|
|
10374
|
-
element.startBinding,
|
|
10375
|
-
deletedElementIds
|
|
10376
|
-
),
|
|
10377
|
-
endBinding: newBindingAfterDeletion(
|
|
10378
|
-
element.endBinding,
|
|
10379
|
-
deletedElementIds
|
|
10380
|
-
)
|
|
10381
|
-
});
|
|
10382
|
-
}
|
|
10383
|
-
});
|
|
9798
|
+
return [apply(offset2, a2), apply(offset2, b2)];
|
|
10384
9799
|
};
|
|
10385
|
-
var
|
|
10386
|
-
|
|
10387
|
-
|
|
9800
|
+
var getEllipseIntersections = (element, gap, line2) => {
|
|
9801
|
+
const a2 = element.width / 2 + gap;
|
|
9802
|
+
const b2 = element.height / 2 + gap;
|
|
9803
|
+
const m = line2[2];
|
|
9804
|
+
const n2 = line2[3];
|
|
9805
|
+
const c = line2[1];
|
|
9806
|
+
const squares = a2 * a2 * m * m + b2 * b2 * n2 * n2;
|
|
9807
|
+
const discr = squares - c * c;
|
|
9808
|
+
if (squares === 0 || discr <= 0) {
|
|
9809
|
+
return [];
|
|
10388
9810
|
}
|
|
10389
|
-
|
|
9811
|
+
const discrRoot = Math.sqrt(discr);
|
|
9812
|
+
const xn = -a2 * a2 * m * c;
|
|
9813
|
+
const yn = -b2 * b2 * n2 * c;
|
|
9814
|
+
return [
|
|
9815
|
+
point(
|
|
9816
|
+
(xn + a2 * b2 * n2 * discrRoot) / squares,
|
|
9817
|
+
(yn - a2 * b2 * m * discrRoot) / squares
|
|
9818
|
+
),
|
|
9819
|
+
point(
|
|
9820
|
+
(xn - a2 * b2 * n2 * discrRoot) / squares,
|
|
9821
|
+
(yn + a2 * b2 * m * discrRoot) / squares
|
|
9822
|
+
)
|
|
9823
|
+
];
|
|
10390
9824
|
};
|
|
10391
|
-
var
|
|
10392
|
-
if (
|
|
10393
|
-
return
|
|
9825
|
+
var getCircleIntersections = (center, radius, line2) => {
|
|
9826
|
+
if (radius === 0) {
|
|
9827
|
+
return distanceToLine(line2, center) === 0 ? [center] : [];
|
|
10394
9828
|
}
|
|
10395
|
-
|
|
9829
|
+
const m = line2[2];
|
|
9830
|
+
const n2 = line2[3];
|
|
9831
|
+
const c = line2[1];
|
|
9832
|
+
const [a2, b2] = toTuple(center);
|
|
9833
|
+
const r = radius;
|
|
9834
|
+
const squares = m * m + n2 * n2;
|
|
9835
|
+
const discr = r * r * squares - (m * a2 + n2 * b2 + c) ** 2;
|
|
9836
|
+
if (squares === 0 || discr <= 0) {
|
|
9837
|
+
return [];
|
|
9838
|
+
}
|
|
9839
|
+
const discrRoot = Math.sqrt(discr);
|
|
9840
|
+
const xn = a2 * n2 * n2 - b2 * m * n2 - m * c;
|
|
9841
|
+
const yn = b2 * m * m - a2 * m * n2 - n2 * c;
|
|
9842
|
+
return [
|
|
9843
|
+
point((xn + n2 * discrRoot) / squares, (yn - m * discrRoot) / squares),
|
|
9844
|
+
point((xn - n2 * discrRoot) / squares, (yn + m * discrRoot) / squares)
|
|
9845
|
+
];
|
|
9846
|
+
};
|
|
9847
|
+
var findFocusPointForEllipse = (ellipse2, relativeDistance, point2) => {
|
|
9848
|
+
const relativeDistanceAbs = Math.abs(relativeDistance);
|
|
9849
|
+
const a2 = ellipse2.width * relativeDistanceAbs / 2;
|
|
9850
|
+
const b2 = ellipse2.height * relativeDistanceAbs / 2;
|
|
9851
|
+
const orientation = Math.sign(relativeDistance);
|
|
9852
|
+
const [px, pyo] = toTuple(point2);
|
|
9853
|
+
const py = pyo === 0 ? 1e-4 : pyo;
|
|
9854
|
+
const squares = px ** 2 * b2 ** 2 + py ** 2 * a2 ** 2;
|
|
9855
|
+
const m = (-px * b2 ** 2 + orientation * py * Math.sqrt(Math.max(0, squares - a2 ** 2 * b2 ** 2))) / squares;
|
|
9856
|
+
let n2 = (-m * px - 1) / py;
|
|
9857
|
+
if (n2 === 0) {
|
|
9858
|
+
n2 = (Object.is(n2, -0) ? -1 : 1) * 0.01;
|
|
9859
|
+
}
|
|
9860
|
+
const x = -(a2 ** 2 * m) / (n2 ** 2 * b2 ** 2 + m ** 2 * a2 ** 2);
|
|
9861
|
+
return point(x, (-m * x - 1) / n2);
|
|
9862
|
+
};
|
|
9863
|
+
var findFocusPointForRectangulars = (element, relativeDistance, point2) => {
|
|
9864
|
+
const relativeDistanceAbs = Math.abs(relativeDistance);
|
|
9865
|
+
const orientation = Math.sign(relativeDistance);
|
|
9866
|
+
const corners = getCorners(element, relativeDistanceAbs);
|
|
9867
|
+
let maxDistance = 0;
|
|
9868
|
+
let tangentPoint = null;
|
|
9869
|
+
corners.forEach((corner) => {
|
|
9870
|
+
const distance4 = orientation * through(point2, corner)[1];
|
|
9871
|
+
if (distance4 > maxDistance) {
|
|
9872
|
+
maxDistance = distance4;
|
|
9873
|
+
tangentPoint = corner;
|
|
9874
|
+
}
|
|
9875
|
+
});
|
|
9876
|
+
return tangentPoint;
|
|
9877
|
+
};
|
|
9878
|
+
|
|
9879
|
+
// scene/ShapeCache.ts
|
|
9880
|
+
init_define_import_meta_env();
|
|
9881
|
+
var ShapeCache = class _ShapeCache {
|
|
9882
|
+
static rg = new RoughGenerator();
|
|
9883
|
+
static cache = /* @__PURE__ */ new WeakMap();
|
|
9884
|
+
/**
|
|
9885
|
+
* Retrieves shape from cache if available. Use this only if shape
|
|
9886
|
+
* is optional and you have a fallback in case it's not cached.
|
|
9887
|
+
*/
|
|
9888
|
+
static get = (element) => {
|
|
9889
|
+
return _ShapeCache.cache.get(
|
|
9890
|
+
element
|
|
9891
|
+
);
|
|
9892
|
+
};
|
|
9893
|
+
static set = (element, shape) => _ShapeCache.cache.set(element, shape);
|
|
9894
|
+
static delete = (element) => _ShapeCache.cache.delete(element);
|
|
9895
|
+
static destroy = () => {
|
|
9896
|
+
_ShapeCache.cache = /* @__PURE__ */ new WeakMap();
|
|
9897
|
+
};
|
|
9898
|
+
/**
|
|
9899
|
+
* Generates & caches shape for element if not already cached, otherwise
|
|
9900
|
+
* returns cached shape.
|
|
9901
|
+
*/
|
|
9902
|
+
static generateElementShape = (element, renderConfig) => {
|
|
9903
|
+
const cachedShape = renderConfig?.isExporting ? void 0 : _ShapeCache.get(element);
|
|
9904
|
+
if (cachedShape !== void 0) {
|
|
9905
|
+
return cachedShape;
|
|
9906
|
+
}
|
|
9907
|
+
elementWithCanvasCache.delete(element);
|
|
9908
|
+
const shape = _generateElementShape(
|
|
9909
|
+
element,
|
|
9910
|
+
_ShapeCache.rg,
|
|
9911
|
+
renderConfig || {
|
|
9912
|
+
isExporting: false,
|
|
9913
|
+
canvasBackgroundColor: COLOR_PALETTE.white,
|
|
9914
|
+
embedsValidationStatus: null
|
|
9915
|
+
}
|
|
9916
|
+
);
|
|
9917
|
+
_ShapeCache.cache.set(element, shape);
|
|
9918
|
+
return shape;
|
|
9919
|
+
};
|
|
10396
9920
|
};
|
|
10397
9921
|
|
|
10398
9922
|
// element/linearElementEditor.ts
|
|
@@ -10576,7 +10100,8 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
10576
10100
|
}
|
|
10577
10101
|
return false;
|
|
10578
10102
|
}
|
|
10579
|
-
static handlePointerUp(event, editingLinearElement, appState,
|
|
10103
|
+
static handlePointerUp(event, editingLinearElement, appState, app) {
|
|
10104
|
+
const elementsMap = app.scene.getNonDeletedElementsMap();
|
|
10580
10105
|
const { elementId, selectedPointsIndices, isDragging, pointerDownState } = editingLinearElement;
|
|
10581
10106
|
const element = _LinearElementEditor.getElement(elementId, elementsMap);
|
|
10582
10107
|
if (!element) {
|
|
@@ -10602,8 +10127,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
10602
10127
|
elementsMap
|
|
10603
10128
|
)
|
|
10604
10129
|
),
|
|
10605
|
-
|
|
10606
|
-
elementsMap
|
|
10130
|
+
app
|
|
10607
10131
|
) : null;
|
|
10608
10132
|
bindings[selectedPoint === 0 ? "startBindingElement" : "endBindingElement"] = bindingElement;
|
|
10609
10133
|
}
|
|
@@ -10697,13 +10221,13 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
10697
10221
|
const threshold = _LinearElementEditor.POINT_HANDLE_SIZE / appState.zoom.value;
|
|
10698
10222
|
const existingSegmentMidpointHitCoords = linearElementEditor.segmentMidPointHoveredCoords;
|
|
10699
10223
|
if (existingSegmentMidpointHitCoords) {
|
|
10700
|
-
const
|
|
10224
|
+
const distance4 = distance2d(
|
|
10701
10225
|
existingSegmentMidpointHitCoords[0],
|
|
10702
10226
|
existingSegmentMidpointHitCoords[1],
|
|
10703
10227
|
scenePointer.x,
|
|
10704
10228
|
scenePointer.y
|
|
10705
10229
|
);
|
|
10706
|
-
if (
|
|
10230
|
+
if (distance4 <= threshold) {
|
|
10707
10231
|
return existingSegmentMidpointHitCoords;
|
|
10708
10232
|
}
|
|
10709
10233
|
}
|
|
@@ -10711,13 +10235,13 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
10711
10235
|
const midPoints = _LinearElementEditor.getEditorMidPoints(element, elementsMap, appState);
|
|
10712
10236
|
while (index < midPoints.length) {
|
|
10713
10237
|
if (midPoints[index] !== null) {
|
|
10714
|
-
const
|
|
10238
|
+
const distance4 = distance2d(
|
|
10715
10239
|
midPoints[index][0],
|
|
10716
10240
|
midPoints[index][1],
|
|
10717
10241
|
scenePointer.x,
|
|
10718
10242
|
scenePointer.y
|
|
10719
10243
|
);
|
|
10720
|
-
if (
|
|
10244
|
+
if (distance4 <= threshold) {
|
|
10721
10245
|
return midPoints[index];
|
|
10722
10246
|
}
|
|
10723
10247
|
}
|
|
@@ -10726,16 +10250,16 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
10726
10250
|
return null;
|
|
10727
10251
|
};
|
|
10728
10252
|
static isSegmentTooShort(element, startPoint, endPoint, zoom) {
|
|
10729
|
-
let
|
|
10253
|
+
let distance4 = distance2d(
|
|
10730
10254
|
startPoint[0],
|
|
10731
10255
|
startPoint[1],
|
|
10732
10256
|
endPoint[0],
|
|
10733
10257
|
endPoint[1]
|
|
10734
10258
|
);
|
|
10735
10259
|
if (element.points.length > 2 && element.roundness) {
|
|
10736
|
-
|
|
10260
|
+
distance4 = getBezierCurveLength(element, endPoint);
|
|
10737
10261
|
}
|
|
10738
|
-
return
|
|
10262
|
+
return distance4 * zoom.value < _LinearElementEditor.POINT_HANDLE_SIZE * 4;
|
|
10739
10263
|
}
|
|
10740
10264
|
static getSegmentMidPoint(element, startPoint, endPoint, endPointIndex, elementsMap) {
|
|
10741
10265
|
let segmentMidPoint = centerPoint(startPoint, endPoint);
|
|
@@ -10788,7 +10312,8 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
10788
10312
|
}
|
|
10789
10313
|
return -1;
|
|
10790
10314
|
}
|
|
10791
|
-
static handlePointerDown(event, appState, history, scenePointer, linearElementEditor,
|
|
10315
|
+
static handlePointerDown(event, appState, history, scenePointer, linearElementEditor, app) {
|
|
10316
|
+
const elementsMap = app.scene.getNonDeletedElementsMap();
|
|
10792
10317
|
const ret = {
|
|
10793
10318
|
didAddPoint: false,
|
|
10794
10319
|
hitElement: null,
|
|
@@ -10848,11 +10373,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
10848
10373
|
},
|
|
10849
10374
|
selectedPointsIndices: [element.points.length - 1],
|
|
10850
10375
|
lastUncommittedPoint: null,
|
|
10851
|
-
endBindingElement: getHoveredElementForBinding(
|
|
10852
|
-
scenePointer,
|
|
10853
|
-
elements,
|
|
10854
|
-
elementsMap
|
|
10855
|
-
)
|
|
10376
|
+
endBindingElement: getHoveredElementForBinding(scenePointer, app)
|
|
10856
10377
|
};
|
|
10857
10378
|
ret.didAddPoint = true;
|
|
10858
10379
|
return ret;
|
|
@@ -10880,7 +10401,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
10880
10401
|
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
|
|
10881
10402
|
const cx = (x1 + x2) / 2;
|
|
10882
10403
|
const cy = (y1 + y2) / 2;
|
|
10883
|
-
const targetPoint = clickedPointIndex > -1 &&
|
|
10404
|
+
const targetPoint = clickedPointIndex > -1 && rotate3(
|
|
10884
10405
|
element.x + element.points[clickedPointIndex][0],
|
|
10885
10406
|
element.y + element.points[clickedPointIndex][1],
|
|
10886
10407
|
cx,
|
|
@@ -10984,7 +10505,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
10984
10505
|
const cx = (x1 + x2) / 2;
|
|
10985
10506
|
const cy = (y1 + y2) / 2;
|
|
10986
10507
|
let { x, y } = element;
|
|
10987
|
-
[x, y] =
|
|
10508
|
+
[x, y] = rotate3(x + point2[0], y + point2[1], cx, cy, element.angle);
|
|
10988
10509
|
return [x, y];
|
|
10989
10510
|
}
|
|
10990
10511
|
/** scene coords */
|
|
@@ -10994,7 +10515,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
10994
10515
|
const cy = (y1 + y2) / 2;
|
|
10995
10516
|
return element.points.map((point2) => {
|
|
10996
10517
|
let { x, y } = element;
|
|
10997
|
-
[x, y] =
|
|
10518
|
+
[x, y] = rotate3(x + point2[0], y + point2[1], cx, cy, element.angle);
|
|
10998
10519
|
return [x, y];
|
|
10999
10520
|
});
|
|
11000
10521
|
}
|
|
@@ -11005,13 +10526,13 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
11005
10526
|
const cy = (y1 + y2) / 2;
|
|
11006
10527
|
const point2 = element.points[index];
|
|
11007
10528
|
const { x, y } = element;
|
|
11008
|
-
return point2 ?
|
|
10529
|
+
return point2 ? rotate3(x + point2[0], y + point2[1], cx, cy, element.angle) : rotate3(x, y, cx, cy, element.angle);
|
|
11009
10530
|
}
|
|
11010
10531
|
static pointFromAbsoluteCoords(element, absoluteCoords, elementsMap) {
|
|
11011
10532
|
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
|
|
11012
10533
|
const cx = (x1 + x2) / 2;
|
|
11013
10534
|
const cy = (y1 + y2) / 2;
|
|
11014
|
-
const [x, y] =
|
|
10535
|
+
const [x, y] = rotate3(
|
|
11015
10536
|
absoluteCoords[0],
|
|
11016
10537
|
absoluteCoords[1],
|
|
11017
10538
|
cx,
|
|
@@ -11040,7 +10561,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
11040
10561
|
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
|
|
11041
10562
|
const cx = (x1 + x2) / 2;
|
|
11042
10563
|
const cy = (y1 + y2) / 2;
|
|
11043
|
-
const [rotatedX, rotatedY] =
|
|
10564
|
+
const [rotatedX, rotatedY] = rotate3(
|
|
11044
10565
|
pointerOnGrid[0],
|
|
11045
10566
|
pointerOnGrid[1],
|
|
11046
10567
|
cx,
|
|
@@ -11216,7 +10737,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
11216
10737
|
pointerDownState: linearElementEditor.pointerDownState,
|
|
11217
10738
|
selectedPointsIndices: linearElementEditor.selectedPointsIndices
|
|
11218
10739
|
};
|
|
11219
|
-
const
|
|
10740
|
+
const midpoint2 = _LinearElementEditor.createPointAt(
|
|
11220
10741
|
element,
|
|
11221
10742
|
elementsMap,
|
|
11222
10743
|
pointerCoords.x,
|
|
@@ -11225,7 +10746,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
11225
10746
|
);
|
|
11226
10747
|
const points = [
|
|
11227
10748
|
...element.points.slice(0, segmentMidpoint.index),
|
|
11228
|
-
|
|
10749
|
+
midpoint2,
|
|
11229
10750
|
...element.points.slice(segmentMidpoint.index)
|
|
11230
10751
|
];
|
|
11231
10752
|
mutateElement(element, {
|
|
@@ -11251,7 +10772,7 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
11251
10772
|
const prevCenterY = (prevCoords[1] + prevCoords[3]) / 2;
|
|
11252
10773
|
const dX = prevCenterX - nextCenterX;
|
|
11253
10774
|
const dY = prevCenterY - nextCenterY;
|
|
11254
|
-
const rotated =
|
|
10775
|
+
const rotated = rotate3(offsetX, offsetY, dX, dY, element.angle);
|
|
11255
10776
|
mutateElement(element, {
|
|
11256
10777
|
...otherUpdates,
|
|
11257
10778
|
points: nextPoints,
|
|
@@ -11941,36 +11462,6 @@ var suppportsHorizontalAlign = (selectedElements, elementsMap) => {
|
|
|
11941
11462
|
return isTextElement(element);
|
|
11942
11463
|
});
|
|
11943
11464
|
};
|
|
11944
|
-
var getTextBindableContainerAtPosition = (elements, appState, x, y, elementsMap) => {
|
|
11945
|
-
const selectedElements = getSelectedElements(elements, appState);
|
|
11946
|
-
if (selectedElements.length === 1) {
|
|
11947
|
-
return isTextBindableContainer(selectedElements[0], false) ? selectedElements[0] : null;
|
|
11948
|
-
}
|
|
11949
|
-
let hitElement = null;
|
|
11950
|
-
for (let index = elements.length - 1; index >= 0; --index) {
|
|
11951
|
-
if (elements[index].isDeleted) {
|
|
11952
|
-
continue;
|
|
11953
|
-
}
|
|
11954
|
-
const [x1, y1, x2, y2] = getElementAbsoluteCoords(
|
|
11955
|
-
elements[index],
|
|
11956
|
-
elementsMap
|
|
11957
|
-
);
|
|
11958
|
-
if (isArrowElement(elements[index]) && isHittingElementNotConsideringBoundingBox(
|
|
11959
|
-
elements[index],
|
|
11960
|
-
appState,
|
|
11961
|
-
null,
|
|
11962
|
-
[x, y],
|
|
11963
|
-
elementsMap
|
|
11964
|
-
)) {
|
|
11965
|
-
hitElement = elements[index];
|
|
11966
|
-
break;
|
|
11967
|
-
} else if (x1 < x && x < x2 && y1 < y && y < y2) {
|
|
11968
|
-
hitElement = elements[index];
|
|
11969
|
-
break;
|
|
11970
|
-
}
|
|
11971
|
-
}
|
|
11972
|
-
return isTextBindableContainer(hitElement, false) ? hitElement : null;
|
|
11973
|
-
};
|
|
11974
11465
|
var VALID_CONTAINER_TYPES = /* @__PURE__ */ new Set([
|
|
11975
11466
|
"rectangle",
|
|
11976
11467
|
"ellipse",
|
|
@@ -12076,7 +11567,7 @@ var IMAGE_INVERT_FILTER = "invert(100%) hue-rotate(180deg) saturate(1.25)";
|
|
|
12076
11567
|
var defaultAppState = getDefaultAppState();
|
|
12077
11568
|
var isPendingImageElement = (element, renderConfig) => isInitializedImageElement(element) && !renderConfig.imageCache.has(element.fileId);
|
|
12078
11569
|
var shouldResetImageFilter = (element, renderConfig, appState) => {
|
|
12079
|
-
return appState.theme ===
|
|
11570
|
+
return appState.theme === THEME.DARK && isInitializedImageElement(element) && !isPendingImageElement(element, renderConfig) && renderConfig.imageCache.get(element.fileId)?.mimeType !== MIME_TYPES.svg;
|
|
12080
11571
|
};
|
|
12081
11572
|
var getCanvasPadding = (element) => element.type === "freedraw" ? element.strokeWidth * 12 : 20;
|
|
12082
11573
|
var getRenderOpacity = (element, containingFrame, elementsPendingErasure) => {
|
|
@@ -12414,7 +11905,7 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
|
|
|
12414
11905
|
context.lineWidth = FRAME_STYLE.strokeWidth / appState.zoom.value;
|
|
12415
11906
|
context.strokeStyle = FRAME_STYLE.strokeColor;
|
|
12416
11907
|
if (isMagicFrameElement(element)) {
|
|
12417
|
-
context.strokeStyle = appState.theme ===
|
|
11908
|
+
context.strokeStyle = appState.theme === THEME.LIGHT ? "#7affd7" : "#1d8264";
|
|
12418
11909
|
}
|
|
12419
11910
|
if (FRAME_STYLE.radius && context.roundRect) {
|
|
12420
11911
|
context.beginPath();
|
|
@@ -12637,6 +12128,54 @@ function getSvgPathFromStroke2(points) {
|
|
|
12637
12128
|
).join(" ").replace(TO_FIXED_PRECISION, "$1");
|
|
12638
12129
|
}
|
|
12639
12130
|
|
|
12131
|
+
// node_modules/points-on-curve/lib/index.js
|
|
12132
|
+
init_define_import_meta_env();
|
|
12133
|
+
function distanceSq2(p1, p2) {
|
|
12134
|
+
return Math.pow(p1[0] - p2[0], 2) + Math.pow(p1[1] - p2[1], 2);
|
|
12135
|
+
}
|
|
12136
|
+
function distanceToSegmentSq2(p, v, w) {
|
|
12137
|
+
const l2 = distanceSq2(v, w);
|
|
12138
|
+
if (l2 === 0) {
|
|
12139
|
+
return distanceSq2(p, v);
|
|
12140
|
+
}
|
|
12141
|
+
let t2 = ((p[0] - v[0]) * (w[0] - v[0]) + (p[1] - v[1]) * (w[1] - v[1])) / l2;
|
|
12142
|
+
t2 = Math.max(0, Math.min(1, t2));
|
|
12143
|
+
return distanceSq2(p, lerp2(v, w, t2));
|
|
12144
|
+
}
|
|
12145
|
+
function lerp2(a2, b2, t2) {
|
|
12146
|
+
return [
|
|
12147
|
+
a2[0] + (b2[0] - a2[0]) * t2,
|
|
12148
|
+
a2[1] + (b2[1] - a2[1]) * t2
|
|
12149
|
+
];
|
|
12150
|
+
}
|
|
12151
|
+
function simplify2(points, distance4) {
|
|
12152
|
+
return simplifyPoints2(points, 0, points.length, distance4);
|
|
12153
|
+
}
|
|
12154
|
+
function simplifyPoints2(points, start, end, epsilon, newPoints) {
|
|
12155
|
+
const outPoints = newPoints || [];
|
|
12156
|
+
const s2 = points[start];
|
|
12157
|
+
const e2 = points[end - 1];
|
|
12158
|
+
let maxDistSq = 0;
|
|
12159
|
+
let maxNdx = 1;
|
|
12160
|
+
for (let i2 = start + 1; i2 < end - 1; ++i2) {
|
|
12161
|
+
const distSq = distanceToSegmentSq2(points[i2], s2, e2);
|
|
12162
|
+
if (distSq > maxDistSq) {
|
|
12163
|
+
maxDistSq = distSq;
|
|
12164
|
+
maxNdx = i2;
|
|
12165
|
+
}
|
|
12166
|
+
}
|
|
12167
|
+
if (Math.sqrt(maxDistSq) > epsilon) {
|
|
12168
|
+
simplifyPoints2(points, start, maxNdx + 1, epsilon, outPoints);
|
|
12169
|
+
simplifyPoints2(points, maxNdx, end, epsilon, outPoints);
|
|
12170
|
+
} else {
|
|
12171
|
+
if (!outPoints.length) {
|
|
12172
|
+
outPoints.push(s2);
|
|
12173
|
+
}
|
|
12174
|
+
outPoints.push(e2);
|
|
12175
|
+
}
|
|
12176
|
+
return outPoints;
|
|
12177
|
+
}
|
|
12178
|
+
|
|
12640
12179
|
// scene/Shape.ts
|
|
12641
12180
|
var getDashArrayDashed = (strokeWidth) => [8, 8 + strokeWidth];
|
|
12642
12181
|
var getDashArrayDotted = (strokeWidth) => [1.5, 6 + strokeWidth];
|
|
@@ -13034,7 +12573,7 @@ var ElementBounds = class _ElementBounds {
|
|
|
13034
12573
|
if (isFreeDrawElement(element)) {
|
|
13035
12574
|
const [minX, minY, maxX, maxY] = getBoundsFromPoints(
|
|
13036
12575
|
element.points.map(
|
|
13037
|
-
([x, y]) =>
|
|
12576
|
+
([x, y]) => rotate3(x, y, cx - element.x, cy - element.y, element.angle)
|
|
13038
12577
|
)
|
|
13039
12578
|
);
|
|
13040
12579
|
return [
|
|
@@ -13046,10 +12585,10 @@ var ElementBounds = class _ElementBounds {
|
|
|
13046
12585
|
} else if (isLinearElement(element)) {
|
|
13047
12586
|
bounds = getLinearElementRotatedBounds(element, cx, cy, elementsMap);
|
|
13048
12587
|
} else if (element.type === "diamond") {
|
|
13049
|
-
const [x11, y11] =
|
|
13050
|
-
const [x12, y12] =
|
|
13051
|
-
const [x22, y22] =
|
|
13052
|
-
const [x21, y21] =
|
|
12588
|
+
const [x11, y11] = rotate3(cx, y1, cx, cy, element.angle);
|
|
12589
|
+
const [x12, y12] = rotate3(cx, y2, cx, cy, element.angle);
|
|
12590
|
+
const [x22, y22] = rotate3(x1, cy, cx, cy, element.angle);
|
|
12591
|
+
const [x21, y21] = rotate3(x2, cy, cx, cy, element.angle);
|
|
13053
12592
|
const minX = Math.min(x11, x12, x22, x21);
|
|
13054
12593
|
const minY = Math.min(y11, y12, y22, y21);
|
|
13055
12594
|
const maxX = Math.max(x11, x12, x22, x21);
|
|
@@ -13064,10 +12603,10 @@ var ElementBounds = class _ElementBounds {
|
|
|
13064
12603
|
const hh = Math.hypot(h * cos, w * sin);
|
|
13065
12604
|
bounds = [cx - ww, cy - hh, cx + ww, cy + hh];
|
|
13066
12605
|
} else {
|
|
13067
|
-
const [x11, y11] =
|
|
13068
|
-
const [x12, y12] =
|
|
13069
|
-
const [x22, y22] =
|
|
13070
|
-
const [x21, y21] =
|
|
12606
|
+
const [x11, y11] = rotate3(x1, y1, cx, cy, element.angle);
|
|
12607
|
+
const [x12, y12] = rotate3(x1, y2, cx, cy, element.angle);
|
|
12608
|
+
const [x22, y22] = rotate3(x2, y2, cx, cy, element.angle);
|
|
12609
|
+
const [x21, y21] = rotate3(x2, y1, cx, cy, element.angle);
|
|
13071
12610
|
const minX = Math.min(x11, x12, x22, x21);
|
|
13072
12611
|
const minY = Math.min(y11, y12, y22, y21);
|
|
13073
12612
|
const maxX = Math.max(x11, x12, x22, x21);
|
|
@@ -13186,16 +12725,6 @@ var getElementLineSegments = (element, elementsMap) => {
|
|
|
13186
12725
|
[se2, w]
|
|
13187
12726
|
];
|
|
13188
12727
|
};
|
|
13189
|
-
var getRectangleBoxAbsoluteCoords = (boxSceneCoords) => {
|
|
13190
|
-
return [
|
|
13191
|
-
boxSceneCoords.x,
|
|
13192
|
-
boxSceneCoords.y,
|
|
13193
|
-
boxSceneCoords.x + boxSceneCoords.width,
|
|
13194
|
-
boxSceneCoords.y + boxSceneCoords.height,
|
|
13195
|
-
boxSceneCoords.x + boxSceneCoords.width / 2,
|
|
13196
|
-
boxSceneCoords.y + boxSceneCoords.height / 2
|
|
13197
|
-
];
|
|
13198
|
-
};
|
|
13199
12728
|
var getDiamondPoints = (element) => {
|
|
13200
12729
|
const topX = Math.floor(element.width / 2) + 1;
|
|
13201
12730
|
const topY = 0;
|
|
@@ -13364,9 +12893,9 @@ var getArrowheadPoints = (element, shape, position, arrowhead) => {
|
|
|
13364
12893
|
const equation2 = (t2, idx) => Math.pow(1 - t2, 3) * p3[idx] + 3 * t2 * Math.pow(1 - t2, 2) * p2[idx] + 3 * Math.pow(t2, 2) * (1 - t2) * p1[idx] + p0[idx] * Math.pow(t2, 3);
|
|
13365
12894
|
const [x2, y2] = position === "start" ? p0 : p3;
|
|
13366
12895
|
const [x1, y1] = [equation2(0.3, 0), equation2(0.3, 1)];
|
|
13367
|
-
const
|
|
13368
|
-
const nx = (x2 - x1) /
|
|
13369
|
-
const ny = (y2 - y1) /
|
|
12896
|
+
const distance4 = Math.hypot(x2 - x1, y2 - y1);
|
|
12897
|
+
const nx = (x2 - x1) / distance4;
|
|
12898
|
+
const ny = (y2 - y1) / distance4;
|
|
13370
12899
|
const size = getArrowheadSize(arrowhead);
|
|
13371
12900
|
let length = 0;
|
|
13372
12901
|
{
|
|
@@ -13383,14 +12912,14 @@ var getArrowheadPoints = (element, shape, position, arrowhead) => {
|
|
|
13383
12912
|
return [x2, y2, diameter];
|
|
13384
12913
|
}
|
|
13385
12914
|
const angle = getArrowheadAngle(arrowhead);
|
|
13386
|
-
const [x3, y3] =
|
|
13387
|
-
const [x4, y4] =
|
|
12915
|
+
const [x3, y3] = rotate3(xs, ys, x2, y2, -angle * Math.PI / 180);
|
|
12916
|
+
const [x4, y4] = rotate3(xs, ys, x2, y2, angle * Math.PI / 180);
|
|
13388
12917
|
if (arrowhead === "diamond" || arrowhead === "diamond_outline") {
|
|
13389
12918
|
let ox;
|
|
13390
12919
|
let oy;
|
|
13391
12920
|
if (position === "start") {
|
|
13392
12921
|
const [px, py] = element.points.length > 1 ? element.points[1] : [0, 0];
|
|
13393
|
-
[ox, oy] =
|
|
12922
|
+
[ox, oy] = rotate3(
|
|
13394
12923
|
x2 + minSize * 2,
|
|
13395
12924
|
y2,
|
|
13396
12925
|
x2,
|
|
@@ -13399,7 +12928,7 @@ var getArrowheadPoints = (element, shape, position, arrowhead) => {
|
|
|
13399
12928
|
);
|
|
13400
12929
|
} else {
|
|
13401
12930
|
const [px, py] = element.points.length > 1 ? element.points[element.points.length - 2] : [0, 0];
|
|
13402
|
-
[ox, oy] =
|
|
12931
|
+
[ox, oy] = rotate3(
|
|
13403
12932
|
x2 - minSize * 2,
|
|
13404
12933
|
y2,
|
|
13405
12934
|
x2,
|
|
@@ -13429,7 +12958,7 @@ var getLinearElementRotatedBounds = (element, cx, cy, elementsMap) => {
|
|
|
13429
12958
|
const boundTextElement = getBoundTextElement(element, elementsMap);
|
|
13430
12959
|
if (element.points.length < 2) {
|
|
13431
12960
|
const [pointX, pointY] = element.points[0];
|
|
13432
|
-
const [x, y] =
|
|
12961
|
+
const [x, y] = rotate3(
|
|
13433
12962
|
element.x + pointX,
|
|
13434
12963
|
element.y + pointY,
|
|
13435
12964
|
cx,
|
|
@@ -13456,7 +12985,7 @@ var getLinearElementRotatedBounds = (element, cx, cy, elementsMap) => {
|
|
|
13456
12985
|
const cachedShape = ShapeCache.get(element)?.[0];
|
|
13457
12986
|
const shape = cachedShape ?? generateLinearElementShape(element);
|
|
13458
12987
|
const ops = getCurvePathOps(shape);
|
|
13459
|
-
const transformXY = (x, y) =>
|
|
12988
|
+
const transformXY = (x, y) => rotate3(element.x + x, element.y + y, cx, cy, element.angle);
|
|
13460
12989
|
const res = getMinMaxXYFromCurvePathOps(ops, transformXY);
|
|
13461
12990
|
let coords = [res[0], res[1], res[2], res[3]];
|
|
13462
12991
|
if (boundTextElement) {
|
|
@@ -13564,9 +13093,9 @@ var getClosestElementBounds = (elements, from3) => {
|
|
|
13564
13093
|
const elementsMap = arrayToMap(elements);
|
|
13565
13094
|
elements.forEach((element) => {
|
|
13566
13095
|
const [x1, y1, x2, y2] = getElementBounds(element, elementsMap);
|
|
13567
|
-
const
|
|
13568
|
-
if (
|
|
13569
|
-
minDistance =
|
|
13096
|
+
const distance4 = distance2d((x1 + x2) / 2, (y1 + y2) / 2, from3.x, from3.y);
|
|
13097
|
+
if (distance4 < minDistance) {
|
|
13098
|
+
minDistance = distance4;
|
|
13570
13099
|
closestElement = element;
|
|
13571
13100
|
}
|
|
13572
13101
|
});
|
|
@@ -13601,7 +13130,7 @@ var getVisibleSceneBounds = ({
|
|
|
13601
13130
|
};
|
|
13602
13131
|
|
|
13603
13132
|
// math.ts
|
|
13604
|
-
var
|
|
13133
|
+
var rotate3 = (x, y, cx, cy, angle) => (
|
|
13605
13134
|
// 𝑎′𝑥=(𝑎𝑥−𝑐𝑥)cos𝜃−(𝑎𝑦−𝑐𝑦)sin𝜃+𝑐𝑥
|
|
13606
13135
|
// 𝑎′𝑦=(𝑎𝑥−𝑐𝑥)sin𝜃+(𝑎𝑦−𝑐𝑦)cos𝜃+𝑐𝑦.
|
|
13607
13136
|
// https://math.stackexchange.com/questions/2204520/how-do-i-rotate-a-line-segment-in-a-specific-point-on-the-line
|
|
@@ -13610,7 +13139,7 @@ var rotate2 = (x, y, cx, cy, angle) => (
|
|
|
13610
13139
|
(x - cx) * Math.sin(angle) + (y - cy) * Math.cos(angle) + cy
|
|
13611
13140
|
]
|
|
13612
13141
|
);
|
|
13613
|
-
var rotatePoint = (point2, center, angle) =>
|
|
13142
|
+
var rotatePoint = (point2, center, angle) => rotate3(point2[0], point2[1], center[0], center[1], angle);
|
|
13614
13143
|
var adjustXYWithRotation = (sides, x, y, angle, deltaX1, deltaY1, deltaX2, deltaY2) => {
|
|
13615
13144
|
const cos = Math.cos(angle);
|
|
13616
13145
|
const sin = Math.sin(angle);
|
|
@@ -13653,63 +13182,14 @@ var centerPoint = (a2, b2) => {
|
|
|
13653
13182
|
var isPathALoop = (points, zoomValue = 1) => {
|
|
13654
13183
|
if (points.length >= 3) {
|
|
13655
13184
|
const [first, last] = [points[0], points[points.length - 1]];
|
|
13656
|
-
const
|
|
13657
|
-
return
|
|
13185
|
+
const distance4 = distance2d(first[0], first[1], last[0], last[1]);
|
|
13186
|
+
return distance4 <= LINE_CONFIRM_THRESHOLD / zoomValue;
|
|
13658
13187
|
}
|
|
13659
13188
|
return false;
|
|
13660
13189
|
};
|
|
13661
|
-
var isPointInPolygon = (points, x, y) => {
|
|
13662
|
-
const vertices = points.length;
|
|
13663
|
-
if (vertices < 3) {
|
|
13664
|
-
return false;
|
|
13665
|
-
}
|
|
13666
|
-
const extreme = [Number.MAX_SAFE_INTEGER, y];
|
|
13667
|
-
const p = [x, y];
|
|
13668
|
-
let count = 0;
|
|
13669
|
-
for (let i2 = 0; i2 < vertices; i2++) {
|
|
13670
|
-
const current = points[i2];
|
|
13671
|
-
const next = points[(i2 + 1) % vertices];
|
|
13672
|
-
if (doSegmentsIntersect(current, next, p, extreme)) {
|
|
13673
|
-
if (orderedColinearOrientation(current, p, next) === 0) {
|
|
13674
|
-
return isPointWithinBounds(current, p, next);
|
|
13675
|
-
}
|
|
13676
|
-
count++;
|
|
13677
|
-
}
|
|
13678
|
-
}
|
|
13679
|
-
return count % 2 === 1;
|
|
13680
|
-
};
|
|
13681
13190
|
var isPointWithinBounds = (p, q, r) => {
|
|
13682
13191
|
return q[0] <= Math.max(p[0], r[0]) && q[0] >= Math.min(p[0], r[0]) && q[1] <= Math.max(p[1], r[1]) && q[1] >= Math.min(p[1], r[1]);
|
|
13683
13192
|
};
|
|
13684
|
-
var orderedColinearOrientation = (p, q, r) => {
|
|
13685
|
-
const val = (q[1] - p[1]) * (r[0] - q[0]) - (q[0] - p[0]) * (r[1] - q[1]);
|
|
13686
|
-
if (val === 0) {
|
|
13687
|
-
return 0;
|
|
13688
|
-
}
|
|
13689
|
-
return val > 0 ? 1 : 2;
|
|
13690
|
-
};
|
|
13691
|
-
var doSegmentsIntersect = (p1, q1, p2, q2) => {
|
|
13692
|
-
const o1 = orderedColinearOrientation(p1, q1, p2);
|
|
13693
|
-
const o2 = orderedColinearOrientation(p1, q1, q2);
|
|
13694
|
-
const o3 = orderedColinearOrientation(p2, q2, p1);
|
|
13695
|
-
const o4 = orderedColinearOrientation(p2, q2, q1);
|
|
13696
|
-
if (o1 !== o2 && o3 !== o4) {
|
|
13697
|
-
return true;
|
|
13698
|
-
}
|
|
13699
|
-
if (o1 === 0 && isPointWithinBounds(p1, p2, q1)) {
|
|
13700
|
-
return true;
|
|
13701
|
-
}
|
|
13702
|
-
if (o2 === 0 && isPointWithinBounds(p1, q2, q1)) {
|
|
13703
|
-
return true;
|
|
13704
|
-
}
|
|
13705
|
-
if (o3 === 0 && isPointWithinBounds(p2, p1, q2)) {
|
|
13706
|
-
return true;
|
|
13707
|
-
}
|
|
13708
|
-
if (o4 === 0 && isPointWithinBounds(p2, q1, q2)) {
|
|
13709
|
-
return true;
|
|
13710
|
-
}
|
|
13711
|
-
return false;
|
|
13712
|
-
};
|
|
13713
13193
|
var getGridPoint = (x, y, gridSize) => {
|
|
13714
13194
|
if (gridSize) {
|
|
13715
13195
|
return [
|
|
@@ -13753,9 +13233,9 @@ var getControlPointsForBezierCurve = (element, endPoint) => {
|
|
|
13753
13233
|
const p1 = [data[0], data[1]];
|
|
13754
13234
|
const p2 = [data[2], data[3]];
|
|
13755
13235
|
const p3 = [data[4], data[5]];
|
|
13756
|
-
const
|
|
13757
|
-
if (
|
|
13758
|
-
minDistance =
|
|
13236
|
+
const distance4 = distance2d(p3[0], p3[1], endPoint[0], endPoint[1]);
|
|
13237
|
+
if (distance4 < minDistance) {
|
|
13238
|
+
minDistance = distance4;
|
|
13759
13239
|
controlPoints = [p0, p1, p2, p3];
|
|
13760
13240
|
}
|
|
13761
13241
|
currentP = p3;
|
|
@@ -13803,7 +13283,7 @@ var getBezierCurveArcLengths = (element, endPoint) => {
|
|
|
13803
13283
|
arcLengths[0] = 0;
|
|
13804
13284
|
const points = getPointsInBezierCurve(element, endPoint);
|
|
13805
13285
|
let index = 0;
|
|
13806
|
-
let
|
|
13286
|
+
let distance4 = 0;
|
|
13807
13287
|
while (index < points.length - 1) {
|
|
13808
13288
|
const segmentDistance = distance2d(
|
|
13809
13289
|
points[index][0],
|
|
@@ -13811,8 +13291,8 @@ var getBezierCurveArcLengths = (element, endPoint) => {
|
|
|
13811
13291
|
points[index + 1][0],
|
|
13812
13292
|
points[index + 1][1]
|
|
13813
13293
|
);
|
|
13814
|
-
|
|
13815
|
-
arcLengths.push(
|
|
13294
|
+
distance4 += segmentDistance;
|
|
13295
|
+
arcLengths.push(distance4);
|
|
13816
13296
|
index++;
|
|
13817
13297
|
}
|
|
13818
13298
|
return arcLengths;
|
|
@@ -14216,6 +13696,7 @@ var _newElementBase = (type, {
|
|
|
14216
13696
|
angle = 0,
|
|
14217
13697
|
groupIds = [],
|
|
14218
13698
|
frameId = null,
|
|
13699
|
+
index = null,
|
|
14219
13700
|
roundness = null,
|
|
14220
13701
|
boundElements = null,
|
|
14221
13702
|
link = null,
|
|
@@ -14239,6 +13720,7 @@ var _newElementBase = (type, {
|
|
|
14239
13720
|
opacity,
|
|
14240
13721
|
groupIds,
|
|
14241
13722
|
frameId,
|
|
13723
|
+
index,
|
|
14242
13724
|
roundness,
|
|
14243
13725
|
seed: rest.seed ?? randomInteger(),
|
|
14244
13726
|
version: rest.version || 1,
|
|
@@ -14578,13 +14060,13 @@ var duplicateElements = (elements, opts) => {
|
|
|
14578
14060
|
// element/embeddable.ts
|
|
14579
14061
|
var embeddedLinkCache = /* @__PURE__ */ new Map();
|
|
14580
14062
|
var RE_YOUTUBE = /^(?:http(?:s)?:\/\/)?(?:www\.)?youtu(?:be\.com|\.be)\/(embed\/|watch\?v=|shorts\/|playlist\?list=|embed\/videoseries\?list=)?([a-zA-Z0-9_-]+)(?:\?t=|&t=|\?start=|&start=)?([a-zA-Z0-9_-]+)?[^\s]*$/;
|
|
14581
|
-
var RE_VIMEO = /^(?:http(?:s)?:\/\/)?(?:(?:w){3}
|
|
14063
|
+
var RE_VIMEO = /^(?:http(?:s)?:\/\/)?(?:(?:w){3}\.)?(?:player\.)?vimeo\.com\/(?:video\/)?([^?\s]+)(?:\?.*)?$/;
|
|
14582
14064
|
var RE_FIGMA = /^https:\/\/(?:www\.)?figma\.com/;
|
|
14583
14065
|
var RE_GH_GIST = /^https:\/\/gist\.github\.com/;
|
|
14584
|
-
var RE_GH_GIST_EMBED =
|
|
14585
|
-
var RE_TWITTER = /(?:
|
|
14586
|
-
var RE_TWITTER_EMBED = /^<blockquote[\s\S]*?\shref=["'](https
|
|
14587
|
-
var RE_VALTOWN = /^https:\/\/(?:www\.)?val
|
|
14066
|
+
var RE_GH_GIST_EMBED = /https?:\/\/gist\.github\.com\/([\w_-]+)\/([\w_-]+)\.js["']/i;
|
|
14067
|
+
var RE_TWITTER = /(?:https?:\/\/)?(?:(?:w){3}\.)?(?:twitter|x)\.com/;
|
|
14068
|
+
var RE_TWITTER_EMBED = /^<blockquote[\s\S]*?\shref=["'](https?:\/\/(?:twitter|x)\.com\/[^"']*)/i;
|
|
14069
|
+
var RE_VALTOWN = /^https:\/\/(?:www\.)?val\.town\/(v|embed)\/[a-zA-Z_$][0-9a-zA-Z_$]+\.[a-zA-Z_$][0-9a-zA-Z_$]+/;
|
|
14588
14070
|
var RE_GENERIC_EMBED = /^<(?:iframe|blockquote)[\s\S]*?\s(?:src|href)=["']([^"']*)["'][\s\S]*?>$/i;
|
|
14589
14071
|
var RE_GIPHY = /giphy.com\/(?:clips|embed|gifs)\/[a-zA-Z0-9]*?-?([a-zA-Z0-9]+)(?:[^a-zA-Z0-9]|$)/;
|
|
14590
14072
|
var ALLOWED_DOMAINS = /* @__PURE__ */ new Set([
|
|
@@ -14683,39 +14165,21 @@ var getEmbedLink = (link) => {
|
|
|
14683
14165
|
}
|
|
14684
14166
|
if (RE_TWITTER.test(link)) {
|
|
14685
14167
|
link = link.replace(/\bx.com\b/, "twitter.com");
|
|
14686
|
-
|
|
14687
|
-
|
|
14688
|
-
|
|
14689
|
-
|
|
14690
|
-
|
|
14691
|
-
|
|
14692
|
-
|
|
14693
|
-
|
|
14694
|
-
} else {
|
|
14695
|
-
ret = {
|
|
14696
|
-
type: "document",
|
|
14697
|
-
srcdoc: (theme) => createSrcDoc(
|
|
14698
|
-
`<blockquote class="twitter-tweet" data-dnt="true" data-theme="${theme}"><a href="${link}"></a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"><\/script>`
|
|
14699
|
-
),
|
|
14700
|
-
intrinsicSize: { w: 480, h: 480 }
|
|
14701
|
-
};
|
|
14702
|
-
}
|
|
14168
|
+
const ret = {
|
|
14169
|
+
type: "document",
|
|
14170
|
+
srcdoc: (theme) => createSrcDoc(
|
|
14171
|
+
`<blockquote class="twitter-tweet" data-dnt="true" data-theme="${theme}"><a href="${link}"></a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"><\/script>`
|
|
14172
|
+
),
|
|
14173
|
+
intrinsicSize: { w: 480, h: 480 },
|
|
14174
|
+
sandbox: { allowSameOrigin: true }
|
|
14175
|
+
};
|
|
14703
14176
|
embeddedLinkCache.set(originalLink, ret);
|
|
14704
14177
|
return ret;
|
|
14705
14178
|
}
|
|
14706
14179
|
if (RE_GH_GIST.test(link)) {
|
|
14707
|
-
|
|
14708
|
-
|
|
14709
|
-
|
|
14710
|
-
ret = {
|
|
14711
|
-
type: "document",
|
|
14712
|
-
srcdoc: () => srcDoc,
|
|
14713
|
-
intrinsicSize: { w: 550, h: 720 }
|
|
14714
|
-
};
|
|
14715
|
-
} else {
|
|
14716
|
-
ret = {
|
|
14717
|
-
type: "document",
|
|
14718
|
-
srcdoc: () => createSrcDoc(`
|
|
14180
|
+
const ret = {
|
|
14181
|
+
type: "document",
|
|
14182
|
+
srcdoc: () => createSrcDoc(`
|
|
14719
14183
|
<script src="${link}.js"><\/script>
|
|
14720
14184
|
<style type="text/css">
|
|
14721
14185
|
* { margin: 0px; }
|
|
@@ -14723,9 +14187,8 @@ var getEmbedLink = (link) => {
|
|
|
14723
14187
|
.gist .gist-file { height: calc(100vh - 2px); padding: 0px; display: grid; grid-template-rows: 1fr auto; }
|
|
14724
14188
|
</style>
|
|
14725
14189
|
`),
|
|
14726
|
-
|
|
14727
|
-
|
|
14728
|
-
}
|
|
14190
|
+
intrinsicSize: { w: 550, h: 720 }
|
|
14191
|
+
};
|
|
14729
14192
|
embeddedLinkCache.set(link, ret);
|
|
14730
14193
|
return ret;
|
|
14731
14194
|
}
|
|
@@ -14810,8 +14273,8 @@ var maybeParseEmbedSrc = (str) => {
|
|
|
14810
14273
|
return twitterMatch[1];
|
|
14811
14274
|
}
|
|
14812
14275
|
const gistMatch = str.match(RE_GH_GIST_EMBED);
|
|
14813
|
-
if (gistMatch && gistMatch.length ===
|
|
14814
|
-
return gistMatch[1]
|
|
14276
|
+
if (gistMatch && gistMatch.length === 3) {
|
|
14277
|
+
return `https://gist.github.com/${gistMatch[1]}/${gistMatch[2]}`;
|
|
14815
14278
|
}
|
|
14816
14279
|
if (RE_GIPHY.test(str)) {
|
|
14817
14280
|
return `https://giphy.com/embed/${RE_GIPHY.exec(str)[1]}`;
|
|
@@ -15382,6 +14845,9 @@ var ImageSceneDataError = class extends Error {
|
|
|
15382
14845
|
this.code = code;
|
|
15383
14846
|
}
|
|
15384
14847
|
};
|
|
14848
|
+
var InvalidFractionalIndexError = class extends Error {
|
|
14849
|
+
code = "ELEMENT_HAS_INVALID_INDEX";
|
|
14850
|
+
};
|
|
15385
14851
|
|
|
15386
14852
|
// data/filesystem.ts
|
|
15387
14853
|
var INPUT_CHANGE_INTERVAL_MS = 500;
|
|
@@ -15616,12 +15082,576 @@ var normalizeSVG = async (SVGString) => {
|
|
|
15616
15082
|
return svg.outerHTML;
|
|
15617
15083
|
}
|
|
15618
15084
|
};
|
|
15619
|
-
|
|
15620
|
-
//
|
|
15621
|
-
init_define_import_meta_env();
|
|
15085
|
+
|
|
15086
|
+
// fractionalIndex.ts
|
|
15087
|
+
init_define_import_meta_env();
|
|
15088
|
+
|
|
15089
|
+
// ../../node_modules/fractional-indexing/src/index.js
|
|
15090
|
+
init_define_import_meta_env();
|
|
15091
|
+
var BASE_62_DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
15092
|
+
function midpoint(a2, b2, digits) {
|
|
15093
|
+
const zero = digits[0];
|
|
15094
|
+
if (b2 != null && a2 >= b2) {
|
|
15095
|
+
throw new Error(a2 + " >= " + b2);
|
|
15096
|
+
}
|
|
15097
|
+
if (a2.slice(-1) === zero || b2 && b2.slice(-1) === zero) {
|
|
15098
|
+
throw new Error("trailing zero");
|
|
15099
|
+
}
|
|
15100
|
+
if (b2) {
|
|
15101
|
+
let n2 = 0;
|
|
15102
|
+
while ((a2[n2] || zero) === b2[n2]) {
|
|
15103
|
+
n2++;
|
|
15104
|
+
}
|
|
15105
|
+
if (n2 > 0) {
|
|
15106
|
+
return b2.slice(0, n2) + midpoint(a2.slice(n2), b2.slice(n2), digits);
|
|
15107
|
+
}
|
|
15108
|
+
}
|
|
15109
|
+
const digitA = a2 ? digits.indexOf(a2[0]) : 0;
|
|
15110
|
+
const digitB = b2 != null ? digits.indexOf(b2[0]) : digits.length;
|
|
15111
|
+
if (digitB - digitA > 1) {
|
|
15112
|
+
const midDigit = Math.round(0.5 * (digitA + digitB));
|
|
15113
|
+
return digits[midDigit];
|
|
15114
|
+
} else {
|
|
15115
|
+
if (b2 && b2.length > 1) {
|
|
15116
|
+
return b2.slice(0, 1);
|
|
15117
|
+
} else {
|
|
15118
|
+
return digits[digitA] + midpoint(a2.slice(1), null, digits);
|
|
15119
|
+
}
|
|
15120
|
+
}
|
|
15121
|
+
}
|
|
15122
|
+
function validateInteger(int) {
|
|
15123
|
+
if (int.length !== getIntegerLength(int[0])) {
|
|
15124
|
+
throw new Error("invalid integer part of order key: " + int);
|
|
15125
|
+
}
|
|
15126
|
+
}
|
|
15127
|
+
function getIntegerLength(head) {
|
|
15128
|
+
if (head >= "a" && head <= "z") {
|
|
15129
|
+
return head.charCodeAt(0) - "a".charCodeAt(0) + 2;
|
|
15130
|
+
} else if (head >= "A" && head <= "Z") {
|
|
15131
|
+
return "Z".charCodeAt(0) - head.charCodeAt(0) + 2;
|
|
15132
|
+
} else {
|
|
15133
|
+
throw new Error("invalid order key head: " + head);
|
|
15134
|
+
}
|
|
15135
|
+
}
|
|
15136
|
+
function getIntegerPart(key) {
|
|
15137
|
+
const integerPartLength = getIntegerLength(key[0]);
|
|
15138
|
+
if (integerPartLength > key.length) {
|
|
15139
|
+
throw new Error("invalid order key: " + key);
|
|
15140
|
+
}
|
|
15141
|
+
return key.slice(0, integerPartLength);
|
|
15142
|
+
}
|
|
15143
|
+
function validateOrderKey(key, digits) {
|
|
15144
|
+
if (key === "A" + digits[0].repeat(26)) {
|
|
15145
|
+
throw new Error("invalid order key: " + key);
|
|
15146
|
+
}
|
|
15147
|
+
const i2 = getIntegerPart(key);
|
|
15148
|
+
const f = key.slice(i2.length);
|
|
15149
|
+
if (f.slice(-1) === digits[0]) {
|
|
15150
|
+
throw new Error("invalid order key: " + key);
|
|
15151
|
+
}
|
|
15152
|
+
}
|
|
15153
|
+
function incrementInteger(x, digits) {
|
|
15154
|
+
validateInteger(x);
|
|
15155
|
+
const [head, ...digs] = x.split("");
|
|
15156
|
+
let carry = true;
|
|
15157
|
+
for (let i2 = digs.length - 1; carry && i2 >= 0; i2--) {
|
|
15158
|
+
const d = digits.indexOf(digs[i2]) + 1;
|
|
15159
|
+
if (d === digits.length) {
|
|
15160
|
+
digs[i2] = digits[0];
|
|
15161
|
+
} else {
|
|
15162
|
+
digs[i2] = digits[d];
|
|
15163
|
+
carry = false;
|
|
15164
|
+
}
|
|
15165
|
+
}
|
|
15166
|
+
if (carry) {
|
|
15167
|
+
if (head === "Z") {
|
|
15168
|
+
return "a" + digits[0];
|
|
15169
|
+
}
|
|
15170
|
+
if (head === "z") {
|
|
15171
|
+
return null;
|
|
15172
|
+
}
|
|
15173
|
+
const h = String.fromCharCode(head.charCodeAt(0) + 1);
|
|
15174
|
+
if (h > "a") {
|
|
15175
|
+
digs.push(digits[0]);
|
|
15176
|
+
} else {
|
|
15177
|
+
digs.pop();
|
|
15178
|
+
}
|
|
15179
|
+
return h + digs.join("");
|
|
15180
|
+
} else {
|
|
15181
|
+
return head + digs.join("");
|
|
15182
|
+
}
|
|
15183
|
+
}
|
|
15184
|
+
function decrementInteger(x, digits) {
|
|
15185
|
+
validateInteger(x);
|
|
15186
|
+
const [head, ...digs] = x.split("");
|
|
15187
|
+
let borrow = true;
|
|
15188
|
+
for (let i2 = digs.length - 1; borrow && i2 >= 0; i2--) {
|
|
15189
|
+
const d = digits.indexOf(digs[i2]) - 1;
|
|
15190
|
+
if (d === -1) {
|
|
15191
|
+
digs[i2] = digits.slice(-1);
|
|
15192
|
+
} else {
|
|
15193
|
+
digs[i2] = digits[d];
|
|
15194
|
+
borrow = false;
|
|
15195
|
+
}
|
|
15196
|
+
}
|
|
15197
|
+
if (borrow) {
|
|
15198
|
+
if (head === "a") {
|
|
15199
|
+
return "Z" + digits.slice(-1);
|
|
15200
|
+
}
|
|
15201
|
+
if (head === "A") {
|
|
15202
|
+
return null;
|
|
15203
|
+
}
|
|
15204
|
+
const h = String.fromCharCode(head.charCodeAt(0) - 1);
|
|
15205
|
+
if (h < "Z") {
|
|
15206
|
+
digs.push(digits.slice(-1));
|
|
15207
|
+
} else {
|
|
15208
|
+
digs.pop();
|
|
15209
|
+
}
|
|
15210
|
+
return h + digs.join("");
|
|
15211
|
+
} else {
|
|
15212
|
+
return head + digs.join("");
|
|
15213
|
+
}
|
|
15214
|
+
}
|
|
15215
|
+
function generateKeyBetween(a2, b2, digits = BASE_62_DIGITS) {
|
|
15216
|
+
if (a2 != null) {
|
|
15217
|
+
validateOrderKey(a2, digits);
|
|
15218
|
+
}
|
|
15219
|
+
if (b2 != null) {
|
|
15220
|
+
validateOrderKey(b2, digits);
|
|
15221
|
+
}
|
|
15222
|
+
if (a2 != null && b2 != null && a2 >= b2) {
|
|
15223
|
+
throw new Error(a2 + " >= " + b2);
|
|
15224
|
+
}
|
|
15225
|
+
if (a2 == null) {
|
|
15226
|
+
if (b2 == null) {
|
|
15227
|
+
return "a" + digits[0];
|
|
15228
|
+
}
|
|
15229
|
+
const ib2 = getIntegerPart(b2);
|
|
15230
|
+
const fb2 = b2.slice(ib2.length);
|
|
15231
|
+
if (ib2 === "A" + digits[0].repeat(26)) {
|
|
15232
|
+
return ib2 + midpoint("", fb2, digits);
|
|
15233
|
+
}
|
|
15234
|
+
if (ib2 < b2) {
|
|
15235
|
+
return ib2;
|
|
15236
|
+
}
|
|
15237
|
+
const res = decrementInteger(ib2, digits);
|
|
15238
|
+
if (res == null) {
|
|
15239
|
+
throw new Error("cannot decrement any more");
|
|
15240
|
+
}
|
|
15241
|
+
return res;
|
|
15242
|
+
}
|
|
15243
|
+
if (b2 == null) {
|
|
15244
|
+
const ia2 = getIntegerPart(a2);
|
|
15245
|
+
const fa2 = a2.slice(ia2.length);
|
|
15246
|
+
const i3 = incrementInteger(ia2, digits);
|
|
15247
|
+
return i3 == null ? ia2 + midpoint(fa2, null, digits) : i3;
|
|
15248
|
+
}
|
|
15249
|
+
const ia = getIntegerPart(a2);
|
|
15250
|
+
const fa = a2.slice(ia.length);
|
|
15251
|
+
const ib = getIntegerPart(b2);
|
|
15252
|
+
const fb = b2.slice(ib.length);
|
|
15253
|
+
if (ia === ib) {
|
|
15254
|
+
return ia + midpoint(fa, fb, digits);
|
|
15255
|
+
}
|
|
15256
|
+
const i2 = incrementInteger(ia, digits);
|
|
15257
|
+
if (i2 == null) {
|
|
15258
|
+
throw new Error("cannot increment any more");
|
|
15259
|
+
}
|
|
15260
|
+
if (i2 < b2) {
|
|
15261
|
+
return i2;
|
|
15262
|
+
}
|
|
15263
|
+
return ia + midpoint(fa, null, digits);
|
|
15264
|
+
}
|
|
15265
|
+
function generateNKeysBetween(a2, b2, n2, digits = BASE_62_DIGITS) {
|
|
15266
|
+
if (n2 === 0) {
|
|
15267
|
+
return [];
|
|
15268
|
+
}
|
|
15269
|
+
if (n2 === 1) {
|
|
15270
|
+
return [generateKeyBetween(a2, b2, digits)];
|
|
15271
|
+
}
|
|
15272
|
+
if (b2 == null) {
|
|
15273
|
+
let c2 = generateKeyBetween(a2, b2, digits);
|
|
15274
|
+
const result = [c2];
|
|
15275
|
+
for (let i2 = 0; i2 < n2 - 1; i2++) {
|
|
15276
|
+
c2 = generateKeyBetween(c2, b2, digits);
|
|
15277
|
+
result.push(c2);
|
|
15278
|
+
}
|
|
15279
|
+
return result;
|
|
15280
|
+
}
|
|
15281
|
+
if (a2 == null) {
|
|
15282
|
+
let c2 = generateKeyBetween(a2, b2, digits);
|
|
15283
|
+
const result = [c2];
|
|
15284
|
+
for (let i2 = 0; i2 < n2 - 1; i2++) {
|
|
15285
|
+
c2 = generateKeyBetween(a2, c2, digits);
|
|
15286
|
+
result.push(c2);
|
|
15287
|
+
}
|
|
15288
|
+
result.reverse();
|
|
15289
|
+
return result;
|
|
15290
|
+
}
|
|
15291
|
+
const mid = Math.floor(n2 / 2);
|
|
15292
|
+
const c = generateKeyBetween(a2, b2, digits);
|
|
15293
|
+
return [
|
|
15294
|
+
...generateNKeysBetween(a2, c, mid, digits),
|
|
15295
|
+
c,
|
|
15296
|
+
...generateNKeysBetween(c, b2, n2 - mid - 1, digits)
|
|
15297
|
+
];
|
|
15298
|
+
}
|
|
15299
|
+
|
|
15300
|
+
// fractionalIndex.ts
|
|
15301
|
+
var validateFractionalIndices = (indices) => {
|
|
15302
|
+
for (const [i2, index] of indices.entries()) {
|
|
15303
|
+
const predecessorIndex = indices[i2 - 1];
|
|
15304
|
+
const successorIndex = indices[i2 + 1];
|
|
15305
|
+
if (!isValidFractionalIndex(index, predecessorIndex, successorIndex)) {
|
|
15306
|
+
throw new InvalidFractionalIndexError(
|
|
15307
|
+
`Fractional indices invariant for element has been compromised - ["${predecessorIndex}", "${index}", "${successorIndex}"] [predecessor, current, successor]`
|
|
15308
|
+
);
|
|
15309
|
+
}
|
|
15310
|
+
}
|
|
15311
|
+
};
|
|
15312
|
+
var syncMovedIndices = (elements, movedElements) => {
|
|
15313
|
+
try {
|
|
15314
|
+
const indicesGroups = getMovedIndicesGroups(elements, movedElements);
|
|
15315
|
+
const elementsUpdates = generateIndices(elements, indicesGroups);
|
|
15316
|
+
validateFractionalIndices(
|
|
15317
|
+
elements.map((x) => elementsUpdates.get(x)?.index || x.index)
|
|
15318
|
+
);
|
|
15319
|
+
for (const [element, update] of elementsUpdates) {
|
|
15320
|
+
mutateElement(element, update, false);
|
|
15321
|
+
}
|
|
15322
|
+
} catch (e2) {
|
|
15323
|
+
syncInvalidIndices(elements);
|
|
15324
|
+
}
|
|
15325
|
+
return elements;
|
|
15326
|
+
};
|
|
15327
|
+
var syncInvalidIndices = (elements) => {
|
|
15328
|
+
const indicesGroups = getInvalidIndicesGroups(elements);
|
|
15329
|
+
const elementsUpdates = generateIndices(elements, indicesGroups);
|
|
15330
|
+
for (const [element, update] of elementsUpdates) {
|
|
15331
|
+
mutateElement(element, update, false);
|
|
15332
|
+
}
|
|
15333
|
+
return elements;
|
|
15334
|
+
};
|
|
15335
|
+
var getMovedIndicesGroups = (elements, movedElements) => {
|
|
15336
|
+
const indicesGroups = [];
|
|
15337
|
+
let i2 = 0;
|
|
15338
|
+
while (i2 < elements.length) {
|
|
15339
|
+
if (movedElements.has(elements[i2].id) && !isValidFractionalIndex(
|
|
15340
|
+
elements[i2]?.index,
|
|
15341
|
+
elements[i2 - 1]?.index,
|
|
15342
|
+
elements[i2 + 1]?.index
|
|
15343
|
+
)) {
|
|
15344
|
+
const indicesGroup = [i2 - 1, i2];
|
|
15345
|
+
while (++i2 < elements.length) {
|
|
15346
|
+
if (!(movedElements.has(elements[i2].id) && !isValidFractionalIndex(
|
|
15347
|
+
elements[i2]?.index,
|
|
15348
|
+
elements[i2 - 1]?.index,
|
|
15349
|
+
elements[i2 + 1]?.index
|
|
15350
|
+
))) {
|
|
15351
|
+
break;
|
|
15352
|
+
}
|
|
15353
|
+
indicesGroup.push(i2);
|
|
15354
|
+
}
|
|
15355
|
+
indicesGroup.push(i2);
|
|
15356
|
+
indicesGroups.push(indicesGroup);
|
|
15357
|
+
} else {
|
|
15358
|
+
i2++;
|
|
15359
|
+
}
|
|
15360
|
+
}
|
|
15361
|
+
return indicesGroups;
|
|
15362
|
+
};
|
|
15363
|
+
var getInvalidIndicesGroups = (elements) => {
|
|
15364
|
+
const indicesGroups = [];
|
|
15365
|
+
let lowerBound = void 0;
|
|
15366
|
+
let upperBound = void 0;
|
|
15367
|
+
let lowerBoundIndex = -1;
|
|
15368
|
+
let upperBoundIndex = 0;
|
|
15369
|
+
const getLowerBound = (index) => {
|
|
15370
|
+
const lowerBound2 = elements[lowerBoundIndex] ? elements[lowerBoundIndex].index : void 0;
|
|
15371
|
+
const candidate = elements[index - 1]?.index;
|
|
15372
|
+
if (!lowerBound2 && candidate || // first lowerBound
|
|
15373
|
+
lowerBound2 && candidate && candidate > lowerBound2) {
|
|
15374
|
+
return [candidate, index - 1];
|
|
15375
|
+
}
|
|
15376
|
+
return [lowerBound2, lowerBoundIndex];
|
|
15377
|
+
};
|
|
15378
|
+
const getUpperBound = (index) => {
|
|
15379
|
+
const upperBound2 = elements[upperBoundIndex] ? elements[upperBoundIndex].index : void 0;
|
|
15380
|
+
if (upperBound2 && index < upperBoundIndex) {
|
|
15381
|
+
return [upperBound2, upperBoundIndex];
|
|
15382
|
+
}
|
|
15383
|
+
let i3 = upperBoundIndex;
|
|
15384
|
+
while (++i3 < elements.length) {
|
|
15385
|
+
const candidate = elements[i3]?.index;
|
|
15386
|
+
if (!upperBound2 && candidate || // first upperBound
|
|
15387
|
+
upperBound2 && candidate && candidate > upperBound2) {
|
|
15388
|
+
return [candidate, i3];
|
|
15389
|
+
}
|
|
15390
|
+
}
|
|
15391
|
+
return [void 0, i3];
|
|
15392
|
+
};
|
|
15393
|
+
let i2 = 0;
|
|
15394
|
+
while (i2 < elements.length) {
|
|
15395
|
+
const current = elements[i2].index;
|
|
15396
|
+
[lowerBound, lowerBoundIndex] = getLowerBound(i2);
|
|
15397
|
+
[upperBound, upperBoundIndex] = getUpperBound(i2);
|
|
15398
|
+
if (!isValidFractionalIndex(current, lowerBound, upperBound)) {
|
|
15399
|
+
const indicesGroup = [lowerBoundIndex, i2];
|
|
15400
|
+
while (++i2 < elements.length) {
|
|
15401
|
+
const current2 = elements[i2].index;
|
|
15402
|
+
const [nextLowerBound, nextLowerBoundIndex] = getLowerBound(i2);
|
|
15403
|
+
const [nextUpperBound, nextUpperBoundIndex] = getUpperBound(i2);
|
|
15404
|
+
if (isValidFractionalIndex(current2, nextLowerBound, nextUpperBound)) {
|
|
15405
|
+
break;
|
|
15406
|
+
}
|
|
15407
|
+
[lowerBound, lowerBoundIndex] = [nextLowerBound, nextLowerBoundIndex];
|
|
15408
|
+
[upperBound, upperBoundIndex] = [nextUpperBound, nextUpperBoundIndex];
|
|
15409
|
+
indicesGroup.push(i2);
|
|
15410
|
+
}
|
|
15411
|
+
indicesGroup.push(upperBoundIndex);
|
|
15412
|
+
indicesGroups.push(indicesGroup);
|
|
15413
|
+
} else {
|
|
15414
|
+
i2++;
|
|
15415
|
+
}
|
|
15416
|
+
}
|
|
15417
|
+
return indicesGroups;
|
|
15418
|
+
};
|
|
15419
|
+
var isValidFractionalIndex = (index, predecessor, successor) => {
|
|
15420
|
+
if (!index) {
|
|
15421
|
+
return false;
|
|
15422
|
+
}
|
|
15423
|
+
if (predecessor && successor) {
|
|
15424
|
+
return predecessor < index && index < successor;
|
|
15425
|
+
}
|
|
15426
|
+
if (!predecessor && successor) {
|
|
15427
|
+
return index < successor;
|
|
15428
|
+
}
|
|
15429
|
+
if (predecessor && !successor) {
|
|
15430
|
+
return predecessor < index;
|
|
15431
|
+
}
|
|
15432
|
+
return !!index;
|
|
15433
|
+
};
|
|
15434
|
+
var generateIndices = (elements, indicesGroups) => {
|
|
15435
|
+
const elementsUpdates = /* @__PURE__ */ new Map();
|
|
15436
|
+
for (const indices of indicesGroups) {
|
|
15437
|
+
const lowerBoundIndex = indices.shift();
|
|
15438
|
+
const upperBoundIndex = indices.pop();
|
|
15439
|
+
const fractionalIndices = generateNKeysBetween(
|
|
15440
|
+
elements[lowerBoundIndex]?.index,
|
|
15441
|
+
elements[upperBoundIndex]?.index,
|
|
15442
|
+
indices.length
|
|
15443
|
+
);
|
|
15444
|
+
for (let i2 = 0; i2 < indices.length; i2++) {
|
|
15445
|
+
const element = elements[indices[i2]];
|
|
15446
|
+
elementsUpdates.set(element, {
|
|
15447
|
+
index: fractionalIndices[i2]
|
|
15448
|
+
});
|
|
15449
|
+
}
|
|
15450
|
+
}
|
|
15451
|
+
return elementsUpdates;
|
|
15452
|
+
};
|
|
15453
|
+
|
|
15454
|
+
// renderer/staticScene.ts
|
|
15455
|
+
init_define_import_meta_env();
|
|
15456
|
+
|
|
15457
|
+
// components/hyperlink/helpers.ts
|
|
15458
|
+
init_define_import_meta_env();
|
|
15459
|
+
|
|
15460
|
+
// element/collision.ts
|
|
15461
|
+
init_define_import_meta_env();
|
|
15462
|
+
|
|
15463
|
+
// ../utils/geometry/shape.ts
|
|
15464
|
+
init_define_import_meta_env();
|
|
15465
|
+
var getPolygonShape = (element) => {
|
|
15466
|
+
const { angle, width, height, x, y } = element;
|
|
15467
|
+
const angleInDegrees = angleToDegrees(angle);
|
|
15468
|
+
const cx = x + width / 2;
|
|
15469
|
+
const cy = y + height / 2;
|
|
15470
|
+
const center = [cx, cy];
|
|
15471
|
+
let data = [];
|
|
15472
|
+
if (element.type === "diamond") {
|
|
15473
|
+
data = [
|
|
15474
|
+
pointRotate([cx, y], angleInDegrees, center),
|
|
15475
|
+
pointRotate([x + width, cy], angleInDegrees, center),
|
|
15476
|
+
pointRotate([cx, y + height], angleInDegrees, center),
|
|
15477
|
+
pointRotate([x, cy], angleInDegrees, center)
|
|
15478
|
+
];
|
|
15479
|
+
} else {
|
|
15480
|
+
data = [
|
|
15481
|
+
pointRotate([x, y], angleInDegrees, center),
|
|
15482
|
+
pointRotate([x + width, y], angleInDegrees, center),
|
|
15483
|
+
pointRotate([x + width, y + height], angleInDegrees, center),
|
|
15484
|
+
pointRotate([x, y + height], angleInDegrees, center)
|
|
15485
|
+
];
|
|
15486
|
+
}
|
|
15487
|
+
return {
|
|
15488
|
+
type: "polygon",
|
|
15489
|
+
data
|
|
15490
|
+
};
|
|
15491
|
+
};
|
|
15492
|
+
var getEllipseShape = (element) => {
|
|
15493
|
+
const { width, height, angle, x, y } = element;
|
|
15494
|
+
return {
|
|
15495
|
+
type: "ellipse",
|
|
15496
|
+
data: {
|
|
15497
|
+
center: [x + width / 2, y + height / 2],
|
|
15498
|
+
angle,
|
|
15499
|
+
halfWidth: width / 2,
|
|
15500
|
+
halfHeight: height / 2
|
|
15501
|
+
}
|
|
15502
|
+
};
|
|
15503
|
+
};
|
|
15504
|
+
var getCurvePathOps2 = (shape) => {
|
|
15505
|
+
for (const set of shape.sets) {
|
|
15506
|
+
if (set.type === "path") {
|
|
15507
|
+
return set.ops;
|
|
15508
|
+
}
|
|
15509
|
+
}
|
|
15510
|
+
return shape.sets[0].ops;
|
|
15511
|
+
};
|
|
15512
|
+
var getCurveShape = (roughShape, startingPoint = [0, 0], angleInRadian, center) => {
|
|
15513
|
+
const transform = (p) => pointRotate(
|
|
15514
|
+
[p[0] + startingPoint[0], p[1] + startingPoint[1]],
|
|
15515
|
+
angleToDegrees(angleInRadian),
|
|
15516
|
+
center
|
|
15517
|
+
);
|
|
15518
|
+
const ops = getCurvePathOps2(roughShape);
|
|
15519
|
+
const polycurve = [];
|
|
15520
|
+
let p0 = [0, 0];
|
|
15521
|
+
for (const op of ops) {
|
|
15522
|
+
if (op.op === "move") {
|
|
15523
|
+
p0 = transform(op.data);
|
|
15524
|
+
}
|
|
15525
|
+
if (op.op === "bcurveTo") {
|
|
15526
|
+
const p1 = transform([op.data[0], op.data[1]]);
|
|
15527
|
+
const p2 = transform([op.data[2], op.data[3]]);
|
|
15528
|
+
const p3 = transform([op.data[4], op.data[5]]);
|
|
15529
|
+
polycurve.push([p0, p1, p2, p3]);
|
|
15530
|
+
p0 = p3;
|
|
15531
|
+
}
|
|
15532
|
+
}
|
|
15533
|
+
return {
|
|
15534
|
+
type: "polycurve",
|
|
15535
|
+
data: polycurve
|
|
15536
|
+
};
|
|
15537
|
+
};
|
|
15538
|
+
var polylineFromPoints = (points) => {
|
|
15539
|
+
let previousPoint = points[0];
|
|
15540
|
+
const polyline = [];
|
|
15541
|
+
for (let i2 = 1; i2 < points.length; i2++) {
|
|
15542
|
+
const nextPoint = points[i2];
|
|
15543
|
+
polyline.push([previousPoint, nextPoint]);
|
|
15544
|
+
previousPoint = nextPoint;
|
|
15545
|
+
}
|
|
15546
|
+
return polyline;
|
|
15547
|
+
};
|
|
15548
|
+
var getFreedrawShape = (element, center, isClosed2 = false) => {
|
|
15549
|
+
const angle = angleToDegrees(element.angle);
|
|
15550
|
+
const transform = (p) => pointRotate(pointAdd(p, [element.x, element.y]), angle, center);
|
|
15551
|
+
const polyline = polylineFromPoints(
|
|
15552
|
+
element.points.map((p) => transform(p))
|
|
15553
|
+
);
|
|
15554
|
+
return isClosed2 ? {
|
|
15555
|
+
type: "polygon",
|
|
15556
|
+
data: close(polyline.flat())
|
|
15557
|
+
} : {
|
|
15558
|
+
type: "polyline",
|
|
15559
|
+
data: polyline
|
|
15560
|
+
};
|
|
15561
|
+
};
|
|
15562
|
+
var getClosedCurveShape = (element, roughShape, startingPoint = [0, 0], angleInRadian, center) => {
|
|
15563
|
+
const transform = (p) => pointRotate(
|
|
15564
|
+
[p[0] + startingPoint[0], p[1] + startingPoint[1]],
|
|
15565
|
+
angleToDegrees(angleInRadian),
|
|
15566
|
+
center
|
|
15567
|
+
);
|
|
15568
|
+
if (element.roundness === null) {
|
|
15569
|
+
return {
|
|
15570
|
+
type: "polygon",
|
|
15571
|
+
data: close(element.points.map((p) => transform(p)))
|
|
15572
|
+
};
|
|
15573
|
+
}
|
|
15574
|
+
const ops = getCurvePathOps2(roughShape);
|
|
15575
|
+
const points = [];
|
|
15576
|
+
let odd = false;
|
|
15577
|
+
for (const operation of ops) {
|
|
15578
|
+
if (operation.op === "move") {
|
|
15579
|
+
odd = !odd;
|
|
15580
|
+
if (odd) {
|
|
15581
|
+
points.push([operation.data[0], operation.data[1]]);
|
|
15582
|
+
}
|
|
15583
|
+
} else if (operation.op === "bcurveTo") {
|
|
15584
|
+
if (odd) {
|
|
15585
|
+
points.push([operation.data[0], operation.data[1]]);
|
|
15586
|
+
points.push([operation.data[2], operation.data[3]]);
|
|
15587
|
+
points.push([operation.data[4], operation.data[5]]);
|
|
15588
|
+
}
|
|
15589
|
+
} else if (operation.op === "lineTo") {
|
|
15590
|
+
if (odd) {
|
|
15591
|
+
points.push([operation.data[0], operation.data[1]]);
|
|
15592
|
+
}
|
|
15593
|
+
}
|
|
15594
|
+
}
|
|
15595
|
+
const polygonPoints = pointsOnBezierCurves(points, 10, 5).map(
|
|
15596
|
+
(p) => transform(p)
|
|
15597
|
+
);
|
|
15598
|
+
return {
|
|
15599
|
+
type: "polygon",
|
|
15600
|
+
data: polygonPoints
|
|
15601
|
+
};
|
|
15602
|
+
};
|
|
15603
|
+
|
|
15604
|
+
// element/collision.ts
|
|
15605
|
+
var shouldTestInside = (element) => {
|
|
15606
|
+
if (element.type === "arrow") {
|
|
15607
|
+
return false;
|
|
15608
|
+
}
|
|
15609
|
+
const isDraggableFromInside = !isTransparent(element.backgroundColor) || hasBoundTextElement(element) || isIframeLikeElement(element) || isTextElement(element);
|
|
15610
|
+
if (element.type === "line") {
|
|
15611
|
+
return isDraggableFromInside && isPathALoop(element.points);
|
|
15612
|
+
}
|
|
15613
|
+
if (element.type === "freedraw") {
|
|
15614
|
+
return isDraggableFromInside && isPathALoop(element.points);
|
|
15615
|
+
}
|
|
15616
|
+
return isDraggableFromInside || isImageElement(element);
|
|
15617
|
+
};
|
|
15618
|
+
var hitElementItself = ({
|
|
15619
|
+
x,
|
|
15620
|
+
y,
|
|
15621
|
+
element,
|
|
15622
|
+
shape,
|
|
15623
|
+
threshold = 10,
|
|
15624
|
+
frameNameBound = null
|
|
15625
|
+
}) => {
|
|
15626
|
+
let hit = shouldTestInside(element) ? (
|
|
15627
|
+
// Since `inShape` tests STRICTLY againt the insides of a shape
|
|
15628
|
+
// we would need `onShape` as well to include the "borders"
|
|
15629
|
+
isPointInShape([x, y], shape) || isPointOnShape([x, y], shape, threshold)
|
|
15630
|
+
) : isPointOnShape([x, y], shape, threshold);
|
|
15631
|
+
if (!hit && frameNameBound) {
|
|
15632
|
+
hit = isPointInShape([x, y], {
|
|
15633
|
+
type: "polygon",
|
|
15634
|
+
data: getPolygonShape(frameNameBound).data
|
|
15635
|
+
});
|
|
15636
|
+
}
|
|
15637
|
+
return hit;
|
|
15638
|
+
};
|
|
15639
|
+
var hitElementBoundingBox = (x, y, element, elementsMap, tolerance = 0) => {
|
|
15640
|
+
let [x1, y1, x2, y2] = getElementBounds(element, elementsMap);
|
|
15641
|
+
x1 -= tolerance;
|
|
15642
|
+
y1 -= tolerance;
|
|
15643
|
+
x2 += tolerance;
|
|
15644
|
+
y2 += tolerance;
|
|
15645
|
+
return isPointWithinBounds([x1, y1], [x, y], [x2, y2]);
|
|
15646
|
+
};
|
|
15647
|
+
var hitElementBoundingBoxOnly = (hitArgs, elementsMap) => {
|
|
15648
|
+
return !hitElementItself(hitArgs) && hitElementBoundingBox(hitArgs.x, hitArgs.y, hitArgs.element, elementsMap);
|
|
15649
|
+
};
|
|
15650
|
+
var hitElementBoundText = (x, y, textShape) => {
|
|
15651
|
+
return textShape && isPointInShape([x, y], textShape);
|
|
15652
|
+
};
|
|
15622
15653
|
|
|
15623
15654
|
// components/hyperlink/helpers.ts
|
|
15624
|
-
init_define_import_meta_env();
|
|
15625
15655
|
var EXTERNAL_LINK_IMG = document.createElement("img");
|
|
15626
15656
|
EXTERNAL_LINK_IMG.src = `data:${MIME_TYPES.svg}, ${encodeURIComponent(
|
|
15627
15657
|
`<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#1971c2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-external-link"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg>`
|
|
@@ -15637,7 +15667,7 @@ var getLinkHandleFromCoords = ([x1, y1, x2, y2], angle, appState) => {
|
|
|
15637
15667
|
const dashedLineMargin = 4 / appState.zoom.value;
|
|
15638
15668
|
const x = x2 + dashedLineMargin - centeringOffset;
|
|
15639
15669
|
const y = y1 - dashedLineMargin - linkMarginY + centeringOffset;
|
|
15640
|
-
const [rotatedX, rotatedY] =
|
|
15670
|
+
const [rotatedX, rotatedY] = rotate3(
|
|
15641
15671
|
x + linkWidth / 2,
|
|
15642
15672
|
y + linkHeight / 2,
|
|
15643
15673
|
centerX,
|
|
@@ -15666,14 +15696,7 @@ var isPointHittingLink = (element, elementsMap, appState, [x, y], isMobile) => {
|
|
|
15666
15696
|
if (!element.link || appState.selectedElementIds[element.id]) {
|
|
15667
15697
|
return false;
|
|
15668
15698
|
}
|
|
15669
|
-
|
|
15670
|
-
if (!isMobile && appState.viewModeEnabled && isPointHittingElementBoundingBox(
|
|
15671
|
-
element,
|
|
15672
|
-
elementsMap,
|
|
15673
|
-
[x, y],
|
|
15674
|
-
threshold,
|
|
15675
|
-
null
|
|
15676
|
-
)) {
|
|
15699
|
+
if (!isMobile && appState.viewModeEnabled && hitElementBoundingBox(x, y, element, elementsMap)) {
|
|
15677
15700
|
return true;
|
|
15678
15701
|
}
|
|
15679
15702
|
return isPointHittingLinkIcon(element, elementsMap, appState, [x, y]);
|
|
@@ -15704,7 +15727,7 @@ var bootstrapCanvas = ({
|
|
|
15704
15727
|
const context = canvas2.getContext("2d");
|
|
15705
15728
|
context.setTransform(1, 0, 0, 1, 0, 0);
|
|
15706
15729
|
context.scale(scale, scale);
|
|
15707
|
-
if (isExporting && theme ===
|
|
15730
|
+
if (isExporting && theme === THEME.DARK) {
|
|
15708
15731
|
context.filter = THEME_FILTER;
|
|
15709
15732
|
}
|
|
15710
15733
|
if (typeof viewBackgroundColor === "string") {
|
|
@@ -16100,7 +16123,7 @@ var exportToCanvas = async (elements, appState, files, {
|
|
|
16100
16123
|
arrayToMap(elementsForRender)
|
|
16101
16124
|
),
|
|
16102
16125
|
allElementsMap: toBrandedType(
|
|
16103
|
-
arrayToMap(elements)
|
|
16126
|
+
arrayToMap(syncInvalidIndices(elements))
|
|
16104
16127
|
),
|
|
16105
16128
|
visibleElements: elementsForRender,
|
|
16106
16129
|
scale,
|
|
@@ -16112,7 +16135,7 @@ var exportToCanvas = async (elements, appState, files, {
|
|
|
16112
16135
|
scrollY: -minY + exportPadding,
|
|
16113
16136
|
zoom: defaultAppState2.zoom,
|
|
16114
16137
|
shouldCacheIgnoreZoom: false,
|
|
16115
|
-
theme: appState.exportWithDarkMode ?
|
|
16138
|
+
theme: appState.exportWithDarkMode ? THEME.DARK : THEME.LIGHT
|
|
16116
16139
|
},
|
|
16117
16140
|
renderConfig: {
|
|
16118
16141
|
canvasBackgroundColor: viewBackgroundColor,
|
|
@@ -16151,7 +16174,7 @@ var exportToSvg = async (elements, appState, files, opts) => {
|
|
|
16151
16174
|
let metadata = "";
|
|
16152
16175
|
if (exportEmbedScene) {
|
|
16153
16176
|
try {
|
|
16154
|
-
metadata = await (await import("./image-
|
|
16177
|
+
metadata = await (await import("./image-JKT6GXZD.js")).encodeSvgMetadata({
|
|
16155
16178
|
// when embedding scene, we want to embed the origionally supplied
|
|
16156
16179
|
// elements which don't contain the temp frame labels.
|
|
16157
16180
|
// But it also requires that the exportToSvg is being supplied with
|
|
@@ -16305,6 +16328,7 @@ var restoreElementWithProperties = (element, extra) => {
|
|
|
16305
16328
|
// newly added elements
|
|
16306
16329
|
version: element.version || 1,
|
|
16307
16330
|
versionNonce: element.versionNonce ?? 0,
|
|
16331
|
+
index: element.index ?? null,
|
|
16308
16332
|
isDeleted: element.isDeleted ?? false,
|
|
16309
16333
|
id: element.id || randomId(),
|
|
16310
16334
|
fillStyle: element.fillStyle || DEFAULT_ELEMENT_PROPS.fillStyle,
|
|
@@ -16335,9 +16359,6 @@ var restoreElementWithProperties = (element, extra) => {
|
|
|
16335
16359
|
if ("customData" in element || "customData" in extra) {
|
|
16336
16360
|
base.customData = "customData" in extra ? extra.customData : element.customData;
|
|
16337
16361
|
}
|
|
16338
|
-
if (PRECEDING_ELEMENT_KEY in element) {
|
|
16339
|
-
base[PRECEDING_ELEMENT_KEY] = element[PRECEDING_ELEMENT_KEY];
|
|
16340
|
-
}
|
|
16341
16362
|
return {
|
|
16342
16363
|
...base,
|
|
16343
16364
|
...getNormalizedDimensions(base),
|
|
@@ -16488,23 +16509,28 @@ var repairFrameMembership = (element, elementsMap) => {
|
|
|
16488
16509
|
var restoreElements = (elements, localElements, opts) => {
|
|
16489
16510
|
const existingIds = /* @__PURE__ */ new Set();
|
|
16490
16511
|
const localElementsMap = localElements ? arrayToMap(localElements) : null;
|
|
16491
|
-
const restoredElements = (
|
|
16492
|
-
|
|
16493
|
-
|
|
16494
|
-
|
|
16495
|
-
|
|
16496
|
-
|
|
16497
|
-
|
|
16498
|
-
|
|
16499
|
-
|
|
16500
|
-
|
|
16512
|
+
const restoredElements = syncInvalidIndices(
|
|
16513
|
+
(elements || []).reduce((elements2, element) => {
|
|
16514
|
+
if (element.type !== "selection" && !isInvisiblySmallElement(element)) {
|
|
16515
|
+
let migratedElement = restoreElement(element);
|
|
16516
|
+
if (migratedElement) {
|
|
16517
|
+
const localElement = localElementsMap?.get(element.id);
|
|
16518
|
+
if (localElement && localElement.version > migratedElement.version) {
|
|
16519
|
+
migratedElement = bumpVersion(
|
|
16520
|
+
migratedElement,
|
|
16521
|
+
localElement.version
|
|
16522
|
+
);
|
|
16523
|
+
}
|
|
16524
|
+
if (existingIds.has(migratedElement.id)) {
|
|
16525
|
+
migratedElement = { ...migratedElement, id: randomId() };
|
|
16526
|
+
}
|
|
16527
|
+
existingIds.add(migratedElement.id);
|
|
16528
|
+
elements2.push(migratedElement);
|
|
16501
16529
|
}
|
|
16502
|
-
existingIds.add(migratedElement.id);
|
|
16503
|
-
elements2.push(migratedElement);
|
|
16504
16530
|
}
|
|
16505
|
-
|
|
16506
|
-
|
|
16507
|
-
|
|
16531
|
+
return elements2;
|
|
16532
|
+
}, [])
|
|
16533
|
+
);
|
|
16508
16534
|
if (!opts?.repairBindings) {
|
|
16509
16535
|
return restoredElements;
|
|
16510
16536
|
}
|
|
@@ -18117,7 +18143,10 @@ var getNonDeletedElements3 = (allElements) => {
|
|
|
18117
18143
|
for (const element of allElements) {
|
|
18118
18144
|
if (!element.isDeleted) {
|
|
18119
18145
|
elements.push(element);
|
|
18120
|
-
elementsMap.set(
|
|
18146
|
+
elementsMap.set(
|
|
18147
|
+
element.id,
|
|
18148
|
+
element
|
|
18149
|
+
);
|
|
18121
18150
|
}
|
|
18122
18151
|
}
|
|
18123
18152
|
return { elementsMap, elements };
|
|
@@ -18164,6 +18193,7 @@ var Scene = class _Scene {
|
|
|
18164
18193
|
nonDeletedElementsMap = toBrandedType(
|
|
18165
18194
|
/* @__PURE__ */ new Map()
|
|
18166
18195
|
);
|
|
18196
|
+
// ideally all elements within the scene should be wrapped around with `Ordered` type, but right now there is no real benefit doing so
|
|
18167
18197
|
elements = [];
|
|
18168
18198
|
nonDeletedFramesLikes = [];
|
|
18169
18199
|
frames = [];
|
|
@@ -18255,9 +18285,15 @@ var Scene = class _Scene {
|
|
|
18255
18285
|
return didChange;
|
|
18256
18286
|
}
|
|
18257
18287
|
replaceAllElements(nextElements) {
|
|
18258
|
-
|
|
18259
|
-
|
|
18288
|
+
const _nextElements = (
|
|
18289
|
+
// ts doesn't like `Array.isArray` of `instanceof Map`
|
|
18290
|
+
nextElements instanceof Array ? nextElements : Array.from(nextElements.values())
|
|
18291
|
+
);
|
|
18260
18292
|
const nextFrameLikes = [];
|
|
18293
|
+
if (define_import_meta_env_default.DEV || define_import_meta_env_default.MODE === ENV.TEST) {
|
|
18294
|
+
validateFractionalIndices(_nextElements.map((x) => x.index));
|
|
18295
|
+
}
|
|
18296
|
+
this.elements = syncInvalidIndices(_nextElements);
|
|
18261
18297
|
this.elementsMap.clear();
|
|
18262
18298
|
this.elements.forEach((element) => {
|
|
18263
18299
|
if (isFrameLikeElement(element)) {
|
|
@@ -18292,8 +18328,8 @@ var Scene = class _Scene {
|
|
|
18292
18328
|
};
|
|
18293
18329
|
}
|
|
18294
18330
|
destroy() {
|
|
18295
|
-
this.nonDeletedElements = [];
|
|
18296
18331
|
this.elements = [];
|
|
18332
|
+
this.nonDeletedElements = [];
|
|
18297
18333
|
this.nonDeletedFramesLikes = [];
|
|
18298
18334
|
this.frames = [];
|
|
18299
18335
|
this.elementsMap.clear();
|
|
@@ -18318,6 +18354,7 @@ var Scene = class _Scene {
|
|
|
18318
18354
|
element,
|
|
18319
18355
|
...this.elements.slice(index)
|
|
18320
18356
|
];
|
|
18357
|
+
syncMovedIndices(nextElements, arrayToMap([element]));
|
|
18321
18358
|
this.replaceAllElements(nextElements);
|
|
18322
18359
|
}
|
|
18323
18360
|
insertElementsAtIndex(elements, index) {
|
|
@@ -18331,14 +18368,16 @@ var Scene = class _Scene {
|
|
|
18331
18368
|
...elements,
|
|
18332
18369
|
...this.elements.slice(index)
|
|
18333
18370
|
];
|
|
18371
|
+
syncMovedIndices(nextElements, arrayToMap(elements));
|
|
18334
18372
|
this.replaceAllElements(nextElements);
|
|
18335
18373
|
}
|
|
18336
|
-
|
|
18337
|
-
|
|
18338
|
-
|
|
18339
|
-
|
|
18340
|
-
|
|
18341
|
-
|
|
18374
|
+
insertElement = (element) => {
|
|
18375
|
+
const index = element.frameId ? this.getElementIndex(element.frameId) : this.elements.length;
|
|
18376
|
+
this.insertElementAtIndex(element, index);
|
|
18377
|
+
};
|
|
18378
|
+
insertElements = (elements) => {
|
|
18379
|
+
const index = elements[0].frameId ? this.getElementIndex(elements[0].frameId) : this.elements.length;
|
|
18380
|
+
this.insertElementsAtIndex(elements, index);
|
|
18342
18381
|
};
|
|
18343
18382
|
getElementIndex(elementId) {
|
|
18344
18383
|
return this.elements.findIndex((element) => element.id === elementId);
|
|
@@ -18527,6 +18566,210 @@ var getNormalizedDimensions = (element) => {
|
|
|
18527
18566
|
return ret;
|
|
18528
18567
|
};
|
|
18529
18568
|
|
|
18569
|
+
// element/transformHandles.ts
|
|
18570
|
+
init_define_import_meta_env();
|
|
18571
|
+
var transformHandleSizes = {
|
|
18572
|
+
mouse: 8,
|
|
18573
|
+
pen: 16,
|
|
18574
|
+
touch: 28
|
|
18575
|
+
};
|
|
18576
|
+
var ROTATION_RESIZE_HANDLE_GAP = 16;
|
|
18577
|
+
var OMIT_SIDES_FOR_MULTIPLE_ELEMENTS = {
|
|
18578
|
+
e: true,
|
|
18579
|
+
s: true,
|
|
18580
|
+
n: true,
|
|
18581
|
+
w: true
|
|
18582
|
+
};
|
|
18583
|
+
var OMIT_SIDES_FOR_FRAME = {
|
|
18584
|
+
e: true,
|
|
18585
|
+
s: true,
|
|
18586
|
+
n: true,
|
|
18587
|
+
w: true,
|
|
18588
|
+
rotation: true
|
|
18589
|
+
};
|
|
18590
|
+
var OMIT_SIDES_FOR_TEXT_ELEMENT = {
|
|
18591
|
+
e: true,
|
|
18592
|
+
s: true,
|
|
18593
|
+
n: true,
|
|
18594
|
+
w: true
|
|
18595
|
+
};
|
|
18596
|
+
var OMIT_SIDES_FOR_LINE_SLASH = {
|
|
18597
|
+
e: true,
|
|
18598
|
+
s: true,
|
|
18599
|
+
n: true,
|
|
18600
|
+
w: true,
|
|
18601
|
+
nw: true,
|
|
18602
|
+
se: true
|
|
18603
|
+
};
|
|
18604
|
+
var OMIT_SIDES_FOR_LINE_BACKSLASH = {
|
|
18605
|
+
e: true,
|
|
18606
|
+
s: true,
|
|
18607
|
+
n: true,
|
|
18608
|
+
w: true
|
|
18609
|
+
};
|
|
18610
|
+
var generateTransformHandle = (x, y, width, height, cx, cy, angle) => {
|
|
18611
|
+
const [xx, yy] = rotate3(x + width / 2, y + height / 2, cx, cy, angle);
|
|
18612
|
+
return [xx - width / 2, yy - height / 2, width, height];
|
|
18613
|
+
};
|
|
18614
|
+
var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, pointerType, omitSides = {}, margin = 4) => {
|
|
18615
|
+
const size = transformHandleSizes[pointerType];
|
|
18616
|
+
const handleWidth = size / zoom.value;
|
|
18617
|
+
const handleHeight = size / zoom.value;
|
|
18618
|
+
const handleMarginX = size / zoom.value;
|
|
18619
|
+
const handleMarginY = size / zoom.value;
|
|
18620
|
+
const width = x2 - x1;
|
|
18621
|
+
const height = y2 - y1;
|
|
18622
|
+
const dashedLineMargin = margin / zoom.value;
|
|
18623
|
+
const centeringOffset = (size - DEFAULT_TRANSFORM_HANDLE_SPACING * 2) / (2 * zoom.value);
|
|
18624
|
+
const transformHandles = {
|
|
18625
|
+
nw: omitSides.nw ? void 0 : generateTransformHandle(
|
|
18626
|
+
x1 - dashedLineMargin - handleMarginX + centeringOffset,
|
|
18627
|
+
y1 - dashedLineMargin - handleMarginY + centeringOffset,
|
|
18628
|
+
handleWidth,
|
|
18629
|
+
handleHeight,
|
|
18630
|
+
cx,
|
|
18631
|
+
cy,
|
|
18632
|
+
angle
|
|
18633
|
+
),
|
|
18634
|
+
ne: omitSides.ne ? void 0 : generateTransformHandle(
|
|
18635
|
+
x2 + dashedLineMargin - centeringOffset,
|
|
18636
|
+
y1 - dashedLineMargin - handleMarginY + centeringOffset,
|
|
18637
|
+
handleWidth,
|
|
18638
|
+
handleHeight,
|
|
18639
|
+
cx,
|
|
18640
|
+
cy,
|
|
18641
|
+
angle
|
|
18642
|
+
),
|
|
18643
|
+
sw: omitSides.sw ? void 0 : generateTransformHandle(
|
|
18644
|
+
x1 - dashedLineMargin - handleMarginX + centeringOffset,
|
|
18645
|
+
y2 + dashedLineMargin - centeringOffset,
|
|
18646
|
+
handleWidth,
|
|
18647
|
+
handleHeight,
|
|
18648
|
+
cx,
|
|
18649
|
+
cy,
|
|
18650
|
+
angle
|
|
18651
|
+
),
|
|
18652
|
+
se: omitSides.se ? void 0 : generateTransformHandle(
|
|
18653
|
+
x2 + dashedLineMargin - centeringOffset,
|
|
18654
|
+
y2 + dashedLineMargin - centeringOffset,
|
|
18655
|
+
handleWidth,
|
|
18656
|
+
handleHeight,
|
|
18657
|
+
cx,
|
|
18658
|
+
cy,
|
|
18659
|
+
angle
|
|
18660
|
+
),
|
|
18661
|
+
rotation: omitSides.rotation ? void 0 : generateTransformHandle(
|
|
18662
|
+
x1 + width / 2 - handleWidth / 2,
|
|
18663
|
+
y1 - dashedLineMargin - handleMarginY + centeringOffset - ROTATION_RESIZE_HANDLE_GAP / zoom.value,
|
|
18664
|
+
handleWidth,
|
|
18665
|
+
handleHeight,
|
|
18666
|
+
cx,
|
|
18667
|
+
cy,
|
|
18668
|
+
angle
|
|
18669
|
+
)
|
|
18670
|
+
};
|
|
18671
|
+
const minimumSizeForEightHandles = 5 * transformHandleSizes.mouse / zoom.value;
|
|
18672
|
+
if (Math.abs(width) > minimumSizeForEightHandles) {
|
|
18673
|
+
if (!omitSides.n) {
|
|
18674
|
+
transformHandles.n = generateTransformHandle(
|
|
18675
|
+
x1 + width / 2 - handleWidth / 2,
|
|
18676
|
+
y1 - dashedLineMargin - handleMarginY + centeringOffset,
|
|
18677
|
+
handleWidth,
|
|
18678
|
+
handleHeight,
|
|
18679
|
+
cx,
|
|
18680
|
+
cy,
|
|
18681
|
+
angle
|
|
18682
|
+
);
|
|
18683
|
+
}
|
|
18684
|
+
if (!omitSides.s) {
|
|
18685
|
+
transformHandles.s = generateTransformHandle(
|
|
18686
|
+
x1 + width / 2 - handleWidth / 2,
|
|
18687
|
+
y2 + dashedLineMargin - centeringOffset,
|
|
18688
|
+
handleWidth,
|
|
18689
|
+
handleHeight,
|
|
18690
|
+
cx,
|
|
18691
|
+
cy,
|
|
18692
|
+
angle
|
|
18693
|
+
);
|
|
18694
|
+
}
|
|
18695
|
+
}
|
|
18696
|
+
if (Math.abs(height) > minimumSizeForEightHandles) {
|
|
18697
|
+
if (!omitSides.w) {
|
|
18698
|
+
transformHandles.w = generateTransformHandle(
|
|
18699
|
+
x1 - dashedLineMargin - handleMarginX + centeringOffset,
|
|
18700
|
+
y1 + height / 2 - handleHeight / 2,
|
|
18701
|
+
handleWidth,
|
|
18702
|
+
handleHeight,
|
|
18703
|
+
cx,
|
|
18704
|
+
cy,
|
|
18705
|
+
angle
|
|
18706
|
+
);
|
|
18707
|
+
}
|
|
18708
|
+
if (!omitSides.e) {
|
|
18709
|
+
transformHandles.e = generateTransformHandle(
|
|
18710
|
+
x2 + dashedLineMargin - centeringOffset,
|
|
18711
|
+
y1 + height / 2 - handleHeight / 2,
|
|
18712
|
+
handleWidth,
|
|
18713
|
+
handleHeight,
|
|
18714
|
+
cx,
|
|
18715
|
+
cy,
|
|
18716
|
+
angle
|
|
18717
|
+
);
|
|
18718
|
+
}
|
|
18719
|
+
}
|
|
18720
|
+
return transformHandles;
|
|
18721
|
+
};
|
|
18722
|
+
var getTransformHandles = (element, zoom, elementsMap, pointerType = "mouse") => {
|
|
18723
|
+
if (element.locked) {
|
|
18724
|
+
return {};
|
|
18725
|
+
}
|
|
18726
|
+
let omitSides = {};
|
|
18727
|
+
if (element.type === "freedraw" || isLinearElement(element)) {
|
|
18728
|
+
if (element.points.length === 2) {
|
|
18729
|
+
const [, p1] = element.points;
|
|
18730
|
+
if (p1[0] === 0 || p1[1] === 0) {
|
|
18731
|
+
omitSides = OMIT_SIDES_FOR_LINE_BACKSLASH;
|
|
18732
|
+
} else if (p1[0] > 0 && p1[1] < 0) {
|
|
18733
|
+
omitSides = OMIT_SIDES_FOR_LINE_SLASH;
|
|
18734
|
+
} else if (p1[0] > 0 && p1[1] > 0) {
|
|
18735
|
+
omitSides = OMIT_SIDES_FOR_LINE_BACKSLASH;
|
|
18736
|
+
} else if (p1[0] < 0 && p1[1] > 0) {
|
|
18737
|
+
omitSides = OMIT_SIDES_FOR_LINE_SLASH;
|
|
18738
|
+
} else if (p1[0] < 0 && p1[1] < 0) {
|
|
18739
|
+
omitSides = OMIT_SIDES_FOR_LINE_BACKSLASH;
|
|
18740
|
+
}
|
|
18741
|
+
}
|
|
18742
|
+
} else if (isTextElement(element)) {
|
|
18743
|
+
omitSides = OMIT_SIDES_FOR_TEXT_ELEMENT;
|
|
18744
|
+
} else if (isFrameLikeElement(element)) {
|
|
18745
|
+
omitSides = {
|
|
18746
|
+
rotation: true
|
|
18747
|
+
};
|
|
18748
|
+
}
|
|
18749
|
+
const dashedLineMargin = isLinearElement(element) ? DEFAULT_TRANSFORM_HANDLE_SPACING + 8 : DEFAULT_TRANSFORM_HANDLE_SPACING;
|
|
18750
|
+
return getTransformHandlesFromCoords(
|
|
18751
|
+
getElementAbsoluteCoords(element, elementsMap, true),
|
|
18752
|
+
element.angle,
|
|
18753
|
+
zoom,
|
|
18754
|
+
pointerType,
|
|
18755
|
+
omitSides,
|
|
18756
|
+
dashedLineMargin
|
|
18757
|
+
);
|
|
18758
|
+
};
|
|
18759
|
+
var shouldShowBoundingBox = (elements, appState) => {
|
|
18760
|
+
if (appState.editingLinearElement) {
|
|
18761
|
+
return false;
|
|
18762
|
+
}
|
|
18763
|
+
if (elements.length > 1) {
|
|
18764
|
+
return true;
|
|
18765
|
+
}
|
|
18766
|
+
const element = elements[0];
|
|
18767
|
+
if (!isLinearElement(element)) {
|
|
18768
|
+
return true;
|
|
18769
|
+
}
|
|
18770
|
+
return element.points.length > 2;
|
|
18771
|
+
};
|
|
18772
|
+
|
|
18530
18773
|
// element/resizeTest.ts
|
|
18531
18774
|
init_define_import_meta_env();
|
|
18532
18775
|
var isInsideTransformHandle = (transformHandle, x, y) => x >= transformHandle[0] && x <= transformHandle[0] + transformHandle[2] && y >= transformHandle[1] && y <= transformHandle[1] + transformHandle[3];
|
|
@@ -18765,7 +19008,7 @@ var resizeSingleTextElement = (element, elementsMap, transformHandleType, should
|
|
|
18765
19008
|
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
|
|
18766
19009
|
const cx = (x1 + x2) / 2;
|
|
18767
19010
|
const cy = (y1 + y2) / 2;
|
|
18768
|
-
const [rotatedX, rotatedY] =
|
|
19011
|
+
const [rotatedX, rotatedY] = rotate3(
|
|
18769
19012
|
pointerX,
|
|
18770
19013
|
pointerY,
|
|
18771
19014
|
cx,
|
|
@@ -19229,7 +19472,7 @@ var rotateMultipleElements = (originalElements, elements, elementsMap, pointerX,
|
|
|
19229
19472
|
const cx = (x1 + x2) / 2;
|
|
19230
19473
|
const cy = (y1 + y2) / 2;
|
|
19231
19474
|
const origAngle = originalElements.get(element.id)?.angle ?? element.angle;
|
|
19232
|
-
const [rotatedCX, rotatedCY] =
|
|
19475
|
+
const [rotatedCX, rotatedCY] = rotate3(
|
|
19233
19476
|
cx,
|
|
19234
19477
|
cy,
|
|
19235
19478
|
centerX,
|
|
@@ -19268,24 +19511,24 @@ var getResizeOffsetXY = (transformHandleType, selectedElements, elementsMap, x,
|
|
|
19268
19511
|
const cx = (x1 + x2) / 2;
|
|
19269
19512
|
const cy = (y1 + y2) / 2;
|
|
19270
19513
|
const angle = selectedElements.length === 1 ? selectedElements[0].angle : 0;
|
|
19271
|
-
[x, y] =
|
|
19514
|
+
[x, y] = rotate3(x, y, cx, cy, -angle);
|
|
19272
19515
|
switch (transformHandleType) {
|
|
19273
19516
|
case "n":
|
|
19274
|
-
return
|
|
19517
|
+
return rotate3(x - (x1 + x2) / 2, y - y1, 0, 0, angle);
|
|
19275
19518
|
case "s":
|
|
19276
|
-
return
|
|
19519
|
+
return rotate3(x - (x1 + x2) / 2, y - y2, 0, 0, angle);
|
|
19277
19520
|
case "w":
|
|
19278
|
-
return
|
|
19521
|
+
return rotate3(x - x1, y - (y1 + y2) / 2, 0, 0, angle);
|
|
19279
19522
|
case "e":
|
|
19280
|
-
return
|
|
19523
|
+
return rotate3(x - x2, y - (y1 + y2) / 2, 0, 0, angle);
|
|
19281
19524
|
case "nw":
|
|
19282
|
-
return
|
|
19525
|
+
return rotate3(x - x1, y - y1, 0, 0, angle);
|
|
19283
19526
|
case "ne":
|
|
19284
|
-
return
|
|
19527
|
+
return rotate3(x - x2, y - y1, 0, 0, angle);
|
|
19285
19528
|
case "sw":
|
|
19286
|
-
return
|
|
19529
|
+
return rotate3(x - x1, y - y2, 0, 0, angle);
|
|
19287
19530
|
case "se":
|
|
19288
|
-
return
|
|
19531
|
+
return rotate3(x - x2, y - y2, 0, 0, angle);
|
|
19289
19532
|
default:
|
|
19290
19533
|
return [0, 0];
|
|
19291
19534
|
}
|
|
@@ -19455,7 +19698,7 @@ var parseFileContents = async (blob) => {
|
|
|
19455
19698
|
let contents;
|
|
19456
19699
|
if (blob.type === MIME_TYPES.png) {
|
|
19457
19700
|
try {
|
|
19458
|
-
return await (await import("./image-
|
|
19701
|
+
return await (await import("./image-JKT6GXZD.js")).decodePngMetadata(blob);
|
|
19459
19702
|
} catch (error) {
|
|
19460
19703
|
if (error.message === "INVALID") {
|
|
19461
19704
|
throw new ImageSceneDataError(
|
|
@@ -19482,7 +19725,7 @@ var parseFileContents = async (blob) => {
|
|
|
19482
19725
|
}
|
|
19483
19726
|
if (blob.type === MIME_TYPES.svg) {
|
|
19484
19727
|
try {
|
|
19485
|
-
return await (await import("./image-
|
|
19728
|
+
return await (await import("./image-JKT6GXZD.js")).decodeSvgMetadata({
|
|
19486
19729
|
svg: contents
|
|
19487
19730
|
});
|
|
19488
19731
|
} catch (error) {
|
|
@@ -20054,6 +20297,7 @@ export {
|
|
|
20054
20297
|
arrayToMap,
|
|
20055
20298
|
arrayToMapWithIndex,
|
|
20056
20299
|
isTestEnv,
|
|
20300
|
+
isDevEnv,
|
|
20057
20301
|
wrapEvent,
|
|
20058
20302
|
updateObject,
|
|
20059
20303
|
getFrame,
|
|
@@ -20095,6 +20339,10 @@ export {
|
|
|
20095
20339
|
getDefaultRoundnessTypeForElement,
|
|
20096
20340
|
randomInteger,
|
|
20097
20341
|
randomId,
|
|
20342
|
+
AbortError,
|
|
20343
|
+
ImageSceneDataError,
|
|
20344
|
+
syncMovedIndices,
|
|
20345
|
+
syncInvalidIndices,
|
|
20098
20346
|
Scene_default,
|
|
20099
20347
|
getSizeFromPoints,
|
|
20100
20348
|
rotatePoint,
|
|
@@ -20110,17 +20358,7 @@ export {
|
|
|
20110
20358
|
hasStrokeStyle,
|
|
20111
20359
|
canChangeRoundness,
|
|
20112
20360
|
canHaveArrowheads,
|
|
20113
|
-
|
|
20114
|
-
OMIT_SIDES_FOR_MULTIPLE_ELEMENTS,
|
|
20115
|
-
OMIT_SIDES_FOR_FRAME,
|
|
20116
|
-
getTransformHandlesFromCoords,
|
|
20117
|
-
getTransformHandles,
|
|
20118
|
-
shouldShowBoundingBox,
|
|
20119
|
-
hitTest,
|
|
20120
|
-
isHittingElementBoundingBoxWithoutHittingElement,
|
|
20121
|
-
isHittingElementNotConsideringBoundingBox,
|
|
20122
|
-
isPointHittingElementBoundingBox,
|
|
20123
|
-
maxBindingGap,
|
|
20361
|
+
isPointInShape,
|
|
20124
20362
|
CODES,
|
|
20125
20363
|
KEYS,
|
|
20126
20364
|
isArrowKey,
|
|
@@ -20140,6 +20378,7 @@ export {
|
|
|
20140
20378
|
getEligibleElementsForBinding,
|
|
20141
20379
|
fixBindingsAfterDuplication,
|
|
20142
20380
|
fixBindingsAfterDeletion,
|
|
20381
|
+
maxBindingGap,
|
|
20143
20382
|
LinearElementEditor,
|
|
20144
20383
|
originalContainerCache,
|
|
20145
20384
|
updateOriginalContainerCache,
|
|
@@ -20162,7 +20401,6 @@ export {
|
|
|
20162
20401
|
getTextElementAngle,
|
|
20163
20402
|
shouldAllowVerticalAlign,
|
|
20164
20403
|
suppportsHorizontalAlign,
|
|
20165
|
-
getTextBindableContainerAtPosition,
|
|
20166
20404
|
isValidTextContainer,
|
|
20167
20405
|
computeContainerDimensionForBoundText,
|
|
20168
20406
|
getBoundTextMaxWidth,
|
|
@@ -20218,8 +20456,6 @@ export {
|
|
|
20218
20456
|
maybeParseEmbedSrc,
|
|
20219
20457
|
embeddableURLValidator,
|
|
20220
20458
|
e,
|
|
20221
|
-
AbortError,
|
|
20222
|
-
ImageSceneDataError,
|
|
20223
20459
|
fileOpen,
|
|
20224
20460
|
fileSave,
|
|
20225
20461
|
restoreElements,
|
|
@@ -20257,6 +20493,16 @@ export {
|
|
|
20257
20493
|
updateImageCache,
|
|
20258
20494
|
getInitializedImageElements,
|
|
20259
20495
|
normalizeSVG,
|
|
20496
|
+
getPolygonShape,
|
|
20497
|
+
getEllipseShape,
|
|
20498
|
+
getCurveShape,
|
|
20499
|
+
getFreedrawShape,
|
|
20500
|
+
getClosedCurveShape,
|
|
20501
|
+
shouldTestInside,
|
|
20502
|
+
hitElementItself,
|
|
20503
|
+
hitElementBoundingBox,
|
|
20504
|
+
hitElementBoundingBoxOnly,
|
|
20505
|
+
hitElementBoundText,
|
|
20260
20506
|
getLinkHandleFromCoords,
|
|
20261
20507
|
isPointHittingLinkIcon,
|
|
20262
20508
|
isPointHittingLink,
|
|
@@ -20313,6 +20559,11 @@ export {
|
|
|
20313
20559
|
isElementInViewport,
|
|
20314
20560
|
getLockedLinearCursorAlignSize,
|
|
20315
20561
|
getNormalizedDimensions,
|
|
20562
|
+
OMIT_SIDES_FOR_MULTIPLE_ELEMENTS,
|
|
20563
|
+
OMIT_SIDES_FOR_FRAME,
|
|
20564
|
+
getTransformHandlesFromCoords,
|
|
20565
|
+
getTransformHandles,
|
|
20566
|
+
shouldShowBoundingBox,
|
|
20316
20567
|
getElementWithTransformHandleType,
|
|
20317
20568
|
getTransformHandleTypeFromCoords,
|
|
20318
20569
|
getCursorForResizingElement,
|
|
@@ -20342,4 +20593,4 @@ export {
|
|
|
20342
20593
|
getNormalizedZoom,
|
|
20343
20594
|
getStateForZoom
|
|
20344
20595
|
};
|
|
20345
|
-
//# sourceMappingURL=chunk-
|
|
20596
|
+
//# sourceMappingURL=chunk-7D5BMEAB.js.map
|