@myoc/excalidraw 0.19.519 → 0.19.521
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +106 -0
- package/dist/dev/{chunk-ZGRXNVW4.js → chunk-IU2VFRFU.js} +4 -1
- package/dist/dev/chunk-IU2VFRFU.js.map +7 -0
- package/dist/dev/{chunk-RIK6B6HD.js → chunk-MN6E45MP.js} +62 -26
- package/dist/dev/chunk-MN6E45MP.js.map +7 -0
- package/dist/dev/{chunk-MCPNWEHU.js → chunk-P7I4FGOG.js} +2 -2
- package/dist/dev/data/{image-IRC25PM5.js → image-ZYGVHYLC.js} +3 -3
- package/dist/dev/index.css +12 -0
- package/dist/dev/index.css.map +2 -2
- package/dist/dev/index.js +1454 -452
- package/dist/dev/index.js.map +4 -4
- package/dist/dev/locales/{en-RQFAMS2U.js → en-25BPHB4T.js} +2 -2
- package/dist/dev/subset-shared.chunk.js +1 -1
- package/dist/dev/subset-worker.chunk.js +1 -1
- package/dist/prod/{chunk-VHQT4IVX.js → chunk-3UXKIWVY.js} +2 -2
- package/dist/prod/chunk-BNYGVLQX.js +4 -0
- package/dist/prod/{chunk-QW7MIEK6.js → chunk-ZYOK2JIN.js} +1 -1
- package/dist/prod/data/image-OFIWDJ6Z.js +1 -0
- package/dist/prod/index.css +1 -1
- package/dist/prod/index.js +20 -20
- package/dist/prod/locales/{en-6UCVDQQ7.js → en-AH5BYWXT.js} +1 -1
- package/dist/prod/subset-shared.chunk.js +1 -1
- package/dist/prod/subset-worker.chunk.js +1 -1
- 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/clipboard.d.ts +34 -0
- 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/index.d.ts +4 -2
- 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 +18 -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 +4 -4
- package/dist/dev/chunk-RIK6B6HD.js.map +0 -7
- package/dist/dev/chunk-ZGRXNVW4.js.map +0 -7
- package/dist/prod/chunk-FL5QOM6C.js +0 -4
- package/dist/prod/data/image-7LG744DI.js +0 -1
- /package/dist/dev/{chunk-MCPNWEHU.js.map → chunk-P7I4FGOG.js.map} +0 -0
- /package/dist/dev/data/{image-IRC25PM5.js.map → image-ZYGVHYLC.js.map} +0 -0
- /package/dist/dev/locales/{en-RQFAMS2U.js.map → en-25BPHB4T.js.map} +0 -0
package/dist/dev/index.js
CHANGED
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
getSelectedElements,
|
|
36
36
|
getTargetElements,
|
|
37
37
|
hasBackground,
|
|
38
|
+
hasFreedrawMode,
|
|
38
39
|
hasStrokeStyle,
|
|
39
40
|
hasStrokeWidth,
|
|
40
41
|
isEraserActive,
|
|
@@ -57,13 +58,13 @@ import {
|
|
|
57
58
|
saveAsJSON,
|
|
58
59
|
serializeAsJSON,
|
|
59
60
|
strokeRectWithRotation_simple
|
|
60
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-MN6E45MP.js";
|
|
61
62
|
import {
|
|
62
63
|
define_import_meta_env_default
|
|
63
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-P7I4FGOG.js";
|
|
64
65
|
import {
|
|
65
66
|
en_default
|
|
66
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-IU2VFRFU.js";
|
|
67
68
|
import {
|
|
68
69
|
percentages_default
|
|
69
70
|
} from "./chunk-URPEKBQ3.js";
|
|
@@ -85,6 +86,7 @@ import {
|
|
|
85
86
|
applyDarkModeFilter as applyDarkModeFilter5,
|
|
86
87
|
DEFAULT_IMAGE_OPTIONS,
|
|
87
88
|
DEFAULT_UI_OPTIONS,
|
|
89
|
+
getStrokeWidthByKey as getStrokeWidthByKey4,
|
|
88
90
|
isShallowEqual as isShallowEqual9
|
|
89
91
|
} from "@excalidraw/common";
|
|
90
92
|
|
|
@@ -96,7 +98,7 @@ import { flushSync as flushSync2 } from "react-dom";
|
|
|
96
98
|
import rough3 from "roughjs/bin/rough";
|
|
97
99
|
import { nanoid } from "nanoid";
|
|
98
100
|
import {
|
|
99
|
-
clamp as
|
|
101
|
+
clamp as clamp10,
|
|
100
102
|
pointFrom as pointFrom32,
|
|
101
103
|
pointDistance as pointDistance9,
|
|
102
104
|
vector as vector3,
|
|
@@ -116,6 +118,8 @@ import {
|
|
|
116
118
|
KEYS as KEYS50,
|
|
117
119
|
APP_NAME,
|
|
118
120
|
CURSOR_TYPE as CURSOR_TYPE4,
|
|
121
|
+
DEFAULT_STROKE_STREAMLINE as DEFAULT_STROKE_STREAMLINE2,
|
|
122
|
+
DEFAULT_STROKE_STREAMLINE_PRECISE,
|
|
119
123
|
DEFAULT_TRANSFORM_HANDLE_SPACING as DEFAULT_TRANSFORM_HANDLE_SPACING3,
|
|
120
124
|
DEFAULT_VERTICAL_ALIGN,
|
|
121
125
|
DRAGGING_THRESHOLD as DRAGGING_THRESHOLD3,
|
|
@@ -126,7 +130,7 @@ import {
|
|
|
126
130
|
IMAGE_MIME_TYPES as IMAGE_MIME_TYPES2,
|
|
127
131
|
IMAGE_RENDER_TIMEOUT,
|
|
128
132
|
LINE_CONFIRM_THRESHOLD as LINE_CONFIRM_THRESHOLD2,
|
|
129
|
-
MIME_TYPES as
|
|
133
|
+
MIME_TYPES as MIME_TYPES8,
|
|
130
134
|
MQ_RIGHT_SIDEBAR_MIN_WIDTH,
|
|
131
135
|
POINTER_BUTTON as POINTER_BUTTON2,
|
|
132
136
|
ROUNDNESS as ROUNDNESS7,
|
|
@@ -164,11 +168,9 @@ import {
|
|
|
164
168
|
updateObject as updateObject2,
|
|
165
169
|
updateActiveTool as updateActiveTool8,
|
|
166
170
|
isTransparent as isTransparent6,
|
|
167
|
-
easeToValuesRAF,
|
|
168
171
|
muteFSAbortError,
|
|
169
172
|
isTestEnv as isTestEnv5,
|
|
170
173
|
isDevEnv as isDevEnv9,
|
|
171
|
-
easeOut as easeOut4,
|
|
172
174
|
updateStable,
|
|
173
175
|
addEventListener as addEventListener2,
|
|
174
176
|
normalizeEOL as normalizeEOL2,
|
|
@@ -195,7 +197,9 @@ import {
|
|
|
195
197
|
setDesktopUIMode,
|
|
196
198
|
isSelectionLikeTool,
|
|
197
199
|
oneOf,
|
|
198
|
-
|
|
200
|
+
easeOut as easeOut5,
|
|
201
|
+
matchKey as matchKey3,
|
|
202
|
+
getStrokeWidthByKey as getStrokeWidthByKey3
|
|
199
203
|
} from "@excalidraw/common";
|
|
200
204
|
import {
|
|
201
205
|
getObservedAppState,
|
|
@@ -251,6 +255,8 @@ import {
|
|
|
251
255
|
maybeParseEmbedSrc,
|
|
252
256
|
getEmbedLink as getEmbedLink2,
|
|
253
257
|
getInitializedImageElements,
|
|
258
|
+
generateThumbHash,
|
|
259
|
+
loadHTMLImageElement,
|
|
254
260
|
normalizeSVG,
|
|
255
261
|
updateImageCache as _updateImageCache,
|
|
256
262
|
getBoundTextElement as getBoundTextElement15,
|
|
@@ -285,7 +291,6 @@ import {
|
|
|
285
291
|
cropElement,
|
|
286
292
|
wrapText as wrapText5,
|
|
287
293
|
isElementLink as isElementLink2,
|
|
288
|
-
parseElementLinkFromURL,
|
|
289
294
|
isMeasureTextSupported,
|
|
290
295
|
normalizeText as normalizeText2,
|
|
291
296
|
measureText as measureText8,
|
|
@@ -341,7 +346,9 @@ import {
|
|
|
341
346
|
maybeHandleArrowPointlikeDrag,
|
|
342
347
|
getUncroppedWidthAndHeight as getUncroppedWidthAndHeight4,
|
|
343
348
|
getActiveTextElement as getActiveTextElement2,
|
|
344
|
-
isEligibleFrameChildType
|
|
349
|
+
isEligibleFrameChildType,
|
|
350
|
+
getBindingStrategyForDraggingBindingElementEndpoints as getBindingStrategyForDraggingBindingElementEndpoints2,
|
|
351
|
+
parseElementLinkFromURL
|
|
345
352
|
} from "@excalidraw/element";
|
|
346
353
|
import { LinearElementEditor as LinearElementEditor11 } from "@excalidraw/element/linearElementEditor";
|
|
347
354
|
import { findShapeByKey } from "@excalidraw/element/shapes";
|
|
@@ -396,7 +403,7 @@ var globImport_locales_json = __glob({
|
|
|
396
403
|
"./locales/de-CH.json": () => import("./locales/de-CH-QSJHIHEN.js"),
|
|
397
404
|
"./locales/de-DE.json": () => import("./locales/de-DE-2WQ5IRPT.js"),
|
|
398
405
|
"./locales/el-GR.json": () => import("./locales/el-GR-N7JWYMV5.js"),
|
|
399
|
-
"./locales/en.json": () => import("./locales/en-
|
|
406
|
+
"./locales/en.json": () => import("./locales/en-25BPHB4T.js"),
|
|
400
407
|
"./locales/es-ES.json": () => import("./locales/es-ES-37LJTLHM.js"),
|
|
401
408
|
"./locales/eu-ES.json": () => import("./locales/eu-ES-2IFCUP7K.js"),
|
|
402
409
|
"./locales/fa-IR.json": () => import("./locales/fa-IR-VDT7BNM4.js"),
|
|
@@ -1754,6 +1761,96 @@ var SloppinessCartoonistIcon = createIcon(
|
|
|
1754
1761
|
),
|
|
1755
1762
|
modifiedTablerIconProps
|
|
1756
1763
|
);
|
|
1764
|
+
var strokeVariabilityConstantIcon = createIcon(
|
|
1765
|
+
/* @__PURE__ */ jsxs("g", { children: [
|
|
1766
|
+
/* @__PURE__ */ jsx(
|
|
1767
|
+
"path",
|
|
1768
|
+
{
|
|
1769
|
+
d: "M4 12 C 5 8, 6 8, 8 12",
|
|
1770
|
+
fill: "none",
|
|
1771
|
+
strokeWidth: "1",
|
|
1772
|
+
strokeLinecap: "round",
|
|
1773
|
+
strokeLinejoin: "round"
|
|
1774
|
+
}
|
|
1775
|
+
),
|
|
1776
|
+
/* @__PURE__ */ jsx(
|
|
1777
|
+
"path",
|
|
1778
|
+
{
|
|
1779
|
+
d: "M8 12 C 9 16, 10 16, 12 12",
|
|
1780
|
+
fill: "none",
|
|
1781
|
+
strokeWidth: "1",
|
|
1782
|
+
strokeLinecap: "round",
|
|
1783
|
+
strokeLinejoin: "round"
|
|
1784
|
+
}
|
|
1785
|
+
),
|
|
1786
|
+
/* @__PURE__ */ jsx(
|
|
1787
|
+
"path",
|
|
1788
|
+
{
|
|
1789
|
+
d: "M12 12 C 14 8, 15 8, 16 12",
|
|
1790
|
+
fill: "none",
|
|
1791
|
+
strokeWidth: "1",
|
|
1792
|
+
strokeLinecap: "round",
|
|
1793
|
+
strokeLinejoin: "round"
|
|
1794
|
+
}
|
|
1795
|
+
),
|
|
1796
|
+
/* @__PURE__ */ jsx(
|
|
1797
|
+
"path",
|
|
1798
|
+
{
|
|
1799
|
+
d: "M16 12 C 17 16, 18 16, 19 12",
|
|
1800
|
+
fill: "none",
|
|
1801
|
+
strokeWidth: "1",
|
|
1802
|
+
strokeLinecap: "round",
|
|
1803
|
+
strokeLinejoin: "round"
|
|
1804
|
+
}
|
|
1805
|
+
)
|
|
1806
|
+
] }),
|
|
1807
|
+
tablerIconProps
|
|
1808
|
+
);
|
|
1809
|
+
var strokeVariabilityVariableIcon = createIcon(
|
|
1810
|
+
/* @__PURE__ */ jsxs("g", { children: [
|
|
1811
|
+
/* @__PURE__ */ jsx(
|
|
1812
|
+
"path",
|
|
1813
|
+
{
|
|
1814
|
+
d: "M4 12 C 5 8, 6 8, 8 12",
|
|
1815
|
+
fill: "none",
|
|
1816
|
+
strokeWidth: "1.5",
|
|
1817
|
+
strokeLinecap: "round",
|
|
1818
|
+
strokeLinejoin: "round"
|
|
1819
|
+
}
|
|
1820
|
+
),
|
|
1821
|
+
/* @__PURE__ */ jsx(
|
|
1822
|
+
"path",
|
|
1823
|
+
{
|
|
1824
|
+
d: "M8 12 C 9 16, 10 16, 12 12",
|
|
1825
|
+
fill: "none",
|
|
1826
|
+
strokeWidth: "2",
|
|
1827
|
+
strokeLinecap: "round",
|
|
1828
|
+
strokeLinejoin: "round"
|
|
1829
|
+
}
|
|
1830
|
+
),
|
|
1831
|
+
/* @__PURE__ */ jsx(
|
|
1832
|
+
"path",
|
|
1833
|
+
{
|
|
1834
|
+
d: "M12 12 C 14 8, 15 8, 16 12",
|
|
1835
|
+
fill: "none",
|
|
1836
|
+
strokeWidth: "2.75",
|
|
1837
|
+
strokeLinecap: "round",
|
|
1838
|
+
strokeLinejoin: "round"
|
|
1839
|
+
}
|
|
1840
|
+
),
|
|
1841
|
+
/* @__PURE__ */ jsx(
|
|
1842
|
+
"path",
|
|
1843
|
+
{
|
|
1844
|
+
d: "M16 12 C 17 16, 18 16, 19 12",
|
|
1845
|
+
fill: "none",
|
|
1846
|
+
strokeWidth: "3.25",
|
|
1847
|
+
strokeLinecap: "round",
|
|
1848
|
+
strokeLinejoin: "round"
|
|
1849
|
+
}
|
|
1850
|
+
)
|
|
1851
|
+
] }),
|
|
1852
|
+
tablerIconProps
|
|
1853
|
+
);
|
|
1757
1854
|
var EdgeSharpIcon = createIcon(
|
|
1758
1855
|
/* @__PURE__ */ jsxs("svg", { strokeWidth: "1.5", children: [
|
|
1759
1856
|
/* @__PURE__ */ 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" }),
|
|
@@ -3691,7 +3788,7 @@ import {
|
|
|
3691
3788
|
DEFAULT_FONT_SIZE,
|
|
3692
3789
|
FONT_FAMILY as FONT_FAMILY3,
|
|
3693
3790
|
ROUNDNESS,
|
|
3694
|
-
|
|
3791
|
+
STROKE_WIDTH_KEYS,
|
|
3695
3792
|
VERTICAL_ALIGN,
|
|
3696
3793
|
KEYS as KEYS11,
|
|
3697
3794
|
randomInteger,
|
|
@@ -3699,6 +3796,7 @@ import {
|
|
|
3699
3796
|
getFontFamilyString as getFontFamilyString2,
|
|
3700
3797
|
getLineHeight,
|
|
3701
3798
|
isTransparent,
|
|
3799
|
+
getStrokeWidthByKey,
|
|
3702
3800
|
reduceToCommonValue,
|
|
3703
3801
|
invariant,
|
|
3704
3802
|
FONT_SIZES
|
|
@@ -6348,19 +6446,19 @@ var changeProperty = (elements, appState, callback, includeBoundText = false) =>
|
|
|
6348
6446
|
return element;
|
|
6349
6447
|
});
|
|
6350
6448
|
};
|
|
6351
|
-
var getFormValue = function(elements, app,
|
|
6449
|
+
var getFormValue = function(elements, app, getValue, elementPredicate, defaultValue) {
|
|
6352
6450
|
const editingTextElement = app.state.editingTextElement;
|
|
6353
6451
|
const nonDeletedElements = getNonDeletedElements4(elements);
|
|
6354
6452
|
let ret = null;
|
|
6355
6453
|
if (editingTextElement) {
|
|
6356
|
-
ret =
|
|
6454
|
+
ret = getValue(editingTextElement);
|
|
6357
6455
|
}
|
|
6358
6456
|
if (!ret) {
|
|
6359
6457
|
const hasSelection = isSomeElementSelected(nonDeletedElements, app.state);
|
|
6360
6458
|
if (hasSelection) {
|
|
6361
6459
|
const selectedElements = app.scene.getSelectedElements(app.state);
|
|
6362
6460
|
const targetElements = elementPredicate === true ? selectedElements : selectedElements.filter((el) => elementPredicate(el));
|
|
6363
|
-
ret = reduceToCommonValue(targetElements,
|
|
6461
|
+
ret = reduceToCommonValue(targetElements, getValue) ?? (typeof defaultValue === "function" ? defaultValue(true) : defaultValue);
|
|
6364
6462
|
} else {
|
|
6365
6463
|
ret = typeof defaultValue === "function" ? defaultValue(false) : defaultValue;
|
|
6366
6464
|
}
|
|
@@ -6619,20 +6717,29 @@ var actionChangeFillStyle = register({
|
|
|
6619
6717
|
] });
|
|
6620
6718
|
}
|
|
6621
6719
|
});
|
|
6720
|
+
var getStrokeWidthKeyForElement = (element) => {
|
|
6721
|
+
return STROKE_WIDTH_KEYS.find(
|
|
6722
|
+
(key) => getStrokeWidthByKey(element.type, key) === element.strokeWidth
|
|
6723
|
+
) ?? null;
|
|
6724
|
+
};
|
|
6725
|
+
var getStrokeWidthForElement = (element, strokeWidthKey) => {
|
|
6726
|
+
return getStrokeWidthByKey(element.type, strokeWidthKey);
|
|
6727
|
+
};
|
|
6622
6728
|
var actionChangeStrokeWidth = register({
|
|
6623
6729
|
name: "changeStrokeWidth",
|
|
6624
6730
|
label: "labels.strokeWidth",
|
|
6625
6731
|
trackEvent: false,
|
|
6626
6732
|
perform: (elements, appState, value) => {
|
|
6733
|
+
invariant(value, "actionChangeStrokeWidth: value must be defined");
|
|
6627
6734
|
return {
|
|
6628
6735
|
elements: changeProperty(
|
|
6629
6736
|
elements,
|
|
6630
6737
|
appState,
|
|
6631
6738
|
(el) => newElementWith2(el, {
|
|
6632
|
-
strokeWidth: value
|
|
6739
|
+
strokeWidth: getStrokeWidthForElement(el, value)
|
|
6633
6740
|
})
|
|
6634
6741
|
),
|
|
6635
|
-
appState: { ...appState,
|
|
6742
|
+
appState: { ...appState, currentItemStrokeWidthKey: value },
|
|
6636
6743
|
captureUpdate: CaptureUpdateAction5.IMMEDIATELY
|
|
6637
6744
|
};
|
|
6638
6745
|
},
|
|
@@ -6644,30 +6751,30 @@ var actionChangeStrokeWidth = register({
|
|
|
6644
6751
|
group: "stroke-width",
|
|
6645
6752
|
options: [
|
|
6646
6753
|
{
|
|
6647
|
-
value:
|
|
6754
|
+
value: "thin",
|
|
6648
6755
|
text: t("labels.thin"),
|
|
6649
6756
|
icon: StrokeWidthBaseIcon,
|
|
6650
6757
|
testId: "strokeWidth-thin"
|
|
6651
6758
|
},
|
|
6652
6759
|
{
|
|
6653
|
-
value:
|
|
6654
|
-
text: t("labels.
|
|
6760
|
+
value: "medium",
|
|
6761
|
+
text: t("labels.medium"),
|
|
6655
6762
|
icon: StrokeWidthBoldIcon,
|
|
6656
|
-
testId: "strokeWidth-
|
|
6763
|
+
testId: "strokeWidth-medium"
|
|
6657
6764
|
},
|
|
6658
6765
|
{
|
|
6659
|
-
value:
|
|
6660
|
-
text: t("labels.
|
|
6766
|
+
value: "bold",
|
|
6767
|
+
text: t("labels.bold"),
|
|
6661
6768
|
icon: StrokeWidthExtraBoldIcon,
|
|
6662
|
-
testId: "strokeWidth-
|
|
6769
|
+
testId: "strokeWidth-bold"
|
|
6663
6770
|
}
|
|
6664
6771
|
],
|
|
6665
6772
|
value: getFormValue(
|
|
6666
6773
|
elements,
|
|
6667
6774
|
app,
|
|
6668
|
-
|
|
6775
|
+
getStrokeWidthKeyForElement,
|
|
6669
6776
|
(element) => element.hasOwnProperty("strokeWidth"),
|
|
6670
|
-
(hasSelection) => hasSelection ? null : appState.
|
|
6777
|
+
(hasSelection) => hasSelection ? null : appState.currentItemStrokeWidthKey
|
|
6671
6778
|
),
|
|
6672
6779
|
onChange: (value) => updateData(value)
|
|
6673
6780
|
}
|
|
@@ -6727,6 +6834,74 @@ var actionChangeSloppiness = register({
|
|
|
6727
6834
|
) })
|
|
6728
6835
|
] })
|
|
6729
6836
|
});
|
|
6837
|
+
var actionChangeFreedrawMode = register({
|
|
6838
|
+
name: "changeFreedrawMode",
|
|
6839
|
+
label: "labels.pressure",
|
|
6840
|
+
trackEvent: false,
|
|
6841
|
+
perform: (elements, appState, value) => {
|
|
6842
|
+
const variability = value || "constant";
|
|
6843
|
+
return {
|
|
6844
|
+
elements: changeProperty(elements, appState, (el) => {
|
|
6845
|
+
if (el.type !== "freedraw") {
|
|
6846
|
+
return el;
|
|
6847
|
+
}
|
|
6848
|
+
return newElementWith2(el, {
|
|
6849
|
+
strokeOptions: {
|
|
6850
|
+
...el.strokeOptions,
|
|
6851
|
+
variability
|
|
6852
|
+
}
|
|
6853
|
+
});
|
|
6854
|
+
}),
|
|
6855
|
+
appState: { ...appState, currentItemStrokeVariability: variability },
|
|
6856
|
+
captureUpdate: CaptureUpdateAction5.IMMEDIATELY
|
|
6857
|
+
};
|
|
6858
|
+
},
|
|
6859
|
+
PanelComponent: ({ elements, appState, updateData, app, data }) => {
|
|
6860
|
+
const strokeVariability = getFormValue(
|
|
6861
|
+
elements,
|
|
6862
|
+
app,
|
|
6863
|
+
(element) => element.strokeOptions?.variability,
|
|
6864
|
+
(element) => element.type === "freedraw",
|
|
6865
|
+
(hasSelection) => hasSelection ? null : appState.currentItemStrokeVariability
|
|
6866
|
+
) ?? appState.currentItemStrokeVariability;
|
|
6867
|
+
if (data?.cycle) {
|
|
6868
|
+
const isVariable = strokeVariability === "variable";
|
|
6869
|
+
return /* @__PURE__ */ jsx34(
|
|
6870
|
+
ToolButton,
|
|
6871
|
+
{
|
|
6872
|
+
type: "button",
|
|
6873
|
+
icon: isVariable ? strokeVariabilityVariableIcon : strokeVariabilityConstantIcon,
|
|
6874
|
+
title: t("labels.pressure"),
|
|
6875
|
+
"aria-label": t("labels.pressure"),
|
|
6876
|
+
onClick: () => updateData(isVariable ? "constant" : "variable")
|
|
6877
|
+
}
|
|
6878
|
+
);
|
|
6879
|
+
}
|
|
6880
|
+
return /* @__PURE__ */ jsxs20("fieldset", { children: [
|
|
6881
|
+
/* @__PURE__ */ jsx34("legend", { children: t("labels.pressure") }),
|
|
6882
|
+
/* @__PURE__ */ jsx34("div", { className: "buttonList", children: /* @__PURE__ */ jsx34(
|
|
6883
|
+
RadioSelection,
|
|
6884
|
+
{
|
|
6885
|
+
group: "strokeOptions.variability",
|
|
6886
|
+
options: [
|
|
6887
|
+
{
|
|
6888
|
+
value: "constant",
|
|
6889
|
+
text: t("labels.pressure_constant"),
|
|
6890
|
+
icon: strokeVariabilityConstantIcon
|
|
6891
|
+
},
|
|
6892
|
+
{
|
|
6893
|
+
value: "variable",
|
|
6894
|
+
text: t("labels.pressure_variable"),
|
|
6895
|
+
icon: strokeVariabilityVariableIcon
|
|
6896
|
+
}
|
|
6897
|
+
],
|
|
6898
|
+
value: strokeVariability,
|
|
6899
|
+
onChange: (value) => updateData(value)
|
|
6900
|
+
}
|
|
6901
|
+
) })
|
|
6902
|
+
] });
|
|
6903
|
+
}
|
|
6904
|
+
});
|
|
6730
6905
|
var actionChangeStrokeStyle = register({
|
|
6731
6906
|
name: "changeStrokeStyle",
|
|
6732
6907
|
label: "labels.strokeStyle",
|
|
@@ -8567,6 +8742,7 @@ var actionFinalize = register({
|
|
|
8567
8742
|
label: "",
|
|
8568
8743
|
trackEvent: false,
|
|
8569
8744
|
perform: (elements, appState, data, app) => {
|
|
8745
|
+
let shouldCommit = true;
|
|
8570
8746
|
let newElements = elements;
|
|
8571
8747
|
const { interactiveCanvas, focusContainer, scene } = app;
|
|
8572
8748
|
const elementsMap = scene.getNonDeletedElementsMap();
|
|
@@ -8688,9 +8864,39 @@ var actionFinalize = register({
|
|
|
8688
8864
|
const { points } = element;
|
|
8689
8865
|
const { lastCommittedPoint } = appState.selectedLinearElement;
|
|
8690
8866
|
if (!lastCommittedPoint || points[points.length - 1] !== lastCommittedPoint) {
|
|
8867
|
+
shouldCommit = false;
|
|
8691
8868
|
scene.mutateElement(element, {
|
|
8692
8869
|
points: element.points.slice(0, -1)
|
|
8693
8870
|
});
|
|
8871
|
+
if (isBindingElement(element) && element.endBinding && // after slicing the trailing point a <2-point arrow may be left
|
|
8872
|
+
element.points.length > 1) {
|
|
8873
|
+
const newArrow = !!appState.newElement;
|
|
8874
|
+
const draggedPoints = /* @__PURE__ */ new Map([
|
|
8875
|
+
[
|
|
8876
|
+
element.points.length - 1,
|
|
8877
|
+
{
|
|
8878
|
+
point: element.points[element.points.length - 1],
|
|
8879
|
+
isDragging: false
|
|
8880
|
+
}
|
|
8881
|
+
]
|
|
8882
|
+
]);
|
|
8883
|
+
const globalPoint = LinearElementEditor5.getPointAtIndexGlobalCoordinates(
|
|
8884
|
+
element,
|
|
8885
|
+
-1,
|
|
8886
|
+
elementsMap
|
|
8887
|
+
);
|
|
8888
|
+
bindOrUnbindBindingElement(
|
|
8889
|
+
element,
|
|
8890
|
+
draggedPoints,
|
|
8891
|
+
globalPoint[0],
|
|
8892
|
+
globalPoint[1],
|
|
8893
|
+
scene,
|
|
8894
|
+
appState,
|
|
8895
|
+
{
|
|
8896
|
+
newArrow
|
|
8897
|
+
}
|
|
8898
|
+
);
|
|
8899
|
+
}
|
|
8694
8900
|
}
|
|
8695
8901
|
}
|
|
8696
8902
|
if (element && isInvisiblySmallElement(element)) {
|
|
@@ -8773,7 +8979,7 @@ var actionFinalize = register({
|
|
|
8773
8979
|
selectedLinearElement
|
|
8774
8980
|
},
|
|
8775
8981
|
// TODO: #7348 we should not capture everything, but if we don't, it leads to incosistencies -> revisit
|
|
8776
|
-
captureUpdate: CaptureUpdateAction8.IMMEDIATELY
|
|
8982
|
+
captureUpdate: shouldCommit ? CaptureUpdateAction8.IMMEDIATELY : CaptureUpdateAction8.NEVER
|
|
8777
8983
|
};
|
|
8778
8984
|
},
|
|
8779
8985
|
keyTest: (event, appState) => event.key === KEYS13.ESCAPE && appState.selectedLinearElement?.isEditing || (event.key === KEYS13.ESCAPE || event.key === KEYS13.ENTER) && appState.multiElement !== null,
|
|
@@ -9352,6 +9558,133 @@ var getDataTransferFiles = function() {
|
|
|
9352
9558
|
(item) => item.kind === "file"
|
|
9353
9559
|
);
|
|
9354
9560
|
};
|
|
9561
|
+
var captureDragEventData = (event) => {
|
|
9562
|
+
const dataTransfer = isClipboardEvent(event) ? event.clipboardData : event.dataTransfer;
|
|
9563
|
+
const types = Array.from(dataTransfer?.types ?? []);
|
|
9564
|
+
const dataTypes = Array.from(
|
|
9565
|
+
/* @__PURE__ */ new Set([
|
|
9566
|
+
...types.filter((type) => type !== "Files"),
|
|
9567
|
+
MIME_TYPES2.text,
|
|
9568
|
+
MIME_TYPES2.html,
|
|
9569
|
+
"text/uri-list",
|
|
9570
|
+
"public.url",
|
|
9571
|
+
"public.plain-text",
|
|
9572
|
+
"text/x-moz-url"
|
|
9573
|
+
])
|
|
9574
|
+
);
|
|
9575
|
+
const data = {};
|
|
9576
|
+
for (const type of dataTypes) {
|
|
9577
|
+
try {
|
|
9578
|
+
const value = dataTransfer?.getData(type);
|
|
9579
|
+
if (value) {
|
|
9580
|
+
data[type] = value;
|
|
9581
|
+
}
|
|
9582
|
+
} catch {
|
|
9583
|
+
}
|
|
9584
|
+
}
|
|
9585
|
+
return {
|
|
9586
|
+
items: Array.from(dataTransfer?.items ?? []).map((item) => ({
|
|
9587
|
+
kind: item.kind,
|
|
9588
|
+
type: item.type
|
|
9589
|
+
})),
|
|
9590
|
+
files: Array.from(dataTransfer?.files ?? []).map((file2) => ({
|
|
9591
|
+
name: file2.name,
|
|
9592
|
+
type: file2.type,
|
|
9593
|
+
size: file2.size,
|
|
9594
|
+
lastModified: file2.lastModified
|
|
9595
|
+
})),
|
|
9596
|
+
types,
|
|
9597
|
+
data
|
|
9598
|
+
};
|
|
9599
|
+
};
|
|
9600
|
+
var getParsedRawDragItems = (dataTransferList) => dataTransferList.map((item) => {
|
|
9601
|
+
if (item.kind === "string") {
|
|
9602
|
+
return {
|
|
9603
|
+
kind: item.kind,
|
|
9604
|
+
type: item.type,
|
|
9605
|
+
value: item.value
|
|
9606
|
+
};
|
|
9607
|
+
}
|
|
9608
|
+
return {
|
|
9609
|
+
kind: item.kind,
|
|
9610
|
+
type: item.type,
|
|
9611
|
+
file: {
|
|
9612
|
+
name: item.file.name,
|
|
9613
|
+
type: item.file.type,
|
|
9614
|
+
size: item.file.size,
|
|
9615
|
+
lastModified: item.file.lastModified
|
|
9616
|
+
}
|
|
9617
|
+
};
|
|
9618
|
+
});
|
|
9619
|
+
var parseDragImageMetadata = (dataTransferList, imageCount, dragDataSnapshot) => {
|
|
9620
|
+
const htmlImageSources = [];
|
|
9621
|
+
const textImageSources = [];
|
|
9622
|
+
const imageAlts = [];
|
|
9623
|
+
const pushUnique = (values, value) => {
|
|
9624
|
+
const trimmedValue = value?.trim();
|
|
9625
|
+
if (trimmedValue && !values.includes(trimmedValue)) {
|
|
9626
|
+
values.push(trimmedValue);
|
|
9627
|
+
}
|
|
9628
|
+
};
|
|
9629
|
+
const pushUriList = (values, value) => {
|
|
9630
|
+
value.split(/\r?\n/).map((line) => line.trim()).filter((line) => line && !line.startsWith("#")).forEach((line) => pushUnique(values, line));
|
|
9631
|
+
};
|
|
9632
|
+
dataTransferList.forEach((item) => {
|
|
9633
|
+
if (item.kind !== "string") {
|
|
9634
|
+
return;
|
|
9635
|
+
}
|
|
9636
|
+
if (item.type === MIME_TYPES2.html) {
|
|
9637
|
+
try {
|
|
9638
|
+
const doc = new DOMParser().parseFromString(item.value, MIME_TYPES2.html);
|
|
9639
|
+
for (const img of Array.from(doc.body.querySelectorAll("img"))) {
|
|
9640
|
+
pushUnique(htmlImageSources, img.getAttribute("src"));
|
|
9641
|
+
pushUnique(imageAlts, img.getAttribute("alt"));
|
|
9642
|
+
}
|
|
9643
|
+
} catch {
|
|
9644
|
+
}
|
|
9645
|
+
} else if (item.type === MIME_TYPES2.text) {
|
|
9646
|
+
pushUnique(textImageSources, item.value);
|
|
9647
|
+
} else if (item.type === "text/uri-list") {
|
|
9648
|
+
pushUriList(textImageSources, item.value);
|
|
9649
|
+
}
|
|
9650
|
+
});
|
|
9651
|
+
const imageSources = [
|
|
9652
|
+
...htmlImageSources,
|
|
9653
|
+
...textImageSources.filter((src) => !htmlImageSources.includes(src))
|
|
9654
|
+
];
|
|
9655
|
+
const imageDetails = Array.from(
|
|
9656
|
+
{ length: imageCount },
|
|
9657
|
+
() => ({})
|
|
9658
|
+
);
|
|
9659
|
+
const rawDragData = {
|
|
9660
|
+
...dragDataSnapshot ?? {
|
|
9661
|
+
items: [],
|
|
9662
|
+
files: [],
|
|
9663
|
+
types: [],
|
|
9664
|
+
data: {}
|
|
9665
|
+
},
|
|
9666
|
+
parsedItems: getParsedRawDragItems(dataTransferList)
|
|
9667
|
+
};
|
|
9668
|
+
imageDetails.forEach((detail, index) => {
|
|
9669
|
+
const source = imageSources[index];
|
|
9670
|
+
const alt = imageAlts[index];
|
|
9671
|
+
if (source) {
|
|
9672
|
+
detail.src = source;
|
|
9673
|
+
}
|
|
9674
|
+
if (alt) {
|
|
9675
|
+
detail.alt = alt;
|
|
9676
|
+
}
|
|
9677
|
+
detail.rawDragData = rawDragData;
|
|
9678
|
+
});
|
|
9679
|
+
const additionalUrls = imageSources.slice(imageDetails.length);
|
|
9680
|
+
const firstImageDetails = imageDetails[0];
|
|
9681
|
+
if (firstImageDetails && additionalUrls.length > 0) {
|
|
9682
|
+
additionalUrls.forEach((url, index) => {
|
|
9683
|
+
firstImageDetails[`additionalUrl${index + 1}`] = url;
|
|
9684
|
+
});
|
|
9685
|
+
}
|
|
9686
|
+
return imageDetails;
|
|
9687
|
+
};
|
|
9355
9688
|
var parseDataTransferEventMimeTypes = (event) => {
|
|
9356
9689
|
let items = void 0;
|
|
9357
9690
|
if (isClipboardEvent(event)) {
|
|
@@ -9617,7 +9950,7 @@ var exportCanvas = async (type, elements, appState, files, {
|
|
|
9617
9950
|
let blob = canvasToBlob(tempCanvas);
|
|
9618
9951
|
if (appState.exportEmbedScene) {
|
|
9619
9952
|
blob = blob.then(
|
|
9620
|
-
(blob2) => import("./data/image-
|
|
9953
|
+
(blob2) => import("./data/image-ZYGVHYLC.js").then(
|
|
9621
9954
|
({ encodePngMetadata: encodePngMetadata2 }) => encodePngMetadata2({
|
|
9622
9955
|
blob: blob2,
|
|
9623
9956
|
metadata: serializeAsJSON(elements, appState, files, "local")
|
|
@@ -11812,7 +12145,8 @@ import {
|
|
|
11812
12145
|
TEXT_ALIGN,
|
|
11813
12146
|
VERTICAL_ALIGN as VERTICAL_ALIGN2,
|
|
11814
12147
|
arrayToMap as arrayToMap13,
|
|
11815
|
-
getFontString
|
|
12148
|
+
getFontString,
|
|
12149
|
+
getStrokeWidthByKey as getStrokeWidthByKey2
|
|
11816
12150
|
} from "@excalidraw/common";
|
|
11817
12151
|
import {
|
|
11818
12152
|
getOriginalContainerHeightFromCache,
|
|
@@ -11999,7 +12333,10 @@ var actionWrapTextInContainer = register({
|
|
|
11999
12333
|
fillStyle: appState.currentItemFillStyle,
|
|
12000
12334
|
strokeColor: appState.currentItemStrokeColor,
|
|
12001
12335
|
roughness: appState.currentItemRoughness,
|
|
12002
|
-
strokeWidth:
|
|
12336
|
+
strokeWidth: getStrokeWidthByKey2(
|
|
12337
|
+
"rectangle",
|
|
12338
|
+
appState.currentItemStrokeWidthKey
|
|
12339
|
+
),
|
|
12003
12340
|
strokeStyle: appState.currentItemStrokeStyle,
|
|
12004
12341
|
roundness: appState.currentItemRoundness === "round" ? {
|
|
12005
12342
|
type: isUsingAdaptiveRadius2("rectangle") ? ROUNDNESS2.ADAPTIVE_RADIUS : ROUNDNESS2.PROPORTIONAL_RADIUS
|
|
@@ -12647,6 +12984,355 @@ import {
|
|
|
12647
12984
|
import { simplify } from "points-on-curve";
|
|
12648
12985
|
import { getStroke } from "perfect-freehand";
|
|
12649
12986
|
|
|
12987
|
+
// ../laser-pointer/src/math.ts
|
|
12988
|
+
function add([ax, ay, ar], [bx, by, br]) {
|
|
12989
|
+
return [ax + bx, ay + by, ar + br];
|
|
12990
|
+
}
|
|
12991
|
+
function sub([ax, ay, ar], [bx, by, br]) {
|
|
12992
|
+
return [ax - bx, ay - by, ar - br];
|
|
12993
|
+
}
|
|
12994
|
+
function smul([x, y, r], s) {
|
|
12995
|
+
return [x * s, y * s, r * s];
|
|
12996
|
+
}
|
|
12997
|
+
function norm([x, y, r]) {
|
|
12998
|
+
return [x / Math.sqrt(x ** 2 + y ** 2), y / Math.sqrt(x ** 2 + y ** 2), r];
|
|
12999
|
+
}
|
|
13000
|
+
function rot([x, y, r], rad) {
|
|
13001
|
+
return [
|
|
13002
|
+
Math.cos(rad) * x - Math.sin(rad) * y,
|
|
13003
|
+
Math.sin(rad) * x + Math.cos(rad) * y,
|
|
13004
|
+
r
|
|
13005
|
+
];
|
|
13006
|
+
}
|
|
13007
|
+
function plerp(a, b, t2) {
|
|
13008
|
+
return add(a, smul(sub(b, a), t2));
|
|
13009
|
+
}
|
|
13010
|
+
function angle(p, p1, p2) {
|
|
13011
|
+
return Math.atan2(p2[1] - p[1], p2[0] - p[0]) - Math.atan2(p1[1] - p[1], p1[0] - p[0]);
|
|
13012
|
+
}
|
|
13013
|
+
function normAngle(a) {
|
|
13014
|
+
return Math.atan2(Math.sin(a), Math.cos(a));
|
|
13015
|
+
}
|
|
13016
|
+
function mag([x, y]) {
|
|
13017
|
+
return Math.sqrt(x ** 2 + y ** 2);
|
|
13018
|
+
}
|
|
13019
|
+
function dist([ax, ay], [bx, by]) {
|
|
13020
|
+
return Math.sqrt((bx - ax) ** 2 + (by - ay) ** 2);
|
|
13021
|
+
}
|
|
13022
|
+
function runLength(ps) {
|
|
13023
|
+
if (ps.length < 2) {
|
|
13024
|
+
return 0;
|
|
13025
|
+
}
|
|
13026
|
+
let len = 0;
|
|
13027
|
+
for (let i = 1; i <= ps.length - 1; i++) {
|
|
13028
|
+
len += dist(ps[i - 1], ps[i]);
|
|
13029
|
+
}
|
|
13030
|
+
len += dist(ps[ps.length - 2], ps[ps.length - 1]);
|
|
13031
|
+
return len;
|
|
13032
|
+
}
|
|
13033
|
+
var clamp2 = (v, min, max) => Math.max(min, Math.min(max, v));
|
|
13034
|
+
function distancePointToSegment(p3, p1, p2) {
|
|
13035
|
+
const sMag = dist(p1, p2);
|
|
13036
|
+
if (sMag === 0) {
|
|
13037
|
+
return dist(p3, p1);
|
|
13038
|
+
}
|
|
13039
|
+
const u = clamp2(
|
|
13040
|
+
((p3[0] - p1[0]) * (p2[0] - p1[0]) + (p3[1] - p1[1]) * (p2[1] - p1[1])) / sMag ** 2,
|
|
13041
|
+
0,
|
|
13042
|
+
1
|
|
13043
|
+
);
|
|
13044
|
+
const pi = [
|
|
13045
|
+
p1[0] + u * (p2[0] - p1[0]),
|
|
13046
|
+
p1[1] + u * (p2[1] - p1[1]),
|
|
13047
|
+
p3[2]
|
|
13048
|
+
];
|
|
13049
|
+
return dist(pi, p3);
|
|
13050
|
+
}
|
|
13051
|
+
|
|
13052
|
+
// ../laser-pointer/src/simplify.ts
|
|
13053
|
+
function douglasPeucker(points, epsilon) {
|
|
13054
|
+
if (epsilon === 0) {
|
|
13055
|
+
return points;
|
|
13056
|
+
}
|
|
13057
|
+
if (points.length <= 2) {
|
|
13058
|
+
return points;
|
|
13059
|
+
}
|
|
13060
|
+
const first = points[0];
|
|
13061
|
+
const last = points[points.length - 1];
|
|
13062
|
+
const [maxDistance, maxIndex] = points.reduce(
|
|
13063
|
+
([maxDistance2, maxIndex2], point, index) => {
|
|
13064
|
+
const distance3 = distancePointToSegment(point, first, last);
|
|
13065
|
+
return distance3 > maxDistance2 ? [distance3, index] : [maxDistance2, maxIndex2];
|
|
13066
|
+
},
|
|
13067
|
+
[0, -1]
|
|
13068
|
+
);
|
|
13069
|
+
if (maxDistance >= epsilon) {
|
|
13070
|
+
const maxIndexPoint = points[maxIndex];
|
|
13071
|
+
return [
|
|
13072
|
+
...douglasPeucker(
|
|
13073
|
+
[first, ...points.slice(1, maxIndex), maxIndexPoint],
|
|
13074
|
+
epsilon
|
|
13075
|
+
).slice(0, -1),
|
|
13076
|
+
maxIndexPoint,
|
|
13077
|
+
...douglasPeucker(
|
|
13078
|
+
[maxIndexPoint, ...points.slice(maxIndex, -1), last],
|
|
13079
|
+
epsilon
|
|
13080
|
+
).slice(1)
|
|
13081
|
+
];
|
|
13082
|
+
}
|
|
13083
|
+
return [first, last];
|
|
13084
|
+
}
|
|
13085
|
+
|
|
13086
|
+
// ../laser-pointer/src/state.ts
|
|
13087
|
+
var _LaserPointer = class _LaserPointer {
|
|
13088
|
+
constructor(options) {
|
|
13089
|
+
__publicField(this, "options");
|
|
13090
|
+
__publicField(this, "originalPoints", []);
|
|
13091
|
+
__publicField(this, "stablePoints", []);
|
|
13092
|
+
__publicField(this, "tailPoints", []);
|
|
13093
|
+
__publicField(this, "isFresh", true);
|
|
13094
|
+
this.options = Object.assign({}, _LaserPointer.defaults, options);
|
|
13095
|
+
}
|
|
13096
|
+
get lastPoint() {
|
|
13097
|
+
return this.tailPoints[this.tailPoints.length - 1] ?? this.stablePoints[this.stablePoints.length - 1];
|
|
13098
|
+
}
|
|
13099
|
+
addPoint(point) {
|
|
13100
|
+
const lastPoint = this.originalPoints[this.originalPoints.length - 1];
|
|
13101
|
+
if (lastPoint && lastPoint[0] === point[0] && lastPoint[1] === point[1]) {
|
|
13102
|
+
return;
|
|
13103
|
+
}
|
|
13104
|
+
this.originalPoints.push(point);
|
|
13105
|
+
if (this.isFresh) {
|
|
13106
|
+
this.isFresh = false;
|
|
13107
|
+
this.stablePoints.push(point);
|
|
13108
|
+
return;
|
|
13109
|
+
}
|
|
13110
|
+
if (this.options.streamline > 0) {
|
|
13111
|
+
point = plerp(this.lastPoint, point, 1 - this.options.streamline);
|
|
13112
|
+
}
|
|
13113
|
+
this.tailPoints.push(point);
|
|
13114
|
+
if (runLength(this.tailPoints) > _LaserPointer.constants.maxTailLength) {
|
|
13115
|
+
this.stabilizeTail();
|
|
13116
|
+
}
|
|
13117
|
+
}
|
|
13118
|
+
close() {
|
|
13119
|
+
this.stabilizeTail();
|
|
13120
|
+
}
|
|
13121
|
+
stabilizeTail() {
|
|
13122
|
+
if (this.options.simplify > 0 && this.options.simplifyPhase === "tail") {
|
|
13123
|
+
throw new Error("Not implemented yet");
|
|
13124
|
+
} else {
|
|
13125
|
+
this.stablePoints.push(...this.tailPoints);
|
|
13126
|
+
this.tailPoints = [];
|
|
13127
|
+
}
|
|
13128
|
+
}
|
|
13129
|
+
getSize(sizeOverride, pressure, index, totalLength, runningLength) {
|
|
13130
|
+
return (sizeOverride ?? this.options.size) * this.options.sizeMapping({
|
|
13131
|
+
pressure,
|
|
13132
|
+
runningLength,
|
|
13133
|
+
currentIndex: index,
|
|
13134
|
+
totalLength
|
|
13135
|
+
});
|
|
13136
|
+
}
|
|
13137
|
+
getStrokeOutline(sizeOverride) {
|
|
13138
|
+
if (this.isFresh) {
|
|
13139
|
+
return [];
|
|
13140
|
+
}
|
|
13141
|
+
let points = [...this.stablePoints, ...this.tailPoints];
|
|
13142
|
+
if (this.options.simplify > 0 && this.options.simplifyPhase === "input") {
|
|
13143
|
+
points = douglasPeucker(points, this.options.simplify);
|
|
13144
|
+
}
|
|
13145
|
+
const len = points.length;
|
|
13146
|
+
if (len === 0) {
|
|
13147
|
+
return [];
|
|
13148
|
+
}
|
|
13149
|
+
if (len === 1) {
|
|
13150
|
+
const c = points[0];
|
|
13151
|
+
const size = this.getSize(sizeOverride, c[2], 0, len, 0);
|
|
13152
|
+
if (size < 0.5) {
|
|
13153
|
+
return [];
|
|
13154
|
+
}
|
|
13155
|
+
const ps = [];
|
|
13156
|
+
for (let theta = 0; theta <= Math.PI * 2; theta += Math.PI / 16) {
|
|
13157
|
+
ps.push(add(c, smul(rot([1, 0, 0], theta), size)));
|
|
13158
|
+
}
|
|
13159
|
+
ps.push(
|
|
13160
|
+
add(
|
|
13161
|
+
c,
|
|
13162
|
+
smul(
|
|
13163
|
+
[1, 0, 0],
|
|
13164
|
+
this.getSize(sizeOverride, c[2], 0, len, 0)
|
|
13165
|
+
)
|
|
13166
|
+
)
|
|
13167
|
+
);
|
|
13168
|
+
return ps;
|
|
13169
|
+
}
|
|
13170
|
+
if (len === 2) {
|
|
13171
|
+
const c = points[0];
|
|
13172
|
+
const n = points[1];
|
|
13173
|
+
const cSize = this.getSize(sizeOverride, c[2], 0, len, 0);
|
|
13174
|
+
const nSize = this.getSize(sizeOverride, n[2], 0, len, 0);
|
|
13175
|
+
if (cSize < 0.5 || nSize < 0.5) {
|
|
13176
|
+
return [];
|
|
13177
|
+
}
|
|
13178
|
+
const ps = [];
|
|
13179
|
+
const pAngle = angle(c, [c[0], c[1] - 100, c[2]], n);
|
|
13180
|
+
for (let theta = pAngle; theta <= Math.PI + pAngle; theta += Math.PI / 16) {
|
|
13181
|
+
ps.push(add(c, smul(rot([1, 0, 0], theta), cSize)));
|
|
13182
|
+
}
|
|
13183
|
+
for (let theta = Math.PI + pAngle; theta <= Math.PI * 2 + pAngle; theta += Math.PI / 16) {
|
|
13184
|
+
ps.push(add(n, smul(rot([1, 0, 0], theta), nSize)));
|
|
13185
|
+
}
|
|
13186
|
+
ps.push(ps[0]);
|
|
13187
|
+
return ps;
|
|
13188
|
+
}
|
|
13189
|
+
const forwardPoints = [];
|
|
13190
|
+
const backwardPoints = [];
|
|
13191
|
+
let speed = 0;
|
|
13192
|
+
let prevSpeed = 0;
|
|
13193
|
+
let visibleStartIndex = 0;
|
|
13194
|
+
let runningLength = 0;
|
|
13195
|
+
for (let i = 1; i < len - 1; i++) {
|
|
13196
|
+
const p = points[i - 1];
|
|
13197
|
+
const c = points[i];
|
|
13198
|
+
const n = points[i + 1];
|
|
13199
|
+
const pressure = c[2];
|
|
13200
|
+
const d = dist(p, c);
|
|
13201
|
+
runningLength += d;
|
|
13202
|
+
speed = prevSpeed + (d - prevSpeed) * 0.2;
|
|
13203
|
+
const cSize = this.getSize(sizeOverride, pressure, i, len, runningLength);
|
|
13204
|
+
if (cSize === 0) {
|
|
13205
|
+
visibleStartIndex = i + 1;
|
|
13206
|
+
continue;
|
|
13207
|
+
}
|
|
13208
|
+
const dirPC = norm(sub(p, c));
|
|
13209
|
+
const dirNC = norm(sub(n, c));
|
|
13210
|
+
const p1dirPC = rot(dirPC, Math.PI / 2);
|
|
13211
|
+
const p2dirPC = rot(dirPC, -Math.PI / 2);
|
|
13212
|
+
const p1dirNC = rot(dirNC, Math.PI / 2);
|
|
13213
|
+
const p2dirNC = rot(dirNC, -Math.PI / 2);
|
|
13214
|
+
const p1PC = add(c, smul(p1dirPC, cSize));
|
|
13215
|
+
const p2PC = add(c, smul(p2dirPC, cSize));
|
|
13216
|
+
const p1NC = add(c, smul(p1dirNC, cSize));
|
|
13217
|
+
const p2NC = add(c, smul(p2dirNC, cSize));
|
|
13218
|
+
const ftdir = add(p1dirPC, p2dirNC);
|
|
13219
|
+
const btdir = add(p2dirPC, p1dirNC);
|
|
13220
|
+
const paPC = add(
|
|
13221
|
+
c,
|
|
13222
|
+
smul(mag(ftdir) === 0 ? dirPC : norm(ftdir), cSize)
|
|
13223
|
+
);
|
|
13224
|
+
const paNC = add(
|
|
13225
|
+
c,
|
|
13226
|
+
smul(mag(btdir) === 0 ? dirNC : norm(btdir), cSize)
|
|
13227
|
+
);
|
|
13228
|
+
const cAngle = normAngle(angle(c, p, n));
|
|
13229
|
+
const D_ANGLE = _LaserPointer.constants.cornerDetectionMaxAngle / 180 * Math.PI * _LaserPointer.constants.cornerDetectionVariance(speed);
|
|
13230
|
+
if (Math.abs(cAngle) < D_ANGLE) {
|
|
13231
|
+
const tAngle = Math.abs(normAngle(Math.PI - cAngle));
|
|
13232
|
+
if (tAngle === 0) {
|
|
13233
|
+
continue;
|
|
13234
|
+
}
|
|
13235
|
+
if (cAngle < 0) {
|
|
13236
|
+
backwardPoints.push(p2PC, paNC);
|
|
13237
|
+
for (let theta = 0; theta <= tAngle; theta += tAngle / 4) {
|
|
13238
|
+
forwardPoints.push(add(c, rot(smul(p1dirPC, cSize), theta)));
|
|
13239
|
+
}
|
|
13240
|
+
for (let theta = tAngle; theta >= 0; theta -= tAngle / 4) {
|
|
13241
|
+
backwardPoints.push(add(c, rot(smul(p1dirPC, cSize), theta)));
|
|
13242
|
+
}
|
|
13243
|
+
backwardPoints.push(paNC, p1NC);
|
|
13244
|
+
} else {
|
|
13245
|
+
forwardPoints.push(p1PC, paPC);
|
|
13246
|
+
for (let theta = 0; theta <= tAngle; theta += tAngle / 4) {
|
|
13247
|
+
backwardPoints.push(
|
|
13248
|
+
add(c, rot(smul(p1dirPC, -cSize), -theta))
|
|
13249
|
+
);
|
|
13250
|
+
}
|
|
13251
|
+
for (let theta = tAngle; theta >= 0; theta -= tAngle / 4) {
|
|
13252
|
+
forwardPoints.push(
|
|
13253
|
+
add(c, rot(smul(p1dirPC, -cSize), -theta))
|
|
13254
|
+
);
|
|
13255
|
+
}
|
|
13256
|
+
forwardPoints.push(paPC, p2NC);
|
|
13257
|
+
}
|
|
13258
|
+
} else {
|
|
13259
|
+
forwardPoints.push(paPC);
|
|
13260
|
+
backwardPoints.push(paNC);
|
|
13261
|
+
}
|
|
13262
|
+
prevSpeed = speed;
|
|
13263
|
+
}
|
|
13264
|
+
if (visibleStartIndex >= len - 2) {
|
|
13265
|
+
if (this.options.keepHead) {
|
|
13266
|
+
const c = points[len - 1];
|
|
13267
|
+
const ps = [];
|
|
13268
|
+
for (let theta = 0; theta <= Math.PI * 2; theta += Math.PI / 16) {
|
|
13269
|
+
ps.push(
|
|
13270
|
+
add(
|
|
13271
|
+
c,
|
|
13272
|
+
smul(rot([1, 0, 0], theta), this.options.size)
|
|
13273
|
+
)
|
|
13274
|
+
);
|
|
13275
|
+
}
|
|
13276
|
+
ps.push(add(c, smul([1, 0, 0], this.options.size)));
|
|
13277
|
+
return ps;
|
|
13278
|
+
}
|
|
13279
|
+
return [];
|
|
13280
|
+
}
|
|
13281
|
+
const first = points[visibleStartIndex];
|
|
13282
|
+
const second = points[visibleStartIndex + 1];
|
|
13283
|
+
const penultimate = points[len - 2];
|
|
13284
|
+
const ultimate = points[len - 1];
|
|
13285
|
+
const dirFS = norm(sub(second, first));
|
|
13286
|
+
const dirPU = norm(sub(penultimate, ultimate));
|
|
13287
|
+
const ppdirFS = rot(dirFS, -Math.PI / 2);
|
|
13288
|
+
const ppdirPU = rot(dirPU, Math.PI / 2);
|
|
13289
|
+
const startCapSize = this.getSize(sizeOverride, first[2], 0, len, 0);
|
|
13290
|
+
const startCap = [];
|
|
13291
|
+
const endCapSize = this.options.keepHead ? this.options.size : this.getSize(sizeOverride, penultimate[2], len - 2, len, runningLength);
|
|
13292
|
+
const endCap = [];
|
|
13293
|
+
if (startCapSize > 0.1) {
|
|
13294
|
+
for (let theta = 0; theta <= Math.PI; theta += Math.PI / 16) {
|
|
13295
|
+
startCap.unshift(
|
|
13296
|
+
add(first, rot(smul(ppdirFS, startCapSize), -theta))
|
|
13297
|
+
);
|
|
13298
|
+
}
|
|
13299
|
+
startCap.unshift(add(first, smul(ppdirFS, -startCapSize)));
|
|
13300
|
+
} else {
|
|
13301
|
+
startCap.push(first);
|
|
13302
|
+
}
|
|
13303
|
+
for (let theta = 0; theta <= Math.PI * 3; theta += Math.PI / 16) {
|
|
13304
|
+
endCap.push(add(ultimate, rot(smul(ppdirPU, -endCapSize), -theta)));
|
|
13305
|
+
}
|
|
13306
|
+
const strokeOutline = [
|
|
13307
|
+
...startCap,
|
|
13308
|
+
...forwardPoints,
|
|
13309
|
+
...endCap.reverse(),
|
|
13310
|
+
...backwardPoints.reverse()
|
|
13311
|
+
];
|
|
13312
|
+
if (startCap.length > 0) {
|
|
13313
|
+
strokeOutline.push(startCap[0]);
|
|
13314
|
+
}
|
|
13315
|
+
if (this.options.simplify > 0 && this.options.simplifyPhase === "output") {
|
|
13316
|
+
return douglasPeucker(strokeOutline, this.options.simplify);
|
|
13317
|
+
}
|
|
13318
|
+
return strokeOutline;
|
|
13319
|
+
}
|
|
13320
|
+
};
|
|
13321
|
+
__publicField(_LaserPointer, "defaults", {
|
|
13322
|
+
size: 2,
|
|
13323
|
+
streamline: 0.45,
|
|
13324
|
+
simplify: 0.1,
|
|
13325
|
+
simplifyPhase: "output",
|
|
13326
|
+
keepHead: false,
|
|
13327
|
+
sizeMapping: () => 1
|
|
13328
|
+
});
|
|
13329
|
+
__publicField(_LaserPointer, "constants", {
|
|
13330
|
+
cornerDetectionMaxAngle: 75,
|
|
13331
|
+
cornerDetectionVariance: (s) => s > 35 ? 0.5 : 1,
|
|
13332
|
+
maxTailLength: 50
|
|
13333
|
+
});
|
|
13334
|
+
var LaserPointer = _LaserPointer;
|
|
13335
|
+
|
|
12650
13336
|
// ../utils/src/shape.ts
|
|
12651
13337
|
import { pointsOnBezierCurves } from "points-on-curve";
|
|
12652
13338
|
import { invariant as invariant4 } from "@excalidraw/common";
|
|
@@ -12693,7 +13379,8 @@ import {
|
|
|
12693
13379
|
assertNever as assertNever2,
|
|
12694
13380
|
COLOR_PALETTE as COLOR_PALETTE3,
|
|
12695
13381
|
LINE_POLYGON_POINT_MERGE_DISTANCE,
|
|
12696
|
-
applyDarkModeFilter as applyDarkModeFilter2
|
|
13382
|
+
applyDarkModeFilter as applyDarkModeFilter2,
|
|
13383
|
+
DEFAULT_STROKE_STREAMLINE
|
|
12697
13384
|
} from "@excalidraw/common";
|
|
12698
13385
|
import { RoughGenerator } from "roughjs/bin/generator";
|
|
12699
13386
|
|
|
@@ -12711,7 +13398,7 @@ import {
|
|
|
12711
13398
|
ELEMENT_READY_TO_ERASE_OPACITY,
|
|
12712
13399
|
FRAME_STYLE,
|
|
12713
13400
|
DARK_THEME_FILTER,
|
|
12714
|
-
MIME_TYPES as
|
|
13401
|
+
MIME_TYPES as MIME_TYPES5,
|
|
12715
13402
|
THEME as THEME9,
|
|
12716
13403
|
distance,
|
|
12717
13404
|
getFontString as getFontString4,
|
|
@@ -12770,7 +13457,7 @@ import {
|
|
|
12770
13457
|
} from "@excalidraw/common";
|
|
12771
13458
|
import {
|
|
12772
13459
|
PRECISION as PRECISION2,
|
|
12773
|
-
clamp as
|
|
13460
|
+
clamp as clamp4,
|
|
12774
13461
|
lineSegment as lineSegment4,
|
|
12775
13462
|
pointDistance as pointDistance4,
|
|
12776
13463
|
pointDistanceSq,
|
|
@@ -12968,7 +13655,7 @@ var headingIsHorizontal = (a) => compareHeading(a, HEADING_RIGHT) || compareHead
|
|
|
12968
13655
|
|
|
12969
13656
|
// ../element/src/elbowArrow.ts
|
|
12970
13657
|
import {
|
|
12971
|
-
clamp as
|
|
13658
|
+
clamp as clamp3,
|
|
12972
13659
|
pointDistance as pointDistance3,
|
|
12973
13660
|
pointFrom as pointFrom9,
|
|
12974
13661
|
pointScaleFromOrigin as pointScaleFromOrigin2,
|
|
@@ -13005,6 +13692,7 @@ import { pointsEqual as pointsEqual6 } from "@excalidraw/math";
|
|
|
13005
13692
|
|
|
13006
13693
|
// ../element/src/zindex.ts
|
|
13007
13694
|
import { arrayToMap as arrayToMap20, findIndex, findLastIndex } from "@excalidraw/common";
|
|
13695
|
+
import { isFiniteNumber } from "@excalidraw/math";
|
|
13008
13696
|
|
|
13009
13697
|
// ../element/src/selection.ts
|
|
13010
13698
|
import { arrayToMap as arrayToMap19, isShallowEqual } from "@excalidraw/common";
|
|
@@ -13276,29 +13964,29 @@ var getArrowheadPoints = (element, shape, position, arrowhead, offsetMultiplier
|
|
|
13276
13964
|
const diameter = Math.hypot(ys - ty, xs - tx) + element.strokeWidth - 2;
|
|
13277
13965
|
return [tx, ty, diameter];
|
|
13278
13966
|
}
|
|
13279
|
-
const
|
|
13967
|
+
const angle2 = getArrowheadAngle(arrowhead);
|
|
13280
13968
|
if (arrowhead === "cardinality_many" || arrowhead === "cardinality_one_or_many") {
|
|
13281
13969
|
const [x32, y32] = pointRotateRads9(
|
|
13282
13970
|
pointFrom13(tx, ty),
|
|
13283
13971
|
pointFrom13(xs, ys),
|
|
13284
|
-
degreesToRadians(-
|
|
13972
|
+
degreesToRadians(-angle2)
|
|
13285
13973
|
);
|
|
13286
13974
|
const [x42, y42] = pointRotateRads9(
|
|
13287
13975
|
pointFrom13(tx, ty),
|
|
13288
13976
|
pointFrom13(xs, ys),
|
|
13289
|
-
degreesToRadians(
|
|
13977
|
+
degreesToRadians(angle2)
|
|
13290
13978
|
);
|
|
13291
13979
|
return [xs, ys, x32, y32, x42, y42];
|
|
13292
13980
|
}
|
|
13293
13981
|
const [x3, y3] = pointRotateRads9(
|
|
13294
13982
|
pointFrom13(xs, ys),
|
|
13295
13983
|
pointFrom13(tx, ty),
|
|
13296
|
-
-
|
|
13984
|
+
-angle2 * Math.PI / 180
|
|
13297
13985
|
);
|
|
13298
13986
|
const [x4, y4] = pointRotateRads9(
|
|
13299
13987
|
pointFrom13(xs, ys),
|
|
13300
13988
|
pointFrom13(tx, ty),
|
|
13301
|
-
degreesToRadians(
|
|
13989
|
+
degreesToRadians(angle2)
|
|
13302
13990
|
);
|
|
13303
13991
|
if (arrowhead === "diamond" || arrowhead === "diamond_outline") {
|
|
13304
13992
|
let ox;
|
|
@@ -13334,17 +14022,21 @@ import {
|
|
|
13334
14022
|
vectorAdd as vectorAdd2,
|
|
13335
14023
|
vectorScale as vectorScale7,
|
|
13336
14024
|
pointFromVector as pointFromVector6,
|
|
13337
|
-
clamp as
|
|
14025
|
+
clamp as clamp5,
|
|
13338
14026
|
isCloseTo
|
|
13339
14027
|
} from "@excalidraw/math";
|
|
13340
14028
|
|
|
14029
|
+
// ../element/src/image.ts
|
|
14030
|
+
import { MIME_TYPES as MIME_TYPES4, SVG_NS } from "@excalidraw/common";
|
|
14031
|
+
import { rgbaToThumbHash, thumbHashToRGBA } from "thumbhash";
|
|
14032
|
+
|
|
13341
14033
|
// ../element/src/renderElement.ts
|
|
13342
14034
|
var IMAGE_PLACEHOLDER_IMG = typeof document !== "undefined" ? document.createElement("img") : { src: "" };
|
|
13343
|
-
IMAGE_PLACEHOLDER_IMG.src = `data:${
|
|
14035
|
+
IMAGE_PLACEHOLDER_IMG.src = `data:${MIME_TYPES5.svg},${encodeURIComponent(
|
|
13344
14036
|
`<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>`
|
|
13345
14037
|
)}`;
|
|
13346
14038
|
var IMAGE_ERROR_PLACEHOLDER_IMG = typeof document !== "undefined" ? document.createElement("img") : { src: "" };
|
|
13347
|
-
IMAGE_ERROR_PLACEHOLDER_IMG.src = `data:${
|
|
14039
|
+
IMAGE_ERROR_PLACEHOLDER_IMG.src = `data:${MIME_TYPES5.svg},${encodeURIComponent(
|
|
13348
14040
|
`<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>`
|
|
13349
14041
|
)}`;
|
|
13350
14042
|
var elementWithCanvasCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -13948,19 +14640,46 @@ var getFreeDrawSvgPath = (element) => {
|
|
|
13948
14640
|
getFreedrawOutlinePoints(element)
|
|
13949
14641
|
);
|
|
13950
14642
|
};
|
|
13951
|
-
var
|
|
13952
|
-
|
|
14643
|
+
var VARIABLE_WIDTH_FREEDRAW = {
|
|
14644
|
+
/** Stroke size relative to `strokeWidth` for pressure-sensitive strokes. */
|
|
14645
|
+
SIZE_FACTOR: 4.25,
|
|
14646
|
+
THINNING: 0.6,
|
|
14647
|
+
SMOOTHING: 0.5
|
|
14648
|
+
};
|
|
14649
|
+
var CONSTANT_WIDTH_FREEDRAW = {
|
|
14650
|
+
/** Stroke size relative to `strokeWidth` for uniform (laser) strokes. */
|
|
14651
|
+
SIZE_FACTOR: 1.4
|
|
14652
|
+
};
|
|
14653
|
+
var getFreedrawStreamline = (element) => element.strokeOptions?.streamline ?? DEFAULT_STROKE_STREAMLINE;
|
|
14654
|
+
var getVariableWidthFreedrawOutline = (element) => {
|
|
14655
|
+
const inputPoints = element.simulatePressure ? element.points : element.points.length ? element.points.map(
|
|
14656
|
+
([x, y], i) => [x, y, element.pressures[i]]
|
|
14657
|
+
) : [[0, 0, 0.5]];
|
|
13953
14658
|
return getStroke(inputPoints, {
|
|
13954
14659
|
simulatePressure: element.simulatePressure,
|
|
13955
|
-
size: element.strokeWidth *
|
|
13956
|
-
thinning:
|
|
13957
|
-
smoothing:
|
|
13958
|
-
streamline:
|
|
14660
|
+
size: element.strokeWidth * VARIABLE_WIDTH_FREEDRAW.SIZE_FACTOR,
|
|
14661
|
+
thinning: VARIABLE_WIDTH_FREEDRAW.THINNING,
|
|
14662
|
+
smoothing: VARIABLE_WIDTH_FREEDRAW.SMOOTHING,
|
|
14663
|
+
streamline: getFreedrawStreamline(element),
|
|
13959
14664
|
easing: (t2) => Math.sin(t2 * Math.PI / 2),
|
|
13960
14665
|
// https://easings.net/#easeOutSine
|
|
13961
14666
|
last: true
|
|
13962
14667
|
});
|
|
13963
14668
|
};
|
|
14669
|
+
var createLaserPointer = (element) => new LaserPointer({
|
|
14670
|
+
size: element.strokeWidth * CONSTANT_WIDTH_FREEDRAW.SIZE_FACTOR,
|
|
14671
|
+
streamline: getFreedrawStreamline(element),
|
|
14672
|
+
simplify: 0,
|
|
14673
|
+
sizeMapping: (details) => Math.max(0.1, details.pressure)
|
|
14674
|
+
});
|
|
14675
|
+
var getConstantWidthFreedrawOutline = (element) => {
|
|
14676
|
+
const laserPointer = createLaserPointer(element);
|
|
14677
|
+
element.points.map(([x, y]) => laserPointer.addPoint([x, y, 1]));
|
|
14678
|
+
return laserPointer.getStrokeOutline().map(([x, y]) => [x, y]);
|
|
14679
|
+
};
|
|
14680
|
+
var getFreedrawOutlinePoints = (element) => {
|
|
14681
|
+
return element.strokeOptions?.variability === "constant" ? getConstantWidthFreedrawOutline(element) : getVariableWidthFreedrawOutline(element);
|
|
14682
|
+
};
|
|
13964
14683
|
var med = (A, B) => {
|
|
13965
14684
|
return [(A[0] + B[0]) / 2, (A[1] + B[1]) / 2];
|
|
13966
14685
|
};
|
|
@@ -16170,56 +16889,9 @@ var Renderer = class {
|
|
|
16170
16889
|
}
|
|
16171
16890
|
};
|
|
16172
16891
|
|
|
16173
|
-
//
|
|
16174
|
-
import {
|
|
16175
|
-
import {
|
|
16176
|
-
import { jsx as jsx57 } from "react/jsx-runtime";
|
|
16177
|
-
var CONTAINER_PADDING = 5;
|
|
16178
|
-
var getContainerCoords2 = (element, appState, elementsMap) => {
|
|
16179
|
-
const [x1, y1] = getElementAbsoluteCoords5(element, elementsMap);
|
|
16180
|
-
const { x: viewportX, y: viewportY } = sceneCoordsToViewportCoords2(
|
|
16181
|
-
{ sceneX: x1 + element.width, sceneY: y1 },
|
|
16182
|
-
appState
|
|
16183
|
-
);
|
|
16184
|
-
const x = viewportX - appState.offsetLeft + 10;
|
|
16185
|
-
const y = viewportY - appState.offsetTop;
|
|
16186
|
-
return { x, y };
|
|
16187
|
-
};
|
|
16188
|
-
var ElementCanvasButtons = ({
|
|
16189
|
-
children,
|
|
16190
|
-
element,
|
|
16191
|
-
elementsMap
|
|
16192
|
-
}) => {
|
|
16193
|
-
const appState = useExcalidrawAppState();
|
|
16194
|
-
if (appState.contextMenu || appState.newElement || appState.resizingElement || appState.isRotating || appState.openMenu || appState.viewModeEnabled) {
|
|
16195
|
-
return null;
|
|
16196
|
-
}
|
|
16197
|
-
const { x, y } = getContainerCoords2(element, appState, elementsMap);
|
|
16198
|
-
return /* @__PURE__ */ jsx57(
|
|
16199
|
-
"div",
|
|
16200
|
-
{
|
|
16201
|
-
className: "excalidraw-canvas-buttons",
|
|
16202
|
-
style: {
|
|
16203
|
-
top: `${y}px`,
|
|
16204
|
-
left: `${x}px`,
|
|
16205
|
-
// width: CONTAINER_WIDTH,
|
|
16206
|
-
padding: CONTAINER_PADDING
|
|
16207
|
-
},
|
|
16208
|
-
children
|
|
16209
|
-
}
|
|
16210
|
-
);
|
|
16211
|
-
};
|
|
16212
|
-
|
|
16213
|
-
// laserTrails.ts
|
|
16214
|
-
import { DEFAULT_LASER_COLOR, easeOut } from "@excalidraw/common";
|
|
16215
|
-
|
|
16216
|
-
// animatedTrail.ts
|
|
16217
|
-
import { LaserPointer } from "@excalidraw/laser-pointer";
|
|
16218
|
-
import {
|
|
16219
|
-
SVG_NS,
|
|
16220
|
-
getSvgPathFromStroke as getSvgPathFromStroke2,
|
|
16221
|
-
sceneCoordsToViewportCoords as sceneCoordsToViewportCoords3
|
|
16222
|
-
} from "@excalidraw/common";
|
|
16892
|
+
// scroll.ts
|
|
16893
|
+
import { easeOut } from "@excalidraw/common";
|
|
16894
|
+
import { clamp as clamp6 } from "@excalidraw/math";
|
|
16223
16895
|
|
|
16224
16896
|
// reactUtils.ts
|
|
16225
16897
|
import { version as ReactVersion } from "react";
|
|
@@ -16345,12 +17017,139 @@ var _AnimationController = class _AnimationController {
|
|
|
16345
17017
|
_AnimationController.animations.delete(key);
|
|
16346
17018
|
_AnimationController.cancelScheduledFrameIfIdle();
|
|
16347
17019
|
}
|
|
17020
|
+
static reset() {
|
|
17021
|
+
_AnimationController.animations.clear();
|
|
17022
|
+
_AnimationController.cancelScheduledFrame();
|
|
17023
|
+
}
|
|
16348
17024
|
};
|
|
16349
17025
|
__publicField(_AnimationController, "scheduledFrame", null);
|
|
16350
17026
|
__publicField(_AnimationController, "animations", /* @__PURE__ */ new Map());
|
|
16351
17027
|
var AnimationController = _AnimationController;
|
|
16352
17028
|
|
|
17029
|
+
// scroll.ts
|
|
17030
|
+
var SCROLL_TO_CONTENT_ANIMATION_KEY = "animateScrollToContent";
|
|
17031
|
+
var DEFAULT_ANIMATION_DURATION = 500;
|
|
17032
|
+
var scrollToElements = (state, target, onFrame, opts) => {
|
|
17033
|
+
AnimationController.cancel(SCROLL_TO_CONTENT_ANIMATION_KEY);
|
|
17034
|
+
const viewport = getTargetViewport(state, target, opts);
|
|
17035
|
+
if (opts?.animate) {
|
|
17036
|
+
animateToViewport(
|
|
17037
|
+
state,
|
|
17038
|
+
viewport,
|
|
17039
|
+
opts.duration ?? DEFAULT_ANIMATION_DURATION,
|
|
17040
|
+
onFrame
|
|
17041
|
+
);
|
|
17042
|
+
} else {
|
|
17043
|
+
onFrame({ ...viewport, shouldCacheIgnoreZoom: false });
|
|
17044
|
+
}
|
|
17045
|
+
};
|
|
17046
|
+
var getTargetViewport = (state, targetElements, opts) => {
|
|
17047
|
+
if (opts?.fitToContent || opts?.fitToViewport) {
|
|
17048
|
+
const { appState } = zoomToFit({
|
|
17049
|
+
canvasOffsets: opts.canvasOffsets,
|
|
17050
|
+
targetElements,
|
|
17051
|
+
appState: state,
|
|
17052
|
+
fitToViewport: !!opts.fitToViewport,
|
|
17053
|
+
viewportZoomFactor: opts.viewportZoomFactor,
|
|
17054
|
+
minZoom: opts.minZoom,
|
|
17055
|
+
maxZoom: opts.maxZoom
|
|
17056
|
+
});
|
|
17057
|
+
return {
|
|
17058
|
+
scrollX: appState.scrollX,
|
|
17059
|
+
scrollY: appState.scrollY,
|
|
17060
|
+
zoom: appState.zoom
|
|
17061
|
+
};
|
|
17062
|
+
}
|
|
17063
|
+
const { scrollX, scrollY } = calculateScrollCenter(targetElements, state);
|
|
17064
|
+
return { scrollX, scrollY, zoom: state.zoom };
|
|
17065
|
+
};
|
|
17066
|
+
var interpolateViewport = ({
|
|
17067
|
+
from,
|
|
17068
|
+
target,
|
|
17069
|
+
factor
|
|
17070
|
+
}) => {
|
|
17071
|
+
const zoom = from.zoom.value * Math.pow(
|
|
17072
|
+
target.zoom.value / from.zoom.value,
|
|
17073
|
+
factor
|
|
17074
|
+
);
|
|
17075
|
+
const fromCenterX = from.width / 2 / from.zoom.value - from.scrollX;
|
|
17076
|
+
const fromCenterY = from.height / 2 / from.zoom.value - from.scrollY;
|
|
17077
|
+
const toCenterX = from.width / 2 / target.zoom.value - target.scrollX;
|
|
17078
|
+
const toCenterY = from.height / 2 / target.zoom.value - target.scrollY;
|
|
17079
|
+
const centerX = fromCenterX + (toCenterX - fromCenterX) * factor;
|
|
17080
|
+
const centerY = fromCenterY + (toCenterY - fromCenterY) * factor;
|
|
17081
|
+
return {
|
|
17082
|
+
scrollX: from.width / 2 / zoom - centerX,
|
|
17083
|
+
scrollY: from.height / 2 / zoom - centerY,
|
|
17084
|
+
zoom: { value: zoom }
|
|
17085
|
+
};
|
|
17086
|
+
};
|
|
17087
|
+
var animateToViewport = (from, target, duration, onFrame) => {
|
|
17088
|
+
AnimationController.start(
|
|
17089
|
+
SCROLL_TO_CONTENT_ANIMATION_KEY,
|
|
17090
|
+
({ deltaTime, state }) => {
|
|
17091
|
+
const elapsed = (state?.elapsed ?? 0) + deltaTime;
|
|
17092
|
+
const progress = Math.min(elapsed / duration, 1);
|
|
17093
|
+
const factor = easeOut(clamp6(progress, 0, 1));
|
|
17094
|
+
onFrame({
|
|
17095
|
+
...interpolateViewport({ from, target, factor }),
|
|
17096
|
+
shouldCacheIgnoreZoom: progress < 1
|
|
17097
|
+
// ignore zoom caching while animating
|
|
17098
|
+
});
|
|
17099
|
+
return progress < 1 ? { elapsed } : null;
|
|
17100
|
+
}
|
|
17101
|
+
);
|
|
17102
|
+
};
|
|
17103
|
+
|
|
17104
|
+
// components/ElementCanvasButtons.tsx
|
|
17105
|
+
import { sceneCoordsToViewportCoords as sceneCoordsToViewportCoords2 } from "@excalidraw/common";
|
|
17106
|
+
import { getElementAbsoluteCoords as getElementAbsoluteCoords5 } from "@excalidraw/element";
|
|
17107
|
+
import { jsx as jsx57 } from "react/jsx-runtime";
|
|
17108
|
+
var CONTAINER_PADDING = 5;
|
|
17109
|
+
var getContainerCoords2 = (element, appState, elementsMap) => {
|
|
17110
|
+
const [x1, y1] = getElementAbsoluteCoords5(element, elementsMap);
|
|
17111
|
+
const { x: viewportX, y: viewportY } = sceneCoordsToViewportCoords2(
|
|
17112
|
+
{ sceneX: x1 + element.width, sceneY: y1 },
|
|
17113
|
+
appState
|
|
17114
|
+
);
|
|
17115
|
+
const x = viewportX - appState.offsetLeft + 10;
|
|
17116
|
+
const y = viewportY - appState.offsetTop;
|
|
17117
|
+
return { x, y };
|
|
17118
|
+
};
|
|
17119
|
+
var ElementCanvasButtons = ({
|
|
17120
|
+
children,
|
|
17121
|
+
element,
|
|
17122
|
+
elementsMap
|
|
17123
|
+
}) => {
|
|
17124
|
+
const appState = useExcalidrawAppState();
|
|
17125
|
+
if (appState.contextMenu || appState.newElement || appState.resizingElement || appState.isRotating || appState.openMenu || appState.viewModeEnabled) {
|
|
17126
|
+
return null;
|
|
17127
|
+
}
|
|
17128
|
+
const { x, y } = getContainerCoords2(element, appState, elementsMap);
|
|
17129
|
+
return /* @__PURE__ */ jsx57(
|
|
17130
|
+
"div",
|
|
17131
|
+
{
|
|
17132
|
+
className: "excalidraw-canvas-buttons",
|
|
17133
|
+
style: {
|
|
17134
|
+
top: `${y}px`,
|
|
17135
|
+
left: `${x}px`,
|
|
17136
|
+
// width: CONTAINER_WIDTH,
|
|
17137
|
+
padding: CONTAINER_PADDING
|
|
17138
|
+
},
|
|
17139
|
+
children
|
|
17140
|
+
}
|
|
17141
|
+
);
|
|
17142
|
+
};
|
|
17143
|
+
|
|
17144
|
+
// laserTrails.ts
|
|
17145
|
+
import { DEFAULT_LASER_COLOR, easeOut as easeOut2 } from "@excalidraw/common";
|
|
17146
|
+
|
|
16353
17147
|
// animatedTrail.ts
|
|
17148
|
+
import {
|
|
17149
|
+
SVG_NS as SVG_NS2,
|
|
17150
|
+
getSvgPathFromStroke as getSvgPathFromStroke2,
|
|
17151
|
+
sceneCoordsToViewportCoords as sceneCoordsToViewportCoords3
|
|
17152
|
+
} from "@excalidraw/common";
|
|
16354
17153
|
var _AnimatedTrail = class _AnimatedTrail {
|
|
16355
17154
|
constructor(app, options) {
|
|
16356
17155
|
this.app = app;
|
|
@@ -16362,9 +17161,9 @@ var _AnimatedTrail = class _AnimatedTrail {
|
|
|
16362
17161
|
__publicField(this, "trailAnimation");
|
|
16363
17162
|
__publicField(this, "key");
|
|
16364
17163
|
this.key = `animated-trail-${_AnimatedTrail.counter++}`;
|
|
16365
|
-
this.trailElement = document.createElementNS(
|
|
17164
|
+
this.trailElement = document.createElementNS(SVG_NS2, "path");
|
|
16366
17165
|
if (this.options.animateTrail) {
|
|
16367
|
-
this.trailAnimation = document.createElementNS(
|
|
17166
|
+
this.trailAnimation = document.createElementNS(SVG_NS2, "animate");
|
|
16368
17167
|
this.trailAnimation.setAttribute("attributeName", "stroke-dashoffset");
|
|
16369
17168
|
this.trailElement.setAttribute("stroke-dasharray", "7 7");
|
|
16370
17169
|
this.trailElement.setAttribute("stroke-dashoffset", "10");
|
|
@@ -16522,7 +17321,7 @@ var LaserTrails = class {
|
|
|
16522
17321
|
1 - (performance.now() - c.pressure) / DECAY_TIME
|
|
16523
17322
|
);
|
|
16524
17323
|
const l = (DECAY_LENGTH - Math.min(DECAY_LENGTH, c.totalLength - c.currentIndex)) / DECAY_LENGTH;
|
|
16525
|
-
return Math.min(
|
|
17324
|
+
return Math.min(easeOut2(l), easeOut2(t2));
|
|
16526
17325
|
}
|
|
16527
17326
|
};
|
|
16528
17327
|
}
|
|
@@ -16662,7 +17461,7 @@ import {
|
|
|
16662
17461
|
getFontString as getFontString6,
|
|
16663
17462
|
getFontFamilyString as getFontFamilyString3,
|
|
16664
17463
|
isTestEnv as isTestEnv4,
|
|
16665
|
-
MIME_TYPES as
|
|
17464
|
+
MIME_TYPES as MIME_TYPES6,
|
|
16666
17465
|
applyDarkModeFilter as applyDarkModeFilter3,
|
|
16667
17466
|
isRTL as isRTL2
|
|
16668
17467
|
} from "@excalidraw/common";
|
|
@@ -16697,9 +17496,9 @@ import {
|
|
|
16697
17496
|
isBoundToContainer as isBoundToContainer7,
|
|
16698
17497
|
isTextElement as isTextElement8
|
|
16699
17498
|
} from "@excalidraw/element";
|
|
16700
|
-
var getTransform = (width, height,
|
|
17499
|
+
var getTransform = (width, height, angle2, appState, maxWidth, maxHeight) => {
|
|
16701
17500
|
const { zoom } = appState;
|
|
16702
|
-
const degree = 180 *
|
|
17501
|
+
const degree = 180 * angle2 / Math.PI;
|
|
16703
17502
|
let translateX = width * (zoom.value - 1) / 2;
|
|
16704
17503
|
let translateY = height * (zoom.value - 1) / 2;
|
|
16705
17504
|
if (width > maxWidth && zoom.value !== 1) {
|
|
@@ -16905,7 +17704,7 @@ var textWysiwyg = ({
|
|
|
16905
17704
|
}
|
|
16906
17705
|
height *= 1.05;
|
|
16907
17706
|
const font = getFontString6(updatedTextElement);
|
|
16908
|
-
const
|
|
17707
|
+
const angle2 = getTextElementAngle(updatedTextElement, container);
|
|
16909
17708
|
const editorMaxHeight = (appState.height - viewportY) / appState.zoom.value;
|
|
16910
17709
|
Object.assign(editable.style, {
|
|
16911
17710
|
font,
|
|
@@ -16918,7 +17717,7 @@ var textWysiwyg = ({
|
|
|
16918
17717
|
transform: getTransform(
|
|
16919
17718
|
width,
|
|
16920
17719
|
height,
|
|
16921
|
-
|
|
17720
|
+
angle2,
|
|
16922
17721
|
appState,
|
|
16923
17722
|
maxWidth,
|
|
16924
17723
|
editorMaxHeight
|
|
@@ -16933,7 +17732,7 @@ var textWysiwyg = ({
|
|
|
16933
17732
|
maxHeight: `${editorMaxHeight}px`
|
|
16934
17733
|
});
|
|
16935
17734
|
currentTextLayout = {
|
|
16936
|
-
angle,
|
|
17735
|
+
angle: angle2,
|
|
16937
17736
|
font,
|
|
16938
17737
|
height: updatedTextElement.height,
|
|
16939
17738
|
lineHeightPx: getLineHeightInPx2(
|
|
@@ -17042,7 +17841,7 @@ var textWysiwyg = ({
|
|
|
17042
17841
|
editable.onpaste = async (event) => {
|
|
17043
17842
|
const mimeTypes = parseDataTransferEventMimeTypes(event);
|
|
17044
17843
|
let dataList = null;
|
|
17045
|
-
if (mimeTypes.has(
|
|
17844
|
+
if (mimeTypes.has(MIME_TYPES6.excalidrawClipboard) || mimeTypes.has(MIME_TYPES6.excalidraw)) {
|
|
17046
17845
|
event.preventDefault();
|
|
17047
17846
|
dataList = await parseDataTransferEvent(event);
|
|
17048
17847
|
try {
|
|
@@ -17063,7 +17862,7 @@ var textWysiwyg = ({
|
|
|
17063
17862
|
}
|
|
17064
17863
|
}
|
|
17065
17864
|
dataList = dataList || await parseDataTransferEvent(event);
|
|
17066
|
-
const textItem = dataList.findByType(
|
|
17865
|
+
const textItem = dataList.findByType(MIME_TYPES6.text);
|
|
17067
17866
|
if (!textItem) {
|
|
17068
17867
|
return;
|
|
17069
17868
|
}
|
|
@@ -17455,7 +18254,7 @@ import {
|
|
|
17455
18254
|
import { getFrameChildren as getFrameChildren4 } from "@excalidraw/element";
|
|
17456
18255
|
import { selectGroupsForSelectedElements as selectGroupsForSelectedElements6 } from "@excalidraw/element";
|
|
17457
18256
|
import { getContainerElement as getContainerElement4 } from "@excalidraw/element";
|
|
17458
|
-
import { arrayToMap as arrayToMap25, easeOut as
|
|
18257
|
+
import { arrayToMap as arrayToMap25, easeOut as easeOut3, isShallowEqual as isShallowEqual3 } from "@excalidraw/common";
|
|
17459
18258
|
|
|
17460
18259
|
// lasso/utils.ts
|
|
17461
18260
|
import { simplify as simplify2 } from "points-on-curve";
|
|
@@ -17567,7 +18366,7 @@ var LassoTrail = class extends AnimatedTrail {
|
|
|
17567
18366
|
1 - (performance.now() - c.pressure) / DECAY_TIME
|
|
17568
18367
|
);
|
|
17569
18368
|
const l = (DECAY_LENGTH - Math.min(DECAY_LENGTH, c.totalLength - c.currentIndex)) / DECAY_LENGTH;
|
|
17570
|
-
return Math.min(
|
|
18369
|
+
return Math.min(easeOut3(l), easeOut3(t2));
|
|
17571
18370
|
},
|
|
17572
18371
|
fill: () => "rgba(105,101,219,0.05)",
|
|
17573
18372
|
stroke: () => "rgba(105,101,219)"
|
|
@@ -17735,7 +18534,7 @@ var actionSmartZoom = register({
|
|
|
17735
18534
|
});
|
|
17736
18535
|
|
|
17737
18536
|
// eraser/index.ts
|
|
17738
|
-
import { arrayToMap as arrayToMap26, easeOut as
|
|
18537
|
+
import { arrayToMap as arrayToMap26, easeOut as easeOut4, THEME as THEME12 } from "@excalidraw/common";
|
|
17739
18538
|
import {
|
|
17740
18539
|
computeBoundTextPosition as computeBoundTextPosition4,
|
|
17741
18540
|
doBoundsIntersect as doBoundsIntersect3,
|
|
@@ -17775,7 +18574,7 @@ var EraserTrail = class extends AnimatedTrail {
|
|
|
17775
18574
|
1 - (performance.now() - c.pressure) / DECAY_TIME
|
|
17776
18575
|
);
|
|
17777
18576
|
const l = (DECAY_LENGTH - Math.min(DECAY_LENGTH, c.totalLength - c.currentIndex)) / DECAY_LENGTH;
|
|
17778
|
-
return Math.min(
|
|
18577
|
+
return Math.min(easeOut4(l), easeOut4(t2));
|
|
17779
18578
|
},
|
|
17780
18579
|
fill: () => app.state.theme === THEME12.LIGHT ? "rgba(0, 0, 0, 0.2)" : "rgba(255, 255, 255, 0.2)"
|
|
17781
18580
|
});
|
|
@@ -18165,7 +18964,7 @@ var createRadarAxisLabels = (labels, angles, centerX, centerY, radius, backgroun
|
|
|
18165
18964
|
);
|
|
18166
18965
|
const minLabelWidth = getApproxMinLineWidth(fontString, lineHeight);
|
|
18167
18966
|
const axisLabels = labels.map((label, index) => {
|
|
18168
|
-
const
|
|
18967
|
+
const angle2 = angles[index];
|
|
18169
18968
|
const longestWordWidth = Math.max(
|
|
18170
18969
|
0,
|
|
18171
18970
|
...label.trim().split(/\s+/).filter(Boolean).map((word) => measureText4(word, fontString, lineHeight).width)
|
|
@@ -18177,8 +18976,8 @@ var createRadarAxisLabels = (labels, angles, centerX, centerY, radius, backgroun
|
|
|
18177
18976
|
);
|
|
18178
18977
|
const displayLabel = getRadarDisplayText(label, fontString, maxLabelWidth);
|
|
18179
18978
|
const metrics = measureText4(displayLabel, fontString, lineHeight);
|
|
18180
|
-
const cos = Math.cos(
|
|
18181
|
-
const sin = Math.sin(
|
|
18979
|
+
const cos = Math.cos(angle2);
|
|
18980
|
+
const sin = Math.sin(angle2);
|
|
18182
18981
|
const textAlign = cos > RADAR_AXIS_LABEL_ALIGNMENT_THRESHOLD ? "left" : cos < -RADAR_AXIS_LABEL_ALIGNMENT_THRESHOLD ? "right" : "center";
|
|
18183
18982
|
const centerAlignedXExtent = textAlign === "center" ? metrics.width / 2 : 0;
|
|
18184
18983
|
const projectedExtent = Math.abs(cos) * centerAlignedXExtent + Math.abs(sin) * (metrics.height / 2);
|
|
@@ -18324,9 +19123,9 @@ var wrapOrEllipsifyTextToWidth = (text, maxWidth, fontString, lineHeight) => {
|
|
|
18324
19123
|
text: ellipsifyTextToWidth(text, maxWidth, fontString, lineHeight)
|
|
18325
19124
|
};
|
|
18326
19125
|
};
|
|
18327
|
-
var getRotatedBoundingBox = (width, height,
|
|
18328
|
-
const cos = Math.abs(Math.cos(
|
|
18329
|
-
const sin = Math.abs(Math.sin(
|
|
19126
|
+
var getRotatedBoundingBox = (width, height, angle2) => {
|
|
19127
|
+
const cos = Math.abs(Math.cos(angle2));
|
|
19128
|
+
const sin = Math.abs(Math.sin(angle2));
|
|
18330
19129
|
return {
|
|
18331
19130
|
width: width * cos + height * sin,
|
|
18332
19131
|
height: width * sin + height * cos
|
|
@@ -18900,9 +19699,9 @@ var renderRadarChart = (spreadsheet, x, y, colorSeed) => {
|
|
|
18900
19699
|
const levelRatio = (levelIndex + 1) / RADAR_GRID_LEVELS;
|
|
18901
19700
|
const levelRadius = radius * levelRatio;
|
|
18902
19701
|
const points = angles.map(
|
|
18903
|
-
(
|
|
18904
|
-
Math.cos(
|
|
18905
|
-
Math.sin(
|
|
19702
|
+
(angle2) => pointFrom24(
|
|
19703
|
+
Math.cos(angle2) * levelRadius,
|
|
19704
|
+
Math.sin(angle2) * levelRadius
|
|
18906
19705
|
)
|
|
18907
19706
|
);
|
|
18908
19707
|
points.push(pointFrom24(points[0][0], points[0][1]));
|
|
@@ -18921,9 +19720,9 @@ var renderRadarChart = (spreadsheet, x, y, colorSeed) => {
|
|
|
18921
19720
|
points
|
|
18922
19721
|
});
|
|
18923
19722
|
}) : [];
|
|
18924
|
-
const spokes = angles.map((
|
|
18925
|
-
const px = Math.cos(
|
|
18926
|
-
const py = Math.sin(
|
|
19723
|
+
const spokes = angles.map((angle2) => {
|
|
19724
|
+
const px = Math.cos(angle2) * radius;
|
|
19725
|
+
const py = Math.sin(angle2) * radius;
|
|
18927
19726
|
return newLinearElement3({
|
|
18928
19727
|
backgroundColor: "transparent",
|
|
18929
19728
|
...commonProps,
|
|
@@ -18939,12 +19738,12 @@ var renderRadarChart = (spreadsheet, x, y, colorSeed) => {
|
|
|
18939
19738
|
});
|
|
18940
19739
|
});
|
|
18941
19740
|
const seriesPolygons = series.map((seriesData, index) => {
|
|
18942
|
-
const points = angles.map((
|
|
19741
|
+
const points = angles.map((angle2, axisIndex) => {
|
|
18943
19742
|
const value = seriesData.values[axisIndex] ?? 0;
|
|
18944
19743
|
const pointRadius = normalize(value, axisIndex) * radius;
|
|
18945
19744
|
return pointFrom24(
|
|
18946
|
-
Math.cos(
|
|
18947
|
-
Math.sin(
|
|
19745
|
+
Math.cos(angle2) * pointRadius,
|
|
19746
|
+
Math.sin(angle2) * pointRadius
|
|
18948
19747
|
);
|
|
18949
19748
|
});
|
|
18950
19749
|
points.push(pointFrom24(points[0][0], points[0][1]));
|
|
@@ -19430,7 +20229,7 @@ var filterLinearConvertibleElements = (elements) => elements.filter(
|
|
|
19430
20229
|
var THRESHOLD = 20;
|
|
19431
20230
|
var isVert = (a, b) => a[0] === b[0];
|
|
19432
20231
|
var isHorz = (a, b) => a[1] === b[1];
|
|
19433
|
-
var
|
|
20232
|
+
var dist2 = (a, b) => isVert(a, b) ? Math.abs(a[1] - b[1]) : Math.abs(a[0] - b[0]);
|
|
19434
20233
|
var convertLineToElbow = (line) => {
|
|
19435
20234
|
const ortho = [line.points[0]];
|
|
19436
20235
|
const src = sanitizePoints(line.points);
|
|
@@ -19464,8 +20263,8 @@ var convertLineToElbow = (line) => {
|
|
|
19464
20263
|
const v1 = isVert(a, b);
|
|
19465
20264
|
const v2 = isVert(b, c);
|
|
19466
20265
|
if (v1 !== v2) {
|
|
19467
|
-
const d1 =
|
|
19468
|
-
const d2 =
|
|
20266
|
+
const d1 = dist2(a, b);
|
|
20267
|
+
const d2 = dist2(b, c);
|
|
19469
20268
|
if (d1 < THRESHOLD || d2 < THRESHOLD) {
|
|
19470
20269
|
if (d2 < d1) {
|
|
19471
20270
|
if (v1) {
|
|
@@ -19522,7 +20321,7 @@ var convertElementType = (element, targetType, app) => {
|
|
|
19522
20321
|
newElement5({
|
|
19523
20322
|
...element,
|
|
19524
20323
|
type: targetType,
|
|
19525
|
-
roundness:
|
|
20324
|
+
roundness: element.roundness ? {
|
|
19526
20325
|
type: isUsingAdaptiveRadius3(targetType) ? ROUNDNESS6.ADAPTIVE_RADIUS : ROUNDNESS6.PROPORTIONAL_RADIUS
|
|
19527
20326
|
} : element.roundness
|
|
19528
20327
|
})
|
|
@@ -20645,7 +21444,7 @@ var SelectedShapeActions = ({
|
|
|
20645
21444
|
canChangeBackgroundColor(appState, targetElements) && /* @__PURE__ */ jsx75("div", { children: renderAction("changeBackgroundColor") }),
|
|
20646
21445
|
showFillIcons && renderAction("changeFillStyle"),
|
|
20647
21446
|
(hasStrokeWidth(appState.activeTool.type) || targetElements.some((element) => hasStrokeWidth(element.type))) && renderAction("changeStrokeWidth"),
|
|
20648
|
-
(appState.activeTool.type
|
|
21447
|
+
(hasFreedrawMode(appState.activeTool.type) || targetElements.some((element) => hasFreedrawMode(element.type))) && renderAction("changeFreedrawMode"),
|
|
20649
21448
|
(hasStrokeStyle(appState.activeTool.type) || targetElements.some((element) => hasStrokeStyle(element.type))) && /* @__PURE__ */ jsxs35(Fragment8, { children: [
|
|
20650
21449
|
renderAction("changeStrokeStyle"),
|
|
20651
21450
|
renderAction("changeSloppiness")
|
|
@@ -20778,6 +21577,13 @@ var CombinedShapeProperties = ({
|
|
|
20778
21577
|
(hasStrokeWidth(appState.activeTool.type) || targetElements.some(
|
|
20779
21578
|
(element) => hasStrokeWidth(element.type)
|
|
20780
21579
|
)) && renderAction("changeStrokeWidth"),
|
|
21580
|
+
/* in compact UI the freedraw pressure setting is rendered as a
|
|
21581
|
+
standalone cycle button in the compact actions list; we render
|
|
21582
|
+
it in the combined properties popup as well for clarity
|
|
21583
|
+
*/
|
|
21584
|
+
(hasFreedrawMode(appState.activeTool.type) || targetElements.some(
|
|
21585
|
+
(element) => hasFreedrawMode(element.type)
|
|
21586
|
+
)) && renderAction("changeFreedrawMode"),
|
|
20781
21587
|
(hasStrokeStyle(appState.activeTool.type) || targetElements.some(
|
|
20782
21588
|
(element) => hasStrokeStyle(element.type)
|
|
20783
21589
|
)) && /* @__PURE__ */ jsxs35(Fragment8, { children: [
|
|
@@ -21105,6 +21911,7 @@ var CompactShapeActions = ({
|
|
|
21105
21911
|
return /* @__PURE__ */ jsxs35("div", { className: "compact-shape-actions", children: [
|
|
21106
21912
|
canChangeStrokeColor(appState, targetElements) && /* @__PURE__ */ jsx75("div", { className: clsx29("compact-action-item"), children: renderAction("changeStrokeColor") }),
|
|
21107
21913
|
canChangeBackgroundColor(appState, targetElements) && /* @__PURE__ */ jsx75("div", { className: "compact-action-item", children: renderAction("changeBackgroundColor") }),
|
|
21914
|
+
(hasFreedrawMode(appState.activeTool.type) || targetElements.some((element) => hasFreedrawMode(element.type))) && /* @__PURE__ */ jsx75("div", { className: "compact-action-item", children: renderAction("changeFreedrawMode", { cycle: true }) }),
|
|
21108
21915
|
/* @__PURE__ */ jsx75(
|
|
21109
21916
|
CombinedShapeProperties,
|
|
21110
21917
|
{
|
|
@@ -21293,6 +22100,7 @@ var ShapesSwitcher = ({
|
|
|
21293
22100
|
const stylesPanelMode = useStylesPanelMode();
|
|
21294
22101
|
const isFullStylesPanel = stylesPanelMode === "full";
|
|
21295
22102
|
const isCompactStylesPanel = stylesPanelMode === "compact";
|
|
22103
|
+
const pendingPenDetectionRef = useRef16(false);
|
|
21296
22104
|
const SELECTION_TOOLS2 = [
|
|
21297
22105
|
{
|
|
21298
22106
|
type: "selection",
|
|
@@ -21418,7 +22226,7 @@ var ShapesSwitcher = ({
|
|
|
21418
22226
|
"data-testid": `toolbar-${value}`,
|
|
21419
22227
|
onPointerDown: ({ pointerType }) => {
|
|
21420
22228
|
if (!app.state.penDetected && pointerType === "pen") {
|
|
21421
|
-
|
|
22229
|
+
pendingPenDetectionRef.current = true;
|
|
21422
22230
|
}
|
|
21423
22231
|
if (value === "selection") {
|
|
21424
22232
|
if (app.state.activeTool.type === "selection") {
|
|
@@ -21428,16 +22236,14 @@ var ShapesSwitcher = ({
|
|
|
21428
22236
|
}
|
|
21429
22237
|
}
|
|
21430
22238
|
},
|
|
21431
|
-
onChange: (
|
|
22239
|
+
onChange: () => {
|
|
21432
22240
|
if (app.state.activeTool.type !== value) {
|
|
21433
22241
|
trackEvent("toolbar", value, "ui");
|
|
21434
22242
|
}
|
|
21435
|
-
|
|
21436
|
-
|
|
21437
|
-
|
|
21438
|
-
|
|
21439
|
-
} else {
|
|
21440
|
-
app.setActiveTool({ type: value });
|
|
22243
|
+
app.setActiveTool({ type: value });
|
|
22244
|
+
if (pendingPenDetectionRef.current) {
|
|
22245
|
+
pendingPenDetectionRef.current = false;
|
|
22246
|
+
requestAnimationFrame(() => app.togglePenMode(true));
|
|
21441
22247
|
}
|
|
21442
22248
|
}
|
|
21443
22249
|
},
|
|
@@ -25250,7 +26056,7 @@ var CanvasGrid = ({
|
|
|
25250
26056
|
var CanvasGrid_default = CanvasGrid;
|
|
25251
26057
|
|
|
25252
26058
|
// components/Stats/Dimension.tsx
|
|
25253
|
-
import { clamp as
|
|
26059
|
+
import { clamp as clamp7, round as round3 } from "@excalidraw/math";
|
|
25254
26060
|
import { MIN_WIDTH_OR_HEIGHT } from "@excalidraw/common";
|
|
25255
26061
|
import {
|
|
25256
26062
|
MINIMAL_CROP_SIZE,
|
|
@@ -25305,7 +26111,7 @@ var handleDimensionChange = ({
|
|
|
25305
26111
|
if (nextValue !== void 0) {
|
|
25306
26112
|
if (property === "width") {
|
|
25307
26113
|
const nextValueInNatural = nextValue * naturalToUncroppedWidthRatio;
|
|
25308
|
-
const nextCropWidth2 =
|
|
26114
|
+
const nextCropWidth2 = clamp7(
|
|
25309
26115
|
nextValueInNatural,
|
|
25310
26116
|
MIN_WIDTH,
|
|
25311
26117
|
MAX_POSSIBLE_WIDTH
|
|
@@ -25317,7 +26123,7 @@ var handleDimensionChange = ({
|
|
|
25317
26123
|
};
|
|
25318
26124
|
} else if (property === "height") {
|
|
25319
26125
|
const nextValueInNatural = nextValue * naturalToUncroppedHeightRatio;
|
|
25320
|
-
const nextCropHeight2 =
|
|
26126
|
+
const nextCropHeight2 = clamp7(
|
|
25321
26127
|
nextValueInNatural,
|
|
25322
26128
|
MIN_HEIGHT,
|
|
25323
26129
|
MAX_POSSIBLE_HEIGHT
|
|
@@ -25337,12 +26143,12 @@ var handleDimensionChange = ({
|
|
|
25337
26143
|
}
|
|
25338
26144
|
const changeInWidth = property === "width" ? instantChange : 0;
|
|
25339
26145
|
const changeInHeight = property === "height" ? instantChange : 0;
|
|
25340
|
-
const nextCropWidth =
|
|
26146
|
+
const nextCropWidth = clamp7(
|
|
25341
26147
|
crop.width + changeInWidth,
|
|
25342
26148
|
MIN_WIDTH,
|
|
25343
26149
|
MAX_POSSIBLE_WIDTH
|
|
25344
26150
|
);
|
|
25345
|
-
const nextCropHeight =
|
|
26151
|
+
const nextCropHeight = clamp7(
|
|
25346
26152
|
crop.height + changeInHeight,
|
|
25347
26153
|
MIN_WIDTH,
|
|
25348
26154
|
MAX_POSSIBLE_HEIGHT
|
|
@@ -25696,7 +26502,7 @@ import { getBoundTextElement as getBoundTextElement13, handleBindTextResize as h
|
|
|
25696
26502
|
import { isTextElement as isTextElement13 } from "@excalidraw/element";
|
|
25697
26503
|
|
|
25698
26504
|
// ../utils/src/export.ts
|
|
25699
|
-
import { MIME_TYPES as
|
|
26505
|
+
import { MIME_TYPES as MIME_TYPES7 } from "@excalidraw/common";
|
|
25700
26506
|
var exportToCanvas2 = ({
|
|
25701
26507
|
elements,
|
|
25702
26508
|
appState,
|
|
@@ -25744,16 +26550,16 @@ var exportToCanvas2 = ({
|
|
|
25744
26550
|
);
|
|
25745
26551
|
};
|
|
25746
26552
|
var exportToBlob = async (opts) => {
|
|
25747
|
-
let { mimeType =
|
|
25748
|
-
if (mimeType ===
|
|
25749
|
-
console.warn(`"quality" will be ignored for "${
|
|
26553
|
+
let { mimeType = MIME_TYPES7.png, quality } = opts;
|
|
26554
|
+
if (mimeType === MIME_TYPES7.png && typeof quality === "number") {
|
|
26555
|
+
console.warn(`"quality" will be ignored for "${MIME_TYPES7.png}" mimeType`);
|
|
25750
26556
|
}
|
|
25751
26557
|
if (mimeType === "image/jpg") {
|
|
25752
|
-
mimeType =
|
|
26558
|
+
mimeType = MIME_TYPES7.jpg;
|
|
25753
26559
|
}
|
|
25754
|
-
if (mimeType ===
|
|
26560
|
+
if (mimeType === MIME_TYPES7.jpg && !opts.appState?.exportBackground) {
|
|
25755
26561
|
console.warn(
|
|
25756
|
-
`Defaulting "exportBackground" to "true" for "${
|
|
26562
|
+
`Defaulting "exportBackground" to "true" for "${MIME_TYPES7.jpg}" mimeType`
|
|
25757
26563
|
);
|
|
25758
26564
|
opts = {
|
|
25759
26565
|
...opts,
|
|
@@ -25768,7 +26574,7 @@ var exportToBlob = async (opts) => {
|
|
|
25768
26574
|
if (!blob) {
|
|
25769
26575
|
return reject(new Error("couldn't export to blob"));
|
|
25770
26576
|
}
|
|
25771
|
-
if (blob && mimeType ===
|
|
26577
|
+
if (blob && mimeType === MIME_TYPES7.png && opts.appState?.exportEmbedScene) {
|
|
25772
26578
|
blob = await encodePngMetadata({
|
|
25773
26579
|
blob,
|
|
25774
26580
|
metadata: serializeAsJSON(
|
|
@@ -26469,7 +27275,7 @@ var MultiPosition = ({
|
|
|
26469
27275
|
var MultiPosition_default = MultiPosition;
|
|
26470
27276
|
|
|
26471
27277
|
// components/Stats/Position.tsx
|
|
26472
|
-
import { clamp as
|
|
27278
|
+
import { clamp as clamp8, pointFrom as pointFrom29, pointRotateRads as pointRotateRads19, round as round4 } from "@excalidraw/math";
|
|
26473
27279
|
import {
|
|
26474
27280
|
getFlipAdjustedCropPosition,
|
|
26475
27281
|
getUncroppedWidthAndHeight as getUncroppedWidthAndHeight2
|
|
@@ -26515,7 +27321,7 @@ var handlePositionChange2 = ({
|
|
|
26515
27321
|
if (isFlippedByX) {
|
|
26516
27322
|
nextCrop = {
|
|
26517
27323
|
...crop,
|
|
26518
|
-
x:
|
|
27324
|
+
x: clamp8(
|
|
26519
27325
|
crop.naturalWidth - nextValueInNatural - crop.width,
|
|
26520
27326
|
0,
|
|
26521
27327
|
crop.naturalWidth - crop.width
|
|
@@ -26524,7 +27330,7 @@ var handlePositionChange2 = ({
|
|
|
26524
27330
|
} else {
|
|
26525
27331
|
nextCrop = {
|
|
26526
27332
|
...crop,
|
|
26527
|
-
x:
|
|
27333
|
+
x: clamp8(
|
|
26528
27334
|
nextValue * (crop.naturalWidth / uncroppedWidth),
|
|
26529
27335
|
0,
|
|
26530
27336
|
crop.naturalWidth - crop.width
|
|
@@ -26535,7 +27341,7 @@ var handlePositionChange2 = ({
|
|
|
26535
27341
|
if (property === "y") {
|
|
26536
27342
|
nextCrop = {
|
|
26537
27343
|
...crop,
|
|
26538
|
-
y:
|
|
27344
|
+
y: clamp8(
|
|
26539
27345
|
nextValue * (crop.naturalHeight / uncroppedHeight),
|
|
26540
27346
|
0,
|
|
26541
27347
|
crop.naturalHeight - crop.height
|
|
@@ -26551,8 +27357,8 @@ var handlePositionChange2 = ({
|
|
|
26551
27357
|
const changeInY = (property === "y" ? instantChange : 0) * (isFlippedByY ? -1 : 1);
|
|
26552
27358
|
nextCrop = {
|
|
26553
27359
|
...crop,
|
|
26554
|
-
x:
|
|
26555
|
-
y:
|
|
27360
|
+
x: clamp8(crop.x + changeInX, 0, crop.naturalWidth - crop.width),
|
|
27361
|
+
y: clamp8(crop.y + changeInY, 0, crop.naturalHeight - crop.height)
|
|
26556
27362
|
};
|
|
26557
27363
|
scene.mutateElement(element, {
|
|
26558
27364
|
crop: nextCrop
|
|
@@ -28794,7 +29600,6 @@ var LayerUI = ({
|
|
|
28794
29600
|
renderWelcomeScreen && /* @__PURE__ */ jsx130(tunnels.WelcomeScreenMenuHintTunnel.Out, {})
|
|
28795
29601
|
] });
|
|
28796
29602
|
const renderSelectedShapeActions = () => {
|
|
28797
|
-
const isCompactMode = isCompactStylesPanel;
|
|
28798
29603
|
return /* @__PURE__ */ jsx130(
|
|
28799
29604
|
Section,
|
|
28800
29605
|
{
|
|
@@ -28802,7 +29607,7 @@ var LayerUI = ({
|
|
|
28802
29607
|
className: clsx55("selected-shape-actions zen-mode-transition", {
|
|
28803
29608
|
"transition-left": appState.zenModeEnabled
|
|
28804
29609
|
}),
|
|
28805
|
-
children:
|
|
29610
|
+
children: isCompactStylesPanel ? /* @__PURE__ */ jsx130(
|
|
28806
29611
|
Island,
|
|
28807
29612
|
{
|
|
28808
29613
|
className: clsx55("compact-shape-actions-island"),
|
|
@@ -28873,6 +29678,17 @@ var LayerUI = ({
|
|
|
28873
29678
|
}),
|
|
28874
29679
|
children: shouldRenderSelectedShapeActions && renderSelectedShapeActions()
|
|
28875
29680
|
}
|
|
29681
|
+
),
|
|
29682
|
+
isCompactStylesPanel && !appState.viewModeEnabled && shouldRenderSelectedShapeActions && /* @__PURE__ */ jsx130(
|
|
29683
|
+
PenModeButton,
|
|
29684
|
+
{
|
|
29685
|
+
zenModeEnabled: appState.zenModeEnabled,
|
|
29686
|
+
checked: appState.penMode,
|
|
29687
|
+
onChange: () => onPenModeToggle(null),
|
|
29688
|
+
title: t("toolBar.penMode"),
|
|
29689
|
+
isMobile: true,
|
|
29690
|
+
penDetected: appState.penDetected
|
|
29691
|
+
}
|
|
28876
29692
|
)
|
|
28877
29693
|
]
|
|
28878
29694
|
}
|
|
@@ -28907,7 +29723,7 @@ var LayerUI = ({
|
|
|
28907
29723
|
),
|
|
28908
29724
|
heading,
|
|
28909
29725
|
/* @__PURE__ */ jsxs67(Stack_default.Row, { gap: spacing.toolbarInnerRowGap, children: [
|
|
28910
|
-
/* @__PURE__ */ jsx130(
|
|
29726
|
+
!isCompactStylesPanel && /* @__PURE__ */ jsx130(
|
|
28911
29727
|
PenModeButton,
|
|
28912
29728
|
{
|
|
28913
29729
|
zenModeEnabled: appState.zenModeEnabled,
|
|
@@ -29295,7 +30111,7 @@ import {
|
|
|
29295
30111
|
|
|
29296
30112
|
// renderer/interactiveScene.ts
|
|
29297
30113
|
import {
|
|
29298
|
-
clamp as
|
|
30114
|
+
clamp as clamp9,
|
|
29299
30115
|
pointFrom as pointFrom31,
|
|
29300
30116
|
pointsEqual as pointsEqual8,
|
|
29301
30117
|
bezierEquation as bezierEquation2,
|
|
@@ -29601,7 +30417,7 @@ var renderBindingHighlightForBindableElement_simple = (context, suggestedBinding
|
|
|
29601
30417
|
context.rotate(suggestedBinding.element.angle);
|
|
29602
30418
|
context.translate(-center[0], -center[1]);
|
|
29603
30419
|
context.translate(suggestedBinding.element.x, suggestedBinding.element.y);
|
|
29604
|
-
context.lineWidth =
|
|
30420
|
+
context.lineWidth = clamp9(1.75, suggestedBinding.element.strokeWidth, 4) / Math.max(0.25, appState.zoom.value);
|
|
29605
30421
|
context.strokeStyle = appState.theme === THEME16.DARK ? `rgba(3, 93, 161, 1)` : `rgba(106, 189, 252, 1)`;
|
|
29606
30422
|
switch (suggestedBinding.element.type) {
|
|
29607
30423
|
case "ellipse":
|
|
@@ -29792,7 +30608,7 @@ var renderBindingHighlightForBindableElement_simple = (context, suggestedBinding
|
|
|
29792
30608
|
var renderBindingHighlightForBindableElement_complex = (app, context, element, allElementsMap, appState, deltaTime, state) => {
|
|
29793
30609
|
const countdownInProgress = app.state.bindMode === "orbit" && app.bindModeHandler !== null;
|
|
29794
30610
|
const remainingTime = BIND_MODE_TIMEOUT - (state?.runtime ?? (countdownInProgress ? 0 : BIND_MODE_TIMEOUT));
|
|
29795
|
-
const opacity =
|
|
30611
|
+
const opacity = clamp9(1 / BIND_MODE_TIMEOUT * remainingTime, 1e-4, 1);
|
|
29796
30612
|
const offset = element.strokeWidth / 2;
|
|
29797
30613
|
const enclosingFrame = element.frameId && allElementsMap.get(element.frameId);
|
|
29798
30614
|
if (enclosingFrame && isFrameLikeElement14(enclosingFrame)) {
|
|
@@ -29847,7 +30663,7 @@ var renderBindingHighlightForBindableElement_complex = (app, context, element, a
|
|
|
29847
30663
|
element.x + appState.scrollX - offset,
|
|
29848
30664
|
element.y + appState.scrollY - offset
|
|
29849
30665
|
);
|
|
29850
|
-
context.lineWidth =
|
|
30666
|
+
context.lineWidth = clamp9(2.5, element.strokeWidth * 1.75, 4) / Math.max(0.25, appState.zoom.value);
|
|
29851
30667
|
context.strokeStyle = appState.theme === THEME16.DARK ? `rgba(3, 93, 161, ${opacity / 2})` : `rgba(106, 189, 252, ${opacity / 2})`;
|
|
29852
30668
|
switch (element.type) {
|
|
29853
30669
|
case "ellipse":
|
|
@@ -30083,7 +30899,7 @@ var renderBindingHighlightForBindableElement = (app, context, suggestedBinding,
|
|
|
30083
30899
|
};
|
|
30084
30900
|
var renderSelectionBorder = (context, appState, elementProperties) => {
|
|
30085
30901
|
const {
|
|
30086
|
-
angle,
|
|
30902
|
+
angle: angle2,
|
|
30087
30903
|
x1,
|
|
30088
30904
|
y1,
|
|
30089
30905
|
x2,
|
|
@@ -30121,7 +30937,7 @@ var renderSelectionBorder = (context, appState, elementProperties) => {
|
|
|
30121
30937
|
elementHeight + linePadding * 2,
|
|
30122
30938
|
cx,
|
|
30123
30939
|
cy,
|
|
30124
|
-
|
|
30940
|
+
angle2
|
|
30125
30941
|
);
|
|
30126
30942
|
}
|
|
30127
30943
|
context.restore();
|
|
@@ -30353,7 +31169,7 @@ var renderFocusPointIndicator = ({
|
|
|
30353
31169
|
);
|
|
30354
31170
|
}
|
|
30355
31171
|
};
|
|
30356
|
-
var renderTransformHandles = (context, renderConfig, appState, transformHandles,
|
|
31172
|
+
var renderTransformHandles = (context, renderConfig, appState, transformHandles, angle2) => {
|
|
30357
31173
|
Object.keys(transformHandles).forEach((key) => {
|
|
30358
31174
|
const transformHandle = transformHandles[key];
|
|
30359
31175
|
if (transformHandle !== void 0) {
|
|
@@ -30379,7 +31195,7 @@ var renderTransformHandles = (context, renderConfig, appState, transformHandles,
|
|
|
30379
31195
|
height,
|
|
30380
31196
|
x + width / 2,
|
|
30381
31197
|
y + height / 2,
|
|
30382
|
-
|
|
31198
|
+
angle2,
|
|
30383
31199
|
true
|
|
30384
31200
|
// fill before stroke
|
|
30385
31201
|
);
|
|
@@ -30511,6 +31327,46 @@ var renderResetAutoResizeHandle = (text, context, appState, selectionColor, form
|
|
|
30511
31327
|
context.stroke();
|
|
30512
31328
|
context.restore();
|
|
30513
31329
|
};
|
|
31330
|
+
var renderImageLoadingProgress = (context, visibleElements, elementsMap, app, appState, selectionColor) => {
|
|
31331
|
+
for (const element of visibleElements) {
|
|
31332
|
+
if (!isImageElement8(element) || !element.fileId || element.status === "error") {
|
|
31333
|
+
continue;
|
|
31334
|
+
}
|
|
31335
|
+
const progress = app.imageLoadingProgress.get(element.fileId);
|
|
31336
|
+
if (progress === void 0) {
|
|
31337
|
+
continue;
|
|
31338
|
+
}
|
|
31339
|
+
const [x1, y1, x2, y2] = getElementAbsoluteCoords7(element, elementsMap);
|
|
31340
|
+
const centerX = (x1 + x2) / 2 + appState.scrollX;
|
|
31341
|
+
const centerY = (y1 + y2) / 2 + appState.scrollY;
|
|
31342
|
+
const zoom = appState.zoom.value;
|
|
31343
|
+
const radius = Math.min(14, Math.min(x2 - x1, y2 - y1) * zoom / 4) / zoom;
|
|
31344
|
+
const lineWidth = Math.min(3 / zoom, radius / 2);
|
|
31345
|
+
if (radius <= 0 || lineWidth <= 0) {
|
|
31346
|
+
continue;
|
|
31347
|
+
}
|
|
31348
|
+
context.save();
|
|
31349
|
+
context.lineWidth = lineWidth;
|
|
31350
|
+
context.lineCap = "round";
|
|
31351
|
+
context.strokeStyle = appState.theme === THEME16.DARK ? "rgba(255, 255, 255, 0.35)" : "rgba(0, 0, 0, 0.25)";
|
|
31352
|
+
context.beginPath();
|
|
31353
|
+
context.arc(centerX, centerY, radius, 0, Math.PI * 2);
|
|
31354
|
+
context.stroke();
|
|
31355
|
+
if (progress > 0) {
|
|
31356
|
+
context.strokeStyle = selectionColor;
|
|
31357
|
+
context.beginPath();
|
|
31358
|
+
context.arc(
|
|
31359
|
+
centerX,
|
|
31360
|
+
centerY,
|
|
31361
|
+
radius,
|
|
31362
|
+
-Math.PI / 2,
|
|
31363
|
+
-Math.PI / 2 + Math.PI * 2 * progress
|
|
31364
|
+
);
|
|
31365
|
+
context.stroke();
|
|
31366
|
+
}
|
|
31367
|
+
context.restore();
|
|
31368
|
+
}
|
|
31369
|
+
};
|
|
30514
31370
|
var _renderInteractiveScene = ({
|
|
30515
31371
|
app,
|
|
30516
31372
|
canvas,
|
|
@@ -30868,6 +31724,14 @@ var _renderInteractiveScene = ({
|
|
|
30868
31724
|
}
|
|
30869
31725
|
});
|
|
30870
31726
|
renderSnaps(context, appState);
|
|
31727
|
+
renderImageLoadingProgress(
|
|
31728
|
+
context,
|
|
31729
|
+
visibleElements,
|
|
31730
|
+
elementsMap,
|
|
31731
|
+
app,
|
|
31732
|
+
appState,
|
|
31733
|
+
renderConfig.selectionColor
|
|
31734
|
+
);
|
|
30871
31735
|
context.restore();
|
|
30872
31736
|
renderRemoteCursors({
|
|
30873
31737
|
context,
|
|
@@ -30920,6 +31784,31 @@ var INTERACTIVE_SCENE_ANIMATION_KEY = "animateInteractiveScene";
|
|
|
30920
31784
|
var InteractiveCanvas = (props) => {
|
|
30921
31785
|
const isComponentMounted = useRef27(false);
|
|
30922
31786
|
const rendererParams = useRef27(null);
|
|
31787
|
+
useEffect31(() => {
|
|
31788
|
+
let scheduledFrame = null;
|
|
31789
|
+
const unsubscribe = props.app.imageLoadingProgressEmitter.on(() => {
|
|
31790
|
+
if (scheduledFrame !== null) {
|
|
31791
|
+
return;
|
|
31792
|
+
}
|
|
31793
|
+
scheduledFrame = requestAnimationFrame(() => {
|
|
31794
|
+
scheduledFrame = null;
|
|
31795
|
+
if (!rendererParams.current) {
|
|
31796
|
+
return;
|
|
31797
|
+
}
|
|
31798
|
+
renderInteractiveScene({
|
|
31799
|
+
...rendererParams.current,
|
|
31800
|
+
callback: () => {
|
|
31801
|
+
}
|
|
31802
|
+
});
|
|
31803
|
+
});
|
|
31804
|
+
});
|
|
31805
|
+
return () => {
|
|
31806
|
+
unsubscribe();
|
|
31807
|
+
if (scheduledFrame !== null) {
|
|
31808
|
+
cancelAnimationFrame(scheduledFrame);
|
|
31809
|
+
}
|
|
31810
|
+
};
|
|
31811
|
+
}, [props.app]);
|
|
30923
31812
|
useEffect31(() => {
|
|
30924
31813
|
if (!isComponentMounted.current) {
|
|
30925
31814
|
isComponentMounted.current = true;
|
|
@@ -31099,6 +31988,54 @@ import { jsx as jsx134 } from "react/jsx-runtime";
|
|
|
31099
31988
|
var StaticCanvas = (props) => {
|
|
31100
31989
|
const wrapperRef = useRef28(null);
|
|
31101
31990
|
const isComponentMounted = useRef28(false);
|
|
31991
|
+
const propsRef = useRef28(props);
|
|
31992
|
+
const renderCanvasRef = useRef28(() => {
|
|
31993
|
+
});
|
|
31994
|
+
const transitionFrameRef = useRef28(null);
|
|
31995
|
+
propsRef.current = props;
|
|
31996
|
+
const renderCanvas = React39.useCallback(() => {
|
|
31997
|
+
const currentProps = propsRef.current;
|
|
31998
|
+
const wrapper = wrapperRef.current;
|
|
31999
|
+
if (!wrapper) {
|
|
32000
|
+
return;
|
|
32001
|
+
}
|
|
32002
|
+
const gridColorBold = getComputedStyle(wrapper).getPropertyValue("--color-grid-bold").trim();
|
|
32003
|
+
const gridColorRegular = getComputedStyle(wrapper).getPropertyValue("--color-grid-regular").trim();
|
|
32004
|
+
renderStaticScene(
|
|
32005
|
+
{
|
|
32006
|
+
canvas: currentProps.canvas,
|
|
32007
|
+
rc: currentProps.rc,
|
|
32008
|
+
scale: currentProps.scale,
|
|
32009
|
+
elementsMap: currentProps.elementsMap,
|
|
32010
|
+
allElementsMap: currentProps.allElementsMap,
|
|
32011
|
+
visibleElements: currentProps.visibleElements,
|
|
32012
|
+
appState: currentProps.appState,
|
|
32013
|
+
renderConfig: {
|
|
32014
|
+
...currentProps.renderConfig,
|
|
32015
|
+
gridColorBold,
|
|
32016
|
+
gridColorRegular
|
|
32017
|
+
}
|
|
32018
|
+
},
|
|
32019
|
+
isRenderThrottlingEnabled()
|
|
32020
|
+
);
|
|
32021
|
+
const transitionDuration = currentProps.renderConfig.imageTransitionDuration ?? 0;
|
|
32022
|
+
const hasActiveTransition = transitionDuration > 0 && currentProps.visibleElements.some((element) => {
|
|
32023
|
+
if (element.type !== "image" || !element.fileId) {
|
|
32024
|
+
return false;
|
|
32025
|
+
}
|
|
32026
|
+
const transitionStart = currentProps.renderConfig.imageCache.get(
|
|
32027
|
+
element.fileId
|
|
32028
|
+
)?.transitionStart;
|
|
32029
|
+
return transitionStart !== void 0 && performance.now() - transitionStart < transitionDuration;
|
|
32030
|
+
});
|
|
32031
|
+
if (hasActiveTransition && transitionFrameRef.current === null) {
|
|
32032
|
+
transitionFrameRef.current = requestAnimationFrame(() => {
|
|
32033
|
+
transitionFrameRef.current = null;
|
|
32034
|
+
renderCanvasRef.current();
|
|
32035
|
+
});
|
|
32036
|
+
}
|
|
32037
|
+
}, []);
|
|
32038
|
+
renderCanvasRef.current = renderCanvas;
|
|
31102
32039
|
useEffect32(() => {
|
|
31103
32040
|
props.canvas.style.width = `${props.appState.width}px`;
|
|
31104
32041
|
props.canvas.style.height = `${props.appState.height}px`;
|
|
@@ -31116,26 +32053,34 @@ var StaticCanvas = (props) => {
|
|
|
31116
32053
|
wrapper.replaceChildren(canvas);
|
|
31117
32054
|
canvas.classList.add("excalidraw__canvas", "static");
|
|
31118
32055
|
}
|
|
31119
|
-
|
|
31120
|
-
const gridColorRegular = getComputedStyle(wrapper).getPropertyValue("--color-grid-regular").trim();
|
|
31121
|
-
renderStaticScene(
|
|
31122
|
-
{
|
|
31123
|
-
canvas,
|
|
31124
|
-
rc: props.rc,
|
|
31125
|
-
scale: props.scale,
|
|
31126
|
-
elementsMap: props.elementsMap,
|
|
31127
|
-
allElementsMap: props.allElementsMap,
|
|
31128
|
-
visibleElements: props.visibleElements,
|
|
31129
|
-
appState: props.appState,
|
|
31130
|
-
renderConfig: {
|
|
31131
|
-
...props.renderConfig,
|
|
31132
|
-
gridColorBold,
|
|
31133
|
-
gridColorRegular
|
|
31134
|
-
}
|
|
31135
|
-
},
|
|
31136
|
-
isRenderThrottlingEnabled()
|
|
31137
|
-
);
|
|
32056
|
+
renderCanvas();
|
|
31138
32057
|
});
|
|
32058
|
+
useEffect32(() => {
|
|
32059
|
+
let scheduledFrame = null;
|
|
32060
|
+
const unsubscribe = props.app.imagePlaceholderUpdateEmitter.on(() => {
|
|
32061
|
+
if (scheduledFrame !== null) {
|
|
32062
|
+
return;
|
|
32063
|
+
}
|
|
32064
|
+
scheduledFrame = requestAnimationFrame(() => {
|
|
32065
|
+
scheduledFrame = null;
|
|
32066
|
+
renderCanvas();
|
|
32067
|
+
});
|
|
32068
|
+
});
|
|
32069
|
+
return () => {
|
|
32070
|
+
unsubscribe();
|
|
32071
|
+
if (scheduledFrame !== null) {
|
|
32072
|
+
cancelAnimationFrame(scheduledFrame);
|
|
32073
|
+
}
|
|
32074
|
+
};
|
|
32075
|
+
}, [props.app, renderCanvas]);
|
|
32076
|
+
useEffect32(
|
|
32077
|
+
() => () => {
|
|
32078
|
+
if (transitionFrameRef.current !== null) {
|
|
32079
|
+
cancelAnimationFrame(transitionFrameRef.current);
|
|
32080
|
+
}
|
|
32081
|
+
},
|
|
32082
|
+
[]
|
|
32083
|
+
);
|
|
31139
32084
|
return /* @__PURE__ */ jsx134("div", { className: "excalidraw__canvas-wrapper", ref: wrapperRef });
|
|
31140
32085
|
};
|
|
31141
32086
|
var getRelevantAppStateProps2 = (appState) => {
|
|
@@ -31571,6 +32516,10 @@ var App = class _App extends React40.Component {
|
|
|
31571
32516
|
__publicField(this, "excalidrawContainerValue");
|
|
31572
32517
|
__publicField(this, "files", {});
|
|
31573
32518
|
__publicField(this, "imageCache", /* @__PURE__ */ new Map());
|
|
32519
|
+
__publicField(this, "imageLoadingProgress", /* @__PURE__ */ new Map());
|
|
32520
|
+
__publicField(this, "imageLoadingProgressEmitter", new Emitter2());
|
|
32521
|
+
__publicField(this, "imagePlaceholderUpdateEmitter", new Emitter2());
|
|
32522
|
+
__publicField(this, "imageTransitionPlaceholders", /* @__PURE__ */ new Map());
|
|
31574
32523
|
__publicField(this, "iFrameRefs", /* @__PURE__ */ new Map());
|
|
31575
32524
|
/**
|
|
31576
32525
|
* Indicates whether the embeddable's url has been validated for rendering.
|
|
@@ -32610,7 +33559,8 @@ var App = class _App extends React40.Component {
|
|
|
32610
33559
|
this.setState((prevState) => {
|
|
32611
33560
|
return {
|
|
32612
33561
|
penMode: force ?? !prevState.penMode,
|
|
32613
|
-
penDetected: true
|
|
33562
|
+
penDetected: true,
|
|
33563
|
+
currentItemStrokeVariability: !prevState.penDetected ? "variable" : prevState.currentItemStrokeVariability
|
|
32614
33564
|
};
|
|
32615
33565
|
});
|
|
32616
33566
|
});
|
|
@@ -32635,120 +33585,92 @@ var App = class _App extends React40.Component {
|
|
|
32635
33585
|
__publicField(this, "cancelInProgressAnimation", null);
|
|
32636
33586
|
__publicField(this, "scrollToViewport", (target, opts) => {
|
|
32637
33587
|
this.cancelInProgressAnimation?.();
|
|
33588
|
+
AnimationController.cancel(SCROLL_TO_CONTENT_ANIMATION_KEY);
|
|
32638
33589
|
const zoom = { value: getNormalizedZoom(target.zoom) };
|
|
32639
33590
|
const animateDuration = opts?.duration ?? 500;
|
|
32640
33591
|
if (opts?.animate && animateDuration > 0) {
|
|
32641
|
-
const
|
|
32642
|
-
|
|
32643
|
-
|
|
32644
|
-
|
|
32645
|
-
|
|
32646
|
-
|
|
32647
|
-
|
|
32648
|
-
|
|
32649
|
-
|
|
32650
|
-
|
|
32651
|
-
|
|
32652
|
-
|
|
32653
|
-
|
|
32654
|
-
|
|
32655
|
-
|
|
32656
|
-
|
|
32657
|
-
|
|
32658
|
-
|
|
32659
|
-
|
|
32660
|
-
|
|
32661
|
-
|
|
32662
|
-
|
|
32663
|
-
|
|
32664
|
-
|
|
32665
|
-
|
|
32666
|
-
|
|
32667
|
-
},
|
|
32668
|
-
onStart: () => {
|
|
32669
|
-
this.setState({ shouldCacheIgnoreZoom: true });
|
|
32670
|
-
},
|
|
32671
|
-
onEnd: () => {
|
|
32672
|
-
this.cancelInProgressAnimation = null;
|
|
32673
|
-
this.setState({ shouldCacheIgnoreZoom: false });
|
|
32674
|
-
},
|
|
32675
|
-
onCancel: () => {
|
|
33592
|
+
const from = this.state;
|
|
33593
|
+
let startTime = null;
|
|
33594
|
+
let frameId = null;
|
|
33595
|
+
let cancelled = false;
|
|
33596
|
+
const targetViewport = {
|
|
33597
|
+
scrollX: target.scrollX,
|
|
33598
|
+
scrollY: target.scrollY,
|
|
33599
|
+
zoom
|
|
33600
|
+
};
|
|
33601
|
+
const step = (timestamp) => {
|
|
33602
|
+
if (cancelled) {
|
|
33603
|
+
return;
|
|
33604
|
+
}
|
|
33605
|
+
startTime ?? (startTime = timestamp);
|
|
33606
|
+
const progress = Math.min((timestamp - startTime) / animateDuration, 1);
|
|
33607
|
+
this.setState({
|
|
33608
|
+
...interpolateViewport({
|
|
33609
|
+
from,
|
|
33610
|
+
target: targetViewport,
|
|
33611
|
+
factor: easeOut5(progress)
|
|
33612
|
+
}),
|
|
33613
|
+
shouldCacheIgnoreZoom: progress < 1
|
|
33614
|
+
});
|
|
33615
|
+
if (progress < 1) {
|
|
33616
|
+
frameId = requestAnimationFrame(step);
|
|
33617
|
+
} else {
|
|
32676
33618
|
this.cancelInProgressAnimation = null;
|
|
32677
|
-
|
|
32678
|
-
|
|
32679
|
-
duration: animateDuration
|
|
32680
|
-
});
|
|
33619
|
+
}
|
|
33620
|
+
};
|
|
32681
33621
|
this.cancelInProgressAnimation = () => {
|
|
32682
|
-
|
|
33622
|
+
cancelled = true;
|
|
33623
|
+
if (frameId !== null) {
|
|
33624
|
+
cancelAnimationFrame(frameId);
|
|
33625
|
+
}
|
|
32683
33626
|
this.cancelInProgressAnimation = null;
|
|
33627
|
+
this.setState({ shouldCacheIgnoreZoom: false });
|
|
32684
33628
|
};
|
|
33629
|
+
frameId = requestAnimationFrame(step);
|
|
32685
33630
|
} else {
|
|
32686
33631
|
this.setState({
|
|
32687
33632
|
scrollX: target.scrollX,
|
|
32688
33633
|
scrollY: target.scrollY,
|
|
32689
|
-
zoom
|
|
33634
|
+
zoom,
|
|
33635
|
+
shouldCacheIgnoreZoom: false
|
|
32690
33636
|
});
|
|
32691
33637
|
}
|
|
32692
33638
|
});
|
|
32693
|
-
__publicField(this, "scrollToContent", (target
|
|
33639
|
+
__publicField(this, "scrollToContent", (target, opts) => {
|
|
33640
|
+
let elements;
|
|
32694
33641
|
if (typeof target === "string") {
|
|
32695
|
-
|
|
32696
|
-
|
|
32697
|
-
|
|
32698
|
-
|
|
32699
|
-
|
|
32700
|
-
|
|
32701
|
-
if (id) {
|
|
32702
|
-
const elements = this.scene.getElementsFromId(id);
|
|
32703
|
-
if (elements?.length) {
|
|
32704
|
-
this.scrollToContent(elements, {
|
|
32705
|
-
fitToContent: opts?.fitToContent ?? true,
|
|
32706
|
-
animate: opts?.animate ?? true
|
|
32707
|
-
});
|
|
32708
|
-
} else if (isElementLink2(target)) {
|
|
32709
|
-
this.setState({
|
|
32710
|
-
toast: {
|
|
32711
|
-
message: t("elementLink.notFound"),
|
|
32712
|
-
duration: 3e3,
|
|
32713
|
-
closable: true
|
|
32714
|
-
}
|
|
32715
|
-
});
|
|
32716
|
-
}
|
|
32717
|
-
}
|
|
32718
|
-
return;
|
|
32719
|
-
}
|
|
32720
|
-
const targetElements = Array.isArray(target) ? target : [target];
|
|
32721
|
-
let zoom = this.state.zoom;
|
|
32722
|
-
let scrollX = this.state.scrollX;
|
|
32723
|
-
let scrollY = this.state.scrollY;
|
|
32724
|
-
if (opts?.fitToContent || opts?.fitToViewport) {
|
|
32725
|
-
const { appState } = zoomToFit({
|
|
32726
|
-
canvasOffsets: opts.canvasOffsets,
|
|
32727
|
-
targetElements,
|
|
32728
|
-
appState: this.state,
|
|
32729
|
-
fitToViewport: !!opts?.fitToViewport,
|
|
32730
|
-
viewportZoomFactor: opts?.viewportZoomFactor,
|
|
32731
|
-
minZoom: opts?.minZoom,
|
|
32732
|
-
maxZoom: opts?.maxZoom
|
|
32733
|
-
});
|
|
32734
|
-
zoom = appState.zoom;
|
|
32735
|
-
scrollX = appState.scrollX;
|
|
32736
|
-
scrollY = appState.scrollY;
|
|
33642
|
+
const id = isElementLink2(target) ? parseElementLinkFromURL(target) : target;
|
|
33643
|
+
elements = id ? this.scene.getElementsFromId(id) : [];
|
|
33644
|
+
} else if (Array.isArray(target)) {
|
|
33645
|
+
elements = target;
|
|
33646
|
+
} else if (target) {
|
|
33647
|
+
elements = [target];
|
|
32737
33648
|
} else {
|
|
32738
|
-
|
|
32739
|
-
scrollX = scroll.scrollX;
|
|
32740
|
-
scrollY = scroll.scrollY;
|
|
33649
|
+
elements = this.scene.getNonDeletedElements();
|
|
32741
33650
|
}
|
|
32742
|
-
|
|
32743
|
-
{
|
|
32744
|
-
|
|
32745
|
-
|
|
32746
|
-
|
|
32747
|
-
|
|
32748
|
-
|
|
32749
|
-
|
|
32750
|
-
|
|
33651
|
+
if (!elements.length) {
|
|
33652
|
+
if (typeof target === "string" && isElementLink2(target)) {
|
|
33653
|
+
this.setState({
|
|
33654
|
+
toast: {
|
|
33655
|
+
message: t("elementLink.notFound"),
|
|
33656
|
+
duration: 3e3,
|
|
33657
|
+
closable: true
|
|
33658
|
+
}
|
|
33659
|
+
});
|
|
32751
33660
|
}
|
|
33661
|
+
return;
|
|
33662
|
+
}
|
|
33663
|
+
const resolvedOpts = typeof target === "string" ? {
|
|
33664
|
+
...opts,
|
|
33665
|
+
fitToViewport: void 0,
|
|
33666
|
+
fitToContent: opts?.fitToContent ?? true,
|
|
33667
|
+
animate: opts?.animate ?? true
|
|
33668
|
+
} : opts;
|
|
33669
|
+
scrollToElements(
|
|
33670
|
+
this.state,
|
|
33671
|
+
elements,
|
|
33672
|
+
this.setState.bind(this),
|
|
33673
|
+
resolvedOpts
|
|
32752
33674
|
);
|
|
32753
33675
|
});
|
|
32754
33676
|
__publicField(this, "maybeUnfollowRemoteUser", () => {
|
|
@@ -32759,6 +33681,8 @@ var App = class _App extends React40.Component {
|
|
|
32759
33681
|
/** use when changing scrollX/scrollY/zoom based on user interaction */
|
|
32760
33682
|
__publicField(this, "translateCanvas", (state) => {
|
|
32761
33683
|
this.cancelInProgressAnimation?.();
|
|
33684
|
+
AnimationController.cancel(SCROLL_TO_CONTENT_ANIMATION_KEY);
|
|
33685
|
+
this.setState({ shouldCacheIgnoreZoom: false });
|
|
32762
33686
|
this.maybeUnfollowRemoteUser();
|
|
32763
33687
|
this.setState(state);
|
|
32764
33688
|
});
|
|
@@ -32790,11 +33714,93 @@ var App = class _App extends React40.Component {
|
|
|
32790
33714
|
__publicField(this, "addFiles", withBatchedUpdates(
|
|
32791
33715
|
(files) => {
|
|
32792
33716
|
const { addedFiles } = this.addMissingFiles(files);
|
|
33717
|
+
for (const fileId of Object.keys(addedFiles)) {
|
|
33718
|
+
const cacheEntry = this.imageCache.get(fileId);
|
|
33719
|
+
if (cacheEntry?.isPlaceholder && !(cacheEntry.image instanceof Promise)) {
|
|
33720
|
+
this.imageTransitionPlaceholders.set(fileId, cacheEntry.image);
|
|
33721
|
+
}
|
|
33722
|
+
}
|
|
32793
33723
|
this.clearImageShapeCache(addedFiles);
|
|
32794
33724
|
this.scene.triggerUpdate();
|
|
32795
|
-
this.addNewImagesToImageCache()
|
|
33725
|
+
this.addNewImagesToImageCache().then(() => {
|
|
33726
|
+
for (const fileId of Object.keys(addedFiles)) {
|
|
33727
|
+
const cacheEntry = this.imageCache.get(fileId);
|
|
33728
|
+
if (cacheEntry && !(cacheEntry.image instanceof Promise)) {
|
|
33729
|
+
this.clearImageLoadingProgress(fileId);
|
|
33730
|
+
}
|
|
33731
|
+
this.imageTransitionPlaceholders.delete(fileId);
|
|
33732
|
+
}
|
|
33733
|
+
});
|
|
32796
33734
|
}
|
|
32797
33735
|
));
|
|
33736
|
+
__publicField(this, "addImagePlaceholder", async (fileId, file2) => {
|
|
33737
|
+
if (this.files[fileId]) {
|
|
33738
|
+
return;
|
|
33739
|
+
}
|
|
33740
|
+
let normalizedFile = await normalizeFile(file2);
|
|
33741
|
+
if (!isSupportedImageFile(normalizedFile)) {
|
|
33742
|
+
throw new Error(t("errors.unsupportedFileType"));
|
|
33743
|
+
}
|
|
33744
|
+
if (normalizedFile.type === MIME_TYPES8.svg) {
|
|
33745
|
+
normalizedFile = SVGStringToFile(
|
|
33746
|
+
normalizeSVG(await normalizedFile.text()),
|
|
33747
|
+
normalizedFile.name
|
|
33748
|
+
);
|
|
33749
|
+
}
|
|
33750
|
+
const dataURL = await getDataURL(normalizedFile);
|
|
33751
|
+
if (this.files[fileId]) {
|
|
33752
|
+
return;
|
|
33753
|
+
}
|
|
33754
|
+
const imagePromise = loadHTMLImageElement(dataURL);
|
|
33755
|
+
const placeholderEntry = {
|
|
33756
|
+
image: imagePromise,
|
|
33757
|
+
mimeType: normalizedFile.type,
|
|
33758
|
+
isPlaceholder: true
|
|
33759
|
+
};
|
|
33760
|
+
this.imageCache.set(fileId, placeholderEntry);
|
|
33761
|
+
try {
|
|
33762
|
+
const image = await imagePromise;
|
|
33763
|
+
if (this.imageCache.get(fileId) !== placeholderEntry || this.files[fileId]) {
|
|
33764
|
+
return;
|
|
33765
|
+
}
|
|
33766
|
+
this.imageCache.set(fileId, { ...placeholderEntry, image });
|
|
33767
|
+
this.clearImageShapeCacheForFileId(fileId);
|
|
33768
|
+
this.imagePlaceholderUpdateEmitter.trigger();
|
|
33769
|
+
} catch (error) {
|
|
33770
|
+
if (this.imageCache.get(fileId) === placeholderEntry) {
|
|
33771
|
+
this.imageCache.delete(fileId);
|
|
33772
|
+
this.imagePlaceholderUpdateEmitter.trigger();
|
|
33773
|
+
}
|
|
33774
|
+
throw error;
|
|
33775
|
+
}
|
|
33776
|
+
});
|
|
33777
|
+
__publicField(this, "setImageLoadingProgress", (fileId, progress) => {
|
|
33778
|
+
if (progress === null) {
|
|
33779
|
+
this.clearImageLoadingProgress(fileId);
|
|
33780
|
+
return;
|
|
33781
|
+
}
|
|
33782
|
+
if (!Number.isFinite(progress)) {
|
|
33783
|
+
return;
|
|
33784
|
+
}
|
|
33785
|
+
const nextProgress = clamp10(progress, 0, 1);
|
|
33786
|
+
if (this.imageLoadingProgress.get(fileId) === nextProgress) {
|
|
33787
|
+
return;
|
|
33788
|
+
}
|
|
33789
|
+
this.imageLoadingProgress.set(fileId, nextProgress);
|
|
33790
|
+
this.imageLoadingProgressEmitter.trigger();
|
|
33791
|
+
});
|
|
33792
|
+
__publicField(this, "clearImageLoadingProgress", (fileId) => {
|
|
33793
|
+
if (this.imageLoadingProgress.delete(fileId)) {
|
|
33794
|
+
this.imageLoadingProgressEmitter.trigger();
|
|
33795
|
+
}
|
|
33796
|
+
});
|
|
33797
|
+
__publicField(this, "clearImageShapeCacheForFileId", (fileId) => {
|
|
33798
|
+
for (const element of this.scene.getNonDeletedElements()) {
|
|
33799
|
+
if (isInitializedImageElement3(element) && element.fileId === fileId) {
|
|
33800
|
+
ShapeCache4.delete(element);
|
|
33801
|
+
}
|
|
33802
|
+
}
|
|
33803
|
+
});
|
|
32798
33804
|
__publicField(this, "addMissingFiles", (files, replace = false) => {
|
|
32799
33805
|
const nextFiles = replace ? {} : { ...this.files };
|
|
32800
33806
|
const addedFiles = {};
|
|
@@ -32805,11 +33811,11 @@ var App = class _App extends React40.Component {
|
|
|
32805
33811
|
}
|
|
32806
33812
|
addedFiles[fileData.id] = fileData;
|
|
32807
33813
|
nextFiles[fileData.id] = fileData;
|
|
32808
|
-
if (fileData.mimeType ===
|
|
33814
|
+
if (fileData.mimeType === MIME_TYPES8.svg) {
|
|
32809
33815
|
try {
|
|
32810
33816
|
const restoredDataURL = getDataURL_sync(
|
|
32811
33817
|
normalizeSVG(dataURLToString(fileData.dataURL)),
|
|
32812
|
-
|
|
33818
|
+
MIME_TYPES8.svg
|
|
32813
33819
|
);
|
|
32814
33820
|
if (fileData.dataURL !== restoredDataURL) {
|
|
32815
33821
|
fileData.version = (fileData.version ?? 1) + 1;
|
|
@@ -33719,7 +34725,7 @@ var App = class _App extends React40.Component {
|
|
|
33719
34725
|
strokeColor: this.state.currentItemStrokeColor,
|
|
33720
34726
|
backgroundColor: this.state.currentItemBackgroundColor,
|
|
33721
34727
|
fillStyle: this.state.currentItemFillStyle,
|
|
33722
|
-
strokeWidth: this.
|
|
34728
|
+
strokeWidth: this.getCurrentItemStrokeWidth("text"),
|
|
33723
34729
|
strokeStyle: this.state.currentItemStrokeStyle,
|
|
33724
34730
|
roughness: this.state.currentItemRoughness,
|
|
33725
34731
|
opacity: this.state.currentItemOpacity,
|
|
@@ -34278,42 +35284,7 @@ var App = class _App extends React40.Component {
|
|
|
34278
35284
|
const { lastCommittedPoint } = selectedLinearElement;
|
|
34279
35285
|
setCursorForShape(this.interactiveCanvas, this.state);
|
|
34280
35286
|
if (lastPoint === lastCommittedPoint) {
|
|
34281
|
-
|
|
34282
|
-
pointFrom32(scenePointerX, scenePointerY),
|
|
34283
|
-
this.scene.getNonDeletedElements(),
|
|
34284
|
-
this.scene.getNonDeletedElementsMap(),
|
|
34285
|
-
maxBindingDistance_simple3(this.state.zoom)
|
|
34286
|
-
);
|
|
34287
|
-
if (hoveredElement) {
|
|
34288
|
-
this.actionManager.executeAction(actionFinalize, "ui", {
|
|
34289
|
-
event: event.nativeEvent,
|
|
34290
|
-
sceneCoords: {
|
|
34291
|
-
x: scenePointerX,
|
|
34292
|
-
y: scenePointerY
|
|
34293
|
-
}
|
|
34294
|
-
});
|
|
34295
|
-
this.setState({ suggestedBinding: null });
|
|
34296
|
-
if (!this.state.activeTool.locked) {
|
|
34297
|
-
resetCursor(this.interactiveCanvas);
|
|
34298
|
-
this.setState((prevState) => ({
|
|
34299
|
-
newElement: null,
|
|
34300
|
-
activeTool: updateActiveTool8(this.state, {
|
|
34301
|
-
type: this.state.preferredSelectionTool.type
|
|
34302
|
-
}),
|
|
34303
|
-
selectedElementIds: makeNextSelectedElementIds3(
|
|
34304
|
-
{
|
|
34305
|
-
...prevState.selectedElementIds,
|
|
34306
|
-
[multiElement.id]: true
|
|
34307
|
-
},
|
|
34308
|
-
prevState
|
|
34309
|
-
),
|
|
34310
|
-
selectedLinearElement: new LinearElementEditor11(
|
|
34311
|
-
multiElement,
|
|
34312
|
-
this.scene.getNonDeletedElementsMap()
|
|
34313
|
-
)
|
|
34314
|
-
}));
|
|
34315
|
-
}
|
|
34316
|
-
} else if (
|
|
35287
|
+
if (
|
|
34317
35288
|
// if we haven't yet created a temp point and we're beyond commit-zone
|
|
34318
35289
|
// threshold, add a point
|
|
34319
35290
|
pointDistance9(
|
|
@@ -34321,6 +35292,24 @@ var App = class _App extends React40.Component {
|
|
|
34321
35292
|
lastPoint
|
|
34322
35293
|
) >= LINE_CONFIRM_THRESHOLD2
|
|
34323
35294
|
) {
|
|
35295
|
+
this.store.scheduleCapture();
|
|
35296
|
+
flushSync2(() => {
|
|
35297
|
+
invariant16(
|
|
35298
|
+
this.state.selectedLinearElement?.initialState,
|
|
35299
|
+
"initialState must be set"
|
|
35300
|
+
);
|
|
35301
|
+
this.setState({
|
|
35302
|
+
selectedLinearElement: {
|
|
35303
|
+
...this.state.selectedLinearElement,
|
|
35304
|
+
lastCommittedPoint: points[points.length - 1],
|
|
35305
|
+
selectedPointsIndices: [multiElement.points.length],
|
|
35306
|
+
initialState: {
|
|
35307
|
+
...this.state.selectedLinearElement.initialState,
|
|
35308
|
+
lastClickedPoint: multiElement.points.length
|
|
35309
|
+
}
|
|
35310
|
+
}
|
|
35311
|
+
});
|
|
35312
|
+
});
|
|
34324
35313
|
this.scene.mutateElement(
|
|
34325
35314
|
multiElement,
|
|
34326
35315
|
{
|
|
@@ -34331,21 +35320,6 @@ var App = class _App extends React40.Component {
|
|
|
34331
35320
|
},
|
|
34332
35321
|
{ informMutation: false, isDragging: false }
|
|
34333
35322
|
);
|
|
34334
|
-
invariant16(
|
|
34335
|
-
this.state.selectedLinearElement?.initialState,
|
|
34336
|
-
"initialState must be set"
|
|
34337
|
-
);
|
|
34338
|
-
this.setState({
|
|
34339
|
-
selectedLinearElement: {
|
|
34340
|
-
...this.state.selectedLinearElement,
|
|
34341
|
-
lastCommittedPoint: points[points.length - 1],
|
|
34342
|
-
selectedPointsIndices: [multiElement.points.length - 1],
|
|
34343
|
-
initialState: {
|
|
34344
|
-
...this.state.selectedLinearElement.initialState,
|
|
34345
|
-
lastClickedPoint: multiElement.points.length - 1
|
|
34346
|
-
}
|
|
34347
|
-
}
|
|
34348
|
-
});
|
|
34349
35323
|
} else {
|
|
34350
35324
|
setCursor(this.interactiveCanvas, CURSOR_TYPE4.POINTER);
|
|
34351
35325
|
}
|
|
@@ -34693,7 +35667,8 @@ var App = class _App extends React40.Component {
|
|
|
34693
35667
|
this.setState((prevState) => {
|
|
34694
35668
|
return {
|
|
34695
35669
|
penMode: true,
|
|
34696
|
-
penDetected: true
|
|
35670
|
+
penDetected: true,
|
|
35671
|
+
currentItemStrokeVariability: "variable"
|
|
34697
35672
|
};
|
|
34698
35673
|
});
|
|
34699
35674
|
}
|
|
@@ -35466,6 +36441,7 @@ var App = class _App extends React40.Component {
|
|
|
35466
36441
|
y: gridY
|
|
35467
36442
|
});
|
|
35468
36443
|
const simulatePressure = event.pressure === 0.5;
|
|
36444
|
+
const strokeVariability = this.state.currentItemStrokeVariability;
|
|
35469
36445
|
const element = newFreeDrawElement({
|
|
35470
36446
|
type: elementType,
|
|
35471
36447
|
x: gridX,
|
|
@@ -35473,15 +36449,21 @@ var App = class _App extends React40.Component {
|
|
|
35473
36449
|
strokeColor: this.state.currentItemStrokeColor,
|
|
35474
36450
|
backgroundColor: this.state.currentItemBackgroundColor,
|
|
35475
36451
|
fillStyle: this.state.currentItemFillStyle,
|
|
35476
|
-
strokeWidth: this.
|
|
36452
|
+
strokeWidth: this.getCurrentItemStrokeWidth("freedraw"),
|
|
35477
36453
|
strokeStyle: this.state.currentItemStrokeStyle,
|
|
35478
36454
|
roughness: this.state.currentItemRoughness,
|
|
35479
36455
|
opacity: this.state.currentItemOpacity,
|
|
35480
36456
|
roundness: null,
|
|
35481
36457
|
simulatePressure,
|
|
36458
|
+
strokeOptions: {
|
|
36459
|
+
variability: strokeVariability,
|
|
36460
|
+
streamline: event.pointerType !== "mouse" ? DEFAULT_STROKE_STREAMLINE_PRECISE : DEFAULT_STROKE_STREAMLINE2
|
|
36461
|
+
},
|
|
35482
36462
|
locked: false,
|
|
35483
36463
|
frameId: topLayerFrame ? topLayerFrame.id : null,
|
|
35484
36464
|
points: [pointFrom32(0, 0)],
|
|
36465
|
+
// pressures are only consumed when rendering a real-pressure stroke, so
|
|
36466
|
+
// skip persisting them while pressure is being simulated
|
|
35485
36467
|
pressures: simulatePressure ? [] : [event.pressure]
|
|
35486
36468
|
});
|
|
35487
36469
|
this.insertNewElement(element);
|
|
@@ -35520,7 +36502,7 @@ var App = class _App extends React40.Component {
|
|
|
35520
36502
|
strokeColor: "transparent",
|
|
35521
36503
|
backgroundColor: "transparent",
|
|
35522
36504
|
fillStyle: this.state.currentItemFillStyle,
|
|
35523
|
-
strokeWidth: this.
|
|
36505
|
+
strokeWidth: this.getCurrentItemStrokeWidth("iframe"),
|
|
35524
36506
|
strokeStyle: this.state.currentItemStrokeStyle,
|
|
35525
36507
|
roughness: this.state.currentItemRoughness,
|
|
35526
36508
|
roundness: this.getCurrentItemRoundness("iframe"),
|
|
@@ -35560,7 +36542,7 @@ var App = class _App extends React40.Component {
|
|
|
35560
36542
|
strokeColor: "transparent",
|
|
35561
36543
|
backgroundColor: "transparent",
|
|
35562
36544
|
fillStyle: this.state.currentItemFillStyle,
|
|
35563
|
-
strokeWidth: this.
|
|
36545
|
+
strokeWidth: this.getCurrentItemStrokeWidth("embeddable"),
|
|
35564
36546
|
strokeStyle: this.state.currentItemStrokeStyle,
|
|
35565
36547
|
roughness: this.state.currentItemRoughness,
|
|
35566
36548
|
roundness: this.getCurrentItemRoundness("embeddable"),
|
|
@@ -35594,7 +36576,7 @@ var App = class _App extends React40.Component {
|
|
|
35594
36576
|
strokeColor: this.state.currentItemStrokeColor,
|
|
35595
36577
|
backgroundColor: this.state.currentItemBackgroundColor,
|
|
35596
36578
|
fillStyle: this.state.currentItemFillStyle,
|
|
35597
|
-
strokeWidth: this.
|
|
36579
|
+
strokeWidth: this.getCurrentItemStrokeWidth("image"),
|
|
35598
36580
|
strokeStyle: this.state.currentItemStrokeStyle,
|
|
35599
36581
|
roughness: this.state.currentItemRoughness,
|
|
35600
36582
|
roundness: null,
|
|
@@ -35651,21 +36633,41 @@ var App = class _App extends React40.Component {
|
|
|
35651
36633
|
}
|
|
35652
36634
|
const { x: rx, y: ry } = multiElement;
|
|
35653
36635
|
const { lastCommittedPoint } = selectedLinearElement;
|
|
35654
|
-
const
|
|
35655
|
-
|
|
35656
|
-
|
|
35657
|
-
|
|
35658
|
-
|
|
36636
|
+
const sceneCoords = viewportCoordsToSceneCoords3(event, this.state);
|
|
36637
|
+
const { start: start2, end } = isBindingElement4(multiElement) && isBindingEnabled2(this.state) ? getBindingStrategyForDraggingBindingElementEndpoints2(
|
|
36638
|
+
multiElement,
|
|
36639
|
+
/* @__PURE__ */ new Map([
|
|
36640
|
+
[
|
|
36641
|
+
multiElement.points.length - 1,
|
|
36642
|
+
{
|
|
36643
|
+
point: multiElement.points[multiElement.points.length - 1],
|
|
36644
|
+
isDragging: false
|
|
36645
|
+
}
|
|
36646
|
+
]
|
|
36647
|
+
]),
|
|
36648
|
+
sceneCoords.x,
|
|
36649
|
+
sceneCoords.y,
|
|
36650
|
+
this.scene.getNonDeletedElementsMap(),
|
|
35659
36651
|
this.scene.getNonDeletedElements(),
|
|
35660
|
-
this.
|
|
35661
|
-
|
|
35662
|
-
|
|
36652
|
+
this.state,
|
|
36653
|
+
{
|
|
36654
|
+
newArrow: Boolean(this.state.newElement),
|
|
36655
|
+
zoom: this.state.zoom
|
|
36656
|
+
}
|
|
36657
|
+
) : { end: { mode: void 0 } };
|
|
36658
|
+
const elementsMap = this.scene.getNonDeletedElementsMap();
|
|
36659
|
+
const endOutsideSameElement = start2?.mode != null && end.mode != null && start2.element.id === end.element.id && !isPointInElement3(end.focusPoint, end.element, elementsMap);
|
|
36660
|
+
const boundOutsideFromElsewhere = end.mode === "orbit" && multiElement.startBinding?.elementId !== end.element?.id;
|
|
36661
|
+
const lastCommittedPointIsInsideCommitZone = lastCommittedPoint && pointDistance9(
|
|
35663
36662
|
pointFrom32(
|
|
35664
36663
|
pointerDownState.origin.x - rx,
|
|
35665
36664
|
pointerDownState.origin.y - ry
|
|
35666
36665
|
),
|
|
35667
36666
|
lastCommittedPoint
|
|
35668
|
-
) < LINE_CONFIRM_THRESHOLD2
|
|
36667
|
+
) < LINE_CONFIRM_THRESHOLD2;
|
|
36668
|
+
if (boundOutsideFromElsewhere || // Outside -> orbit: Bind immediately
|
|
36669
|
+
endOutsideSameElement || // End outside the start's element: Bind immediately
|
|
36670
|
+
multiElement.points.length > 1 && lastCommittedPointIsInsideCommitZone) {
|
|
35669
36671
|
this.actionManager.executeAction(actionFinalize, "ui", {
|
|
35670
36672
|
event: event.nativeEvent,
|
|
35671
36673
|
sceneCoords: {
|
|
@@ -35704,7 +36706,7 @@ var App = class _App extends React40.Component {
|
|
|
35704
36706
|
strokeColor: this.state.currentItemStrokeColor,
|
|
35705
36707
|
backgroundColor: this.state.currentItemBackgroundColor,
|
|
35706
36708
|
fillStyle: this.state.currentItemFillStyle,
|
|
35707
|
-
strokeWidth: this.
|
|
36709
|
+
strokeWidth: this.getCurrentItemStrokeWidth(elementType),
|
|
35708
36710
|
strokeStyle: this.state.currentItemStrokeStyle,
|
|
35709
36711
|
roughness: this.state.currentItemRoughness,
|
|
35710
36712
|
opacity: this.state.currentItemOpacity,
|
|
@@ -35726,7 +36728,7 @@ var App = class _App extends React40.Component {
|
|
|
35726
36728
|
strokeColor: this.state.currentItemStrokeColor,
|
|
35727
36729
|
backgroundColor: this.state.currentItemBackgroundColor,
|
|
35728
36730
|
fillStyle: this.state.currentItemFillStyle,
|
|
35729
|
-
strokeWidth: this.
|
|
36731
|
+
strokeWidth: this.getCurrentItemStrokeWidth(elementType),
|
|
35730
36732
|
strokeStyle: this.state.currentItemStrokeStyle,
|
|
35731
36733
|
roughness: this.state.currentItemRoughness,
|
|
35732
36734
|
opacity: this.state.currentItemOpacity,
|
|
@@ -35837,7 +36839,7 @@ var App = class _App extends React40.Component {
|
|
|
35837
36839
|
strokeColor: this.state.currentItemStrokeColor,
|
|
35838
36840
|
backgroundColor: this.state.currentItemBackgroundColor,
|
|
35839
36841
|
fillStyle: this.state.currentItemFillStyle,
|
|
35840
|
-
strokeWidth: this.
|
|
36842
|
+
strokeWidth: this.getCurrentItemStrokeWidth(elementType),
|
|
35841
36843
|
strokeStyle: this.state.currentItemStrokeStyle,
|
|
35842
36844
|
roughness: this.state.currentItemRoughness,
|
|
35843
36845
|
opacity: this.state.currentItemOpacity,
|
|
@@ -35965,7 +36967,7 @@ var App = class _App extends React40.Component {
|
|
|
35965
36967
|
let fileName = imageFile.name;
|
|
35966
36968
|
const fileNeedsResizing = imageFile.size >= this.state.dontResizeLimitMBs * 1024 * 1024;
|
|
35967
36969
|
setCursor(this.interactiveCanvas, "wait");
|
|
35968
|
-
if (mimeType ===
|
|
36970
|
+
if (mimeType === MIME_TYPES8.svg) {
|
|
35969
36971
|
try {
|
|
35970
36972
|
imageFile = SVGStringToFile(
|
|
35971
36973
|
normalizeSVG(await imageFile.text()),
|
|
@@ -36030,8 +37032,15 @@ var App = class _App extends React40.Component {
|
|
|
36030
37032
|
lastRetrieved: Date.now()
|
|
36031
37033
|
}
|
|
36032
37034
|
]);
|
|
37035
|
+
if (this.imageCache.get(fileId)?.isPlaceholder) {
|
|
37036
|
+
const cacheEntry = this.imageCache.get(fileId);
|
|
37037
|
+
if (cacheEntry && !(cacheEntry.image instanceof Promise)) {
|
|
37038
|
+
this.imageTransitionPlaceholders.set(fileId, cacheEntry.image);
|
|
37039
|
+
}
|
|
37040
|
+
this.imageCache.delete(fileId);
|
|
37041
|
+
this.clearImageShapeCacheForFileId(fileId);
|
|
37042
|
+
}
|
|
36033
37043
|
if (!this.imageCache.get(fileId)) {
|
|
36034
|
-
this.addNewImagesToImageCache();
|
|
36035
37044
|
const { erroredFiles } = await this.updateImageCache([
|
|
36036
37045
|
initializedImageElement
|
|
36037
37046
|
]);
|
|
@@ -36040,18 +37049,33 @@ var App = class _App extends React40.Component {
|
|
|
36040
37049
|
}
|
|
36041
37050
|
}
|
|
36042
37051
|
const imageHTML = await this.imageCache.get(fileId)?.image;
|
|
36043
|
-
|
|
37052
|
+
let thumbHash = null;
|
|
37053
|
+
if (imageHTML) {
|
|
37054
|
+
try {
|
|
37055
|
+
thumbHash = generateThumbHash(imageHTML);
|
|
37056
|
+
} catch (error) {
|
|
37057
|
+
console.warn("Failed to generate image ThumbHash", error);
|
|
37058
|
+
}
|
|
37059
|
+
}
|
|
37060
|
+
if (thumbHash && this.files[fileId]) {
|
|
37061
|
+
this.files[fileId].thumbHash = thumbHash;
|
|
37062
|
+
}
|
|
37063
|
+
if (imageHTML) {
|
|
36044
37064
|
initializedImageElement = this.getLatestInitializedImageElement(
|
|
36045
37065
|
placeholderImageElement,
|
|
36046
37066
|
fileId,
|
|
36047
|
-
fileName
|
|
36048
|
-
|
|
36049
|
-
const naturalDimensions = this.getImageNaturalDimensions(
|
|
36050
|
-
initializedImageElement,
|
|
36051
|
-
imageHTML
|
|
37067
|
+
fileName,
|
|
37068
|
+
thumbHash
|
|
36052
37069
|
);
|
|
36053
|
-
|
|
37070
|
+
if (this.state.newElement?.id !== initializedImageElement.id) {
|
|
37071
|
+
const naturalDimensions = this.getImageNaturalDimensions(
|
|
37072
|
+
initializedImageElement,
|
|
37073
|
+
imageHTML
|
|
37074
|
+
);
|
|
37075
|
+
Object.assign(initializedImageElement, naturalDimensions);
|
|
37076
|
+
}
|
|
36054
37077
|
}
|
|
37078
|
+
this.clearImageLoadingProgress(fileId);
|
|
36055
37079
|
resolve(initializedImageElement);
|
|
36056
37080
|
} catch (error) {
|
|
36057
37081
|
console.error(error);
|
|
@@ -36065,13 +37089,14 @@ var App = class _App extends React40.Component {
|
|
|
36065
37089
|
* when the placeholder image could have been modified in the meantime,
|
|
36066
37090
|
* and when you don't want to loose those modifications
|
|
36067
37091
|
*/
|
|
36068
|
-
__publicField(this, "getLatestInitializedImageElement", (imagePlaceholder, fileId, fileName) => {
|
|
37092
|
+
__publicField(this, "getLatestInitializedImageElement", (imagePlaceholder, fileId, fileName, thumbHash = null) => {
|
|
36069
37093
|
const latestImageElement = this.scene.getElement(imagePlaceholder.id) ?? imagePlaceholder;
|
|
36070
37094
|
return newElementWith10(
|
|
36071
37095
|
latestImageElement,
|
|
36072
37096
|
{
|
|
36073
37097
|
fileId,
|
|
36074
|
-
fileName
|
|
37098
|
+
fileName,
|
|
37099
|
+
thumbHash
|
|
36075
37100
|
}
|
|
36076
37101
|
);
|
|
36077
37102
|
});
|
|
@@ -36142,7 +37167,23 @@ var App = class _App extends React40.Component {
|
|
|
36142
37167
|
fileIds: elements.map((element) => element.fileId),
|
|
36143
37168
|
files
|
|
36144
37169
|
});
|
|
37170
|
+
const transitionStart = performance.now();
|
|
37171
|
+
for (const fileId of updatedFiles.keys()) {
|
|
37172
|
+
const cacheEntry = this.imageCache.get(fileId);
|
|
37173
|
+
if (cacheEntry && !(cacheEntry.image instanceof Promise)) {
|
|
37174
|
+
this.imageCache.set(fileId, {
|
|
37175
|
+
...cacheEntry,
|
|
37176
|
+
placeholderImage: this.imageTransitionPlaceholders.get(fileId),
|
|
37177
|
+
transitionStart
|
|
37178
|
+
});
|
|
37179
|
+
}
|
|
37180
|
+
this.imageTransitionPlaceholders.delete(fileId);
|
|
37181
|
+
}
|
|
36145
37182
|
if (erroredFiles.size) {
|
|
37183
|
+
for (const fileId of erroredFiles.keys()) {
|
|
37184
|
+
this.imageTransitionPlaceholders.delete(fileId);
|
|
37185
|
+
this.clearImageLoadingProgress(fileId);
|
|
37186
|
+
}
|
|
36146
37187
|
this.store.scheduleAction(CaptureUpdateAction41.NEVER);
|
|
36147
37188
|
this.scene.replaceAllElements(
|
|
36148
37189
|
this.scene.getElementsIncludingDeleted().map((element) => {
|
|
@@ -36256,6 +37297,7 @@ var App = class _App extends React40.Component {
|
|
|
36256
37297
|
});
|
|
36257
37298
|
});
|
|
36258
37299
|
__publicField(this, "handleAppOnDrop", async (event) => {
|
|
37300
|
+
const dragDataSnapshot = captureDragEventData(event);
|
|
36259
37301
|
const { x: sceneX, y: sceneY } = viewportCoordsToSceneCoords3(
|
|
36260
37302
|
event,
|
|
36261
37303
|
this.state
|
|
@@ -36264,7 +37306,7 @@ var App = class _App extends React40.Component {
|
|
|
36264
37306
|
const fileItems = dataTransferList.getFiles();
|
|
36265
37307
|
if (fileItems.length === 1) {
|
|
36266
37308
|
const { file: file2, fileHandle } = fileItems[0];
|
|
36267
|
-
if (file2 && (file2.type ===
|
|
37309
|
+
if (file2 && (file2.type === MIME_TYPES8.png || file2.type === MIME_TYPES8.svg)) {
|
|
36268
37310
|
try {
|
|
36269
37311
|
const scene = await loadFromBlob(
|
|
36270
37312
|
file2,
|
|
@@ -36292,65 +37334,14 @@ var App = class _App extends React40.Component {
|
|
|
36292
37334
|
const imageFiles = fileItems.map((data) => data.file).filter((file2) => isSupportedImageFile(file2));
|
|
36293
37335
|
if (imageFiles.length > 0) {
|
|
36294
37336
|
if (this.isToolSupported("image")) {
|
|
36295
|
-
const
|
|
36296
|
-
|
|
36297
|
-
|
|
36298
|
-
|
|
36299
|
-
|
|
36300
|
-
|
|
36301
|
-
|
|
36302
|
-
|
|
36303
|
-
}
|
|
36304
|
-
};
|
|
36305
|
-
dataTransferList.forEach((item) => {
|
|
36306
|
-
if (item.kind !== "string") {
|
|
36307
|
-
return;
|
|
36308
|
-
}
|
|
36309
|
-
if (item.type === MIME_TYPES7.html) {
|
|
36310
|
-
try {
|
|
36311
|
-
const doc = new DOMParser().parseFromString(
|
|
36312
|
-
item.value,
|
|
36313
|
-
MIME_TYPES7.html
|
|
36314
|
-
);
|
|
36315
|
-
for (const img of Array.from(
|
|
36316
|
-
doc.body.querySelectorAll("img")
|
|
36317
|
-
)) {
|
|
36318
|
-
pushUnique(htmlImageSources, img.getAttribute("src"));
|
|
36319
|
-
pushUnique(imageAlts, img.getAttribute("alt"));
|
|
36320
|
-
}
|
|
36321
|
-
} catch {
|
|
36322
|
-
}
|
|
36323
|
-
} else if (item.type === MIME_TYPES7.text) {
|
|
36324
|
-
pushUnique(textImageSources, item.value);
|
|
36325
|
-
}
|
|
36326
|
-
});
|
|
36327
|
-
const imageSources = [
|
|
36328
|
-
...htmlImageSources,
|
|
36329
|
-
...textImageSources.filter(
|
|
36330
|
-
(src) => !htmlImageSources.includes(src)
|
|
36331
|
-
)
|
|
36332
|
-
];
|
|
36333
|
-
const imageDetails = imageFiles.map(() => ({}));
|
|
36334
|
-
imageDetails.forEach((detail, index) => {
|
|
36335
|
-
const source = imageSources[index];
|
|
36336
|
-
const alt = imageAlts[index];
|
|
36337
|
-
if (source) {
|
|
36338
|
-
detail.src = source;
|
|
36339
|
-
}
|
|
36340
|
-
if (alt) {
|
|
36341
|
-
detail.alt = alt;
|
|
36342
|
-
}
|
|
36343
|
-
});
|
|
36344
|
-
const additionalUrls = imageSources.slice(imageDetails.length);
|
|
36345
|
-
const firstImageDetails = imageDetails[0];
|
|
36346
|
-
if (firstImageDetails && additionalUrls.length > 0) {
|
|
36347
|
-
additionalUrls.forEach((url, index) => {
|
|
36348
|
-
firstImageDetails[`additionalUrl${index + 1}`] = url;
|
|
36349
|
-
});
|
|
36350
|
-
}
|
|
36351
|
-
return imageDetails;
|
|
36352
|
-
};
|
|
36353
|
-
const droppedImageDetails = parseDroppedImageDetails();
|
|
37337
|
+
const droppedImageDetails = parseDragImageMetadata(
|
|
37338
|
+
dataTransferList,
|
|
37339
|
+
imageFiles.length,
|
|
37340
|
+
dragDataSnapshot
|
|
37341
|
+
);
|
|
37342
|
+
if (this.props.showDropEventDebugAlert) {
|
|
37343
|
+
alert(`${JSON.stringify(droppedImageDetails)}`);
|
|
37344
|
+
}
|
|
36354
37345
|
return this.insertImages(
|
|
36355
37346
|
imageFiles.map((file2, index) => ({
|
|
36356
37347
|
file: file2,
|
|
@@ -36369,7 +37360,7 @@ var App = class _App extends React40.Component {
|
|
|
36369
37360
|
await this.loadFileToCanvas(file2, fileHandle);
|
|
36370
37361
|
}
|
|
36371
37362
|
}
|
|
36372
|
-
const textItem = dataTransferList.findByType(
|
|
37363
|
+
const textItem = dataTransferList.findByType(MIME_TYPES8.text);
|
|
36373
37364
|
if (textItem) {
|
|
36374
37365
|
const text = textItem.value;
|
|
36375
37366
|
if (text && embeddableURLValidator2(text, this.props.validateEmbeddable) && (/^(http|https):\/\/[^\s/$.?#].[^\s]*$/.test(text) || getEmbedLink2(text)?.type === "video")) {
|
|
@@ -37013,6 +38004,8 @@ var App = class _App extends React40.Component {
|
|
|
37013
38004
|
applyDeltas: this.applyDeltas,
|
|
37014
38005
|
mutateElement: this.mutateElement,
|
|
37015
38006
|
addFiles: this.addFiles,
|
|
38007
|
+
addImagePlaceholder: this.addImagePlaceholder,
|
|
38008
|
+
setImageLoadingProgress: this.setImageLoadingProgress,
|
|
37016
38009
|
addImageElementsToScene: this.addImageElementsToScene,
|
|
37017
38010
|
resetScene: this.resetScene,
|
|
37018
38011
|
getSceneElementsIncludingDeleted: this.getSceneElementsIncludingDeleted,
|
|
@@ -37592,7 +38585,7 @@ var App = class _App extends React40.Component {
|
|
|
37592
38585
|
const isActive = this.state.activeEmbeddable?.element === el && this.state.activeEmbeddable?.state === "active";
|
|
37593
38586
|
const isHovered = this.state.activeEmbeddable?.element === el && this.state.activeEmbeddable?.state === "hover";
|
|
37594
38587
|
const shouldScaleEmbeddableViewport = src?.type === "video";
|
|
37595
|
-
const embeddableViewportScale =
|
|
38588
|
+
const embeddableViewportScale = clamp10(
|
|
37596
38589
|
shouldScaleEmbeddableViewport ? scale : 1,
|
|
37597
38590
|
0.75,
|
|
37598
38591
|
MAX_EMBEDDABLE_VIEWPORT_SCALE
|
|
@@ -37878,6 +38871,7 @@ var App = class _App extends React40.Component {
|
|
|
37878
38871
|
/* @__PURE__ */ jsx137(
|
|
37879
38872
|
StaticCanvas_default,
|
|
37880
38873
|
{
|
|
38874
|
+
app: this,
|
|
37881
38875
|
canvas: this.canvas,
|
|
37882
38876
|
rc: this.rc,
|
|
37883
38877
|
elementsMap,
|
|
@@ -37889,6 +38883,7 @@ var App = class _App extends React40.Component {
|
|
|
37889
38883
|
appState: this.state,
|
|
37890
38884
|
renderConfig: {
|
|
37891
38885
|
imageCache: this.imageCache,
|
|
38886
|
+
imageTransitionDuration: this.props.imageOptions.placeholderTransitionDuration,
|
|
37892
38887
|
isExporting: false,
|
|
37893
38888
|
renderGrid: isGridModeEnabled(this),
|
|
37894
38889
|
canvasBackgroundColor: this.state.viewBackgroundColor,
|
|
@@ -37910,6 +38905,7 @@ var App = class _App extends React40.Component {
|
|
|
37910
38905
|
allElementsMap,
|
|
37911
38906
|
renderConfig: {
|
|
37912
38907
|
imageCache: this.imageCache,
|
|
38908
|
+
imageTransitionDuration: this.props.imageOptions.placeholderTransitionDuration,
|
|
37913
38909
|
isExporting: false,
|
|
37914
38910
|
renderGrid: false,
|
|
37915
38911
|
canvasBackgroundColor: this.state.viewBackgroundColor,
|
|
@@ -38177,6 +39173,10 @@ var App = class _App extends React40.Component {
|
|
|
38177
39173
|
this.renderer = new Renderer(this.scene);
|
|
38178
39174
|
this.files = {};
|
|
38179
39175
|
this.imageCache.clear();
|
|
39176
|
+
this.imageLoadingProgress.clear();
|
|
39177
|
+
this.imageTransitionPlaceholders.clear();
|
|
39178
|
+
this.imageLoadingProgressEmitter.clear();
|
|
39179
|
+
this.imagePlaceholderUpdateEmitter.clear();
|
|
38180
39180
|
this.resizeObserver?.disconnect();
|
|
38181
39181
|
this.unmounted = true;
|
|
38182
39182
|
this.removeEventListeners();
|
|
@@ -38581,7 +39581,7 @@ var App = class _App extends React40.Component {
|
|
|
38581
39581
|
strokeColor: this.state.currentItemStrokeColor,
|
|
38582
39582
|
backgroundColor: this.state.currentItemBackgroundColor,
|
|
38583
39583
|
fillStyle: this.state.currentItemFillStyle,
|
|
38584
|
-
strokeWidth: this.
|
|
39584
|
+
strokeWidth: this.getCurrentItemStrokeWidth("text"),
|
|
38585
39585
|
strokeStyle: this.state.currentItemStrokeStyle,
|
|
38586
39586
|
roundness: null,
|
|
38587
39587
|
roughness: this.state.currentItemRoughness,
|
|
@@ -39160,6 +40160,12 @@ var App = class _App extends React40.Component {
|
|
|
39160
40160
|
type: isUsingAdaptiveRadius4(elementType) ? ROUNDNESS7.ADAPTIVE_RADIUS : ROUNDNESS7.PROPORTIONAL_RADIUS
|
|
39161
40161
|
} : null;
|
|
39162
40162
|
}
|
|
40163
|
+
getCurrentItemStrokeWidth(elementType) {
|
|
40164
|
+
return getStrokeWidthByKey3(
|
|
40165
|
+
elementType,
|
|
40166
|
+
this.state.currentItemStrokeWidthKey
|
|
40167
|
+
);
|
|
40168
|
+
}
|
|
39163
40169
|
maybeCacheReferenceSnapPoints(event, selectedElements, recomputeAnyways = false) {
|
|
39164
40170
|
if (isSnappingEnabled({
|
|
39165
40171
|
event,
|
|
@@ -39498,12 +40504,12 @@ var App = class _App extends React40.Component {
|
|
|
39498
40504
|
);
|
|
39499
40505
|
const nextCrop = {
|
|
39500
40506
|
...crop,
|
|
39501
|
-
x:
|
|
40507
|
+
x: clamp10(
|
|
39502
40508
|
crop.x - offsetVector[0] * Math.sign(croppingElement.scale[0]),
|
|
39503
40509
|
0,
|
|
39504
40510
|
image.naturalWidth - crop.width
|
|
39505
40511
|
),
|
|
39506
|
-
y:
|
|
40512
|
+
y: clamp10(
|
|
39507
40513
|
crop.y - offsetVector[1] * Math.sign(croppingElement.scale[1]),
|
|
39508
40514
|
0,
|
|
39509
40515
|
image.naturalHeight - crop.height
|
|
@@ -40056,9 +41062,6 @@ var App = class _App extends React40.Component {
|
|
|
40056
41062
|
return;
|
|
40057
41063
|
}
|
|
40058
41064
|
if (isLinearElement11(newElement7)) {
|
|
40059
|
-
if (newElement7.points.length > 1 && newElement7.points[1][0] !== 0 && newElement7.points[1][1] !== 0) {
|
|
40060
|
-
this.store.scheduleCapture();
|
|
40061
|
-
}
|
|
40062
41065
|
const pointerCoords = viewportCoordsToSceneCoords3(
|
|
40063
41066
|
childEvent,
|
|
40064
41067
|
this.state
|
|
@@ -40086,21 +41089,13 @@ var App = class _App extends React40.Component {
|
|
|
40086
41089
|
);
|
|
40087
41090
|
this.actionManager.executeAction(actionFinalize);
|
|
40088
41091
|
} else {
|
|
40089
|
-
const dx = pointerCoords.x - newElement7.x;
|
|
40090
|
-
const dy = pointerCoords.y - newElement7.y;
|
|
40091
|
-
this.scene.mutateElement(
|
|
40092
|
-
newElement7,
|
|
40093
|
-
{
|
|
40094
|
-
points: [newElement7.points[0], pointFrom32(dx, dy)]
|
|
40095
|
-
},
|
|
40096
|
-
{ informMutation: false, isDragging: false }
|
|
40097
|
-
);
|
|
40098
41092
|
this.setState({
|
|
40099
41093
|
multiElement: newElement7,
|
|
40100
41094
|
newElement: newElement7
|
|
40101
41095
|
});
|
|
40102
41096
|
}
|
|
40103
41097
|
} else if (pointerDownState.drag.hasOccurred && !multiElement) {
|
|
41098
|
+
this.store.scheduleCapture();
|
|
40104
41099
|
if (isLinearElement11(newElement7)) {
|
|
40105
41100
|
this.actionManager.executeAction(actionFinalize, "ui", {
|
|
40106
41101
|
event: childEvent,
|
|
@@ -41220,7 +42215,7 @@ import { isLinearElement as isLinearElement12 } from "@excalidraw/element";
|
|
|
41220
42215
|
import {
|
|
41221
42216
|
FONT_FAMILY as FONT_FAMILY7,
|
|
41222
42217
|
THEME as THEME18,
|
|
41223
|
-
MIME_TYPES as
|
|
42218
|
+
MIME_TYPES as MIME_TYPES9,
|
|
41224
42219
|
ROUNDNESS as ROUNDNESS8,
|
|
41225
42220
|
DEFAULT_LASER_COLOR as DEFAULT_LASER_COLOR2,
|
|
41226
42221
|
UserIdleState as UserIdleState2,
|
|
@@ -41312,7 +42307,8 @@ var ExcalidrawBase = (props) => {
|
|
|
41312
42307
|
strokeColorTopPicks,
|
|
41313
42308
|
backgroundColorTopPicks,
|
|
41314
42309
|
renderScrollbars,
|
|
41315
|
-
imageOptions
|
|
42310
|
+
imageOptions,
|
|
42311
|
+
showDropEventDebugAlert
|
|
41316
42312
|
} = props;
|
|
41317
42313
|
const canvasActions = props.UIOptions?.canvasActions;
|
|
41318
42314
|
const UIOptions = {
|
|
@@ -41333,7 +42329,8 @@ var ExcalidrawBase = (props) => {
|
|
|
41333
42329
|
}
|
|
41334
42330
|
const normalizedImageOptions = {
|
|
41335
42331
|
maxFileSizeBytes: imageOptions?.maxFileSizeBytes ?? DEFAULT_IMAGE_OPTIONS.maxFileSizeBytes,
|
|
41336
|
-
maxWidthOrHeight: imageOptions?.maxWidthOrHeight ?? DEFAULT_IMAGE_OPTIONS.maxWidthOrHeight
|
|
42332
|
+
maxWidthOrHeight: imageOptions?.maxWidthOrHeight ?? DEFAULT_IMAGE_OPTIONS.maxWidthOrHeight,
|
|
42333
|
+
placeholderTransitionDuration: imageOptions?.placeholderTransitionDuration ?? DEFAULT_IMAGE_OPTIONS.placeholderTransitionDuration
|
|
41337
42334
|
};
|
|
41338
42335
|
const setExcalidrawAPI = useContext4(ExcalidrawAPISetContext);
|
|
41339
42336
|
const onExcalidrawAPIRef = useRef31(onExcalidrawAPI);
|
|
@@ -41410,6 +42407,7 @@ var ExcalidrawBase = (props) => {
|
|
|
41410
42407
|
backgroundColorTopPicks,
|
|
41411
42408
|
renderScrollbars,
|
|
41412
42409
|
imageOptions: normalizedImageOptions,
|
|
42410
|
+
showDropEventDebugAlert,
|
|
41413
42411
|
children
|
|
41414
42412
|
}
|
|
41415
42413
|
) }) });
|
|
@@ -41452,7 +42450,7 @@ var areEqual5 = (prevProps, nextProps) => {
|
|
|
41452
42450
|
}
|
|
41453
42451
|
return prevUIOptions[key] === nextUIOptions[key];
|
|
41454
42452
|
});
|
|
41455
|
-
const isImageOptionsSame = (prevImageOptions?.maxWidthOrHeight ?? DEFAULT_IMAGE_OPTIONS.maxWidthOrHeight) === (nextImageOptions?.maxWidthOrHeight ?? DEFAULT_IMAGE_OPTIONS.maxWidthOrHeight) && (prevImageOptions?.maxFileSizeBytes ?? DEFAULT_IMAGE_OPTIONS.maxFileSizeBytes) === (nextImageOptions?.maxFileSizeBytes ?? DEFAULT_IMAGE_OPTIONS.maxFileSizeBytes);
|
|
42453
|
+
const isImageOptionsSame = (prevImageOptions?.maxWidthOrHeight ?? DEFAULT_IMAGE_OPTIONS.maxWidthOrHeight) === (nextImageOptions?.maxWidthOrHeight ?? DEFAULT_IMAGE_OPTIONS.maxWidthOrHeight) && (prevImageOptions?.maxFileSizeBytes ?? DEFAULT_IMAGE_OPTIONS.maxFileSizeBytes) === (nextImageOptions?.maxFileSizeBytes ?? DEFAULT_IMAGE_OPTIONS.maxFileSizeBytes) && (prevImageOptions?.placeholderTransitionDuration ?? DEFAULT_IMAGE_OPTIONS.placeholderTransitionDuration) === (nextImageOptions?.placeholderTransitionDuration ?? DEFAULT_IMAGE_OPTIONS.placeholderTransitionDuration);
|
|
41456
42454
|
return isUIOptionsSame && isImageOptionsSame && isShallowEqual9(prev, next);
|
|
41457
42455
|
};
|
|
41458
42456
|
var Excalidraw = React42.memo(ExcalidrawBase, areEqual5);
|
|
@@ -41474,7 +42472,7 @@ export {
|
|
|
41474
42472
|
Fonts,
|
|
41475
42473
|
FooterCenter_default as Footer,
|
|
41476
42474
|
LiveCollaborationTrigger_default as LiveCollaborationTrigger,
|
|
41477
|
-
|
|
42475
|
+
MIME_TYPES9 as MIME_TYPES,
|
|
41478
42476
|
MainMenu_default as MainMenu,
|
|
41479
42477
|
ROUNDNESS8 as ROUNDNESS,
|
|
41480
42478
|
Sidebar,
|
|
@@ -41484,6 +42482,7 @@ export {
|
|
|
41484
42482
|
WelcomeScreen_default as WelcomeScreen,
|
|
41485
42483
|
applyDarkModeFilter5 as applyDarkModeFilter,
|
|
41486
42484
|
bumpVersion3 as bumpVersion,
|
|
42485
|
+
captureDragEventData,
|
|
41487
42486
|
convertToExcalidrawElements2 as convertToExcalidrawElements,
|
|
41488
42487
|
defaultLang,
|
|
41489
42488
|
elementsOverlappingBBox3 as elementsOverlappingBBox,
|
|
@@ -41496,6 +42495,7 @@ export {
|
|
|
41496
42495
|
getFormFactor2 as getFormFactor,
|
|
41497
42496
|
getNonDeletedElements13 as getNonDeletedElements,
|
|
41498
42497
|
getSceneVersion,
|
|
42498
|
+
getStrokeWidthByKey4 as getStrokeWidthByKey,
|
|
41499
42499
|
getTextFromElements3 as getTextFromElements,
|
|
41500
42500
|
getVisibleSceneBounds2 as getVisibleSceneBounds,
|
|
41501
42501
|
hashElementsVersion,
|
|
@@ -41509,6 +42509,8 @@ export {
|
|
|
41509
42509
|
mutateElement7 as mutateElement,
|
|
41510
42510
|
newElementWith11 as newElementWith,
|
|
41511
42511
|
normalizeLink4 as normalizeLink,
|
|
42512
|
+
parseDataTransferEvent,
|
|
42513
|
+
parseDragImageMetadata,
|
|
41512
42514
|
reconcileElements,
|
|
41513
42515
|
renderSpreadsheet,
|
|
41514
42516
|
restoreAppState,
|