@myoc/element 0.19.519 → 0.19.520
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dev/index.js +1138 -355
- package/dist/dev/index.js.map +4 -4
- package/dist/prod/index.js +13 -13
- package/dist/types/common/src/constants.d.ts +8 -5
- package/dist/types/common/src/utils.d.ts +0 -42
- package/dist/types/element/src/comparisons.d.ts +1 -0
- package/dist/types/element/src/image.d.ts +5 -0
- package/dist/types/element/src/newElement.d.ts +2 -0
- package/dist/types/element/src/types.d.ts +8 -0
- package/dist/types/excalidraw/actions/actionBoundText.d.ts +4 -2
- package/dist/types/excalidraw/actions/actionCanvas.d.ts +22 -11
- package/dist/types/excalidraw/actions/actionClipboard.d.ts +4 -2
- package/dist/types/excalidraw/actions/actionCropEditor.d.ts +2 -1
- package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +6 -3
- package/dist/types/excalidraw/actions/actionDeselect.d.ts +2 -1
- package/dist/types/excalidraw/actions/actionElementLink.d.ts +2 -1
- package/dist/types/excalidraw/actions/actionElementLock.d.ts +4 -2
- package/dist/types/excalidraw/actions/actionEmbeddable.d.ts +2 -1
- package/dist/types/excalidraw/actions/actionExport.d.ts +4 -2
- package/dist/types/excalidraw/actions/actionFrame.d.ts +10 -4
- package/dist/types/excalidraw/actions/actionGroup.d.ts +4 -2
- package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +4 -1
- package/dist/types/excalidraw/actions/actionLink.d.ts +2 -1
- package/dist/types/excalidraw/actions/actionMenu.d.ts +2 -1
- package/dist/types/excalidraw/actions/actionProperties.d.ts +16 -5
- package/dist/types/excalidraw/actions/actionSelectAll.d.ts +2 -1
- package/dist/types/excalidraw/actions/actionStyles.d.ts +2 -1
- package/dist/types/excalidraw/actions/actionToggleArrowBinding.d.ts +2 -1
- package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +2 -1
- package/dist/types/excalidraw/actions/actionToggleMidpointSnapping.d.ts +2 -1
- package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +2 -1
- package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +2 -1
- package/dist/types/excalidraw/actions/actionToggleStats.d.ts +2 -1
- package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +2 -1
- package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +2 -1
- package/dist/types/excalidraw/actions/index.d.ts +1 -1
- package/dist/types/excalidraw/actions/types.d.ts +1 -1
- package/dist/types/excalidraw/appState.d.ts +2 -1
- package/dist/types/excalidraw/components/App.d.ts +12 -28
- package/dist/types/excalidraw/components/ColorPicker/colorPickerUtils.d.ts +1 -1
- package/dist/types/excalidraw/components/ConvertElementTypePopup.d.ts +1 -1
- package/dist/types/excalidraw/components/EyeDropper.d.ts +1 -1
- package/dist/types/excalidraw/components/OverwriteConfirm/OverwriteConfirmState.d.ts +1 -1
- package/dist/types/excalidraw/components/SearchMenu.d.ts +1 -1
- package/dist/types/excalidraw/components/Sidebar/Sidebar.d.ts +1 -1
- package/dist/types/excalidraw/components/canvases/StaticCanvas.d.ts +2 -1
- package/dist/types/excalidraw/components/icons.d.ts +2 -0
- package/dist/types/excalidraw/data/blob.d.ts +2 -1
- package/dist/types/excalidraw/data/json.d.ts +2 -1
- package/dist/types/excalidraw/renderer/animation.d.ts +1 -0
- package/dist/types/excalidraw/scene/Renderer.d.ts +2 -0
- package/dist/types/excalidraw/scene/index.d.ts +1 -1
- package/dist/types/excalidraw/scene/types.d.ts +1 -0
- package/dist/types/excalidraw/scroll.d.ts +46 -0
- package/dist/types/excalidraw/types.d.ts +16 -3
- package/dist/types/laser-pointer/src/index.d.ts +2 -0
- package/dist/types/laser-pointer/src/math.d.ts +16 -0
- package/dist/types/laser-pointer/src/simplify.d.ts +2 -0
- package/dist/types/laser-pointer/src/state.d.ts +35 -0
- package/package.json +5 -4
package/dist/dev/index.js
CHANGED
|
@@ -1832,9 +1832,9 @@ init_define_import_meta_env();
|
|
|
1832
1832
|
function rotatePoints(points, center, degrees) {
|
|
1833
1833
|
if (points && points.length) {
|
|
1834
1834
|
const [cx, cy] = center;
|
|
1835
|
-
const
|
|
1836
|
-
const cos = Math.cos(
|
|
1837
|
-
const sin = Math.sin(
|
|
1835
|
+
const angle2 = Math.PI / 180 * degrees;
|
|
1836
|
+
const cos = Math.cos(angle2);
|
|
1837
|
+
const sin = Math.sin(angle2);
|
|
1838
1838
|
for (const p of points) {
|
|
1839
1839
|
const [x, y] = p;
|
|
1840
1840
|
p[0] = (x - cx) * cos - (y - cy) * sin + cx;
|
|
@@ -1851,21 +1851,21 @@ function areSamePoints(p1, p2) {
|
|
|
1851
1851
|
return p1[0] === p2[0] && p1[1] === p2[1];
|
|
1852
1852
|
}
|
|
1853
1853
|
function hachureLines(polygons, hachureGap, hachureAngle, hachureStepOffset = 1) {
|
|
1854
|
-
const
|
|
1854
|
+
const angle2 = hachureAngle;
|
|
1855
1855
|
const gap = Math.max(hachureGap, 0.1);
|
|
1856
1856
|
const polygonList = polygons[0] && polygons[0][0] && typeof polygons[0][0] === "number" ? [polygons] : polygons;
|
|
1857
1857
|
const rotationCenter = [0, 0];
|
|
1858
|
-
if (
|
|
1858
|
+
if (angle2) {
|
|
1859
1859
|
for (const polygon3 of polygonList) {
|
|
1860
|
-
rotatePoints(polygon3, rotationCenter,
|
|
1860
|
+
rotatePoints(polygon3, rotationCenter, angle2);
|
|
1861
1861
|
}
|
|
1862
1862
|
}
|
|
1863
1863
|
const lines = straightHachureLines(polygonList, gap, hachureStepOffset);
|
|
1864
|
-
if (
|
|
1864
|
+
if (angle2) {
|
|
1865
1865
|
for (const polygon3 of polygonList) {
|
|
1866
|
-
rotatePoints(polygon3, rotationCenter, -
|
|
1866
|
+
rotatePoints(polygon3, rotationCenter, -angle2);
|
|
1867
1867
|
}
|
|
1868
|
-
rotateLines(lines, rotationCenter, -
|
|
1868
|
+
rotateLines(lines, rotationCenter, -angle2);
|
|
1869
1869
|
}
|
|
1870
1870
|
return lines;
|
|
1871
1871
|
}
|
|
@@ -1976,7 +1976,7 @@ function straightHachureLines(polygons, gap, hachureStepOffset) {
|
|
|
1976
1976
|
// ../../node_modules/roughjs/bin/fillers/scan-line-hachure.js
|
|
1977
1977
|
function polygonHachureLines(polygonList, o) {
|
|
1978
1978
|
var _a;
|
|
1979
|
-
const
|
|
1979
|
+
const angle2 = o.hachureAngle + 90;
|
|
1980
1980
|
let gap = o.hachureGap;
|
|
1981
1981
|
if (gap < 0) {
|
|
1982
1982
|
gap = o.strokeWidth * 4;
|
|
@@ -1988,7 +1988,7 @@ function polygonHachureLines(polygonList, o) {
|
|
|
1988
1988
|
skipOffset = gap;
|
|
1989
1989
|
}
|
|
1990
1990
|
}
|
|
1991
|
-
return hachureLines(polygonList, gap,
|
|
1991
|
+
return hachureLines(polygonList, gap, angle2, skipOffset || 1);
|
|
1992
1992
|
}
|
|
1993
1993
|
|
|
1994
1994
|
// ../../node_modules/roughjs/bin/fillers/hachure-filler.js
|
|
@@ -2526,7 +2526,7 @@ function normalize(segments) {
|
|
|
2526
2526
|
case "A": {
|
|
2527
2527
|
const r1 = Math.abs(data[0]);
|
|
2528
2528
|
const r2 = Math.abs(data[1]);
|
|
2529
|
-
const
|
|
2529
|
+
const angle2 = data[2];
|
|
2530
2530
|
const largeArcFlag = data[3];
|
|
2531
2531
|
const sweepFlag = data[4];
|
|
2532
2532
|
const x = data[5];
|
|
@@ -2537,7 +2537,7 @@ function normalize(segments) {
|
|
|
2537
2537
|
cy = y;
|
|
2538
2538
|
} else {
|
|
2539
2539
|
if (cx !== x || cy !== y) {
|
|
2540
|
-
const curves = arcToCubicCurves(cx, cy, x, y, r1, r2,
|
|
2540
|
+
const curves = arcToCubicCurves(cx, cy, x, y, r1, r2, angle2, largeArcFlag, sweepFlag);
|
|
2541
2541
|
curves.forEach(function(curve4) {
|
|
2542
2542
|
out.push({ key: "C", data: curve4 });
|
|
2543
2543
|
});
|
|
@@ -2565,8 +2565,8 @@ function rotate(x, y, angleRad) {
|
|
|
2565
2565
|
const Y = x * Math.sin(angleRad) + y * Math.cos(angleRad);
|
|
2566
2566
|
return [X, Y];
|
|
2567
2567
|
}
|
|
2568
|
-
function arcToCubicCurves(x1, y1, x2, y2, r1, r2,
|
|
2569
|
-
const angleRad = degToRad(
|
|
2568
|
+
function arcToCubicCurves(x1, y1, x2, y2, r1, r2, angle2, largeArcFlag, sweepFlag, recursive) {
|
|
2569
|
+
const angleRad = degToRad(angle2);
|
|
2570
2570
|
let params = [];
|
|
2571
2571
|
let f1 = 0, f2 = 0, cx = 0, cy = 0;
|
|
2572
2572
|
if (recursive) {
|
|
@@ -2623,7 +2623,7 @@ function arcToCubicCurves(x1, y1, x2, y2, r1, r2, angle, largeArcFlag, sweepFlag
|
|
|
2623
2623
|
}
|
|
2624
2624
|
x2 = cx + r1 * Math.cos(f2);
|
|
2625
2625
|
y2 = cy + r2 * Math.sin(f2);
|
|
2626
|
-
params = arcToCubicCurves(x2, y2, x2old, y2old, r1, r2,
|
|
2626
|
+
params = arcToCubicCurves(x2, y2, x2old, y2old, r1, r2, angle2, 0, sweepFlag, [f2, f2old, cx, cy]);
|
|
2627
2627
|
}
|
|
2628
2628
|
df = f2 - f1;
|
|
2629
2629
|
const c1 = Math.cos(f1);
|
|
@@ -2829,8 +2829,8 @@ function patternFillArc(x, y, width, height, start2, stop2, o) {
|
|
|
2829
2829
|
}
|
|
2830
2830
|
const increment = (stp - strt) / o.curveStepCount;
|
|
2831
2831
|
const points = [];
|
|
2832
|
-
for (let
|
|
2833
|
-
points.push([cx + rx * Math.cos(
|
|
2832
|
+
for (let angle2 = strt; angle2 <= stp; angle2 = angle2 + increment) {
|
|
2833
|
+
points.push([cx + rx * Math.cos(angle2), cy + ry * Math.sin(angle2)]);
|
|
2834
2834
|
}
|
|
2835
2835
|
points.push([cx + rx * Math.cos(stp), cy + ry * Math.sin(stp)]);
|
|
2836
2836
|
points.push([cx, cy]);
|
|
@@ -3016,10 +3016,10 @@ function _computeEllipsePoints(increment, cx, cy, rx, ry, offset, overlap, o) {
|
|
|
3016
3016
|
cx + rx * Math.cos(-increment),
|
|
3017
3017
|
cy + ry * Math.sin(-increment)
|
|
3018
3018
|
]);
|
|
3019
|
-
for (let
|
|
3019
|
+
for (let angle2 = 0; angle2 <= Math.PI * 2; angle2 = angle2 + increment) {
|
|
3020
3020
|
const p = [
|
|
3021
|
-
cx + rx * Math.cos(
|
|
3022
|
-
cy + ry * Math.sin(
|
|
3021
|
+
cx + rx * Math.cos(angle2),
|
|
3022
|
+
cy + ry * Math.sin(angle2)
|
|
3023
3023
|
];
|
|
3024
3024
|
corePoints.push(p);
|
|
3025
3025
|
allPoints.push(p);
|
|
@@ -3039,10 +3039,10 @@ function _computeEllipsePoints(increment, cx, cy, rx, ry, offset, overlap, o) {
|
|
|
3039
3039
|
_offsetOpt(offset, o) + cy + 0.9 * ry * Math.sin(radOffset - increment)
|
|
3040
3040
|
]);
|
|
3041
3041
|
const endAngle = Math.PI * 2 + radOffset - 0.01;
|
|
3042
|
-
for (let
|
|
3042
|
+
for (let angle2 = radOffset; angle2 < endAngle; angle2 = angle2 + increment) {
|
|
3043
3043
|
const p = [
|
|
3044
|
-
_offsetOpt(offset, o) + cx + rx * Math.cos(
|
|
3045
|
-
_offsetOpt(offset, o) + cy + ry * Math.sin(
|
|
3044
|
+
_offsetOpt(offset, o) + cx + rx * Math.cos(angle2),
|
|
3045
|
+
_offsetOpt(offset, o) + cy + ry * Math.sin(angle2)
|
|
3046
3046
|
];
|
|
3047
3047
|
corePoints.push(p);
|
|
3048
3048
|
allPoints.push(p);
|
|
@@ -3069,10 +3069,10 @@ function _arc(increment, cx, cy, rx, ry, strt, stp, offset, o) {
|
|
|
3069
3069
|
_offsetOpt(offset, o) + cx + 0.9 * rx * Math.cos(radOffset - increment),
|
|
3070
3070
|
_offsetOpt(offset, o) + cy + 0.9 * ry * Math.sin(radOffset - increment)
|
|
3071
3071
|
]);
|
|
3072
|
-
for (let
|
|
3072
|
+
for (let angle2 = radOffset; angle2 <= stp; angle2 = angle2 + increment) {
|
|
3073
3073
|
points.push([
|
|
3074
|
-
_offsetOpt(offset, o) + cx + rx * Math.cos(
|
|
3075
|
-
_offsetOpt(offset, o) + cy + ry * Math.sin(
|
|
3074
|
+
_offsetOpt(offset, o) + cx + rx * Math.cos(angle2),
|
|
3075
|
+
_offsetOpt(offset, o) + cy + ry * Math.sin(angle2)
|
|
3076
3076
|
]);
|
|
3077
3077
|
}
|
|
3078
3078
|
points.push([
|
|
@@ -3898,24 +3898,24 @@ import {
|
|
|
3898
3898
|
} from "@excalidraw/math";
|
|
3899
3899
|
import { getElementAbsoluteCoords } from "@excalidraw/element";
|
|
3900
3900
|
var getPolygonShape = (element) => {
|
|
3901
|
-
const { angle, width, height, x, y } = element;
|
|
3901
|
+
const { angle: angle2, width, height, x, y } = element;
|
|
3902
3902
|
const cx = x + width / 2;
|
|
3903
3903
|
const cy = y + height / 2;
|
|
3904
3904
|
const center = pointFrom(cx, cy);
|
|
3905
3905
|
let data;
|
|
3906
3906
|
if (element.type === "diamond") {
|
|
3907
3907
|
data = polygon2(
|
|
3908
|
-
pointRotateRads(pointFrom(cx, y), center,
|
|
3909
|
-
pointRotateRads(pointFrom(x + width, cy), center,
|
|
3910
|
-
pointRotateRads(pointFrom(cx, y + height), center,
|
|
3911
|
-
pointRotateRads(pointFrom(x, cy), center,
|
|
3908
|
+
pointRotateRads(pointFrom(cx, y), center, angle2),
|
|
3909
|
+
pointRotateRads(pointFrom(x + width, cy), center, angle2),
|
|
3910
|
+
pointRotateRads(pointFrom(cx, y + height), center, angle2),
|
|
3911
|
+
pointRotateRads(pointFrom(x, cy), center, angle2)
|
|
3912
3912
|
);
|
|
3913
3913
|
} else {
|
|
3914
3914
|
data = polygon2(
|
|
3915
|
-
pointRotateRads(pointFrom(x, y), center,
|
|
3916
|
-
pointRotateRads(pointFrom(x + width, y), center,
|
|
3917
|
-
pointRotateRads(pointFrom(x + width, y + height), center,
|
|
3918
|
-
pointRotateRads(pointFrom(x, y + height), center,
|
|
3915
|
+
pointRotateRads(pointFrom(x, y), center, angle2),
|
|
3916
|
+
pointRotateRads(pointFrom(x + width, y), center, angle2),
|
|
3917
|
+
pointRotateRads(pointFrom(x + width, y + height), center, angle2),
|
|
3918
|
+
pointRotateRads(pointFrom(x, y + height), center, angle2)
|
|
3919
3919
|
);
|
|
3920
3920
|
}
|
|
3921
3921
|
return {
|
|
@@ -3924,12 +3924,12 @@ var getPolygonShape = (element) => {
|
|
|
3924
3924
|
};
|
|
3925
3925
|
};
|
|
3926
3926
|
var getEllipseShape = (element) => {
|
|
3927
|
-
const { width, height, angle, x, y } = element;
|
|
3927
|
+
const { width, height, angle: angle2, x, y } = element;
|
|
3928
3928
|
return {
|
|
3929
3929
|
type: "ellipse",
|
|
3930
3930
|
data: {
|
|
3931
3931
|
center: pointFrom(x + width / 2, y + height / 2),
|
|
3932
|
-
angle,
|
|
3932
|
+
angle: angle2,
|
|
3933
3933
|
halfWidth: width / 2,
|
|
3934
3934
|
halfHeight: height / 2
|
|
3935
3935
|
}
|
|
@@ -4213,6 +4213,362 @@ function ae(e, t = {}) {
|
|
|
4213
4213
|
return ce(me(e, t), t);
|
|
4214
4214
|
}
|
|
4215
4215
|
|
|
4216
|
+
// ../laser-pointer/src/index.ts
|
|
4217
|
+
init_define_import_meta_env();
|
|
4218
|
+
|
|
4219
|
+
// ../laser-pointer/src/state.ts
|
|
4220
|
+
init_define_import_meta_env();
|
|
4221
|
+
|
|
4222
|
+
// ../laser-pointer/src/math.ts
|
|
4223
|
+
init_define_import_meta_env();
|
|
4224
|
+
function add([ax, ay, ar], [bx, by, br]) {
|
|
4225
|
+
return [ax + bx, ay + by, ar + br];
|
|
4226
|
+
}
|
|
4227
|
+
function sub([ax, ay, ar], [bx, by, br]) {
|
|
4228
|
+
return [ax - bx, ay - by, ar - br];
|
|
4229
|
+
}
|
|
4230
|
+
function smul([x, y, r], s) {
|
|
4231
|
+
return [x * s, y * s, r * s];
|
|
4232
|
+
}
|
|
4233
|
+
function norm([x, y, r]) {
|
|
4234
|
+
return [x / Math.sqrt(x ** 2 + y ** 2), y / Math.sqrt(x ** 2 + y ** 2), r];
|
|
4235
|
+
}
|
|
4236
|
+
function rot([x, y, r], rad) {
|
|
4237
|
+
return [
|
|
4238
|
+
Math.cos(rad) * x - Math.sin(rad) * y,
|
|
4239
|
+
Math.sin(rad) * x + Math.cos(rad) * y,
|
|
4240
|
+
r
|
|
4241
|
+
];
|
|
4242
|
+
}
|
|
4243
|
+
function plerp(a2, b2, t) {
|
|
4244
|
+
return add(a2, smul(sub(b2, a2), t));
|
|
4245
|
+
}
|
|
4246
|
+
function angle(p, p1, p2) {
|
|
4247
|
+
return Math.atan2(p2[1] - p[1], p2[0] - p[0]) - Math.atan2(p1[1] - p[1], p1[0] - p[0]);
|
|
4248
|
+
}
|
|
4249
|
+
function normAngle(a2) {
|
|
4250
|
+
return Math.atan2(Math.sin(a2), Math.cos(a2));
|
|
4251
|
+
}
|
|
4252
|
+
function mag([x, y]) {
|
|
4253
|
+
return Math.sqrt(x ** 2 + y ** 2);
|
|
4254
|
+
}
|
|
4255
|
+
function dist([ax, ay], [bx, by]) {
|
|
4256
|
+
return Math.sqrt((bx - ax) ** 2 + (by - ay) ** 2);
|
|
4257
|
+
}
|
|
4258
|
+
function runLength(ps) {
|
|
4259
|
+
if (ps.length < 2) {
|
|
4260
|
+
return 0;
|
|
4261
|
+
}
|
|
4262
|
+
let len = 0;
|
|
4263
|
+
for (let i = 1; i <= ps.length - 1; i++) {
|
|
4264
|
+
len += dist(ps[i - 1], ps[i]);
|
|
4265
|
+
}
|
|
4266
|
+
len += dist(ps[ps.length - 2], ps[ps.length - 1]);
|
|
4267
|
+
return len;
|
|
4268
|
+
}
|
|
4269
|
+
var clamp = (v, min, max) => Math.max(min, Math.min(max, v));
|
|
4270
|
+
function distancePointToSegment(p3, p1, p2) {
|
|
4271
|
+
const sMag = dist(p1, p2);
|
|
4272
|
+
if (sMag === 0) {
|
|
4273
|
+
return dist(p3, p1);
|
|
4274
|
+
}
|
|
4275
|
+
const u = clamp(
|
|
4276
|
+
((p3[0] - p1[0]) * (p2[0] - p1[0]) + (p3[1] - p1[1]) * (p2[1] - p1[1])) / sMag ** 2,
|
|
4277
|
+
0,
|
|
4278
|
+
1
|
|
4279
|
+
);
|
|
4280
|
+
const pi = [
|
|
4281
|
+
p1[0] + u * (p2[0] - p1[0]),
|
|
4282
|
+
p1[1] + u * (p2[1] - p1[1]),
|
|
4283
|
+
p3[2]
|
|
4284
|
+
];
|
|
4285
|
+
return dist(pi, p3);
|
|
4286
|
+
}
|
|
4287
|
+
|
|
4288
|
+
// ../laser-pointer/src/simplify.ts
|
|
4289
|
+
init_define_import_meta_env();
|
|
4290
|
+
function douglasPeucker(points, epsilon) {
|
|
4291
|
+
if (epsilon === 0) {
|
|
4292
|
+
return points;
|
|
4293
|
+
}
|
|
4294
|
+
if (points.length <= 2) {
|
|
4295
|
+
return points;
|
|
4296
|
+
}
|
|
4297
|
+
const first = points[0];
|
|
4298
|
+
const last = points[points.length - 1];
|
|
4299
|
+
const [maxDistance, maxIndex] = points.reduce(
|
|
4300
|
+
([maxDistance2, maxIndex2], point, index) => {
|
|
4301
|
+
const distance3 = distancePointToSegment(point, first, last);
|
|
4302
|
+
return distance3 > maxDistance2 ? [distance3, index] : [maxDistance2, maxIndex2];
|
|
4303
|
+
},
|
|
4304
|
+
[0, -1]
|
|
4305
|
+
);
|
|
4306
|
+
if (maxDistance >= epsilon) {
|
|
4307
|
+
const maxIndexPoint = points[maxIndex];
|
|
4308
|
+
return [
|
|
4309
|
+
...douglasPeucker(
|
|
4310
|
+
[first, ...points.slice(1, maxIndex), maxIndexPoint],
|
|
4311
|
+
epsilon
|
|
4312
|
+
).slice(0, -1),
|
|
4313
|
+
maxIndexPoint,
|
|
4314
|
+
...douglasPeucker(
|
|
4315
|
+
[maxIndexPoint, ...points.slice(maxIndex, -1), last],
|
|
4316
|
+
epsilon
|
|
4317
|
+
).slice(1)
|
|
4318
|
+
];
|
|
4319
|
+
}
|
|
4320
|
+
return [first, last];
|
|
4321
|
+
}
|
|
4322
|
+
|
|
4323
|
+
// ../laser-pointer/src/state.ts
|
|
4324
|
+
var LaserPointer = class _LaserPointer {
|
|
4325
|
+
static defaults = {
|
|
4326
|
+
size: 2,
|
|
4327
|
+
streamline: 0.45,
|
|
4328
|
+
simplify: 0.1,
|
|
4329
|
+
simplifyPhase: "output",
|
|
4330
|
+
keepHead: false,
|
|
4331
|
+
sizeMapping: () => 1
|
|
4332
|
+
};
|
|
4333
|
+
static constants = {
|
|
4334
|
+
cornerDetectionMaxAngle: 75,
|
|
4335
|
+
cornerDetectionVariance: (s) => s > 35 ? 0.5 : 1,
|
|
4336
|
+
maxTailLength: 50
|
|
4337
|
+
};
|
|
4338
|
+
options;
|
|
4339
|
+
constructor(options) {
|
|
4340
|
+
this.options = Object.assign({}, _LaserPointer.defaults, options);
|
|
4341
|
+
}
|
|
4342
|
+
originalPoints = [];
|
|
4343
|
+
stablePoints = [];
|
|
4344
|
+
tailPoints = [];
|
|
4345
|
+
isFresh = true;
|
|
4346
|
+
get lastPoint() {
|
|
4347
|
+
return this.tailPoints[this.tailPoints.length - 1] ?? this.stablePoints[this.stablePoints.length - 1];
|
|
4348
|
+
}
|
|
4349
|
+
addPoint(point) {
|
|
4350
|
+
const lastPoint = this.originalPoints[this.originalPoints.length - 1];
|
|
4351
|
+
if (lastPoint && lastPoint[0] === point[0] && lastPoint[1] === point[1]) {
|
|
4352
|
+
return;
|
|
4353
|
+
}
|
|
4354
|
+
this.originalPoints.push(point);
|
|
4355
|
+
if (this.isFresh) {
|
|
4356
|
+
this.isFresh = false;
|
|
4357
|
+
this.stablePoints.push(point);
|
|
4358
|
+
return;
|
|
4359
|
+
}
|
|
4360
|
+
if (this.options.streamline > 0) {
|
|
4361
|
+
point = plerp(this.lastPoint, point, 1 - this.options.streamline);
|
|
4362
|
+
}
|
|
4363
|
+
this.tailPoints.push(point);
|
|
4364
|
+
if (runLength(this.tailPoints) > _LaserPointer.constants.maxTailLength) {
|
|
4365
|
+
this.stabilizeTail();
|
|
4366
|
+
}
|
|
4367
|
+
}
|
|
4368
|
+
close() {
|
|
4369
|
+
this.stabilizeTail();
|
|
4370
|
+
}
|
|
4371
|
+
stabilizeTail() {
|
|
4372
|
+
if (this.options.simplify > 0 && this.options.simplifyPhase === "tail") {
|
|
4373
|
+
throw new Error("Not implemented yet");
|
|
4374
|
+
} else {
|
|
4375
|
+
this.stablePoints.push(...this.tailPoints);
|
|
4376
|
+
this.tailPoints = [];
|
|
4377
|
+
}
|
|
4378
|
+
}
|
|
4379
|
+
getSize(sizeOverride, pressure, index, totalLength, runningLength) {
|
|
4380
|
+
return (sizeOverride ?? this.options.size) * this.options.sizeMapping({
|
|
4381
|
+
pressure,
|
|
4382
|
+
runningLength,
|
|
4383
|
+
currentIndex: index,
|
|
4384
|
+
totalLength
|
|
4385
|
+
});
|
|
4386
|
+
}
|
|
4387
|
+
getStrokeOutline(sizeOverride) {
|
|
4388
|
+
if (this.isFresh) {
|
|
4389
|
+
return [];
|
|
4390
|
+
}
|
|
4391
|
+
let points = [...this.stablePoints, ...this.tailPoints];
|
|
4392
|
+
if (this.options.simplify > 0 && this.options.simplifyPhase === "input") {
|
|
4393
|
+
points = douglasPeucker(points, this.options.simplify);
|
|
4394
|
+
}
|
|
4395
|
+
const len = points.length;
|
|
4396
|
+
if (len === 0) {
|
|
4397
|
+
return [];
|
|
4398
|
+
}
|
|
4399
|
+
if (len === 1) {
|
|
4400
|
+
const c = points[0];
|
|
4401
|
+
const size = this.getSize(sizeOverride, c[2], 0, len, 0);
|
|
4402
|
+
if (size < 0.5) {
|
|
4403
|
+
return [];
|
|
4404
|
+
}
|
|
4405
|
+
const ps = [];
|
|
4406
|
+
for (let theta = 0; theta <= Math.PI * 2; theta += Math.PI / 16) {
|
|
4407
|
+
ps.push(add(c, smul(rot([1, 0, 0], theta), size)));
|
|
4408
|
+
}
|
|
4409
|
+
ps.push(
|
|
4410
|
+
add(
|
|
4411
|
+
c,
|
|
4412
|
+
smul(
|
|
4413
|
+
[1, 0, 0],
|
|
4414
|
+
this.getSize(sizeOverride, c[2], 0, len, 0)
|
|
4415
|
+
)
|
|
4416
|
+
)
|
|
4417
|
+
);
|
|
4418
|
+
return ps;
|
|
4419
|
+
}
|
|
4420
|
+
if (len === 2) {
|
|
4421
|
+
const c = points[0];
|
|
4422
|
+
const n = points[1];
|
|
4423
|
+
const cSize = this.getSize(sizeOverride, c[2], 0, len, 0);
|
|
4424
|
+
const nSize = this.getSize(sizeOverride, n[2], 0, len, 0);
|
|
4425
|
+
if (cSize < 0.5 || nSize < 0.5) {
|
|
4426
|
+
return [];
|
|
4427
|
+
}
|
|
4428
|
+
const ps = [];
|
|
4429
|
+
const pAngle = angle(c, [c[0], c[1] - 100, c[2]], n);
|
|
4430
|
+
for (let theta = pAngle; theta <= Math.PI + pAngle; theta += Math.PI / 16) {
|
|
4431
|
+
ps.push(add(c, smul(rot([1, 0, 0], theta), cSize)));
|
|
4432
|
+
}
|
|
4433
|
+
for (let theta = Math.PI + pAngle; theta <= Math.PI * 2 + pAngle; theta += Math.PI / 16) {
|
|
4434
|
+
ps.push(add(n, smul(rot([1, 0, 0], theta), nSize)));
|
|
4435
|
+
}
|
|
4436
|
+
ps.push(ps[0]);
|
|
4437
|
+
return ps;
|
|
4438
|
+
}
|
|
4439
|
+
const forwardPoints = [];
|
|
4440
|
+
const backwardPoints = [];
|
|
4441
|
+
let speed = 0;
|
|
4442
|
+
let prevSpeed = 0;
|
|
4443
|
+
let visibleStartIndex = 0;
|
|
4444
|
+
let runningLength = 0;
|
|
4445
|
+
for (let i = 1; i < len - 1; i++) {
|
|
4446
|
+
const p = points[i - 1];
|
|
4447
|
+
const c = points[i];
|
|
4448
|
+
const n = points[i + 1];
|
|
4449
|
+
const pressure = c[2];
|
|
4450
|
+
const d = dist(p, c);
|
|
4451
|
+
runningLength += d;
|
|
4452
|
+
speed = prevSpeed + (d - prevSpeed) * 0.2;
|
|
4453
|
+
const cSize = this.getSize(sizeOverride, pressure, i, len, runningLength);
|
|
4454
|
+
if (cSize === 0) {
|
|
4455
|
+
visibleStartIndex = i + 1;
|
|
4456
|
+
continue;
|
|
4457
|
+
}
|
|
4458
|
+
const dirPC = norm(sub(p, c));
|
|
4459
|
+
const dirNC = norm(sub(n, c));
|
|
4460
|
+
const p1dirPC = rot(dirPC, Math.PI / 2);
|
|
4461
|
+
const p2dirPC = rot(dirPC, -Math.PI / 2);
|
|
4462
|
+
const p1dirNC = rot(dirNC, Math.PI / 2);
|
|
4463
|
+
const p2dirNC = rot(dirNC, -Math.PI / 2);
|
|
4464
|
+
const p1PC = add(c, smul(p1dirPC, cSize));
|
|
4465
|
+
const p2PC = add(c, smul(p2dirPC, cSize));
|
|
4466
|
+
const p1NC = add(c, smul(p1dirNC, cSize));
|
|
4467
|
+
const p2NC = add(c, smul(p2dirNC, cSize));
|
|
4468
|
+
const ftdir = add(p1dirPC, p2dirNC);
|
|
4469
|
+
const btdir = add(p2dirPC, p1dirNC);
|
|
4470
|
+
const paPC = add(
|
|
4471
|
+
c,
|
|
4472
|
+
smul(mag(ftdir) === 0 ? dirPC : norm(ftdir), cSize)
|
|
4473
|
+
);
|
|
4474
|
+
const paNC = add(
|
|
4475
|
+
c,
|
|
4476
|
+
smul(mag(btdir) === 0 ? dirNC : norm(btdir), cSize)
|
|
4477
|
+
);
|
|
4478
|
+
const cAngle = normAngle(angle(c, p, n));
|
|
4479
|
+
const D_ANGLE = _LaserPointer.constants.cornerDetectionMaxAngle / 180 * Math.PI * _LaserPointer.constants.cornerDetectionVariance(speed);
|
|
4480
|
+
if (Math.abs(cAngle) < D_ANGLE) {
|
|
4481
|
+
const tAngle = Math.abs(normAngle(Math.PI - cAngle));
|
|
4482
|
+
if (tAngle === 0) {
|
|
4483
|
+
continue;
|
|
4484
|
+
}
|
|
4485
|
+
if (cAngle < 0) {
|
|
4486
|
+
backwardPoints.push(p2PC, paNC);
|
|
4487
|
+
for (let theta = 0; theta <= tAngle; theta += tAngle / 4) {
|
|
4488
|
+
forwardPoints.push(add(c, rot(smul(p1dirPC, cSize), theta)));
|
|
4489
|
+
}
|
|
4490
|
+
for (let theta = tAngle; theta >= 0; theta -= tAngle / 4) {
|
|
4491
|
+
backwardPoints.push(add(c, rot(smul(p1dirPC, cSize), theta)));
|
|
4492
|
+
}
|
|
4493
|
+
backwardPoints.push(paNC, p1NC);
|
|
4494
|
+
} else {
|
|
4495
|
+
forwardPoints.push(p1PC, paPC);
|
|
4496
|
+
for (let theta = 0; theta <= tAngle; theta += tAngle / 4) {
|
|
4497
|
+
backwardPoints.push(
|
|
4498
|
+
add(c, rot(smul(p1dirPC, -cSize), -theta))
|
|
4499
|
+
);
|
|
4500
|
+
}
|
|
4501
|
+
for (let theta = tAngle; theta >= 0; theta -= tAngle / 4) {
|
|
4502
|
+
forwardPoints.push(
|
|
4503
|
+
add(c, rot(smul(p1dirPC, -cSize), -theta))
|
|
4504
|
+
);
|
|
4505
|
+
}
|
|
4506
|
+
forwardPoints.push(paPC, p2NC);
|
|
4507
|
+
}
|
|
4508
|
+
} else {
|
|
4509
|
+
forwardPoints.push(paPC);
|
|
4510
|
+
backwardPoints.push(paNC);
|
|
4511
|
+
}
|
|
4512
|
+
prevSpeed = speed;
|
|
4513
|
+
}
|
|
4514
|
+
if (visibleStartIndex >= len - 2) {
|
|
4515
|
+
if (this.options.keepHead) {
|
|
4516
|
+
const c = points[len - 1];
|
|
4517
|
+
const ps = [];
|
|
4518
|
+
for (let theta = 0; theta <= Math.PI * 2; theta += Math.PI / 16) {
|
|
4519
|
+
ps.push(
|
|
4520
|
+
add(
|
|
4521
|
+
c,
|
|
4522
|
+
smul(rot([1, 0, 0], theta), this.options.size)
|
|
4523
|
+
)
|
|
4524
|
+
);
|
|
4525
|
+
}
|
|
4526
|
+
ps.push(add(c, smul([1, 0, 0], this.options.size)));
|
|
4527
|
+
return ps;
|
|
4528
|
+
}
|
|
4529
|
+
return [];
|
|
4530
|
+
}
|
|
4531
|
+
const first = points[visibleStartIndex];
|
|
4532
|
+
const second = points[visibleStartIndex + 1];
|
|
4533
|
+
const penultimate = points[len - 2];
|
|
4534
|
+
const ultimate = points[len - 1];
|
|
4535
|
+
const dirFS = norm(sub(second, first));
|
|
4536
|
+
const dirPU = norm(sub(penultimate, ultimate));
|
|
4537
|
+
const ppdirFS = rot(dirFS, -Math.PI / 2);
|
|
4538
|
+
const ppdirPU = rot(dirPU, Math.PI / 2);
|
|
4539
|
+
const startCapSize = this.getSize(sizeOverride, first[2], 0, len, 0);
|
|
4540
|
+
const startCap = [];
|
|
4541
|
+
const endCapSize = this.options.keepHead ? this.options.size : this.getSize(sizeOverride, penultimate[2], len - 2, len, runningLength);
|
|
4542
|
+
const endCap = [];
|
|
4543
|
+
if (startCapSize > 0.1) {
|
|
4544
|
+
for (let theta = 0; theta <= Math.PI; theta += Math.PI / 16) {
|
|
4545
|
+
startCap.unshift(
|
|
4546
|
+
add(first, rot(smul(ppdirFS, startCapSize), -theta))
|
|
4547
|
+
);
|
|
4548
|
+
}
|
|
4549
|
+
startCap.unshift(add(first, smul(ppdirFS, -startCapSize)));
|
|
4550
|
+
} else {
|
|
4551
|
+
startCap.push(first);
|
|
4552
|
+
}
|
|
4553
|
+
for (let theta = 0; theta <= Math.PI * 3; theta += Math.PI / 16) {
|
|
4554
|
+
endCap.push(add(ultimate, rot(smul(ppdirPU, -endCapSize), -theta)));
|
|
4555
|
+
}
|
|
4556
|
+
const strokeOutline = [
|
|
4557
|
+
...startCap,
|
|
4558
|
+
...forwardPoints,
|
|
4559
|
+
...endCap.reverse(),
|
|
4560
|
+
...backwardPoints.reverse()
|
|
4561
|
+
];
|
|
4562
|
+
if (startCap.length > 0) {
|
|
4563
|
+
strokeOutline.push(startCap[0]);
|
|
4564
|
+
}
|
|
4565
|
+
if (this.options.simplify > 0 && this.options.simplifyPhase === "output") {
|
|
4566
|
+
return douglasPeucker(strokeOutline, this.options.simplify);
|
|
4567
|
+
}
|
|
4568
|
+
return strokeOutline;
|
|
4569
|
+
}
|
|
4570
|
+
};
|
|
4571
|
+
|
|
4216
4572
|
// src/shape.ts
|
|
4217
4573
|
import {
|
|
4218
4574
|
pointFrom as pointFrom12,
|
|
@@ -4226,7 +4582,8 @@ import {
|
|
|
4226
4582
|
assertNever as assertNever2,
|
|
4227
4583
|
COLOR_PALETTE,
|
|
4228
4584
|
LINE_POLYGON_POINT_MERGE_DISTANCE,
|
|
4229
|
-
applyDarkModeFilter as applyDarkModeFilter2
|
|
4585
|
+
applyDarkModeFilter as applyDarkModeFilter2,
|
|
4586
|
+
DEFAULT_STROKE_STREAMLINE
|
|
4230
4587
|
} from "@excalidraw/common";
|
|
4231
4588
|
|
|
4232
4589
|
// src/renderElement.ts
|
|
@@ -4243,7 +4600,7 @@ import {
|
|
|
4243
4600
|
ELEMENT_READY_TO_ERASE_OPACITY,
|
|
4244
4601
|
FRAME_STYLE,
|
|
4245
4602
|
DARK_THEME_FILTER,
|
|
4246
|
-
MIME_TYPES,
|
|
4603
|
+
MIME_TYPES as MIME_TYPES2,
|
|
4247
4604
|
THEME,
|
|
4248
4605
|
distance as distance2,
|
|
4249
4606
|
getFontString as getFontString3,
|
|
@@ -4266,7 +4623,7 @@ import {
|
|
|
4266
4623
|
vectorAdd as vectorAdd2,
|
|
4267
4624
|
vectorScale as vectorScale2,
|
|
4268
4625
|
pointFromVector as pointFromVector2,
|
|
4269
|
-
clamp,
|
|
4626
|
+
clamp as clamp2,
|
|
4270
4627
|
isCloseTo
|
|
4271
4628
|
} from "@excalidraw/math";
|
|
4272
4629
|
var MINIMAL_CROP_SIZE = 10;
|
|
@@ -4300,7 +4657,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
4300
4657
|
let changeInHeight = pointerY - element.y;
|
|
4301
4658
|
let changeInWidth = pointerX - element.x;
|
|
4302
4659
|
if (transformHandle.includes("n")) {
|
|
4303
|
-
nextHeight =
|
|
4660
|
+
nextHeight = clamp2(
|
|
4304
4661
|
element.height - changeInHeight,
|
|
4305
4662
|
MINIMAL_CROP_SIZE,
|
|
4306
4663
|
isFlippedByY ? uncroppedHeight - croppedTop : element.height + croppedTop
|
|
@@ -4308,7 +4665,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
4308
4665
|
}
|
|
4309
4666
|
if (transformHandle.includes("s")) {
|
|
4310
4667
|
changeInHeight = pointerY - element.y - element.height;
|
|
4311
|
-
nextHeight =
|
|
4668
|
+
nextHeight = clamp2(
|
|
4312
4669
|
element.height + changeInHeight,
|
|
4313
4670
|
MINIMAL_CROP_SIZE,
|
|
4314
4671
|
isFlippedByY ? element.height + croppedTop : uncroppedHeight - croppedTop
|
|
@@ -4316,14 +4673,14 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
4316
4673
|
}
|
|
4317
4674
|
if (transformHandle.includes("e")) {
|
|
4318
4675
|
changeInWidth = pointerX - element.x - element.width;
|
|
4319
|
-
nextWidth =
|
|
4676
|
+
nextWidth = clamp2(
|
|
4320
4677
|
element.width + changeInWidth,
|
|
4321
4678
|
MINIMAL_CROP_SIZE,
|
|
4322
4679
|
isFlippedByX ? element.width + croppedLeft : uncroppedWidth - croppedLeft
|
|
4323
4680
|
);
|
|
4324
4681
|
}
|
|
4325
4682
|
if (transformHandle.includes("w")) {
|
|
4326
|
-
nextWidth =
|
|
4683
|
+
nextWidth = clamp2(
|
|
4327
4684
|
element.width - changeInWidth,
|
|
4328
4685
|
MINIMAL_CROP_SIZE,
|
|
4329
4686
|
isFlippedByX ? uncroppedWidth - croppedLeft : element.width + croppedLeft
|
|
@@ -4363,7 +4720,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
4363
4720
|
const distanceToLeft = croppedLeft + element.width / 2;
|
|
4364
4721
|
const distanceToRight = uncroppedWidth - croppedLeft - element.width / 2;
|
|
4365
4722
|
const MAX_WIDTH = Math.min(distanceToLeft, distanceToRight) * 2;
|
|
4366
|
-
nextWidth =
|
|
4723
|
+
nextWidth = clamp2(
|
|
4367
4724
|
nextHeight * widthAspectRatio,
|
|
4368
4725
|
MINIMAL_CROP_SIZE,
|
|
4369
4726
|
MAX_WIDTH
|
|
@@ -4381,7 +4738,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
4381
4738
|
const distanceToLeft = croppedLeft + element.width / 2;
|
|
4382
4739
|
const distanceToRight = uncroppedWidth - croppedLeft - element.width / 2;
|
|
4383
4740
|
const MAX_WIDTH = Math.min(distanceToLeft, distanceToRight) * 2;
|
|
4384
|
-
nextWidth =
|
|
4741
|
+
nextWidth = clamp2(
|
|
4385
4742
|
nextHeight * widthAspectRatio,
|
|
4386
4743
|
MINIMAL_CROP_SIZE,
|
|
4387
4744
|
MAX_WIDTH
|
|
@@ -4399,7 +4756,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
4399
4756
|
const distanceToTop = croppedTop + element.height / 2;
|
|
4400
4757
|
const distanceToBottom = uncroppedHeight - croppedTop - element.height / 2;
|
|
4401
4758
|
const MAX_HEIGHT = Math.min(distanceToTop, distanceToBottom) * 2;
|
|
4402
|
-
nextHeight =
|
|
4759
|
+
nextHeight = clamp2(
|
|
4403
4760
|
nextWidth / widthAspectRatio,
|
|
4404
4761
|
MINIMAL_CROP_SIZE,
|
|
4405
4762
|
MAX_HEIGHT
|
|
@@ -4417,7 +4774,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
4417
4774
|
const distanceToTop = croppedTop + element.height / 2;
|
|
4418
4775
|
const distanceToBottom = uncroppedHeight - croppedTop - element.height / 2;
|
|
4419
4776
|
const MAX_HEIGHT = Math.min(distanceToTop, distanceToBottom) * 2;
|
|
4420
|
-
nextHeight =
|
|
4777
|
+
nextHeight = clamp2(
|
|
4421
4778
|
nextWidth / widthAspectRatio,
|
|
4422
4779
|
MINIMAL_CROP_SIZE,
|
|
4423
4780
|
MAX_HEIGHT
|
|
@@ -4434,7 +4791,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
4434
4791
|
if (widthAspectRatio) {
|
|
4435
4792
|
if (changeInWidth > -changeInHeight) {
|
|
4436
4793
|
const MAX_HEIGHT = isFlippedByY ? uncroppedHeight - croppedTop : croppedTop + element.height;
|
|
4437
|
-
nextHeight =
|
|
4794
|
+
nextHeight = clamp2(
|
|
4438
4795
|
nextWidth / widthAspectRatio,
|
|
4439
4796
|
MINIMAL_CROP_SIZE,
|
|
4440
4797
|
MAX_HEIGHT
|
|
@@ -4442,7 +4799,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
4442
4799
|
nextWidth = nextHeight * widthAspectRatio;
|
|
4443
4800
|
} else {
|
|
4444
4801
|
const MAX_WIDTH = isFlippedByX ? croppedLeft + element.width : uncroppedWidth - croppedLeft;
|
|
4445
|
-
nextWidth =
|
|
4802
|
+
nextWidth = clamp2(
|
|
4446
4803
|
nextHeight * widthAspectRatio,
|
|
4447
4804
|
MINIMAL_CROP_SIZE,
|
|
4448
4805
|
MAX_WIDTH
|
|
@@ -4457,7 +4814,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
4457
4814
|
if (widthAspectRatio) {
|
|
4458
4815
|
if (changeInWidth < changeInHeight) {
|
|
4459
4816
|
const MAX_HEIGHT = isFlippedByY ? uncroppedHeight - croppedTop : croppedTop + element.height;
|
|
4460
|
-
nextHeight =
|
|
4817
|
+
nextHeight = clamp2(
|
|
4461
4818
|
nextWidth / widthAspectRatio,
|
|
4462
4819
|
MINIMAL_CROP_SIZE,
|
|
4463
4820
|
MAX_HEIGHT
|
|
@@ -4465,7 +4822,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
4465
4822
|
nextWidth = nextHeight * widthAspectRatio;
|
|
4466
4823
|
} else {
|
|
4467
4824
|
const MAX_WIDTH = isFlippedByX ? uncroppedWidth - croppedLeft : croppedLeft + element.width;
|
|
4468
|
-
nextWidth =
|
|
4825
|
+
nextWidth = clamp2(
|
|
4469
4826
|
nextHeight * widthAspectRatio,
|
|
4470
4827
|
MINIMAL_CROP_SIZE,
|
|
4471
4828
|
MAX_WIDTH
|
|
@@ -4480,7 +4837,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
4480
4837
|
if (widthAspectRatio) {
|
|
4481
4838
|
if (changeInWidth > changeInHeight) {
|
|
4482
4839
|
const MAX_HEIGHT = isFlippedByY ? croppedTop + element.height : uncroppedHeight - croppedTop;
|
|
4483
|
-
nextHeight =
|
|
4840
|
+
nextHeight = clamp2(
|
|
4484
4841
|
nextWidth / widthAspectRatio,
|
|
4485
4842
|
MINIMAL_CROP_SIZE,
|
|
4486
4843
|
MAX_HEIGHT
|
|
@@ -4488,7 +4845,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
4488
4845
|
nextWidth = nextHeight * widthAspectRatio;
|
|
4489
4846
|
} else {
|
|
4490
4847
|
const MAX_WIDTH = isFlippedByX ? croppedLeft + element.width : uncroppedWidth - croppedLeft;
|
|
4491
|
-
nextWidth =
|
|
4848
|
+
nextWidth = clamp2(
|
|
4492
4849
|
nextHeight * widthAspectRatio,
|
|
4493
4850
|
MINIMAL_CROP_SIZE,
|
|
4494
4851
|
MAX_WIDTH
|
|
@@ -4503,7 +4860,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
4503
4860
|
if (widthAspectRatio) {
|
|
4504
4861
|
if (-changeInWidth > changeInHeight) {
|
|
4505
4862
|
const MAX_HEIGHT = isFlippedByY ? croppedTop + element.height : uncroppedHeight - croppedTop;
|
|
4506
|
-
nextHeight =
|
|
4863
|
+
nextHeight = clamp2(
|
|
4507
4864
|
nextWidth / widthAspectRatio,
|
|
4508
4865
|
MINIMAL_CROP_SIZE,
|
|
4509
4866
|
MAX_HEIGHT
|
|
@@ -4511,7 +4868,7 @@ var cropElement = (element, elementsMap, transformHandle, naturalWidth, naturalH
|
|
|
4511
4868
|
nextWidth = nextHeight * widthAspectRatio;
|
|
4512
4869
|
} else {
|
|
4513
4870
|
const MAX_WIDTH = isFlippedByX ? uncroppedWidth - croppedLeft : croppedLeft + element.width;
|
|
4514
|
-
nextWidth =
|
|
4871
|
+
nextWidth = clamp2(
|
|
4515
4872
|
nextHeight * widthAspectRatio,
|
|
4516
4873
|
MINIMAL_CROP_SIZE,
|
|
4517
4874
|
MAX_WIDTH
|
|
@@ -4579,17 +4936,17 @@ var recomputeOrigin = (stateAtCropStart, transformHandle, width, height, shouldM
|
|
|
4579
4936
|
newTopLeft[1] = startCenter[1] - newBoundsHeight / 2;
|
|
4580
4937
|
}
|
|
4581
4938
|
}
|
|
4582
|
-
const
|
|
4583
|
-
const rotatedTopLeft = pointRotateRads2(newTopLeft, startCenter,
|
|
4939
|
+
const angle2 = stateAtCropStart.angle;
|
|
4940
|
+
const rotatedTopLeft = pointRotateRads2(newTopLeft, startCenter, angle2);
|
|
4584
4941
|
const newCenter = [
|
|
4585
4942
|
newTopLeft[0] + Math.abs(newBoundsWidth) / 2,
|
|
4586
4943
|
newTopLeft[1] + Math.abs(newBoundsHeight) / 2
|
|
4587
4944
|
];
|
|
4588
|
-
const rotatedNewCenter = pointRotateRads2(newCenter, startCenter,
|
|
4945
|
+
const rotatedNewCenter = pointRotateRads2(newCenter, startCenter, angle2);
|
|
4589
4946
|
newTopLeft = pointRotateRads2(
|
|
4590
4947
|
rotatedTopLeft,
|
|
4591
4948
|
rotatedNewCenter,
|
|
4592
|
-
-
|
|
4949
|
+
-angle2
|
|
4593
4950
|
);
|
|
4594
4951
|
const newOrigin = [...newTopLeft];
|
|
4595
4952
|
newOrigin[0] += stateAtCropStart.x - newBoundsX1;
|
|
@@ -4744,7 +5101,7 @@ import {
|
|
|
4744
5101
|
} from "@excalidraw/common";
|
|
4745
5102
|
import {
|
|
4746
5103
|
PRECISION as PRECISION2,
|
|
4747
|
-
clamp as
|
|
5104
|
+
clamp as clamp4,
|
|
4748
5105
|
lineSegment as lineSegment4,
|
|
4749
5106
|
pointDistance as pointDistance4,
|
|
4750
5107
|
pointDistanceSq,
|
|
@@ -6290,8 +6647,8 @@ var computeBoundTextPosition = (container, boundTextElement, elementsMap) => {
|
|
|
6290
6647
|
} else {
|
|
6291
6648
|
x = containerCoords.x + (maxContainerWidth / 2 - boundTextElement.width / 2);
|
|
6292
6649
|
}
|
|
6293
|
-
const
|
|
6294
|
-
if (
|
|
6650
|
+
const angle2 = container.angle ?? 0;
|
|
6651
|
+
if (angle2 !== 0) {
|
|
6295
6652
|
const contentCenter = pointFrom4(
|
|
6296
6653
|
containerCoords.x + maxContainerWidth / 2,
|
|
6297
6654
|
containerCoords.y + maxContainerHeight / 2
|
|
@@ -6300,7 +6657,7 @@ var computeBoundTextPosition = (container, boundTextElement, elementsMap) => {
|
|
|
6300
6657
|
x + boundTextElement.width / 2,
|
|
6301
6658
|
y + boundTextElement.height / 2
|
|
6302
6659
|
);
|
|
6303
|
-
const [rx, ry] = pointRotateRads4(textCenter, contentCenter,
|
|
6660
|
+
const [rx, ry] = pointRotateRads4(textCenter, contentCenter, angle2);
|
|
6304
6661
|
return {
|
|
6305
6662
|
x: rx - boundTextElement.width / 2,
|
|
6306
6663
|
y: ry - boundTextElement.height / 2
|
|
@@ -6557,6 +6914,7 @@ var hasBackground = (type) => type === "rectangle" || type === "iframe" || type
|
|
|
6557
6914
|
var hasStrokeColor = (type) => type === "rectangle" || type === "ellipse" || type === "diamond" || type === "freedraw" || type === "arrow" || type === "line" || type === "text" || type === "embeddable";
|
|
6558
6915
|
var hasStrokeWidth = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "freedraw" || type === "arrow" || type === "line";
|
|
6559
6916
|
var hasStrokeStyle = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "ellipse" || type === "diamond" || type === "arrow" || type === "line";
|
|
6917
|
+
var hasFreedrawMode = (type) => type === "freedraw";
|
|
6560
6918
|
var canChangeRoundness = (type) => type === "rectangle" || type === "iframe" || type === "embeddable" || type === "line" || type === "diamond" || type === "image";
|
|
6561
6919
|
var toolIsArrow = (type) => type === "arrow";
|
|
6562
6920
|
var canHaveArrowheads = (type) => type === "arrow";
|
|
@@ -6625,8 +6983,8 @@ var hitElementItself = ({
|
|
|
6625
6983
|
cachedHit = result;
|
|
6626
6984
|
return result;
|
|
6627
6985
|
};
|
|
6628
|
-
var isPointInRotatedBounds = (point, bounds,
|
|
6629
|
-
const adjustedPoint =
|
|
6986
|
+
var isPointInRotatedBounds = (point, bounds, angle2, tolerance = 0) => {
|
|
6987
|
+
const adjustedPoint = angle2 === 0 ? point : pointRotateRads6(point, getCenterForBounds(bounds), -angle2);
|
|
6630
6988
|
return isPointWithinBounds(
|
|
6631
6989
|
pointFrom5(bounds[0] - tolerance, bounds[1] - tolerance),
|
|
6632
6990
|
adjustedPoint,
|
|
@@ -6802,7 +7160,7 @@ var intersectElementWithLineSegment = (element, elementsMap, line2, offset = 0,
|
|
|
6802
7160
|
);
|
|
6803
7161
|
}
|
|
6804
7162
|
};
|
|
6805
|
-
var curveIntersections = (curves, segment, intersections, center,
|
|
7163
|
+
var curveIntersections = (curves, segment, intersections, center, angle2, onlyFirst = false) => {
|
|
6806
7164
|
for (const c of curves) {
|
|
6807
7165
|
const b1 = getCubicBezierCurveBound(c[0], c[1], c[2], c[3]);
|
|
6808
7166
|
const b2 = [
|
|
@@ -6817,7 +7175,7 @@ var curveIntersections = (curves, segment, intersections, center, angle, onlyFir
|
|
|
6817
7175
|
const hits = curveIntersectLineSegment(c, segment);
|
|
6818
7176
|
if (hits.length > 0) {
|
|
6819
7177
|
for (const j of hits) {
|
|
6820
|
-
intersections.push(pointRotateRads6(j, center,
|
|
7178
|
+
intersections.push(pointRotateRads6(j, center, angle2));
|
|
6821
7179
|
}
|
|
6822
7180
|
if (onlyFirst) {
|
|
6823
7181
|
return intersections;
|
|
@@ -6826,11 +7184,11 @@ var curveIntersections = (curves, segment, intersections, center, angle, onlyFir
|
|
|
6826
7184
|
}
|
|
6827
7185
|
return intersections;
|
|
6828
7186
|
};
|
|
6829
|
-
var lineIntersections = (lines, segment, intersections, center,
|
|
7187
|
+
var lineIntersections = (lines, segment, intersections, center, angle2, onlyFirst = false) => {
|
|
6830
7188
|
for (const l2 of lines) {
|
|
6831
7189
|
const intersection = lineSegmentIntersectionPoints2(l2, segment);
|
|
6832
7190
|
if (intersection) {
|
|
6833
|
-
intersections.push(pointRotateRads6(intersection, center,
|
|
7191
|
+
intersections.push(pointRotateRads6(intersection, center, angle2));
|
|
6834
7192
|
if (onlyFirst) {
|
|
6835
7193
|
return intersections;
|
|
6836
7194
|
}
|
|
@@ -6976,7 +7334,7 @@ var isPointInElement = (point, element, elementsMap) => {
|
|
|
6976
7334
|
};
|
|
6977
7335
|
var isBindableElementInsideOtherBindable = (innerElement, outerElement, elementsMap) => {
|
|
6978
7336
|
const getCornerPoints = (element, offset2) => {
|
|
6979
|
-
const { x, y, width, height, angle } = element;
|
|
7337
|
+
const { x, y, width, height, angle: angle2 } = element;
|
|
6980
7338
|
const center = elementCenterPoint(element, elementsMap);
|
|
6981
7339
|
if (element.type === "diamond") {
|
|
6982
7340
|
const [topX, topY, rightX, rightY, bottomX, bottomY, leftX, leftY] = getDiamondPoints(element);
|
|
@@ -6990,7 +7348,7 @@ var isBindableElementInsideOtherBindable = (innerElement, outerElement, elements
|
|
|
6990
7348
|
pointFrom5(x + leftX - offset2, y + leftY)
|
|
6991
7349
|
// left
|
|
6992
7350
|
];
|
|
6993
|
-
return corners2.map((corner) => pointRotateRads6(corner, center,
|
|
7351
|
+
return corners2.map((corner) => pointRotateRads6(corner, center, angle2));
|
|
6994
7352
|
}
|
|
6995
7353
|
if (element.type === "ellipse") {
|
|
6996
7354
|
const cx = x + width / 2;
|
|
@@ -7007,7 +7365,7 @@ var isBindableElementInsideOtherBindable = (innerElement, outerElement, elements
|
|
|
7007
7365
|
pointFrom5(cx - rx - offset2, cy)
|
|
7008
7366
|
// left
|
|
7009
7367
|
];
|
|
7010
|
-
return corners2.map((corner) => pointRotateRads6(corner, center,
|
|
7368
|
+
return corners2.map((corner) => pointRotateRads6(corner, center, angle2));
|
|
7011
7369
|
}
|
|
7012
7370
|
const corners = [
|
|
7013
7371
|
pointFrom5(x - offset2, y - offset2),
|
|
@@ -7019,7 +7377,7 @@ var isBindableElementInsideOtherBindable = (innerElement, outerElement, elements
|
|
|
7019
7377
|
pointFrom5(x - offset2, y + height + offset2)
|
|
7020
7378
|
// bottom-left
|
|
7021
7379
|
];
|
|
7022
|
-
return corners.map((corner) => pointRotateRads6(corner, center,
|
|
7380
|
+
return corners.map((corner) => pointRotateRads6(corner, center, angle2));
|
|
7023
7381
|
};
|
|
7024
7382
|
const offset = -1 * Math.max(innerElement.width, innerElement.height) / 20;
|
|
7025
7383
|
const innerCorners = getCornerPoints(innerElement, offset);
|
|
@@ -7245,7 +7603,7 @@ import {
|
|
|
7245
7603
|
// src/elbowArrow.ts
|
|
7246
7604
|
init_define_import_meta_env();
|
|
7247
7605
|
import {
|
|
7248
|
-
clamp as
|
|
7606
|
+
clamp as clamp3,
|
|
7249
7607
|
pointDistance as pointDistance3,
|
|
7250
7608
|
pointFrom as pointFrom7,
|
|
7251
7609
|
pointScaleFromOrigin as pointScaleFromOrigin2,
|
|
@@ -8589,12 +8947,12 @@ var normalizeArrowElementUpdate = (global2, nextFixedSegments, startIsSpecial, e
|
|
|
8589
8947
|
);
|
|
8590
8948
|
}
|
|
8591
8949
|
points = points.map(
|
|
8592
|
-
([x, y]) => pointFrom7(
|
|
8950
|
+
([x, y]) => pointFrom7(clamp3(x, -1e6, 1e6), clamp3(y, -1e6, 1e6))
|
|
8593
8951
|
);
|
|
8594
8952
|
return {
|
|
8595
8953
|
points,
|
|
8596
|
-
x:
|
|
8597
|
-
y:
|
|
8954
|
+
x: clamp3(offsetX, -1e6, 1e6),
|
|
8955
|
+
y: clamp3(offsetY, -1e6, 1e6),
|
|
8598
8956
|
fixedSegments: (nextFixedSegments?.length ?? 0) > 0 ? nextFixedSegments : null,
|
|
8599
8957
|
...getSizeFromPoints(points),
|
|
8600
8958
|
startIsSpecial,
|
|
@@ -8806,7 +9164,7 @@ var getBindingGap = (bindTarget, opts) => {
|
|
|
8806
9164
|
var maxBindingDistance_simple = (zoom) => {
|
|
8807
9165
|
const BASE_BINDING_DISTANCE = Math.max(BASE_BINDING_GAP, 15);
|
|
8808
9166
|
const zoomValue = zoom?.value && zoom.value < 1 ? zoom.value : 1;
|
|
8809
|
-
return
|
|
9167
|
+
return clamp4(
|
|
8810
9168
|
// reducing zoom impact so that the diff between binding distance and
|
|
8811
9169
|
// binding gap is kept to minimum when possible
|
|
8812
9170
|
BASE_BINDING_DISTANCE / (zoomValue * 1.5),
|
|
@@ -9118,10 +9476,12 @@ var getBindingStrategyForDraggingBindingElementEndpoints_simple = (arrow, draggi
|
|
|
9118
9476
|
const endDragged = draggingPoints.has(endIdx);
|
|
9119
9477
|
let start2 = { mode: void 0 };
|
|
9120
9478
|
let end = { mode: void 0 };
|
|
9121
|
-
|
|
9122
|
-
|
|
9123
|
-
|
|
9124
|
-
|
|
9479
|
+
if (arrow.points.length < 2) {
|
|
9480
|
+
console.error(
|
|
9481
|
+
"Attempting to bind a linear element with less than 2 points"
|
|
9482
|
+
);
|
|
9483
|
+
return { start: { mode: void 0 }, end: { mode: void 0 } };
|
|
9484
|
+
}
|
|
9125
9485
|
if (!startDragged && !endDragged) {
|
|
9126
9486
|
return { start: start2, end };
|
|
9127
9487
|
}
|
|
@@ -9282,10 +9642,12 @@ var getBindingStrategyForDraggingBindingElementEndpoints_complex = (arrow, dragg
|
|
|
9282
9642
|
const endDragged = draggingPoints.has(endIdx);
|
|
9283
9643
|
let start2 = { mode: void 0 };
|
|
9284
9644
|
let end = { mode: void 0 };
|
|
9285
|
-
|
|
9286
|
-
|
|
9287
|
-
|
|
9288
|
-
|
|
9645
|
+
if (arrow.points.length < 2) {
|
|
9646
|
+
console.error(
|
|
9647
|
+
"Attempting to bind a linear element with less than 2 points"
|
|
9648
|
+
);
|
|
9649
|
+
return { start: { mode: void 0 }, end: { mode: void 0 } };
|
|
9650
|
+
}
|
|
9289
9651
|
if (!startDragged && !endDragged) {
|
|
9290
9652
|
return { start: start2, end };
|
|
9291
9653
|
}
|
|
@@ -9770,12 +10132,12 @@ var avoidRectangularCorner = (arrowElement, bindTarget, elementsMap, p) => {
|
|
|
9770
10132
|
return p;
|
|
9771
10133
|
};
|
|
9772
10134
|
var snapToMid = (bindTarget, elementsMap, p, tolerance = 0.05, arrowElement) => {
|
|
9773
|
-
const { x, y, width, height, angle } = bindTarget;
|
|
10135
|
+
const { x, y, width, height, angle: angle2 } = bindTarget;
|
|
9774
10136
|
const center = elementCenterPoint(bindTarget, elementsMap, -0.1, -0.1);
|
|
9775
|
-
const nonRotated = pointRotateRads8(p, center, -
|
|
10137
|
+
const nonRotated = pointRotateRads8(p, center, -angle2);
|
|
9776
10138
|
const bindingGap = arrowElement ? getBindingGap(bindTarget, arrowElement) : 0;
|
|
9777
|
-
const verticalThreshold =
|
|
9778
|
-
const horizontalThreshold =
|
|
10139
|
+
const verticalThreshold = clamp4(tolerance * height, 5, 80);
|
|
10140
|
+
const horizontalThreshold = clamp4(tolerance * width, 5, 80);
|
|
9779
10141
|
if (pointDistance4(center, nonRotated) < bindingGap) {
|
|
9780
10142
|
return void 0;
|
|
9781
10143
|
}
|
|
@@ -9783,25 +10145,25 @@ var snapToMid = (bindTarget, elementsMap, p, tolerance = 0.05, arrowElement) =>
|
|
|
9783
10145
|
return pointRotateRads8(
|
|
9784
10146
|
pointFrom8(x - bindingGap, center[1]),
|
|
9785
10147
|
center,
|
|
9786
|
-
|
|
10148
|
+
angle2
|
|
9787
10149
|
);
|
|
9788
10150
|
} else if (nonRotated[1] <= y + height / 2 && nonRotated[0] > center[0] - horizontalThreshold && nonRotated[0] < center[0] + horizontalThreshold) {
|
|
9789
10151
|
return pointRotateRads8(
|
|
9790
10152
|
pointFrom8(center[0], y - bindingGap),
|
|
9791
10153
|
center,
|
|
9792
|
-
|
|
10154
|
+
angle2
|
|
9793
10155
|
);
|
|
9794
10156
|
} else if (nonRotated[0] >= x + width / 2 && nonRotated[1] > center[1] - verticalThreshold && nonRotated[1] < center[1] + verticalThreshold) {
|
|
9795
10157
|
return pointRotateRads8(
|
|
9796
10158
|
pointFrom8(x + width + bindingGap, center[1]),
|
|
9797
10159
|
center,
|
|
9798
|
-
|
|
10160
|
+
angle2
|
|
9799
10161
|
);
|
|
9800
10162
|
} else if (nonRotated[1] >= y + height / 2 && nonRotated[0] > center[0] - horizontalThreshold && nonRotated[0] < center[0] + horizontalThreshold) {
|
|
9801
10163
|
return pointRotateRads8(
|
|
9802
10164
|
pointFrom8(center[0], y + height + bindingGap),
|
|
9803
10165
|
center,
|
|
9804
|
-
|
|
10166
|
+
angle2
|
|
9805
10167
|
);
|
|
9806
10168
|
} else if (bindTarget.type === "diamond") {
|
|
9807
10169
|
const distance3 = bindingGap;
|
|
@@ -9822,16 +10184,16 @@ var snapToMid = (bindTarget, elementsMap, p, tolerance = 0.05, arrowElement) =>
|
|
|
9822
10184
|
y + 3 * height / 4 + distance3
|
|
9823
10185
|
);
|
|
9824
10186
|
if (pointDistance4(topLeft, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {
|
|
9825
|
-
return pointRotateRads8(topLeft, center,
|
|
10187
|
+
return pointRotateRads8(topLeft, center, angle2);
|
|
9826
10188
|
}
|
|
9827
10189
|
if (pointDistance4(topRight, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {
|
|
9828
|
-
return pointRotateRads8(topRight, center,
|
|
10190
|
+
return pointRotateRads8(topRight, center, angle2);
|
|
9829
10191
|
}
|
|
9830
10192
|
if (pointDistance4(bottomLeft, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {
|
|
9831
|
-
return pointRotateRads8(bottomLeft, center,
|
|
10193
|
+
return pointRotateRads8(bottomLeft, center, angle2);
|
|
9832
10194
|
}
|
|
9833
10195
|
if (pointDistance4(bottomRight, nonRotated) < Math.max(horizontalThreshold, verticalThreshold)) {
|
|
9834
|
-
return pointRotateRads8(bottomRight, center,
|
|
10196
|
+
return pointRotateRads8(bottomRight, center, angle2);
|
|
9835
10197
|
}
|
|
9836
10198
|
}
|
|
9837
10199
|
return void 0;
|
|
@@ -10401,11 +10763,11 @@ var getShapeSideAdaptive = (fixedPoint, shapeType) => {
|
|
|
10401
10763
|
const [x, y] = fixedPoint;
|
|
10402
10764
|
const centerX = x - 0.5;
|
|
10403
10765
|
const centerY = y - 0.5;
|
|
10404
|
-
let
|
|
10405
|
-
if (
|
|
10406
|
-
|
|
10766
|
+
let angle2 = Math.atan2(centerY, centerX);
|
|
10767
|
+
if (angle2 < 0) {
|
|
10768
|
+
angle2 += 2 * Math.PI;
|
|
10407
10769
|
}
|
|
10408
|
-
const degrees =
|
|
10770
|
+
const degrees = angle2 * 180 / Math.PI;
|
|
10409
10771
|
const config = SHAPE_CONFIGS[shapeType];
|
|
10410
10772
|
const boundaries = getSectorBoundaries(config);
|
|
10411
10773
|
for (const boundary of boundaries) {
|
|
@@ -10560,33 +10922,33 @@ var getBindingSideMidPoint = (binding, elementsMap) => {
|
|
|
10560
10922
|
break;
|
|
10561
10923
|
}
|
|
10562
10924
|
case "top-right": {
|
|
10563
|
-
const
|
|
10564
|
-
const ellipseX = radiusX * Math.cos(
|
|
10565
|
-
const ellipseY = radiusY * Math.sin(
|
|
10925
|
+
const angle2 = -Math.PI / 4;
|
|
10926
|
+
const ellipseX = radiusX * Math.cos(angle2);
|
|
10927
|
+
const ellipseY = radiusY * Math.sin(angle2);
|
|
10566
10928
|
x = ellipseCenterX + ellipseX + OFFSET * 0.707;
|
|
10567
10929
|
y = ellipseCenterY + ellipseY - OFFSET * 0.707;
|
|
10568
10930
|
break;
|
|
10569
10931
|
}
|
|
10570
10932
|
case "bottom-right": {
|
|
10571
|
-
const
|
|
10572
|
-
const ellipseX = radiusX * Math.cos(
|
|
10573
|
-
const ellipseY = radiusY * Math.sin(
|
|
10933
|
+
const angle2 = Math.PI / 4;
|
|
10934
|
+
const ellipseX = radiusX * Math.cos(angle2);
|
|
10935
|
+
const ellipseY = radiusY * Math.sin(angle2);
|
|
10574
10936
|
x = ellipseCenterX + ellipseX + OFFSET * 0.707;
|
|
10575
10937
|
y = ellipseCenterY + ellipseY + OFFSET * 0.707;
|
|
10576
10938
|
break;
|
|
10577
10939
|
}
|
|
10578
10940
|
case "bottom-left": {
|
|
10579
|
-
const
|
|
10580
|
-
const ellipseX = radiusX * Math.cos(
|
|
10581
|
-
const ellipseY = radiusY * Math.sin(
|
|
10941
|
+
const angle2 = 3 * Math.PI / 4;
|
|
10942
|
+
const ellipseX = radiusX * Math.cos(angle2);
|
|
10943
|
+
const ellipseY = radiusY * Math.sin(angle2);
|
|
10582
10944
|
x = ellipseCenterX + ellipseX - OFFSET * 0.707;
|
|
10583
10945
|
y = ellipseCenterY + ellipseY + OFFSET * 0.707;
|
|
10584
10946
|
break;
|
|
10585
10947
|
}
|
|
10586
10948
|
case "top-left": {
|
|
10587
|
-
const
|
|
10588
|
-
const ellipseX = radiusX * Math.cos(
|
|
10589
|
-
const ellipseY = radiusY * Math.sin(
|
|
10949
|
+
const angle2 = -3 * Math.PI / 4;
|
|
10950
|
+
const ellipseX = radiusX * Math.cos(angle2);
|
|
10951
|
+
const ellipseY = radiusY * Math.sin(angle2);
|
|
10590
10952
|
x = ellipseCenterX + ellipseX - OFFSET * 0.707;
|
|
10591
10953
|
y = ellipseCenterY + ellipseY - OFFSET * 0.707;
|
|
10592
10954
|
break;
|
|
@@ -10700,6 +11062,7 @@ var getMidPoint = (p1, p2) => {
|
|
|
10700
11062
|
// src/zindex.ts
|
|
10701
11063
|
init_define_import_meta_env();
|
|
10702
11064
|
import { arrayToMap as arrayToMap6, findIndex, findLastIndex } from "@excalidraw/common";
|
|
11065
|
+
import { isFiniteNumber } from "@excalidraw/math";
|
|
10703
11066
|
|
|
10704
11067
|
// src/groups.ts
|
|
10705
11068
|
init_define_import_meta_env();
|
|
@@ -11276,9 +11639,6 @@ var addElementsToFrame = (allElements, elementsToAdd, frame) => {
|
|
|
11276
11639
|
if (isFrameLikeElement(element) || element.frameId && otherFrames.has(element.frameId)) {
|
|
11277
11640
|
continue;
|
|
11278
11641
|
}
|
|
11279
|
-
if (element.frameId && element.frameId !== frame.id) {
|
|
11280
|
-
continue;
|
|
11281
|
-
}
|
|
11282
11642
|
finalElementsToAdd.add(element);
|
|
11283
11643
|
const boundTextElement = getBoundTextElement(element, elementsMap);
|
|
11284
11644
|
if (boundTextElement && !finalElementsToAdd.has(boundTextElement)) {
|
|
@@ -12137,7 +12497,34 @@ var getTargetElementsMap = (elements, indices) => {
|
|
|
12137
12497
|
return acc;
|
|
12138
12498
|
}, /* @__PURE__ */ new Map());
|
|
12139
12499
|
};
|
|
12500
|
+
var hasSameElementIds = (prevElements, nextElements) => {
|
|
12501
|
+
if (prevElements.length !== nextElements.length) {
|
|
12502
|
+
console.error(
|
|
12503
|
+
"z-index reordering failed: resulting array have different lengths"
|
|
12504
|
+
);
|
|
12505
|
+
return false;
|
|
12506
|
+
}
|
|
12507
|
+
const prevElementIdCounts = /* @__PURE__ */ new Map();
|
|
12508
|
+
for (const element of prevElements) {
|
|
12509
|
+
prevElementIdCounts.set(
|
|
12510
|
+
element.id,
|
|
12511
|
+
(prevElementIdCounts.get(element.id) || 0) + 1
|
|
12512
|
+
);
|
|
12513
|
+
}
|
|
12514
|
+
for (const element of nextElements) {
|
|
12515
|
+
const count = prevElementIdCounts.get(element.id);
|
|
12516
|
+
if (!count) {
|
|
12517
|
+
console.error(
|
|
12518
|
+
"z-index reordering failed: element id mismatch / duplicate ids"
|
|
12519
|
+
);
|
|
12520
|
+
return false;
|
|
12521
|
+
}
|
|
12522
|
+
prevElementIdCounts.set(element.id, count - 1);
|
|
12523
|
+
}
|
|
12524
|
+
return true;
|
|
12525
|
+
};
|
|
12140
12526
|
var shiftElementsByOne = (elements, appState, direction, scene) => {
|
|
12527
|
+
const originalElements = elements;
|
|
12141
12528
|
const indicesToMove = getIndicesToMove(elements, appState);
|
|
12142
12529
|
const targetElementsMap = getTargetElementsMap(elements, indicesToMove);
|
|
12143
12530
|
let groupedIndices = toContiguousGroups(indicesToMove);
|
|
@@ -12182,11 +12569,17 @@ var shiftElementsByOne = (elements, appState, direction, scene) => {
|
|
|
12182
12569
|
...trailingElements
|
|
12183
12570
|
];
|
|
12184
12571
|
});
|
|
12572
|
+
if (!hasSameElementIds(originalElements, elements)) {
|
|
12573
|
+
return originalElements;
|
|
12574
|
+
}
|
|
12185
12575
|
syncMovedIndices(elements, targetElementsMap);
|
|
12186
12576
|
return elements;
|
|
12187
12577
|
};
|
|
12188
12578
|
var shiftElementsToEnd = (elements, appState, direction, containingFrame, elementsToBeMoved) => {
|
|
12189
12579
|
const indicesToMove = getIndicesToMove(elements, appState, elementsToBeMoved);
|
|
12580
|
+
if (indicesToMove.length === 0) {
|
|
12581
|
+
return elements;
|
|
12582
|
+
}
|
|
12190
12583
|
const targetElementsMap = getTargetElementsMap(elements, indicesToMove);
|
|
12191
12584
|
const displacedElements = [];
|
|
12192
12585
|
let leadingIndex;
|
|
@@ -12233,6 +12626,12 @@ var shiftElementsToEnd = (elements, appState, direction, containingFrame, elemen
|
|
|
12233
12626
|
if (leadingIndex === -1) {
|
|
12234
12627
|
leadingIndex = 0;
|
|
12235
12628
|
}
|
|
12629
|
+
const isValidIndex = (index) => {
|
|
12630
|
+
return isFiniteNumber(index) && index >= 0;
|
|
12631
|
+
};
|
|
12632
|
+
if (!isValidIndex(leadingIndex) || !isValidIndex(trailingIndex) || leadingIndex > trailingIndex || indicesToMove.some((index) => index < leadingIndex || index > trailingIndex)) {
|
|
12633
|
+
return elements;
|
|
12634
|
+
}
|
|
12236
12635
|
for (let index = leadingIndex; index < trailingIndex + 1; index++) {
|
|
12237
12636
|
if (!indicesToMove.includes(index)) {
|
|
12238
12637
|
displacedElements.push(elements[index]);
|
|
@@ -12252,6 +12651,9 @@ var shiftElementsToEnd = (elements, appState, direction, containingFrame, elemen
|
|
|
12252
12651
|
...targetElements,
|
|
12253
12652
|
...trailingElements
|
|
12254
12653
|
];
|
|
12654
|
+
if (!hasSameElementIds(elements, nextElements)) {
|
|
12655
|
+
return elements;
|
|
12656
|
+
}
|
|
12255
12657
|
syncMovedIndices(nextElements, targetElementsMap);
|
|
12256
12658
|
return nextElements;
|
|
12257
12659
|
};
|
|
@@ -12293,7 +12695,7 @@ function shiftElementsAccountingForFrames(allElements, appState, direction, shif
|
|
|
12293
12695
|
);
|
|
12294
12696
|
for (const [frameId, children] of frameChildrenSets) {
|
|
12295
12697
|
nextElements = shiftFunction(
|
|
12296
|
-
|
|
12698
|
+
nextElements,
|
|
12297
12699
|
appState,
|
|
12298
12700
|
direction,
|
|
12299
12701
|
frameId,
|
|
@@ -13416,11 +13818,11 @@ var LinearElementEditor = class _LinearElementEditor {
|
|
|
13416
13818
|
return false;
|
|
13417
13819
|
}
|
|
13418
13820
|
const origin = linearElementEditor.initialState.origin;
|
|
13419
|
-
const
|
|
13821
|
+
const dist2 = pointDistance5(
|
|
13420
13822
|
origin,
|
|
13421
13823
|
pointFrom10(pointerCoords.x, pointerCoords.y)
|
|
13422
13824
|
);
|
|
13423
|
-
if (!appState.selectedLinearElement?.isEditing &&
|
|
13825
|
+
if (!appState.selectedLinearElement?.isEditing && dist2 < DRAGGING_THRESHOLD / appState.zoom.value) {
|
|
13424
13826
|
return false;
|
|
13425
13827
|
}
|
|
13426
13828
|
return true;
|
|
@@ -13983,6 +14385,333 @@ var pointDraggingUpdates = (selectedPointsIndices, deltaX, deltaY, scenePointerX
|
|
|
13983
14385
|
};
|
|
13984
14386
|
var determineCustomLinearAngle = (pivotPoint, draggedPoint) => Math.atan2(draggedPoint[1] - pivotPoint[1], draggedPoint[0] - pivotPoint[0]);
|
|
13985
14387
|
|
|
14388
|
+
// src/image.ts
|
|
14389
|
+
init_define_import_meta_env();
|
|
14390
|
+
import { MIME_TYPES, SVG_NS } from "@excalidraw/common";
|
|
14391
|
+
|
|
14392
|
+
// ../../node_modules/thumbhash/thumbhash.js
|
|
14393
|
+
init_define_import_meta_env();
|
|
14394
|
+
function rgbaToThumbHash(w, h, rgba) {
|
|
14395
|
+
if (w > 100 || h > 100)
|
|
14396
|
+
throw new Error(`${w}x${h} doesn't fit in 100x100`);
|
|
14397
|
+
let { PI, round, max, cos, abs } = Math;
|
|
14398
|
+
let avg_r = 0, avg_g = 0, avg_b = 0, avg_a = 0;
|
|
14399
|
+
for (let i = 0, j = 0; i < w * h; i++, j += 4) {
|
|
14400
|
+
let alpha = rgba[j + 3] / 255;
|
|
14401
|
+
avg_r += alpha / 255 * rgba[j];
|
|
14402
|
+
avg_g += alpha / 255 * rgba[j + 1];
|
|
14403
|
+
avg_b += alpha / 255 * rgba[j + 2];
|
|
14404
|
+
avg_a += alpha;
|
|
14405
|
+
}
|
|
14406
|
+
if (avg_a) {
|
|
14407
|
+
avg_r /= avg_a;
|
|
14408
|
+
avg_g /= avg_a;
|
|
14409
|
+
avg_b /= avg_a;
|
|
14410
|
+
}
|
|
14411
|
+
let hasAlpha = avg_a < w * h;
|
|
14412
|
+
let l_limit = hasAlpha ? 5 : 7;
|
|
14413
|
+
let lx = max(1, round(l_limit * w / max(w, h)));
|
|
14414
|
+
let ly = max(1, round(l_limit * h / max(w, h)));
|
|
14415
|
+
let l2 = [];
|
|
14416
|
+
let p = [];
|
|
14417
|
+
let q = [];
|
|
14418
|
+
let a2 = [];
|
|
14419
|
+
for (let i = 0, j = 0; i < w * h; i++, j += 4) {
|
|
14420
|
+
let alpha = rgba[j + 3] / 255;
|
|
14421
|
+
let r = avg_r * (1 - alpha) + alpha / 255 * rgba[j];
|
|
14422
|
+
let g = avg_g * (1 - alpha) + alpha / 255 * rgba[j + 1];
|
|
14423
|
+
let b2 = avg_b * (1 - alpha) + alpha / 255 * rgba[j + 2];
|
|
14424
|
+
l2[i] = (r + g + b2) / 3;
|
|
14425
|
+
p[i] = (r + g) / 2 - b2;
|
|
14426
|
+
q[i] = r - g;
|
|
14427
|
+
a2[i] = alpha;
|
|
14428
|
+
}
|
|
14429
|
+
let encodeChannel = (channel, nx, ny) => {
|
|
14430
|
+
let dc = 0, ac = [], scale = 0, fx = [];
|
|
14431
|
+
for (let cy = 0; cy < ny; cy++) {
|
|
14432
|
+
for (let cx = 0; cx * ny < nx * (ny - cy); cx++) {
|
|
14433
|
+
let f = 0;
|
|
14434
|
+
for (let x = 0; x < w; x++)
|
|
14435
|
+
fx[x] = cos(PI / w * cx * (x + 0.5));
|
|
14436
|
+
for (let y = 0; y < h; y++)
|
|
14437
|
+
for (let x = 0, fy = cos(PI / h * cy * (y + 0.5)); x < w; x++)
|
|
14438
|
+
f += channel[x + y * w] * fx[x] * fy;
|
|
14439
|
+
f /= w * h;
|
|
14440
|
+
if (cx || cy) {
|
|
14441
|
+
ac.push(f);
|
|
14442
|
+
scale = max(scale, abs(f));
|
|
14443
|
+
} else {
|
|
14444
|
+
dc = f;
|
|
14445
|
+
}
|
|
14446
|
+
}
|
|
14447
|
+
}
|
|
14448
|
+
if (scale)
|
|
14449
|
+
for (let i = 0; i < ac.length; i++)
|
|
14450
|
+
ac[i] = 0.5 + 0.5 / scale * ac[i];
|
|
14451
|
+
return [dc, ac, scale];
|
|
14452
|
+
};
|
|
14453
|
+
let [l_dc, l_ac, l_scale] = encodeChannel(l2, max(3, lx), max(3, ly));
|
|
14454
|
+
let [p_dc, p_ac, p_scale] = encodeChannel(p, 3, 3);
|
|
14455
|
+
let [q_dc, q_ac, q_scale] = encodeChannel(q, 3, 3);
|
|
14456
|
+
let [a_dc, a_ac, a_scale] = hasAlpha ? encodeChannel(a2, 5, 5) : [];
|
|
14457
|
+
let isLandscape = w > h;
|
|
14458
|
+
let header24 = round(63 * l_dc) | round(31.5 + 31.5 * p_dc) << 6 | round(31.5 + 31.5 * q_dc) << 12 | round(31 * l_scale) << 18 | hasAlpha << 23;
|
|
14459
|
+
let header16 = (isLandscape ? ly : lx) | round(63 * p_scale) << 3 | round(63 * q_scale) << 9 | isLandscape << 15;
|
|
14460
|
+
let hash = [header24 & 255, header24 >> 8 & 255, header24 >> 16, header16 & 255, header16 >> 8];
|
|
14461
|
+
let ac_start = hasAlpha ? 6 : 5;
|
|
14462
|
+
let ac_index = 0;
|
|
14463
|
+
if (hasAlpha)
|
|
14464
|
+
hash.push(round(15 * a_dc) | round(15 * a_scale) << 4);
|
|
14465
|
+
for (let ac of hasAlpha ? [l_ac, p_ac, q_ac, a_ac] : [l_ac, p_ac, q_ac])
|
|
14466
|
+
for (let f of ac)
|
|
14467
|
+
hash[ac_start + (ac_index >> 1)] |= round(15 * f) << ((ac_index++ & 1) << 2);
|
|
14468
|
+
return new Uint8Array(hash);
|
|
14469
|
+
}
|
|
14470
|
+
function thumbHashToRGBA(hash) {
|
|
14471
|
+
let { PI, min, max, cos, round } = Math;
|
|
14472
|
+
let header24 = hash[0] | hash[1] << 8 | hash[2] << 16;
|
|
14473
|
+
let header16 = hash[3] | hash[4] << 8;
|
|
14474
|
+
let l_dc = (header24 & 63) / 63;
|
|
14475
|
+
let p_dc = (header24 >> 6 & 63) / 31.5 - 1;
|
|
14476
|
+
let q_dc = (header24 >> 12 & 63) / 31.5 - 1;
|
|
14477
|
+
let l_scale = (header24 >> 18 & 31) / 31;
|
|
14478
|
+
let hasAlpha = header24 >> 23;
|
|
14479
|
+
let p_scale = (header16 >> 3 & 63) / 63;
|
|
14480
|
+
let q_scale = (header16 >> 9 & 63) / 63;
|
|
14481
|
+
let isLandscape = header16 >> 15;
|
|
14482
|
+
let lx = max(3, isLandscape ? hasAlpha ? 5 : 7 : header16 & 7);
|
|
14483
|
+
let ly = max(3, isLandscape ? header16 & 7 : hasAlpha ? 5 : 7);
|
|
14484
|
+
let a_dc = hasAlpha ? (hash[5] & 15) / 15 : 1;
|
|
14485
|
+
let a_scale = (hash[5] >> 4) / 15;
|
|
14486
|
+
let ac_start = hasAlpha ? 6 : 5;
|
|
14487
|
+
let ac_index = 0;
|
|
14488
|
+
let decodeChannel = (nx, ny, scale) => {
|
|
14489
|
+
let ac = [];
|
|
14490
|
+
for (let cy = 0; cy < ny; cy++)
|
|
14491
|
+
for (let cx = cy ? 0 : 1; cx * ny < nx * (ny - cy); cx++)
|
|
14492
|
+
ac.push(((hash[ac_start + (ac_index >> 1)] >> ((ac_index++ & 1) << 2) & 15) / 7.5 - 1) * scale);
|
|
14493
|
+
return ac;
|
|
14494
|
+
};
|
|
14495
|
+
let l_ac = decodeChannel(lx, ly, l_scale);
|
|
14496
|
+
let p_ac = decodeChannel(3, 3, p_scale * 1.25);
|
|
14497
|
+
let q_ac = decodeChannel(3, 3, q_scale * 1.25);
|
|
14498
|
+
let a_ac = hasAlpha && decodeChannel(5, 5, a_scale);
|
|
14499
|
+
let ratio = thumbHashToApproximateAspectRatio(hash);
|
|
14500
|
+
let w = round(ratio > 1 ? 32 : 32 * ratio);
|
|
14501
|
+
let h = round(ratio > 1 ? 32 / ratio : 32);
|
|
14502
|
+
let rgba = new Uint8Array(w * h * 4), fx = [], fy = [];
|
|
14503
|
+
for (let y = 0, i = 0; y < h; y++) {
|
|
14504
|
+
for (let x = 0; x < w; x++, i += 4) {
|
|
14505
|
+
let l2 = l_dc, p = p_dc, q = q_dc, a2 = a_dc;
|
|
14506
|
+
for (let cx = 0, n = max(lx, hasAlpha ? 5 : 3); cx < n; cx++)
|
|
14507
|
+
fx[cx] = cos(PI / w * (x + 0.5) * cx);
|
|
14508
|
+
for (let cy = 0, n = max(ly, hasAlpha ? 5 : 3); cy < n; cy++)
|
|
14509
|
+
fy[cy] = cos(PI / h * (y + 0.5) * cy);
|
|
14510
|
+
for (let cy = 0, j = 0; cy < ly; cy++)
|
|
14511
|
+
for (let cx = cy ? 0 : 1, fy2 = fy[cy] * 2; cx * ly < lx * (ly - cy); cx++, j++)
|
|
14512
|
+
l2 += l_ac[j] * fx[cx] * fy2;
|
|
14513
|
+
for (let cy = 0, j = 0; cy < 3; cy++) {
|
|
14514
|
+
for (let cx = cy ? 0 : 1, fy2 = fy[cy] * 2; cx < 3 - cy; cx++, j++) {
|
|
14515
|
+
let f = fx[cx] * fy2;
|
|
14516
|
+
p += p_ac[j] * f;
|
|
14517
|
+
q += q_ac[j] * f;
|
|
14518
|
+
}
|
|
14519
|
+
}
|
|
14520
|
+
if (hasAlpha)
|
|
14521
|
+
for (let cy = 0, j = 0; cy < 5; cy++)
|
|
14522
|
+
for (let cx = cy ? 0 : 1, fy2 = fy[cy] * 2; cx < 5 - cy; cx++, j++)
|
|
14523
|
+
a2 += a_ac[j] * fx[cx] * fy2;
|
|
14524
|
+
let b2 = l2 - 2 / 3 * p;
|
|
14525
|
+
let r = (3 * l2 - b2 + q) / 2;
|
|
14526
|
+
let g = r - q;
|
|
14527
|
+
rgba[i] = max(0, 255 * min(1, r));
|
|
14528
|
+
rgba[i + 1] = max(0, 255 * min(1, g));
|
|
14529
|
+
rgba[i + 2] = max(0, 255 * min(1, b2));
|
|
14530
|
+
rgba[i + 3] = max(0, 255 * min(1, a2));
|
|
14531
|
+
}
|
|
14532
|
+
}
|
|
14533
|
+
return { w, h, rgba };
|
|
14534
|
+
}
|
|
14535
|
+
function thumbHashToApproximateAspectRatio(hash) {
|
|
14536
|
+
let header = hash[3];
|
|
14537
|
+
let hasAlpha = hash[2] & 128;
|
|
14538
|
+
let isLandscape = hash[4] & 128;
|
|
14539
|
+
let lx = isLandscape ? hasAlpha ? 5 : 7 : header & 7;
|
|
14540
|
+
let ly = isLandscape ? header & 7 : hasAlpha ? 5 : 7;
|
|
14541
|
+
return lx / ly;
|
|
14542
|
+
}
|
|
14543
|
+
|
|
14544
|
+
// src/image.ts
|
|
14545
|
+
var THUMB_HASH_MAX_DIMENSION = 100;
|
|
14546
|
+
var thumbHashCanvasCache = /* @__PURE__ */ new Map();
|
|
14547
|
+
var invalidThumbHashes = /* @__PURE__ */ new Set();
|
|
14548
|
+
var bytesToBase64 = (bytes) => {
|
|
14549
|
+
let binary = "";
|
|
14550
|
+
for (const byte of bytes) {
|
|
14551
|
+
binary += String.fromCharCode(byte);
|
|
14552
|
+
}
|
|
14553
|
+
return btoa(binary);
|
|
14554
|
+
};
|
|
14555
|
+
var base64ToBytes = (base64) => {
|
|
14556
|
+
const binary = atob(base64);
|
|
14557
|
+
const bytes = new Uint8Array(binary.length);
|
|
14558
|
+
for (let index = 0; index < binary.length; index++) {
|
|
14559
|
+
bytes[index] = binary.charCodeAt(index);
|
|
14560
|
+
}
|
|
14561
|
+
return bytes;
|
|
14562
|
+
};
|
|
14563
|
+
var generateThumbHash = (image) => {
|
|
14564
|
+
const naturalWidth = image.naturalWidth || image.width;
|
|
14565
|
+
const naturalHeight = image.naturalHeight || image.height;
|
|
14566
|
+
if (!naturalWidth || !naturalHeight) {
|
|
14567
|
+
return null;
|
|
14568
|
+
}
|
|
14569
|
+
const scale = Math.min(
|
|
14570
|
+
1,
|
|
14571
|
+
THUMB_HASH_MAX_DIMENSION / Math.max(naturalWidth, naturalHeight)
|
|
14572
|
+
);
|
|
14573
|
+
const width = Math.max(1, Math.round(naturalWidth * scale));
|
|
14574
|
+
const height = Math.max(1, Math.round(naturalHeight * scale));
|
|
14575
|
+
const canvas = document.createElement("canvas");
|
|
14576
|
+
canvas.width = width;
|
|
14577
|
+
canvas.height = height;
|
|
14578
|
+
const context = canvas.getContext("2d");
|
|
14579
|
+
if (!context) {
|
|
14580
|
+
return null;
|
|
14581
|
+
}
|
|
14582
|
+
context.drawImage(image, 0, 0, width, height);
|
|
14583
|
+
const imageData = context.getImageData(0, 0, width, height);
|
|
14584
|
+
return bytesToBase64(rgbaToThumbHash(width, height, imageData.data));
|
|
14585
|
+
};
|
|
14586
|
+
var getThumbHashPlaceholder = (thumbHash) => {
|
|
14587
|
+
if (invalidThumbHashes.has(thumbHash)) {
|
|
14588
|
+
return null;
|
|
14589
|
+
}
|
|
14590
|
+
const cached = thumbHashCanvasCache.get(thumbHash);
|
|
14591
|
+
if (cached) {
|
|
14592
|
+
return cached;
|
|
14593
|
+
}
|
|
14594
|
+
try {
|
|
14595
|
+
const { w, h, rgba } = thumbHashToRGBA(base64ToBytes(thumbHash));
|
|
14596
|
+
const canvas = document.createElement("canvas");
|
|
14597
|
+
canvas.width = w;
|
|
14598
|
+
canvas.height = h;
|
|
14599
|
+
const context = canvas.getContext("2d");
|
|
14600
|
+
if (!context) {
|
|
14601
|
+
return null;
|
|
14602
|
+
}
|
|
14603
|
+
const imageData = context.createImageData(w, h);
|
|
14604
|
+
imageData.data.set(rgba);
|
|
14605
|
+
context.putImageData(imageData, 0, 0);
|
|
14606
|
+
thumbHashCanvasCache.set(thumbHash, canvas);
|
|
14607
|
+
return canvas;
|
|
14608
|
+
} catch (error) {
|
|
14609
|
+
invalidThumbHashes.add(thumbHash);
|
|
14610
|
+
console.warn("Invalid ThumbHash", error);
|
|
14611
|
+
return null;
|
|
14612
|
+
}
|
|
14613
|
+
};
|
|
14614
|
+
var loadHTMLImageElement = (dataURL) => {
|
|
14615
|
+
return new Promise((resolve, reject) => {
|
|
14616
|
+
const image = new Image();
|
|
14617
|
+
image.onload = () => {
|
|
14618
|
+
resolve(image);
|
|
14619
|
+
};
|
|
14620
|
+
image.onerror = (error) => {
|
|
14621
|
+
reject(error);
|
|
14622
|
+
};
|
|
14623
|
+
image.src = dataURL;
|
|
14624
|
+
});
|
|
14625
|
+
};
|
|
14626
|
+
var updateImageCache = async ({
|
|
14627
|
+
fileIds,
|
|
14628
|
+
files,
|
|
14629
|
+
imageCache
|
|
14630
|
+
}) => {
|
|
14631
|
+
const updatedFiles = /* @__PURE__ */ new Map();
|
|
14632
|
+
const erroredFiles = /* @__PURE__ */ new Map();
|
|
14633
|
+
await Promise.all(
|
|
14634
|
+
fileIds.reduce((promises, fileId) => {
|
|
14635
|
+
const fileData = files[fileId];
|
|
14636
|
+
if (fileData && !updatedFiles.has(fileId)) {
|
|
14637
|
+
updatedFiles.set(fileId, true);
|
|
14638
|
+
return promises.concat(
|
|
14639
|
+
(async () => {
|
|
14640
|
+
try {
|
|
14641
|
+
if (fileData.mimeType === MIME_TYPES.binary) {
|
|
14642
|
+
throw new Error("Only images can be added to ImageCache");
|
|
14643
|
+
}
|
|
14644
|
+
const imagePromise = loadHTMLImageElement(fileData.dataURL);
|
|
14645
|
+
const data = {
|
|
14646
|
+
image: imagePromise,
|
|
14647
|
+
mimeType: fileData.mimeType
|
|
14648
|
+
};
|
|
14649
|
+
imageCache.set(fileId, data);
|
|
14650
|
+
const image = await imagePromise;
|
|
14651
|
+
imageCache.set(fileId, { ...data, image });
|
|
14652
|
+
} catch (error) {
|
|
14653
|
+
erroredFiles.set(fileId, true);
|
|
14654
|
+
}
|
|
14655
|
+
})()
|
|
14656
|
+
);
|
|
14657
|
+
}
|
|
14658
|
+
return promises;
|
|
14659
|
+
}, [])
|
|
14660
|
+
);
|
|
14661
|
+
return {
|
|
14662
|
+
imageCache,
|
|
14663
|
+
/** includes errored files because they cache was updated nonetheless */
|
|
14664
|
+
updatedFiles,
|
|
14665
|
+
/** files that failed when creating HTMLImageElement */
|
|
14666
|
+
erroredFiles
|
|
14667
|
+
};
|
|
14668
|
+
};
|
|
14669
|
+
var getInitializedImageElements = (elements) => elements.filter(
|
|
14670
|
+
(element) => isInitializedImageElement(element)
|
|
14671
|
+
);
|
|
14672
|
+
var isHTMLSVGElement = (node) => {
|
|
14673
|
+
return node?.nodeName.toLowerCase() === "svg";
|
|
14674
|
+
};
|
|
14675
|
+
var normalizeSVG = (SVGString) => {
|
|
14676
|
+
const doc = new DOMParser().parseFromString(SVGString, MIME_TYPES.svg);
|
|
14677
|
+
const svg = doc.querySelector("svg");
|
|
14678
|
+
const errorNode = doc.querySelector("parsererror");
|
|
14679
|
+
if (errorNode || !isHTMLSVGElement(svg)) {
|
|
14680
|
+
throw new Error("Invalid SVG");
|
|
14681
|
+
} else {
|
|
14682
|
+
if (!svg.hasAttribute("xmlns")) {
|
|
14683
|
+
svg.setAttribute("xmlns", SVG_NS);
|
|
14684
|
+
}
|
|
14685
|
+
let width = svg.getAttribute("width");
|
|
14686
|
+
let height = svg.getAttribute("height");
|
|
14687
|
+
if (width?.includes("%") || width === "auto") {
|
|
14688
|
+
width = null;
|
|
14689
|
+
}
|
|
14690
|
+
if (height?.includes("%") || height === "auto") {
|
|
14691
|
+
height = null;
|
|
14692
|
+
}
|
|
14693
|
+
const viewBox = svg.getAttribute("viewBox");
|
|
14694
|
+
if (!width || !height) {
|
|
14695
|
+
width = width || "50";
|
|
14696
|
+
height = height || "50";
|
|
14697
|
+
if (viewBox) {
|
|
14698
|
+
const match = viewBox.match(
|
|
14699
|
+
/\d+ +\d+ +(\d+(?:\.\d+)?) +(\d+(?:\.\d+)?)/
|
|
14700
|
+
);
|
|
14701
|
+
if (match) {
|
|
14702
|
+
[, width, height] = match;
|
|
14703
|
+
}
|
|
14704
|
+
}
|
|
14705
|
+
svg.setAttribute("width", width);
|
|
14706
|
+
svg.setAttribute("height", height);
|
|
14707
|
+
}
|
|
14708
|
+
if (!viewBox) {
|
|
14709
|
+
svg.setAttribute("viewBox", `0 0 ${width} ${height}`);
|
|
14710
|
+
}
|
|
14711
|
+
return svg.outerHTML;
|
|
14712
|
+
}
|
|
14713
|
+
};
|
|
14714
|
+
|
|
13986
14715
|
// src/renderElement.ts
|
|
13987
14716
|
var isPendingImageElement = (element, renderConfig) => isInitializedImageElement(element) && !renderConfig.imageCache.has(element.fileId);
|
|
13988
14717
|
var getCanvasPadding = (element) => {
|
|
@@ -14112,14 +14841,27 @@ var generateElementCanvas = (element, elementsMap, zoom, renderConfig, appState)
|
|
|
14112
14841
|
};
|
|
14113
14842
|
var DEFAULT_LINK_SIZE = 14;
|
|
14114
14843
|
var IMAGE_PLACEHOLDER_IMG = typeof document !== "undefined" ? document.createElement("img") : { src: "" };
|
|
14115
|
-
IMAGE_PLACEHOLDER_IMG.src = `data:${
|
|
14844
|
+
IMAGE_PLACEHOLDER_IMG.src = `data:${MIME_TYPES2.svg},${encodeURIComponent(
|
|
14116
14845
|
`<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="image" class="svg-inline--fa fa-image fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="#888" d="M464 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM112 120c-30.928 0-56 25.072-56 56s25.072 56 56 56 56-25.072 56-56-25.072-56-56-56zM64 384h384V272l-87.515-87.515c-4.686-4.686-12.284-4.686-16.971 0L208 320l-55.515-55.515c-4.686-4.686-12.284-4.686-16.971 0L64 336v48z"></path></svg>`
|
|
14117
14846
|
)}`;
|
|
14118
14847
|
var IMAGE_ERROR_PLACEHOLDER_IMG = typeof document !== "undefined" ? document.createElement("img") : { src: "" };
|
|
14119
|
-
IMAGE_ERROR_PLACEHOLDER_IMG.src = `data:${
|
|
14848
|
+
IMAGE_ERROR_PLACEHOLDER_IMG.src = `data:${MIME_TYPES2.svg},${encodeURIComponent(
|
|
14120
14849
|
`<svg viewBox="0 0 668 668" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2"><path d="M464 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48ZM112 120c-30.928 0-56 25.072-56 56s25.072 56 56 56 56-25.072 56-56-25.072-56-56-56ZM64 384h384V272l-87.515-87.515c-4.686-4.686-12.284-4.686-16.971 0L208 320l-55.515-55.515c-4.686-4.686-12.284-4.686-16.971 0L64 336v48Z" style="fill:#888;fill-rule:nonzero" transform="matrix(.81709 0 0 .81709 124.825 145.825)"/><path d="M256 8C119.034 8 8 119.033 8 256c0 136.967 111.034 248 248 248s248-111.034 248-248S392.967 8 256 8Zm130.108 117.892c65.448 65.448 70 165.481 20.677 235.637L150.47 105.216c70.204-49.356 170.226-44.735 235.638 20.676ZM125.892 386.108c-65.448-65.448-70-165.481-20.677-235.637L361.53 406.784c-70.203 49.356-170.226 44.736-235.638-20.676Z" style="fill:#888;fill-rule:nonzero" transform="matrix(.30366 0 0 .30366 506.822 60.065)"/></svg>`
|
|
14121
14850
|
)}`;
|
|
14122
14851
|
var drawImagePlaceholder = (element, context, theme) => {
|
|
14852
|
+
if (element.status !== "error" && element.thumbHash) {
|
|
14853
|
+
const thumbHashPlaceholder = getThumbHashPlaceholder(element.thumbHash);
|
|
14854
|
+
if (thumbHashPlaceholder) {
|
|
14855
|
+
context.drawImage(
|
|
14856
|
+
thumbHashPlaceholder,
|
|
14857
|
+
0,
|
|
14858
|
+
0,
|
|
14859
|
+
element.width,
|
|
14860
|
+
element.height
|
|
14861
|
+
);
|
|
14862
|
+
return;
|
|
14863
|
+
}
|
|
14864
|
+
}
|
|
14123
14865
|
context.fillStyle = theme === THEME.DARK ? "#2E2E2E" : "#E7E7E7";
|
|
14124
14866
|
context.fillRect(0, 0, element.width, element.height);
|
|
14125
14867
|
const imageMinWidthOrHeight = Math.min(element.width, element.height);
|
|
@@ -14191,13 +14933,42 @@ var drawElementOnCanvas = (element, rc, context, renderConfig) => {
|
|
|
14191
14933
|
);
|
|
14192
14934
|
context.clip();
|
|
14193
14935
|
}
|
|
14936
|
+
const transitionDuration = renderConfig.imageTransitionDuration ?? 0;
|
|
14937
|
+
if (!renderConfig.isExporting && cacheEntry?.transitionStart !== void 0) {
|
|
14938
|
+
if (transitionDuration > 0) {
|
|
14939
|
+
const transitionProgress = Math.min(
|
|
14940
|
+
1,
|
|
14941
|
+
(performance.now() - cacheEntry.transitionStart) / transitionDuration
|
|
14942
|
+
);
|
|
14943
|
+
if (transitionProgress < 1) {
|
|
14944
|
+
if (cacheEntry.placeholderImage) {
|
|
14945
|
+
context.drawImage(
|
|
14946
|
+
cacheEntry.placeholderImage,
|
|
14947
|
+
0,
|
|
14948
|
+
0,
|
|
14949
|
+
element.width,
|
|
14950
|
+
element.height
|
|
14951
|
+
);
|
|
14952
|
+
} else {
|
|
14953
|
+
drawImagePlaceholder(element, context, renderConfig.theme);
|
|
14954
|
+
}
|
|
14955
|
+
context.globalAlpha *= transitionProgress;
|
|
14956
|
+
} else {
|
|
14957
|
+
delete cacheEntry.placeholderImage;
|
|
14958
|
+
delete cacheEntry.transitionStart;
|
|
14959
|
+
}
|
|
14960
|
+
} else {
|
|
14961
|
+
delete cacheEntry.placeholderImage;
|
|
14962
|
+
delete cacheEntry.transitionStart;
|
|
14963
|
+
}
|
|
14964
|
+
}
|
|
14194
14965
|
const { x, y, width, height } = element.crop ? element.crop : {
|
|
14195
14966
|
x: 0,
|
|
14196
14967
|
y: 0,
|
|
14197
14968
|
width: img.naturalWidth,
|
|
14198
14969
|
height: img.naturalHeight
|
|
14199
14970
|
};
|
|
14200
|
-
const shouldInvertImage = renderConfig.theme === THEME.DARK && cacheEntry?.mimeType ===
|
|
14971
|
+
const shouldInvertImage = renderConfig.theme === THEME.DARK && cacheEntry?.mimeType === MIME_TYPES2.svg;
|
|
14201
14972
|
if (shouldInvertImage && isSafari) {
|
|
14202
14973
|
const devicePixelRatio = window.devicePixelRatio || 1;
|
|
14203
14974
|
const tempCanvas = document.createElement("canvas");
|
|
@@ -14317,8 +15088,9 @@ var generateElementWithCanvas = (element, elementsMap, renderConfig, appState) =
|
|
|
14317
15088
|
const boundTextElement = getBoundTextElement(element, elementsMap);
|
|
14318
15089
|
const boundTextElementVersion = boundTextElement?.version || null;
|
|
14319
15090
|
const imageCrop = isImageElement(element) ? element.crop : null;
|
|
15091
|
+
const hasActiveImageTransition = isInitializedImageElement(element) && renderConfig.imageCache.get(element.fileId)?.transitionStart !== void 0;
|
|
14320
15092
|
const containingFrameOpacity = getContainingFrame(element, elementsMap)?.opacity || 100;
|
|
14321
|
-
if (!prevElementWithCanvas || shouldRegenerateBecauseZoom || prevElementWithCanvas.theme !== appState.theme || prevElementWithCanvas.boundTextElementVersion !== boundTextElementVersion || prevElementWithCanvas.imageCrop !== imageCrop || prevElementWithCanvas.containingFrameOpacity !== containingFrameOpacity || // since we rotate the canvas when copying from cached canvas, we don't
|
|
15093
|
+
if (!prevElementWithCanvas || shouldRegenerateBecauseZoom || prevElementWithCanvas.theme !== appState.theme || prevElementWithCanvas.boundTextElementVersion !== boundTextElementVersion || prevElementWithCanvas.imageCrop !== imageCrop || hasActiveImageTransition || prevElementWithCanvas.containingFrameOpacity !== containingFrameOpacity || // since we rotate the canvas when copying from cached canvas, we don't
|
|
14322
15094
|
// regenerate the cached canvas. But we need to in case of labels which are
|
|
14323
15095
|
// cached alongside the arrow, and we want the labels to remain unrotated
|
|
14324
15096
|
// with respect to the arrow.
|
|
@@ -14494,8 +15266,10 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
|
|
|
14494
15266
|
case "embeddable": {
|
|
14495
15267
|
if (renderConfig.isExporting) {
|
|
14496
15268
|
const [x1, y1, x2, y2] = getElementAbsoluteCoords2(element, elementsMap);
|
|
14497
|
-
const
|
|
14498
|
-
const
|
|
15269
|
+
const centerX = (x1 + x2) / 2;
|
|
15270
|
+
const centerY = (y1 + y2) / 2;
|
|
15271
|
+
const cx = centerX + appState.scrollX;
|
|
15272
|
+
const cy = centerY + appState.scrollY;
|
|
14499
15273
|
let shiftX = (x2 - x1) / 2 - (element.x - x1);
|
|
14500
15274
|
let shiftY = (y2 - y1) / 2 - (element.y - y1);
|
|
14501
15275
|
if (isTextElement(element)) {
|
|
@@ -14514,46 +15288,33 @@ var renderElement = (element, elementsMap, allElementsMap, rc, context, renderCo
|
|
|
14514
15288
|
context.translate(cx, cy);
|
|
14515
15289
|
const boundTextElement = getBoundTextElement(element, elementsMap);
|
|
14516
15290
|
if (isArrowElement(element) && boundTextElement) {
|
|
14517
|
-
const tempCanvas = document.createElement("canvas");
|
|
14518
|
-
const tempCanvasContext = tempCanvas.getContext("2d");
|
|
14519
|
-
const maxDim = Math.max(distance2(x1, x2), distance2(y1, y2));
|
|
14520
|
-
const padding = getCanvasPadding(element);
|
|
14521
|
-
tempCanvas.width = maxDim * appState.exportScale + padding * 10 * appState.exportScale;
|
|
14522
|
-
tempCanvas.height = maxDim * appState.exportScale + padding * 10 * appState.exportScale;
|
|
14523
|
-
tempCanvasContext.translate(
|
|
14524
|
-
tempCanvas.width / 2,
|
|
14525
|
-
tempCanvas.height / 2
|
|
14526
|
-
);
|
|
14527
|
-
tempCanvasContext.scale(appState.exportScale, appState.exportScale);
|
|
14528
15291
|
shiftX = element.width / 2 - (element.x - x1);
|
|
14529
15292
|
shiftY = element.height / 2 - (element.y - y1);
|
|
14530
|
-
|
|
14531
|
-
|
|
14532
|
-
|
|
14533
|
-
drawElementOnCanvas(element,
|
|
14534
|
-
|
|
14535
|
-
tempCanvasContext.rotate(-element.angle);
|
|
15293
|
+
context.save();
|
|
15294
|
+
context.rotate(element.angle);
|
|
15295
|
+
context.translate(-shiftX, -shiftY);
|
|
15296
|
+
drawElementOnCanvas(element, rc, context, renderConfig);
|
|
15297
|
+
context.restore();
|
|
14536
15298
|
const [, , , , boundTextCx, boundTextCy] = getElementAbsoluteCoords2(
|
|
14537
15299
|
boundTextElement,
|
|
14538
15300
|
elementsMap
|
|
14539
15301
|
);
|
|
14540
|
-
const
|
|
14541
|
-
const
|
|
14542
|
-
|
|
14543
|
-
|
|
14544
|
-
|
|
14545
|
-
|
|
14546
|
-
|
|
14547
|
-
|
|
14548
|
-
|
|
14549
|
-
|
|
14550
|
-
|
|
14551
|
-
|
|
14552
|
-
|
|
14553
|
-
|
|
14554
|
-
|
|
14555
|
-
|
|
14556
|
-
);
|
|
15302
|
+
const holeX = boundTextCx - centerX - boundTextElement.width / 2 - BOUND_TEXT_PADDING3;
|
|
15303
|
+
const holeY = boundTextCy - centerY - boundTextElement.height / 2 - BOUND_TEXT_PADDING3;
|
|
15304
|
+
const holeWidth = boundTextElement.width + BOUND_TEXT_PADDING3 * 2;
|
|
15305
|
+
const holeHeight = boundTextElement.height + BOUND_TEXT_PADDING3 * 2;
|
|
15306
|
+
const isTransparentHole = "viewBackgroundColor" in appState && (appState.viewBackgroundColor === "transparent" || !appState.viewBackgroundColor);
|
|
15307
|
+
if (!isTransparentHole) {
|
|
15308
|
+
context.save();
|
|
15309
|
+
context.fillStyle = applyDarkModeFilter(
|
|
15310
|
+
renderConfig.canvasBackgroundColor,
|
|
15311
|
+
renderConfig.theme === THEME.DARK
|
|
15312
|
+
);
|
|
15313
|
+
context.fillRect(holeX, holeY, holeWidth, holeHeight);
|
|
15314
|
+
context.restore();
|
|
15315
|
+
} else {
|
|
15316
|
+
context.clearRect(holeX, holeY, holeWidth, holeHeight);
|
|
15317
|
+
}
|
|
14557
15318
|
} else {
|
|
14558
15319
|
context.rotate(element.angle);
|
|
14559
15320
|
if (element.type === "image") {
|
|
@@ -15474,19 +16235,46 @@ var getFreeDrawSvgPath = (element) => {
|
|
|
15474
16235
|
getFreedrawOutlinePoints(element)
|
|
15475
16236
|
);
|
|
15476
16237
|
};
|
|
15477
|
-
var
|
|
15478
|
-
|
|
16238
|
+
var VARIABLE_WIDTH_FREEDRAW = {
|
|
16239
|
+
/** Stroke size relative to `strokeWidth` for pressure-sensitive strokes. */
|
|
16240
|
+
SIZE_FACTOR: 4.25,
|
|
16241
|
+
THINNING: 0.6,
|
|
16242
|
+
SMOOTHING: 0.5
|
|
16243
|
+
};
|
|
16244
|
+
var CONSTANT_WIDTH_FREEDRAW = {
|
|
16245
|
+
/** Stroke size relative to `strokeWidth` for uniform (laser) strokes. */
|
|
16246
|
+
SIZE_FACTOR: 1.4
|
|
16247
|
+
};
|
|
16248
|
+
var getFreedrawStreamline = (element) => element.strokeOptions?.streamline ?? DEFAULT_STROKE_STREAMLINE;
|
|
16249
|
+
var getVariableWidthFreedrawOutline = (element) => {
|
|
16250
|
+
const inputPoints = element.simulatePressure ? element.points : element.points.length ? element.points.map(
|
|
16251
|
+
([x, y], i) => [x, y, element.pressures[i]]
|
|
16252
|
+
) : [[0, 0, 0.5]];
|
|
15479
16253
|
return ae(inputPoints, {
|
|
15480
16254
|
simulatePressure: element.simulatePressure,
|
|
15481
|
-
size: element.strokeWidth *
|
|
15482
|
-
thinning:
|
|
15483
|
-
smoothing:
|
|
15484
|
-
streamline:
|
|
16255
|
+
size: element.strokeWidth * VARIABLE_WIDTH_FREEDRAW.SIZE_FACTOR,
|
|
16256
|
+
thinning: VARIABLE_WIDTH_FREEDRAW.THINNING,
|
|
16257
|
+
smoothing: VARIABLE_WIDTH_FREEDRAW.SMOOTHING,
|
|
16258
|
+
streamline: getFreedrawStreamline(element),
|
|
15485
16259
|
easing: (t) => Math.sin(t * Math.PI / 2),
|
|
15486
16260
|
// https://easings.net/#easeOutSine
|
|
15487
16261
|
last: true
|
|
15488
16262
|
});
|
|
15489
16263
|
};
|
|
16264
|
+
var createLaserPointer = (element) => new LaserPointer({
|
|
16265
|
+
size: element.strokeWidth * CONSTANT_WIDTH_FREEDRAW.SIZE_FACTOR,
|
|
16266
|
+
streamline: getFreedrawStreamline(element),
|
|
16267
|
+
simplify: 0,
|
|
16268
|
+
sizeMapping: (details) => Math.max(0.1, details.pressure)
|
|
16269
|
+
});
|
|
16270
|
+
var getConstantWidthFreedrawOutline = (element) => {
|
|
16271
|
+
const laserPointer = createLaserPointer(element);
|
|
16272
|
+
element.points.map(([x, y]) => laserPointer.addPoint([x, y, 1]));
|
|
16273
|
+
return laserPointer.getStrokeOutline().map(([x, y]) => [x, y]);
|
|
16274
|
+
};
|
|
16275
|
+
var getFreedrawOutlinePoints = (element) => {
|
|
16276
|
+
return element.strokeOptions?.variability === "constant" ? getConstantWidthFreedrawOutline(element) : getVariableWidthFreedrawOutline(element);
|
|
16277
|
+
};
|
|
15490
16278
|
var med = (A2, B2) => {
|
|
15491
16279
|
return [(A2[0] + B2[0]) / 2, (A2[1] + B2[1]) / 2];
|
|
15492
16280
|
};
|
|
@@ -15763,15 +16551,15 @@ var getElementLineSegments = (element, elementsMap) => {
|
|
|
15763
16551
|
var _isRectanguloidElement = (element) => {
|
|
15764
16552
|
return element != null && (element.type === "rectangle" || element.type === "image" || element.type === "iframe" || element.type === "embeddable" || element.type === "frame" || element.type === "magicframe" || element.type === "text" && !element.containerId);
|
|
15765
16553
|
};
|
|
15766
|
-
var getRotatedSides = (sides, center,
|
|
16554
|
+
var getRotatedSides = (sides, center, angle2) => {
|
|
15767
16555
|
return sides.map((side) => {
|
|
15768
16556
|
return lineSegment6(
|
|
15769
|
-
pointRotateRads12(side[0], center,
|
|
15770
|
-
pointRotateRads12(side[1], center,
|
|
16557
|
+
pointRotateRads12(side[0], center, angle2),
|
|
16558
|
+
pointRotateRads12(side[1], center, angle2)
|
|
15771
16559
|
);
|
|
15772
16560
|
});
|
|
15773
16561
|
};
|
|
15774
|
-
var getSegmentsOnCurve = (curve4, center,
|
|
16562
|
+
var getSegmentsOnCurve = (curve4, center, angle2) => {
|
|
15775
16563
|
const points = pointsOnBezierCurves(curve4, 10);
|
|
15776
16564
|
let i = 0;
|
|
15777
16565
|
const segments = [];
|
|
@@ -15781,12 +16569,12 @@ var getSegmentsOnCurve = (curve4, center, angle) => {
|
|
|
15781
16569
|
pointRotateRads12(
|
|
15782
16570
|
pointFrom13(points[i][0], points[i][1]),
|
|
15783
16571
|
center,
|
|
15784
|
-
|
|
16572
|
+
angle2
|
|
15785
16573
|
),
|
|
15786
16574
|
pointRotateRads12(
|
|
15787
16575
|
pointFrom13(points[i + 1][0], points[i + 1][1]),
|
|
15788
16576
|
center,
|
|
15789
|
-
|
|
16577
|
+
angle2
|
|
15790
16578
|
)
|
|
15791
16579
|
)
|
|
15792
16580
|
);
|
|
@@ -16028,29 +16816,29 @@ var getArrowheadPoints = (element, shape, position, arrowhead, offsetMultiplier
|
|
|
16028
16816
|
const diameter = Math.hypot(ys - ty, xs - tx) + element.strokeWidth - 2;
|
|
16029
16817
|
return [tx, ty, diameter];
|
|
16030
16818
|
}
|
|
16031
|
-
const
|
|
16819
|
+
const angle2 = getArrowheadAngle(arrowhead);
|
|
16032
16820
|
if (arrowhead === "cardinality_many" || arrowhead === "cardinality_one_or_many") {
|
|
16033
16821
|
const [x32, y32] = pointRotateRads12(
|
|
16034
16822
|
pointFrom13(tx, ty),
|
|
16035
16823
|
pointFrom13(xs, ys),
|
|
16036
|
-
degreesToRadians(-
|
|
16824
|
+
degreesToRadians(-angle2)
|
|
16037
16825
|
);
|
|
16038
16826
|
const [x42, y42] = pointRotateRads12(
|
|
16039
16827
|
pointFrom13(tx, ty),
|
|
16040
16828
|
pointFrom13(xs, ys),
|
|
16041
|
-
degreesToRadians(
|
|
16829
|
+
degreesToRadians(angle2)
|
|
16042
16830
|
);
|
|
16043
16831
|
return [xs, ys, x32, y32, x42, y42];
|
|
16044
16832
|
}
|
|
16045
16833
|
const [x3, y3] = pointRotateRads12(
|
|
16046
16834
|
pointFrom13(xs, ys),
|
|
16047
16835
|
pointFrom13(tx, ty),
|
|
16048
|
-
-
|
|
16836
|
+
-angle2 * Math.PI / 180
|
|
16049
16837
|
);
|
|
16050
16838
|
const [x4, y4] = pointRotateRads12(
|
|
16051
16839
|
pointFrom13(xs, ys),
|
|
16052
16840
|
pointFrom13(tx, ty),
|
|
16053
|
-
degreesToRadians(
|
|
16841
|
+
degreesToRadians(angle2)
|
|
16054
16842
|
);
|
|
16055
16843
|
if (arrowhead === "diamond" || arrowhead === "diamond_outline") {
|
|
16056
16844
|
let ox;
|
|
@@ -16620,18 +17408,18 @@ var getPerfectElementSize = (elementType, width, height) => {
|
|
|
16620
17408
|
var getLockedLinearCursorAlignSize = (originX, originY, x, y, customAngle) => {
|
|
16621
17409
|
let width = x - originX;
|
|
16622
17410
|
let height = y - originY;
|
|
16623
|
-
const
|
|
16624
|
-
let lockedAngle = Math.round(
|
|
17411
|
+
const angle2 = Math.atan2(height, width);
|
|
17412
|
+
let lockedAngle = Math.round(angle2 / SHIFT_LOCKING_ANGLE) * SHIFT_LOCKING_ANGLE;
|
|
16625
17413
|
if (customAngle) {
|
|
16626
17414
|
const lower = Math.floor(customAngle / SHIFT_LOCKING_ANGLE) * SHIFT_LOCKING_ANGLE;
|
|
16627
17415
|
if (radiansBetweenAngles(
|
|
16628
|
-
|
|
17416
|
+
angle2,
|
|
16629
17417
|
lower,
|
|
16630
17418
|
lower + SHIFT_LOCKING_ANGLE
|
|
16631
17419
|
)) {
|
|
16632
|
-
if (radiansDifference(
|
|
17420
|
+
if (radiansDifference(angle2, customAngle) < SHIFT_LOCKING_ANGLE / 6) {
|
|
16633
17421
|
lockedAngle = customAngle;
|
|
16634
|
-
} else if (normalizeRadians(
|
|
17422
|
+
} else if (normalizeRadians(angle2) > normalizeRadians(customAngle)) {
|
|
16635
17423
|
lockedAngle = lower + SHIFT_LOCKING_ANGLE;
|
|
16636
17424
|
} else {
|
|
16637
17425
|
lockedAngle = lower;
|
|
@@ -16846,7 +17634,7 @@ var compareScores = (a2, b2) => {
|
|
|
16846
17634
|
return 0;
|
|
16847
17635
|
};
|
|
16848
17636
|
var compareBlocks = (a2, b2) => b2.packedW * b2.packedH - a2.packedW * a2.packedH || Math.max(b2.packedW, b2.packedH) - Math.max(a2.packedW, a2.packedH) || b2.packedH - a2.packedH || b2.packedW - a2.packedW;
|
|
16849
|
-
var
|
|
17637
|
+
var clamp5 = (value, min, max) => Math.min(Math.max(value, min), max);
|
|
16850
17638
|
var intersects = (a2, b2) => a2.x < b2.x + b2.w && a2.x + a2.w > b2.x && a2.y < b2.y + b2.h && a2.y + a2.h > b2.y;
|
|
16851
17639
|
var contains = (outer, inner) => inner.x >= outer.x && inner.y >= outer.y && inner.x + inner.w <= outer.x + outer.w && inner.y + inner.h <= outer.y + outer.h;
|
|
16852
17640
|
var getLayoutBounds = (blocks) => {
|
|
@@ -16958,8 +17746,8 @@ var getCandidatePositions = (freeRect, block, heuristic, targetCenter) => {
|
|
|
16958
17746
|
];
|
|
16959
17747
|
if (heuristic === "center-distance") {
|
|
16960
17748
|
positions.push({
|
|
16961
|
-
x:
|
|
16962
|
-
y:
|
|
17749
|
+
x: clamp5(targetCenter.x - block.actualW / 2, freeRect.x, maxX),
|
|
17750
|
+
y: clamp5(targetCenter.y - block.actualH / 2, freeRect.y, maxY)
|
|
16963
17751
|
});
|
|
16964
17752
|
}
|
|
16965
17753
|
return positions.filter(
|
|
@@ -20210,6 +20998,7 @@ import {
|
|
|
20210
20998
|
DEFAULT_FONT_SIZE as DEFAULT_FONT_SIZE3,
|
|
20211
20999
|
DEFAULT_TEXT_ALIGN,
|
|
20212
21000
|
DEFAULT_VERTICAL_ALIGN,
|
|
21001
|
+
DEFAULT_STROKE_STREAMLINE as DEFAULT_STROKE_STREAMLINE2,
|
|
20213
21002
|
VERTICAL_ALIGN as VERTICAL_ALIGN2,
|
|
20214
21003
|
randomInteger as randomInteger5,
|
|
20215
21004
|
randomId as randomId3,
|
|
@@ -20229,7 +21018,7 @@ var _newElementBase = (type, {
|
|
|
20229
21018
|
opacity = DEFAULT_ELEMENT_PROPS.opacity,
|
|
20230
21019
|
width = 0,
|
|
20231
21020
|
height = 0,
|
|
20232
|
-
angle = 0,
|
|
21021
|
+
angle: angle2 = 0,
|
|
20233
21022
|
groupIds = [],
|
|
20234
21023
|
frameId = null,
|
|
20235
21024
|
index = null,
|
|
@@ -20256,7 +21045,7 @@ var _newElementBase = (type, {
|
|
|
20256
21045
|
y,
|
|
20257
21046
|
width,
|
|
20258
21047
|
height,
|
|
20259
|
-
angle,
|
|
21048
|
+
angle: angle2,
|
|
20260
21049
|
strokeColor,
|
|
20261
21050
|
backgroundColor,
|
|
20262
21051
|
fillStyle,
|
|
@@ -20413,9 +21202,9 @@ var getAdjustedDimensions = (element, elementsMap, nextText) => {
|
|
|
20413
21202
|
y: Number.isFinite(y) ? y : element.y
|
|
20414
21203
|
};
|
|
20415
21204
|
};
|
|
20416
|
-
var adjustXYWithRotation = (sides, x, y,
|
|
20417
|
-
const cos = Math.cos(
|
|
20418
|
-
const sin = Math.sin(
|
|
21205
|
+
var adjustXYWithRotation = (sides, x, y, angle2, deltaX1, deltaY1, deltaX2, deltaY2) => {
|
|
21206
|
+
const cos = Math.cos(angle2);
|
|
21207
|
+
const sin = Math.sin(angle2);
|
|
20419
21208
|
if (sides.e && sides.w) {
|
|
20420
21209
|
x += deltaX1 + deltaX2;
|
|
20421
21210
|
} else if (sides.e) {
|
|
@@ -20463,7 +21252,11 @@ var newFreeDrawElement = (opts) => {
|
|
|
20463
21252
|
..._newElementBase(opts.type, opts),
|
|
20464
21253
|
points: opts.points || [],
|
|
20465
21254
|
pressures: opts.pressures || [],
|
|
20466
|
-
simulatePressure: opts.simulatePressure
|
|
21255
|
+
simulatePressure: opts.simulatePressure,
|
|
21256
|
+
strokeOptions: opts.strokeOptions ?? {
|
|
21257
|
+
variability: "variable",
|
|
21258
|
+
streamline: DEFAULT_STROKE_STREAMLINE2
|
|
21259
|
+
}
|
|
20467
21260
|
};
|
|
20468
21261
|
};
|
|
20469
21262
|
var newLinearElement = (opts) => {
|
|
@@ -20518,6 +21311,7 @@ var newImageElement = (opts) => {
|
|
|
20518
21311
|
status: opts.status ?? "pending",
|
|
20519
21312
|
fileId: opts.fileId ?? null,
|
|
20520
21313
|
fileName: opts.fileName ?? null,
|
|
21314
|
+
thumbHash: opts.thumbHash ?? null,
|
|
20521
21315
|
scale: opts.scale ?? [1, 1],
|
|
20522
21316
|
crop: opts.crop ?? null
|
|
20523
21317
|
};
|
|
@@ -21744,110 +22538,6 @@ var handleFocusPointHover = (arrow, scenePointerX, scenePointerY, scene, appStat
|
|
|
21744
22538
|
return null;
|
|
21745
22539
|
};
|
|
21746
22540
|
|
|
21747
|
-
// src/image.ts
|
|
21748
|
-
init_define_import_meta_env();
|
|
21749
|
-
import { MIME_TYPES as MIME_TYPES2, SVG_NS } from "@excalidraw/common";
|
|
21750
|
-
var loadHTMLImageElement = (dataURL) => {
|
|
21751
|
-
return new Promise((resolve, reject) => {
|
|
21752
|
-
const image = new Image();
|
|
21753
|
-
image.onload = () => {
|
|
21754
|
-
resolve(image);
|
|
21755
|
-
};
|
|
21756
|
-
image.onerror = (error) => {
|
|
21757
|
-
reject(error);
|
|
21758
|
-
};
|
|
21759
|
-
image.src = dataURL;
|
|
21760
|
-
});
|
|
21761
|
-
};
|
|
21762
|
-
var updateImageCache = async ({
|
|
21763
|
-
fileIds,
|
|
21764
|
-
files,
|
|
21765
|
-
imageCache
|
|
21766
|
-
}) => {
|
|
21767
|
-
const updatedFiles = /* @__PURE__ */ new Map();
|
|
21768
|
-
const erroredFiles = /* @__PURE__ */ new Map();
|
|
21769
|
-
await Promise.all(
|
|
21770
|
-
fileIds.reduce((promises, fileId) => {
|
|
21771
|
-
const fileData = files[fileId];
|
|
21772
|
-
if (fileData && !updatedFiles.has(fileId)) {
|
|
21773
|
-
updatedFiles.set(fileId, true);
|
|
21774
|
-
return promises.concat(
|
|
21775
|
-
(async () => {
|
|
21776
|
-
try {
|
|
21777
|
-
if (fileData.mimeType === MIME_TYPES2.binary) {
|
|
21778
|
-
throw new Error("Only images can be added to ImageCache");
|
|
21779
|
-
}
|
|
21780
|
-
const imagePromise = loadHTMLImageElement(fileData.dataURL);
|
|
21781
|
-
const data = {
|
|
21782
|
-
image: imagePromise,
|
|
21783
|
-
mimeType: fileData.mimeType
|
|
21784
|
-
};
|
|
21785
|
-
imageCache.set(fileId, data);
|
|
21786
|
-
const image = await imagePromise;
|
|
21787
|
-
imageCache.set(fileId, { ...data, image });
|
|
21788
|
-
} catch (error) {
|
|
21789
|
-
erroredFiles.set(fileId, true);
|
|
21790
|
-
}
|
|
21791
|
-
})()
|
|
21792
|
-
);
|
|
21793
|
-
}
|
|
21794
|
-
return promises;
|
|
21795
|
-
}, [])
|
|
21796
|
-
);
|
|
21797
|
-
return {
|
|
21798
|
-
imageCache,
|
|
21799
|
-
/** includes errored files because they cache was updated nonetheless */
|
|
21800
|
-
updatedFiles,
|
|
21801
|
-
/** files that failed when creating HTMLImageElement */
|
|
21802
|
-
erroredFiles
|
|
21803
|
-
};
|
|
21804
|
-
};
|
|
21805
|
-
var getInitializedImageElements = (elements) => elements.filter(
|
|
21806
|
-
(element) => isInitializedImageElement(element)
|
|
21807
|
-
);
|
|
21808
|
-
var isHTMLSVGElement = (node) => {
|
|
21809
|
-
return node?.nodeName.toLowerCase() === "svg";
|
|
21810
|
-
};
|
|
21811
|
-
var normalizeSVG = (SVGString) => {
|
|
21812
|
-
const doc = new DOMParser().parseFromString(SVGString, MIME_TYPES2.svg);
|
|
21813
|
-
const svg = doc.querySelector("svg");
|
|
21814
|
-
const errorNode = doc.querySelector("parsererror");
|
|
21815
|
-
if (errorNode || !isHTMLSVGElement(svg)) {
|
|
21816
|
-
throw new Error("Invalid SVG");
|
|
21817
|
-
} else {
|
|
21818
|
-
if (!svg.hasAttribute("xmlns")) {
|
|
21819
|
-
svg.setAttribute("xmlns", SVG_NS);
|
|
21820
|
-
}
|
|
21821
|
-
let width = svg.getAttribute("width");
|
|
21822
|
-
let height = svg.getAttribute("height");
|
|
21823
|
-
if (width?.includes("%") || width === "auto") {
|
|
21824
|
-
width = null;
|
|
21825
|
-
}
|
|
21826
|
-
if (height?.includes("%") || height === "auto") {
|
|
21827
|
-
height = null;
|
|
21828
|
-
}
|
|
21829
|
-
const viewBox = svg.getAttribute("viewBox");
|
|
21830
|
-
if (!width || !height) {
|
|
21831
|
-
width = width || "50";
|
|
21832
|
-
height = height || "50";
|
|
21833
|
-
if (viewBox) {
|
|
21834
|
-
const match = viewBox.match(
|
|
21835
|
-
/\d+ +\d+ +(\d+(?:\.\d+)?) +(\d+(?:\.\d+)?)/
|
|
21836
|
-
);
|
|
21837
|
-
if (match) {
|
|
21838
|
-
[, width, height] = match;
|
|
21839
|
-
}
|
|
21840
|
-
}
|
|
21841
|
-
svg.setAttribute("width", width);
|
|
21842
|
-
svg.setAttribute("height", height);
|
|
21843
|
-
}
|
|
21844
|
-
if (!viewBox) {
|
|
21845
|
-
svg.setAttribute("viewBox", `0 0 ${width} ${height}`);
|
|
21846
|
-
}
|
|
21847
|
-
return svg.outerHTML;
|
|
21848
|
-
}
|
|
21849
|
-
};
|
|
21850
|
-
|
|
21851
22541
|
// src/normalise.ts
|
|
21852
22542
|
init_define_import_meta_env();
|
|
21853
22543
|
var getGroupCenter = (boundingBox) => ({
|
|
@@ -22118,20 +22808,20 @@ var rotateSingleElement = (element, scene, pointerX, pointerY, shouldRotateWithD
|
|
|
22118
22808
|
);
|
|
22119
22809
|
const cx = (x1 + x2) / 2;
|
|
22120
22810
|
const cy = (y1 + y2) / 2;
|
|
22121
|
-
let
|
|
22811
|
+
let angle2;
|
|
22122
22812
|
if (isFrameLikeElement(element)) {
|
|
22123
|
-
|
|
22813
|
+
angle2 = 0;
|
|
22124
22814
|
} else {
|
|
22125
|
-
|
|
22815
|
+
angle2 = 5 * Math.PI / 2 + Math.atan2(pointerY - cy, pointerX - cx);
|
|
22126
22816
|
if (shouldRotateWithDiscreteAngle2) {
|
|
22127
|
-
|
|
22128
|
-
|
|
22817
|
+
angle2 = angle2 + SHIFT_LOCKING_ANGLE2 / 2;
|
|
22818
|
+
angle2 = angle2 - angle2 % SHIFT_LOCKING_ANGLE2;
|
|
22129
22819
|
}
|
|
22130
|
-
|
|
22820
|
+
angle2 = normalizeRadians2(angle2);
|
|
22131
22821
|
}
|
|
22132
22822
|
const boundTextElementId = getBoundTextElementId(element);
|
|
22133
22823
|
let update = {
|
|
22134
|
-
angle
|
|
22824
|
+
angle: angle2
|
|
22135
22825
|
};
|
|
22136
22826
|
if (isBindingElement(element)) {
|
|
22137
22827
|
update = {
|
|
@@ -22154,7 +22844,7 @@ var rotateSingleElement = (element, scene, pointerX, pointerY, shouldRotateWithD
|
|
|
22154
22844
|
scene.getNonDeletedElementsMap()
|
|
22155
22845
|
);
|
|
22156
22846
|
scene.mutateElement(textElement, {
|
|
22157
|
-
angle,
|
|
22847
|
+
angle: angle2,
|
|
22158
22848
|
x,
|
|
22159
22849
|
y
|
|
22160
22850
|
});
|
|
@@ -22322,45 +23012,45 @@ var getResizeOffsetXY = (transformHandleType, selectedElements, elementsMap, x,
|
|
|
22322
23012
|
const [x1, y1, x2, y2] = selectedElements.length === 1 ? getElementAbsoluteCoords2(selectedElements[0], elementsMap) : getCommonBounds(selectedElements);
|
|
22323
23013
|
const cx = (x1 + x2) / 2;
|
|
22324
23014
|
const cy = (y1 + y2) / 2;
|
|
22325
|
-
const
|
|
23015
|
+
const angle2 = selectedElements.length === 1 ? selectedElements[0].angle : 0;
|
|
22326
23016
|
[x, y] = pointRotateRads13(
|
|
22327
23017
|
pointFrom16(x, y),
|
|
22328
23018
|
pointFrom16(cx, cy),
|
|
22329
|
-
-
|
|
23019
|
+
-angle2
|
|
22330
23020
|
);
|
|
22331
23021
|
switch (transformHandleType) {
|
|
22332
23022
|
case "n":
|
|
22333
23023
|
return pointRotateRads13(
|
|
22334
23024
|
pointFrom16(x - (x1 + x2) / 2, y - y1),
|
|
22335
23025
|
pointFrom16(0, 0),
|
|
22336
|
-
|
|
23026
|
+
angle2
|
|
22337
23027
|
);
|
|
22338
23028
|
case "s":
|
|
22339
23029
|
return pointRotateRads13(
|
|
22340
23030
|
pointFrom16(x - (x1 + x2) / 2, y - y2),
|
|
22341
23031
|
pointFrom16(0, 0),
|
|
22342
|
-
|
|
23032
|
+
angle2
|
|
22343
23033
|
);
|
|
22344
23034
|
case "w":
|
|
22345
23035
|
return pointRotateRads13(
|
|
22346
23036
|
pointFrom16(x - x1, y - (y1 + y2) / 2),
|
|
22347
23037
|
pointFrom16(0, 0),
|
|
22348
|
-
|
|
23038
|
+
angle2
|
|
22349
23039
|
);
|
|
22350
23040
|
case "e":
|
|
22351
23041
|
return pointRotateRads13(
|
|
22352
23042
|
pointFrom16(x - x2, y - (y1 + y2) / 2),
|
|
22353
23043
|
pointFrom16(0, 0),
|
|
22354
|
-
|
|
23044
|
+
angle2
|
|
22355
23045
|
);
|
|
22356
23046
|
case "nw":
|
|
22357
|
-
return pointRotateRads13(pointFrom16(x - x1, y - y1), pointFrom16(0, 0),
|
|
23047
|
+
return pointRotateRads13(pointFrom16(x - x1, y - y1), pointFrom16(0, 0), angle2);
|
|
22358
23048
|
case "ne":
|
|
22359
|
-
return pointRotateRads13(pointFrom16(x - x2, y - y1), pointFrom16(0, 0),
|
|
23049
|
+
return pointRotateRads13(pointFrom16(x - x2, y - y1), pointFrom16(0, 0), angle2);
|
|
22360
23050
|
case "sw":
|
|
22361
|
-
return pointRotateRads13(pointFrom16(x - x1, y - y2), pointFrom16(0, 0),
|
|
23051
|
+
return pointRotateRads13(pointFrom16(x - x1, y - y2), pointFrom16(0, 0), angle2);
|
|
22362
23052
|
case "se":
|
|
22363
|
-
return pointRotateRads13(pointFrom16(x - x2, y - y2), pointFrom16(0, 0),
|
|
23053
|
+
return pointRotateRads13(pointFrom16(x - x2, y - y2), pointFrom16(0, 0), angle2);
|
|
22364
23054
|
default:
|
|
22365
23055
|
return [0, 0];
|
|
22366
23056
|
}
|
|
@@ -22404,7 +23094,7 @@ var getResizeAnchor = (handleDirection, shouldMaintainAspectRatio, shouldResizeF
|
|
|
22404
23094
|
}
|
|
22405
23095
|
return "top-right";
|
|
22406
23096
|
};
|
|
22407
|
-
var getResizedOrigin = (prevOrigin, prevWidth, prevHeight, newWidth, newHeight,
|
|
23097
|
+
var getResizedOrigin = (prevOrigin, prevWidth, prevHeight, newWidth, newHeight, angle2, handleDirection, shouldMaintainAspectRatio, shouldResizeFromCenter) => {
|
|
22408
23098
|
const anchor = getResizeAnchor(
|
|
22409
23099
|
handleDirection,
|
|
22410
23100
|
shouldMaintainAspectRatio,
|
|
@@ -22414,23 +23104,23 @@ var getResizedOrigin = (prevOrigin, prevWidth, prevHeight, newWidth, newHeight,
|
|
|
22414
23104
|
switch (anchor) {
|
|
22415
23105
|
case "top-left":
|
|
22416
23106
|
return {
|
|
22417
|
-
x: x + (prevWidth - newWidth) / 2 + (newWidth - prevWidth) / 2 * Math.cos(
|
|
22418
|
-
y: y + (prevHeight - newHeight) / 2 + (newWidth - prevWidth) / 2 * Math.sin(
|
|
23107
|
+
x: x + (prevWidth - newWidth) / 2 + (newWidth - prevWidth) / 2 * Math.cos(angle2) + (prevHeight - newHeight) / 2 * Math.sin(angle2),
|
|
23108
|
+
y: y + (prevHeight - newHeight) / 2 + (newWidth - prevWidth) / 2 * Math.sin(angle2) + (newHeight - prevHeight) / 2 * Math.cos(angle2)
|
|
22419
23109
|
};
|
|
22420
23110
|
case "top-right":
|
|
22421
23111
|
return {
|
|
22422
|
-
x: x + (prevWidth - newWidth) / 2 * (Math.cos(
|
|
22423
|
-
y: y + (prevHeight - newHeight) / 2 + (prevWidth - newWidth) / 2 * Math.sin(
|
|
23112
|
+
x: x + (prevWidth - newWidth) / 2 * (Math.cos(angle2) + 1) + (prevHeight - newHeight) / 2 * Math.sin(angle2),
|
|
23113
|
+
y: y + (prevHeight - newHeight) / 2 + (prevWidth - newWidth) / 2 * Math.sin(angle2) + (newHeight - prevHeight) / 2 * Math.cos(angle2)
|
|
22424
23114
|
};
|
|
22425
23115
|
case "bottom-left":
|
|
22426
23116
|
return {
|
|
22427
|
-
x: x + (prevWidth - newWidth) / 2 * (1 - Math.cos(
|
|
22428
|
-
y: y + (prevHeight - newHeight) / 2 * (Math.cos(
|
|
23117
|
+
x: x + (prevWidth - newWidth) / 2 * (1 - Math.cos(angle2)) + (newHeight - prevHeight) / 2 * Math.sin(angle2),
|
|
23118
|
+
y: y + (prevHeight - newHeight) / 2 * (Math.cos(angle2) + 1) + (newWidth - prevWidth) / 2 * Math.sin(angle2)
|
|
22429
23119
|
};
|
|
22430
23120
|
case "bottom-right":
|
|
22431
23121
|
return {
|
|
22432
|
-
x: x + (prevWidth - newWidth) / 2 * (Math.cos(
|
|
22433
|
-
y: y + (prevHeight - newHeight) / 2 * (Math.cos(
|
|
23122
|
+
x: x + (prevWidth - newWidth) / 2 * (Math.cos(angle2) + 1) + (newHeight - prevHeight) / 2 * Math.sin(angle2),
|
|
23123
|
+
y: y + (prevHeight - newHeight) / 2 * (Math.cos(angle2) + 1) + (prevWidth - newWidth) / 2 * Math.sin(angle2)
|
|
22434
23124
|
};
|
|
22435
23125
|
case "center":
|
|
22436
23126
|
return {
|
|
@@ -22439,23 +23129,23 @@ var getResizedOrigin = (prevOrigin, prevWidth, prevHeight, newWidth, newHeight,
|
|
|
22439
23129
|
};
|
|
22440
23130
|
case "east-side":
|
|
22441
23131
|
return {
|
|
22442
|
-
x: x + (prevWidth - newWidth) / 2 * (Math.cos(
|
|
22443
|
-
y: y + (prevWidth - newWidth) / 2 * Math.sin(
|
|
23132
|
+
x: x + (prevWidth - newWidth) / 2 * (Math.cos(angle2) + 1),
|
|
23133
|
+
y: y + (prevWidth - newWidth) / 2 * Math.sin(angle2) + (prevHeight - newHeight) / 2
|
|
22444
23134
|
};
|
|
22445
23135
|
case "west-side":
|
|
22446
23136
|
return {
|
|
22447
|
-
x: x + (prevWidth - newWidth) / 2 * (1 - Math.cos(
|
|
22448
|
-
y: y + (newWidth - prevWidth) / 2 * Math.sin(
|
|
23137
|
+
x: x + (prevWidth - newWidth) / 2 * (1 - Math.cos(angle2)),
|
|
23138
|
+
y: y + (newWidth - prevWidth) / 2 * Math.sin(angle2) + (prevHeight - newHeight) / 2
|
|
22449
23139
|
};
|
|
22450
23140
|
case "north-side":
|
|
22451
23141
|
return {
|
|
22452
|
-
x: x + (prevWidth - newWidth) / 2 + (prevHeight - newHeight) / 2 * Math.sin(
|
|
22453
|
-
y: y + (newHeight - prevHeight) / 2 * (Math.cos(
|
|
23142
|
+
x: x + (prevWidth - newWidth) / 2 + (prevHeight - newHeight) / 2 * Math.sin(angle2),
|
|
23143
|
+
y: y + (newHeight - prevHeight) / 2 * (Math.cos(angle2) - 1)
|
|
22454
23144
|
};
|
|
22455
23145
|
case "south-side":
|
|
22456
23146
|
return {
|
|
22457
|
-
x: x + (prevWidth - newWidth) / 2 + (newHeight - prevHeight) / 2 * Math.sin(
|
|
22458
|
-
y: y + (prevHeight - newHeight) / 2 * (Math.cos(
|
|
23147
|
+
x: x + (prevWidth - newWidth) / 2 + (newHeight - prevHeight) / 2 * Math.sin(angle2),
|
|
23148
|
+
y: y + (prevHeight - newHeight) / 2 * (Math.cos(angle2) + 1)
|
|
22459
23149
|
};
|
|
22460
23150
|
}
|
|
22461
23151
|
};
|
|
@@ -22877,7 +23567,7 @@ var resizeMultipleElements = (selectedElements, elementsMap, handleDirection, sc
|
|
|
22877
23567
|
}
|
|
22878
23568
|
const width2 = orig.width * scaleX;
|
|
22879
23569
|
const height2 = orig.height * scaleY;
|
|
22880
|
-
const
|
|
23570
|
+
const angle2 = normalizeRadians2(
|
|
22881
23571
|
orig.angle * flipFactorX * flipFactorY
|
|
22882
23572
|
);
|
|
22883
23573
|
const isLinearOrFreeDraw = isLinearElement(orig) || isFreeDrawElement(orig);
|
|
@@ -22898,7 +23588,7 @@ var resizeMultipleElements = (selectedElements, elementsMap, handleDirection, sc
|
|
|
22898
23588
|
y,
|
|
22899
23589
|
width: width2,
|
|
22900
23590
|
height: height2,
|
|
22901
|
-
angle,
|
|
23591
|
+
angle: angle2,
|
|
22902
23592
|
...rescaledPoints
|
|
22903
23593
|
};
|
|
22904
23594
|
if (isElbowArrow(orig)) {
|
|
@@ -22966,7 +23656,7 @@ var resizeMultipleElements = (selectedElements, elementsMap, handleDirection, sc
|
|
|
22966
23656
|
element,
|
|
22967
23657
|
update: { boundTextFontSize, ...update }
|
|
22968
23658
|
} of elementsAndUpdates) {
|
|
22969
|
-
const { angle } = update;
|
|
23659
|
+
const { angle: angle2 } = update;
|
|
22970
23660
|
scene.mutateElement(element, update);
|
|
22971
23661
|
updateBoundElements(element, scene, {
|
|
22972
23662
|
simultaneouslyUpdated: elementsToUpdate
|
|
@@ -22987,7 +23677,7 @@ var resizeMultipleElements = (selectedElements, elementsMap, handleDirection, sc
|
|
|
22987
23677
|
if (boundTextElement && boundTextFontSize) {
|
|
22988
23678
|
scene.mutateElement(boundTextElement, {
|
|
22989
23679
|
fontSize: boundTextFontSize,
|
|
22990
|
-
angle: isLinearElement(element) ? void 0 :
|
|
23680
|
+
angle: isLinearElement(element) ? void 0 : angle2
|
|
22991
23681
|
});
|
|
22992
23682
|
handleBindTextResize(element, scene, handleDirection, true);
|
|
22993
23683
|
}
|
|
@@ -23052,11 +23742,11 @@ var OMIT_SIDES_FOR_LINE_BACKSLASH = {
|
|
|
23052
23742
|
n: true,
|
|
23053
23743
|
w: true
|
|
23054
23744
|
};
|
|
23055
|
-
var generateTransformHandle = (x, y, width, height, cx, cy,
|
|
23745
|
+
var generateTransformHandle = (x, y, width, height, cx, cy, angle2) => {
|
|
23056
23746
|
const [xx, yy] = pointRotateRads14(
|
|
23057
23747
|
pointFrom17(x + width / 2, y + height / 2),
|
|
23058
23748
|
pointFrom17(cx, cy),
|
|
23059
|
-
|
|
23749
|
+
angle2
|
|
23060
23750
|
);
|
|
23061
23751
|
return [xx - width / 2, yy - height / 2, width, height];
|
|
23062
23752
|
};
|
|
@@ -23072,7 +23762,7 @@ var getOmitSidesForEditorInterface = (editorInterface) => {
|
|
|
23072
23762
|
}
|
|
23073
23763
|
return {};
|
|
23074
23764
|
};
|
|
23075
|
-
var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy],
|
|
23765
|
+
var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle2, zoom, pointerType, omitSides = {}, margin = 4, spacing = DEFAULT_TRANSFORM_HANDLE_SPACING) => {
|
|
23076
23766
|
const size = transformHandleSizes[pointerType];
|
|
23077
23767
|
const handleWidth = size / zoom.value;
|
|
23078
23768
|
const handleHeight = size / zoom.value;
|
|
@@ -23090,7 +23780,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
|
|
|
23090
23780
|
handleHeight,
|
|
23091
23781
|
cx,
|
|
23092
23782
|
cy,
|
|
23093
|
-
|
|
23783
|
+
angle2
|
|
23094
23784
|
),
|
|
23095
23785
|
ne: omitSides.ne ? void 0 : generateTransformHandle(
|
|
23096
23786
|
x2 + dashedLineMargin - centeringOffset,
|
|
@@ -23099,7 +23789,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
|
|
|
23099
23789
|
handleHeight,
|
|
23100
23790
|
cx,
|
|
23101
23791
|
cy,
|
|
23102
|
-
|
|
23792
|
+
angle2
|
|
23103
23793
|
),
|
|
23104
23794
|
sw: omitSides.sw ? void 0 : generateTransformHandle(
|
|
23105
23795
|
x1 - dashedLineMargin - handleMarginX + centeringOffset,
|
|
@@ -23108,7 +23798,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
|
|
|
23108
23798
|
handleHeight,
|
|
23109
23799
|
cx,
|
|
23110
23800
|
cy,
|
|
23111
|
-
|
|
23801
|
+
angle2
|
|
23112
23802
|
),
|
|
23113
23803
|
se: omitSides.se ? void 0 : generateTransformHandle(
|
|
23114
23804
|
x2 + dashedLineMargin - centeringOffset,
|
|
@@ -23117,7 +23807,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
|
|
|
23117
23807
|
handleHeight,
|
|
23118
23808
|
cx,
|
|
23119
23809
|
cy,
|
|
23120
|
-
|
|
23810
|
+
angle2
|
|
23121
23811
|
),
|
|
23122
23812
|
rotation: omitSides.rotation ? void 0 : generateTransformHandle(
|
|
23123
23813
|
x1 + width / 2 - handleWidth / 2,
|
|
@@ -23126,7 +23816,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
|
|
|
23126
23816
|
handleHeight,
|
|
23127
23817
|
cx,
|
|
23128
23818
|
cy,
|
|
23129
|
-
|
|
23819
|
+
angle2
|
|
23130
23820
|
)
|
|
23131
23821
|
};
|
|
23132
23822
|
const minimumSizeForEightHandles = 5 * transformHandleSizes.mouse / zoom.value;
|
|
@@ -23139,7 +23829,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
|
|
|
23139
23829
|
handleHeight,
|
|
23140
23830
|
cx,
|
|
23141
23831
|
cy,
|
|
23142
|
-
|
|
23832
|
+
angle2
|
|
23143
23833
|
);
|
|
23144
23834
|
}
|
|
23145
23835
|
if (!omitSides.s) {
|
|
@@ -23150,7 +23840,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
|
|
|
23150
23840
|
handleHeight,
|
|
23151
23841
|
cx,
|
|
23152
23842
|
cy,
|
|
23153
|
-
|
|
23843
|
+
angle2
|
|
23154
23844
|
);
|
|
23155
23845
|
}
|
|
23156
23846
|
}
|
|
@@ -23163,7 +23853,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
|
|
|
23163
23853
|
handleHeight,
|
|
23164
23854
|
cx,
|
|
23165
23855
|
cy,
|
|
23166
|
-
|
|
23856
|
+
angle2
|
|
23167
23857
|
);
|
|
23168
23858
|
}
|
|
23169
23859
|
if (!omitSides.e) {
|
|
@@ -23174,7 +23864,7 @@ var getTransformHandlesFromCoords = ([x1, y1, x2, y2, cx, cy], angle, zoom, poin
|
|
|
23174
23864
|
handleHeight,
|
|
23175
23865
|
cx,
|
|
23176
23866
|
cy,
|
|
23177
|
-
|
|
23867
|
+
angle2
|
|
23178
23868
|
);
|
|
23179
23869
|
}
|
|
23180
23870
|
}
|
|
@@ -23343,10 +24033,10 @@ var getTransformHandleTypeFromCoords = ([x1, y1, x2, y2], scenePointerX, scenePo
|
|
|
23343
24033
|
return false;
|
|
23344
24034
|
};
|
|
23345
24035
|
var RESIZE_CURSORS = ["ns", "nesw", "ew", "nwse"];
|
|
23346
|
-
var rotateResizeCursor = (cursor,
|
|
24036
|
+
var rotateResizeCursor = (cursor, angle2) => {
|
|
23347
24037
|
const index = RESIZE_CURSORS.indexOf(cursor);
|
|
23348
24038
|
if (index >= 0) {
|
|
23349
|
-
const a2 = Math.round(
|
|
24039
|
+
const a2 = Math.round(angle2 / (Math.PI / 4));
|
|
23350
24040
|
cursor = RESIZE_CURSORS[(index + a2) % RESIZE_CURSORS.length];
|
|
23351
24041
|
}
|
|
23352
24042
|
return cursor;
|
|
@@ -23388,11 +24078,11 @@ var getCursorForResizingElement = (resizingElement) => {
|
|
|
23388
24078
|
}
|
|
23389
24079
|
return cursor ? `${cursor}-resize` : "";
|
|
23390
24080
|
};
|
|
23391
|
-
var getSelectionBorders = ([x1, y1], [x2, y2], center,
|
|
23392
|
-
const topLeft = pointRotateRads15(pointFrom18(x1, y1), center,
|
|
23393
|
-
const topRight = pointRotateRads15(pointFrom18(x2, y1), center,
|
|
23394
|
-
const bottomLeft = pointRotateRads15(pointFrom18(x1, y2), center,
|
|
23395
|
-
const bottomRight = pointRotateRads15(pointFrom18(x2, y2), center,
|
|
24081
|
+
var getSelectionBorders = ([x1, y1], [x2, y2], center, angle2) => {
|
|
24082
|
+
const topLeft = pointRotateRads15(pointFrom18(x1, y1), center, angle2);
|
|
24083
|
+
const topRight = pointRotateRads15(pointFrom18(x2, y1), center, angle2);
|
|
24084
|
+
const bottomLeft = pointRotateRads15(pointFrom18(x1, y2), center, angle2);
|
|
24085
|
+
const bottomRight = pointRotateRads15(pointFrom18(x2, y2), center, angle2);
|
|
23396
24086
|
return {
|
|
23397
24087
|
n: [topLeft, topRight],
|
|
23398
24088
|
e: [topRight, bottomRight],
|
|
@@ -24631,6 +25321,96 @@ var SloppinessCartoonistIcon = createIcon(
|
|
|
24631
25321
|
),
|
|
24632
25322
|
modifiedTablerIconProps
|
|
24633
25323
|
);
|
|
25324
|
+
var strokeVariabilityConstantIcon = createIcon(
|
|
25325
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", { children: [
|
|
25326
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
25327
|
+
"path",
|
|
25328
|
+
{
|
|
25329
|
+
d: "M4 12 C 5 8, 6 8, 8 12",
|
|
25330
|
+
fill: "none",
|
|
25331
|
+
strokeWidth: "1",
|
|
25332
|
+
strokeLinecap: "round",
|
|
25333
|
+
strokeLinejoin: "round"
|
|
25334
|
+
}
|
|
25335
|
+
),
|
|
25336
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
25337
|
+
"path",
|
|
25338
|
+
{
|
|
25339
|
+
d: "M8 12 C 9 16, 10 16, 12 12",
|
|
25340
|
+
fill: "none",
|
|
25341
|
+
strokeWidth: "1",
|
|
25342
|
+
strokeLinecap: "round",
|
|
25343
|
+
strokeLinejoin: "round"
|
|
25344
|
+
}
|
|
25345
|
+
),
|
|
25346
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
25347
|
+
"path",
|
|
25348
|
+
{
|
|
25349
|
+
d: "M12 12 C 14 8, 15 8, 16 12",
|
|
25350
|
+
fill: "none",
|
|
25351
|
+
strokeWidth: "1",
|
|
25352
|
+
strokeLinecap: "round",
|
|
25353
|
+
strokeLinejoin: "round"
|
|
25354
|
+
}
|
|
25355
|
+
),
|
|
25356
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
25357
|
+
"path",
|
|
25358
|
+
{
|
|
25359
|
+
d: "M16 12 C 17 16, 18 16, 19 12",
|
|
25360
|
+
fill: "none",
|
|
25361
|
+
strokeWidth: "1",
|
|
25362
|
+
strokeLinecap: "round",
|
|
25363
|
+
strokeLinejoin: "round"
|
|
25364
|
+
}
|
|
25365
|
+
)
|
|
25366
|
+
] }),
|
|
25367
|
+
tablerIconProps
|
|
25368
|
+
);
|
|
25369
|
+
var strokeVariabilityVariableIcon = createIcon(
|
|
25370
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", { children: [
|
|
25371
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
25372
|
+
"path",
|
|
25373
|
+
{
|
|
25374
|
+
d: "M4 12 C 5 8, 6 8, 8 12",
|
|
25375
|
+
fill: "none",
|
|
25376
|
+
strokeWidth: "1.5",
|
|
25377
|
+
strokeLinecap: "round",
|
|
25378
|
+
strokeLinejoin: "round"
|
|
25379
|
+
}
|
|
25380
|
+
),
|
|
25381
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
25382
|
+
"path",
|
|
25383
|
+
{
|
|
25384
|
+
d: "M8 12 C 9 16, 10 16, 12 12",
|
|
25385
|
+
fill: "none",
|
|
25386
|
+
strokeWidth: "2",
|
|
25387
|
+
strokeLinecap: "round",
|
|
25388
|
+
strokeLinejoin: "round"
|
|
25389
|
+
}
|
|
25390
|
+
),
|
|
25391
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
25392
|
+
"path",
|
|
25393
|
+
{
|
|
25394
|
+
d: "M12 12 C 14 8, 15 8, 16 12",
|
|
25395
|
+
fill: "none",
|
|
25396
|
+
strokeWidth: "2.75",
|
|
25397
|
+
strokeLinecap: "round",
|
|
25398
|
+
strokeLinejoin: "round"
|
|
25399
|
+
}
|
|
25400
|
+
),
|
|
25401
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
25402
|
+
"path",
|
|
25403
|
+
{
|
|
25404
|
+
d: "M16 12 C 17 16, 18 16, 19 12",
|
|
25405
|
+
fill: "none",
|
|
25406
|
+
strokeWidth: "3.25",
|
|
25407
|
+
strokeLinecap: "round",
|
|
25408
|
+
strokeLinejoin: "round"
|
|
25409
|
+
}
|
|
25410
|
+
)
|
|
25411
|
+
] }),
|
|
25412
|
+
tablerIconProps
|
|
25413
|
+
);
|
|
24634
25414
|
var EdgeSharpIcon = createIcon(
|
|
24635
25415
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { strokeWidth: "1.5", children: [
|
|
24636
25416
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3.33334 9.99998V6.66665C3.33334 6.04326 3.33403 4.9332 3.33539 3.33646C4.95233 3.33436 6.06276 3.33331 6.66668 3.33331H10" }),
|
|
@@ -26681,6 +27461,7 @@ export {
|
|
|
26681
27461
|
frameAndChildrenSelectedTogether,
|
|
26682
27462
|
generateLinearCollisionShape,
|
|
26683
27463
|
generateRoughOptions,
|
|
27464
|
+
generateThumbHash,
|
|
26684
27465
|
getActiveTextElement,
|
|
26685
27466
|
getAllHoveredElementAtPoint,
|
|
26686
27467
|
getApproxMinLineHeight,
|
|
@@ -26785,6 +27566,7 @@ export {
|
|
|
26785
27566
|
getTextFromElements,
|
|
26786
27567
|
getTextHeight,
|
|
26787
27568
|
getTextWidth,
|
|
27569
|
+
getThumbHashPlaceholder,
|
|
26788
27570
|
getToolbarTools,
|
|
26789
27571
|
getTransformHandleTypeFromCoords,
|
|
26790
27572
|
getTransformHandles,
|
|
@@ -26806,6 +27588,7 @@ export {
|
|
|
26806
27588
|
hasBackground,
|
|
26807
27589
|
hasBoundTextElement,
|
|
26808
27590
|
hasBoundingBox,
|
|
27591
|
+
hasFreedrawMode,
|
|
26809
27592
|
hasStrokeColor,
|
|
26810
27593
|
hasStrokeStyle,
|
|
26811
27594
|
hasStrokeWidth,
|