@myoc/excalidraw 0.19.519 → 0.19.520
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +53 -0
- package/dist/dev/{chunk-RIK6B6HD.js → chunk-FQHULQ5P.js} +62 -26
- package/dist/dev/chunk-FQHULQ5P.js.map +7 -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-MCPNWEHU.js → chunk-SJJUXTTF.js} +2 -2
- package/dist/dev/data/{image-IRC25PM5.js → image-X3JCQEUX.js} +3 -3
- package/dist/dev/index.css +12 -0
- package/dist/dev/index.css.map +2 -2
- package/dist/dev/index.js +1315 -395
- 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-QW7MIEK6.js → chunk-3QXZ5NQO.js} +1 -1
- package/dist/prod/{chunk-VHQT4IVX.js → chunk-3UXKIWVY.js} +2 -2
- package/dist/prod/chunk-YJSNILE6.js +4 -0
- package/dist/prod/data/image-OBEPGJLJ.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/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 +2 -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 +16 -3
- package/dist/types/laser-pointer/src/index.d.ts +2 -0
- package/dist/types/laser-pointer/src/math.d.ts +16 -0
- package/dist/types/laser-pointer/src/simplify.d.ts +2 -0
- package/dist/types/laser-pointer/src/state.d.ts +35 -0
- package/package.json +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-SJJUXTTF.js.map} +0 -0
- /package/dist/dev/data/{image-IRC25PM5.js.map → image-X3JCQEUX.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-FQHULQ5P.js";
|
|
61
62
|
import {
|
|
62
63
|
define_import_meta_env_default
|
|
63
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-SJJUXTTF.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,
|
|
@@ -9617,7 +9823,7 @@ var exportCanvas = async (type, elements, appState, files, {
|
|
|
9617
9823
|
let blob = canvasToBlob(tempCanvas);
|
|
9618
9824
|
if (appState.exportEmbedScene) {
|
|
9619
9825
|
blob = blob.then(
|
|
9620
|
-
(blob2) => import("./data/image-
|
|
9826
|
+
(blob2) => import("./data/image-X3JCQEUX.js").then(
|
|
9621
9827
|
({ encodePngMetadata: encodePngMetadata2 }) => encodePngMetadata2({
|
|
9622
9828
|
blob: blob2,
|
|
9623
9829
|
metadata: serializeAsJSON(elements, appState, files, "local")
|
|
@@ -11812,7 +12018,8 @@ import {
|
|
|
11812
12018
|
TEXT_ALIGN,
|
|
11813
12019
|
VERTICAL_ALIGN as VERTICAL_ALIGN2,
|
|
11814
12020
|
arrayToMap as arrayToMap13,
|
|
11815
|
-
getFontString
|
|
12021
|
+
getFontString,
|
|
12022
|
+
getStrokeWidthByKey as getStrokeWidthByKey2
|
|
11816
12023
|
} from "@excalidraw/common";
|
|
11817
12024
|
import {
|
|
11818
12025
|
getOriginalContainerHeightFromCache,
|
|
@@ -11999,7 +12206,10 @@ var actionWrapTextInContainer = register({
|
|
|
11999
12206
|
fillStyle: appState.currentItemFillStyle,
|
|
12000
12207
|
strokeColor: appState.currentItemStrokeColor,
|
|
12001
12208
|
roughness: appState.currentItemRoughness,
|
|
12002
|
-
strokeWidth:
|
|
12209
|
+
strokeWidth: getStrokeWidthByKey2(
|
|
12210
|
+
"rectangle",
|
|
12211
|
+
appState.currentItemStrokeWidthKey
|
|
12212
|
+
),
|
|
12003
12213
|
strokeStyle: appState.currentItemStrokeStyle,
|
|
12004
12214
|
roundness: appState.currentItemRoundness === "round" ? {
|
|
12005
12215
|
type: isUsingAdaptiveRadius2("rectangle") ? ROUNDNESS2.ADAPTIVE_RADIUS : ROUNDNESS2.PROPORTIONAL_RADIUS
|
|
@@ -12647,6 +12857,355 @@ import {
|
|
|
12647
12857
|
import { simplify } from "points-on-curve";
|
|
12648
12858
|
import { getStroke } from "perfect-freehand";
|
|
12649
12859
|
|
|
12860
|
+
// ../laser-pointer/src/math.ts
|
|
12861
|
+
function add([ax, ay, ar], [bx, by, br]) {
|
|
12862
|
+
return [ax + bx, ay + by, ar + br];
|
|
12863
|
+
}
|
|
12864
|
+
function sub([ax, ay, ar], [bx, by, br]) {
|
|
12865
|
+
return [ax - bx, ay - by, ar - br];
|
|
12866
|
+
}
|
|
12867
|
+
function smul([x, y, r], s) {
|
|
12868
|
+
return [x * s, y * s, r * s];
|
|
12869
|
+
}
|
|
12870
|
+
function norm([x, y, r]) {
|
|
12871
|
+
return [x / Math.sqrt(x ** 2 + y ** 2), y / Math.sqrt(x ** 2 + y ** 2), r];
|
|
12872
|
+
}
|
|
12873
|
+
function rot([x, y, r], rad) {
|
|
12874
|
+
return [
|
|
12875
|
+
Math.cos(rad) * x - Math.sin(rad) * y,
|
|
12876
|
+
Math.sin(rad) * x + Math.cos(rad) * y,
|
|
12877
|
+
r
|
|
12878
|
+
];
|
|
12879
|
+
}
|
|
12880
|
+
function plerp(a, b, t2) {
|
|
12881
|
+
return add(a, smul(sub(b, a), t2));
|
|
12882
|
+
}
|
|
12883
|
+
function angle(p, p1, p2) {
|
|
12884
|
+
return Math.atan2(p2[1] - p[1], p2[0] - p[0]) - Math.atan2(p1[1] - p[1], p1[0] - p[0]);
|
|
12885
|
+
}
|
|
12886
|
+
function normAngle(a) {
|
|
12887
|
+
return Math.atan2(Math.sin(a), Math.cos(a));
|
|
12888
|
+
}
|
|
12889
|
+
function mag([x, y]) {
|
|
12890
|
+
return Math.sqrt(x ** 2 + y ** 2);
|
|
12891
|
+
}
|
|
12892
|
+
function dist([ax, ay], [bx, by]) {
|
|
12893
|
+
return Math.sqrt((bx - ax) ** 2 + (by - ay) ** 2);
|
|
12894
|
+
}
|
|
12895
|
+
function runLength(ps) {
|
|
12896
|
+
if (ps.length < 2) {
|
|
12897
|
+
return 0;
|
|
12898
|
+
}
|
|
12899
|
+
let len = 0;
|
|
12900
|
+
for (let i = 1; i <= ps.length - 1; i++) {
|
|
12901
|
+
len += dist(ps[i - 1], ps[i]);
|
|
12902
|
+
}
|
|
12903
|
+
len += dist(ps[ps.length - 2], ps[ps.length - 1]);
|
|
12904
|
+
return len;
|
|
12905
|
+
}
|
|
12906
|
+
var clamp2 = (v, min, max) => Math.max(min, Math.min(max, v));
|
|
12907
|
+
function distancePointToSegment(p3, p1, p2) {
|
|
12908
|
+
const sMag = dist(p1, p2);
|
|
12909
|
+
if (sMag === 0) {
|
|
12910
|
+
return dist(p3, p1);
|
|
12911
|
+
}
|
|
12912
|
+
const u = clamp2(
|
|
12913
|
+
((p3[0] - p1[0]) * (p2[0] - p1[0]) + (p3[1] - p1[1]) * (p2[1] - p1[1])) / sMag ** 2,
|
|
12914
|
+
0,
|
|
12915
|
+
1
|
|
12916
|
+
);
|
|
12917
|
+
const pi = [
|
|
12918
|
+
p1[0] + u * (p2[0] - p1[0]),
|
|
12919
|
+
p1[1] + u * (p2[1] - p1[1]),
|
|
12920
|
+
p3[2]
|
|
12921
|
+
];
|
|
12922
|
+
return dist(pi, p3);
|
|
12923
|
+
}
|
|
12924
|
+
|
|
12925
|
+
// ../laser-pointer/src/simplify.ts
|
|
12926
|
+
function douglasPeucker(points, epsilon) {
|
|
12927
|
+
if (epsilon === 0) {
|
|
12928
|
+
return points;
|
|
12929
|
+
}
|
|
12930
|
+
if (points.length <= 2) {
|
|
12931
|
+
return points;
|
|
12932
|
+
}
|
|
12933
|
+
const first = points[0];
|
|
12934
|
+
const last = points[points.length - 1];
|
|
12935
|
+
const [maxDistance, maxIndex] = points.reduce(
|
|
12936
|
+
([maxDistance2, maxIndex2], point, index) => {
|
|
12937
|
+
const distance3 = distancePointToSegment(point, first, last);
|
|
12938
|
+
return distance3 > maxDistance2 ? [distance3, index] : [maxDistance2, maxIndex2];
|
|
12939
|
+
},
|
|
12940
|
+
[0, -1]
|
|
12941
|
+
);
|
|
12942
|
+
if (maxDistance >= epsilon) {
|
|
12943
|
+
const maxIndexPoint = points[maxIndex];
|
|
12944
|
+
return [
|
|
12945
|
+
...douglasPeucker(
|
|
12946
|
+
[first, ...points.slice(1, maxIndex), maxIndexPoint],
|
|
12947
|
+
epsilon
|
|
12948
|
+
).slice(0, -1),
|
|
12949
|
+
maxIndexPoint,
|
|
12950
|
+
...douglasPeucker(
|
|
12951
|
+
[maxIndexPoint, ...points.slice(maxIndex, -1), last],
|
|
12952
|
+
epsilon
|
|
12953
|
+
).slice(1)
|
|
12954
|
+
];
|
|
12955
|
+
}
|
|
12956
|
+
return [first, last];
|
|
12957
|
+
}
|
|
12958
|
+
|
|
12959
|
+
// ../laser-pointer/src/state.ts
|
|
12960
|
+
var _LaserPointer = class _LaserPointer {
|
|
12961
|
+
constructor(options) {
|
|
12962
|
+
__publicField(this, "options");
|
|
12963
|
+
__publicField(this, "originalPoints", []);
|
|
12964
|
+
__publicField(this, "stablePoints", []);
|
|
12965
|
+
__publicField(this, "tailPoints", []);
|
|
12966
|
+
__publicField(this, "isFresh", true);
|
|
12967
|
+
this.options = Object.assign({}, _LaserPointer.defaults, options);
|
|
12968
|
+
}
|
|
12969
|
+
get lastPoint() {
|
|
12970
|
+
return this.tailPoints[this.tailPoints.length - 1] ?? this.stablePoints[this.stablePoints.length - 1];
|
|
12971
|
+
}
|
|
12972
|
+
addPoint(point) {
|
|
12973
|
+
const lastPoint = this.originalPoints[this.originalPoints.length - 1];
|
|
12974
|
+
if (lastPoint && lastPoint[0] === point[0] && lastPoint[1] === point[1]) {
|
|
12975
|
+
return;
|
|
12976
|
+
}
|
|
12977
|
+
this.originalPoints.push(point);
|
|
12978
|
+
if (this.isFresh) {
|
|
12979
|
+
this.isFresh = false;
|
|
12980
|
+
this.stablePoints.push(point);
|
|
12981
|
+
return;
|
|
12982
|
+
}
|
|
12983
|
+
if (this.options.streamline > 0) {
|
|
12984
|
+
point = plerp(this.lastPoint, point, 1 - this.options.streamline);
|
|
12985
|
+
}
|
|
12986
|
+
this.tailPoints.push(point);
|
|
12987
|
+
if (runLength(this.tailPoints) > _LaserPointer.constants.maxTailLength) {
|
|
12988
|
+
this.stabilizeTail();
|
|
12989
|
+
}
|
|
12990
|
+
}
|
|
12991
|
+
close() {
|
|
12992
|
+
this.stabilizeTail();
|
|
12993
|
+
}
|
|
12994
|
+
stabilizeTail() {
|
|
12995
|
+
if (this.options.simplify > 0 && this.options.simplifyPhase === "tail") {
|
|
12996
|
+
throw new Error("Not implemented yet");
|
|
12997
|
+
} else {
|
|
12998
|
+
this.stablePoints.push(...this.tailPoints);
|
|
12999
|
+
this.tailPoints = [];
|
|
13000
|
+
}
|
|
13001
|
+
}
|
|
13002
|
+
getSize(sizeOverride, pressure, index, totalLength, runningLength) {
|
|
13003
|
+
return (sizeOverride ?? this.options.size) * this.options.sizeMapping({
|
|
13004
|
+
pressure,
|
|
13005
|
+
runningLength,
|
|
13006
|
+
currentIndex: index,
|
|
13007
|
+
totalLength
|
|
13008
|
+
});
|
|
13009
|
+
}
|
|
13010
|
+
getStrokeOutline(sizeOverride) {
|
|
13011
|
+
if (this.isFresh) {
|
|
13012
|
+
return [];
|
|
13013
|
+
}
|
|
13014
|
+
let points = [...this.stablePoints, ...this.tailPoints];
|
|
13015
|
+
if (this.options.simplify > 0 && this.options.simplifyPhase === "input") {
|
|
13016
|
+
points = douglasPeucker(points, this.options.simplify);
|
|
13017
|
+
}
|
|
13018
|
+
const len = points.length;
|
|
13019
|
+
if (len === 0) {
|
|
13020
|
+
return [];
|
|
13021
|
+
}
|
|
13022
|
+
if (len === 1) {
|
|
13023
|
+
const c = points[0];
|
|
13024
|
+
const size = this.getSize(sizeOverride, c[2], 0, len, 0);
|
|
13025
|
+
if (size < 0.5) {
|
|
13026
|
+
return [];
|
|
13027
|
+
}
|
|
13028
|
+
const ps = [];
|
|
13029
|
+
for (let theta = 0; theta <= Math.PI * 2; theta += Math.PI / 16) {
|
|
13030
|
+
ps.push(add(c, smul(rot([1, 0, 0], theta), size)));
|
|
13031
|
+
}
|
|
13032
|
+
ps.push(
|
|
13033
|
+
add(
|
|
13034
|
+
c,
|
|
13035
|
+
smul(
|
|
13036
|
+
[1, 0, 0],
|
|
13037
|
+
this.getSize(sizeOverride, c[2], 0, len, 0)
|
|
13038
|
+
)
|
|
13039
|
+
)
|
|
13040
|
+
);
|
|
13041
|
+
return ps;
|
|
13042
|
+
}
|
|
13043
|
+
if (len === 2) {
|
|
13044
|
+
const c = points[0];
|
|
13045
|
+
const n = points[1];
|
|
13046
|
+
const cSize = this.getSize(sizeOverride, c[2], 0, len, 0);
|
|
13047
|
+
const nSize = this.getSize(sizeOverride, n[2], 0, len, 0);
|
|
13048
|
+
if (cSize < 0.5 || nSize < 0.5) {
|
|
13049
|
+
return [];
|
|
13050
|
+
}
|
|
13051
|
+
const ps = [];
|
|
13052
|
+
const pAngle = angle(c, [c[0], c[1] - 100, c[2]], n);
|
|
13053
|
+
for (let theta = pAngle; theta <= Math.PI + pAngle; theta += Math.PI / 16) {
|
|
13054
|
+
ps.push(add(c, smul(rot([1, 0, 0], theta), cSize)));
|
|
13055
|
+
}
|
|
13056
|
+
for (let theta = Math.PI + pAngle; theta <= Math.PI * 2 + pAngle; theta += Math.PI / 16) {
|
|
13057
|
+
ps.push(add(n, smul(rot([1, 0, 0], theta), nSize)));
|
|
13058
|
+
}
|
|
13059
|
+
ps.push(ps[0]);
|
|
13060
|
+
return ps;
|
|
13061
|
+
}
|
|
13062
|
+
const forwardPoints = [];
|
|
13063
|
+
const backwardPoints = [];
|
|
13064
|
+
let speed = 0;
|
|
13065
|
+
let prevSpeed = 0;
|
|
13066
|
+
let visibleStartIndex = 0;
|
|
13067
|
+
let runningLength = 0;
|
|
13068
|
+
for (let i = 1; i < len - 1; i++) {
|
|
13069
|
+
const p = points[i - 1];
|
|
13070
|
+
const c = points[i];
|
|
13071
|
+
const n = points[i + 1];
|
|
13072
|
+
const pressure = c[2];
|
|
13073
|
+
const d = dist(p, c);
|
|
13074
|
+
runningLength += d;
|
|
13075
|
+
speed = prevSpeed + (d - prevSpeed) * 0.2;
|
|
13076
|
+
const cSize = this.getSize(sizeOverride, pressure, i, len, runningLength);
|
|
13077
|
+
if (cSize === 0) {
|
|
13078
|
+
visibleStartIndex = i + 1;
|
|
13079
|
+
continue;
|
|
13080
|
+
}
|
|
13081
|
+
const dirPC = norm(sub(p, c));
|
|
13082
|
+
const dirNC = norm(sub(n, c));
|
|
13083
|
+
const p1dirPC = rot(dirPC, Math.PI / 2);
|
|
13084
|
+
const p2dirPC = rot(dirPC, -Math.PI / 2);
|
|
13085
|
+
const p1dirNC = rot(dirNC, Math.PI / 2);
|
|
13086
|
+
const p2dirNC = rot(dirNC, -Math.PI / 2);
|
|
13087
|
+
const p1PC = add(c, smul(p1dirPC, cSize));
|
|
13088
|
+
const p2PC = add(c, smul(p2dirPC, cSize));
|
|
13089
|
+
const p1NC = add(c, smul(p1dirNC, cSize));
|
|
13090
|
+
const p2NC = add(c, smul(p2dirNC, cSize));
|
|
13091
|
+
const ftdir = add(p1dirPC, p2dirNC);
|
|
13092
|
+
const btdir = add(p2dirPC, p1dirNC);
|
|
13093
|
+
const paPC = add(
|
|
13094
|
+
c,
|
|
13095
|
+
smul(mag(ftdir) === 0 ? dirPC : norm(ftdir), cSize)
|
|
13096
|
+
);
|
|
13097
|
+
const paNC = add(
|
|
13098
|
+
c,
|
|
13099
|
+
smul(mag(btdir) === 0 ? dirNC : norm(btdir), cSize)
|
|
13100
|
+
);
|
|
13101
|
+
const cAngle = normAngle(angle(c, p, n));
|
|
13102
|
+
const D_ANGLE = _LaserPointer.constants.cornerDetectionMaxAngle / 180 * Math.PI * _LaserPointer.constants.cornerDetectionVariance(speed);
|
|
13103
|
+
if (Math.abs(cAngle) < D_ANGLE) {
|
|
13104
|
+
const tAngle = Math.abs(normAngle(Math.PI - cAngle));
|
|
13105
|
+
if (tAngle === 0) {
|
|
13106
|
+
continue;
|
|
13107
|
+
}
|
|
13108
|
+
if (cAngle < 0) {
|
|
13109
|
+
backwardPoints.push(p2PC, paNC);
|
|
13110
|
+
for (let theta = 0; theta <= tAngle; theta += tAngle / 4) {
|
|
13111
|
+
forwardPoints.push(add(c, rot(smul(p1dirPC, cSize), theta)));
|
|
13112
|
+
}
|
|
13113
|
+
for (let theta = tAngle; theta >= 0; theta -= tAngle / 4) {
|
|
13114
|
+
backwardPoints.push(add(c, rot(smul(p1dirPC, cSize), theta)));
|
|
13115
|
+
}
|
|
13116
|
+
backwardPoints.push(paNC, p1NC);
|
|
13117
|
+
} else {
|
|
13118
|
+
forwardPoints.push(p1PC, paPC);
|
|
13119
|
+
for (let theta = 0; theta <= tAngle; theta += tAngle / 4) {
|
|
13120
|
+
backwardPoints.push(
|
|
13121
|
+
add(c, rot(smul(p1dirPC, -cSize), -theta))
|
|
13122
|
+
);
|
|
13123
|
+
}
|
|
13124
|
+
for (let theta = tAngle; theta >= 0; theta -= tAngle / 4) {
|
|
13125
|
+
forwardPoints.push(
|
|
13126
|
+
add(c, rot(smul(p1dirPC, -cSize), -theta))
|
|
13127
|
+
);
|
|
13128
|
+
}
|
|
13129
|
+
forwardPoints.push(paPC, p2NC);
|
|
13130
|
+
}
|
|
13131
|
+
} else {
|
|
13132
|
+
forwardPoints.push(paPC);
|
|
13133
|
+
backwardPoints.push(paNC);
|
|
13134
|
+
}
|
|
13135
|
+
prevSpeed = speed;
|
|
13136
|
+
}
|
|
13137
|
+
if (visibleStartIndex >= len - 2) {
|
|
13138
|
+
if (this.options.keepHead) {
|
|
13139
|
+
const c = points[len - 1];
|
|
13140
|
+
const ps = [];
|
|
13141
|
+
for (let theta = 0; theta <= Math.PI * 2; theta += Math.PI / 16) {
|
|
13142
|
+
ps.push(
|
|
13143
|
+
add(
|
|
13144
|
+
c,
|
|
13145
|
+
smul(rot([1, 0, 0], theta), this.options.size)
|
|
13146
|
+
)
|
|
13147
|
+
);
|
|
13148
|
+
}
|
|
13149
|
+
ps.push(add(c, smul([1, 0, 0], this.options.size)));
|
|
13150
|
+
return ps;
|
|
13151
|
+
}
|
|
13152
|
+
return [];
|
|
13153
|
+
}
|
|
13154
|
+
const first = points[visibleStartIndex];
|
|
13155
|
+
const second = points[visibleStartIndex + 1];
|
|
13156
|
+
const penultimate = points[len - 2];
|
|
13157
|
+
const ultimate = points[len - 1];
|
|
13158
|
+
const dirFS = norm(sub(second, first));
|
|
13159
|
+
const dirPU = norm(sub(penultimate, ultimate));
|
|
13160
|
+
const ppdirFS = rot(dirFS, -Math.PI / 2);
|
|
13161
|
+
const ppdirPU = rot(dirPU, Math.PI / 2);
|
|
13162
|
+
const startCapSize = this.getSize(sizeOverride, first[2], 0, len, 0);
|
|
13163
|
+
const startCap = [];
|
|
13164
|
+
const endCapSize = this.options.keepHead ? this.options.size : this.getSize(sizeOverride, penultimate[2], len - 2, len, runningLength);
|
|
13165
|
+
const endCap = [];
|
|
13166
|
+
if (startCapSize > 0.1) {
|
|
13167
|
+
for (let theta = 0; theta <= Math.PI; theta += Math.PI / 16) {
|
|
13168
|
+
startCap.unshift(
|
|
13169
|
+
add(first, rot(smul(ppdirFS, startCapSize), -theta))
|
|
13170
|
+
);
|
|
13171
|
+
}
|
|
13172
|
+
startCap.unshift(add(first, smul(ppdirFS, -startCapSize)));
|
|
13173
|
+
} else {
|
|
13174
|
+
startCap.push(first);
|
|
13175
|
+
}
|
|
13176
|
+
for (let theta = 0; theta <= Math.PI * 3; theta += Math.PI / 16) {
|
|
13177
|
+
endCap.push(add(ultimate, rot(smul(ppdirPU, -endCapSize), -theta)));
|
|
13178
|
+
}
|
|
13179
|
+
const strokeOutline = [
|
|
13180
|
+
...startCap,
|
|
13181
|
+
...forwardPoints,
|
|
13182
|
+
...endCap.reverse(),
|
|
13183
|
+
...backwardPoints.reverse()
|
|
13184
|
+
];
|
|
13185
|
+
if (startCap.length > 0) {
|
|
13186
|
+
strokeOutline.push(startCap[0]);
|
|
13187
|
+
}
|
|
13188
|
+
if (this.options.simplify > 0 && this.options.simplifyPhase === "output") {
|
|
13189
|
+
return douglasPeucker(strokeOutline, this.options.simplify);
|
|
13190
|
+
}
|
|
13191
|
+
return strokeOutline;
|
|
13192
|
+
}
|
|
13193
|
+
};
|
|
13194
|
+
__publicField(_LaserPointer, "defaults", {
|
|
13195
|
+
size: 2,
|
|
13196
|
+
streamline: 0.45,
|
|
13197
|
+
simplify: 0.1,
|
|
13198
|
+
simplifyPhase: "output",
|
|
13199
|
+
keepHead: false,
|
|
13200
|
+
sizeMapping: () => 1
|
|
13201
|
+
});
|
|
13202
|
+
__publicField(_LaserPointer, "constants", {
|
|
13203
|
+
cornerDetectionMaxAngle: 75,
|
|
13204
|
+
cornerDetectionVariance: (s) => s > 35 ? 0.5 : 1,
|
|
13205
|
+
maxTailLength: 50
|
|
13206
|
+
});
|
|
13207
|
+
var LaserPointer = _LaserPointer;
|
|
13208
|
+
|
|
12650
13209
|
// ../utils/src/shape.ts
|
|
12651
13210
|
import { pointsOnBezierCurves } from "points-on-curve";
|
|
12652
13211
|
import { invariant as invariant4 } from "@excalidraw/common";
|
|
@@ -12693,7 +13252,8 @@ import {
|
|
|
12693
13252
|
assertNever as assertNever2,
|
|
12694
13253
|
COLOR_PALETTE as COLOR_PALETTE3,
|
|
12695
13254
|
LINE_POLYGON_POINT_MERGE_DISTANCE,
|
|
12696
|
-
applyDarkModeFilter as applyDarkModeFilter2
|
|
13255
|
+
applyDarkModeFilter as applyDarkModeFilter2,
|
|
13256
|
+
DEFAULT_STROKE_STREAMLINE
|
|
12697
13257
|
} from "@excalidraw/common";
|
|
12698
13258
|
import { RoughGenerator } from "roughjs/bin/generator";
|
|
12699
13259
|
|
|
@@ -12711,7 +13271,7 @@ import {
|
|
|
12711
13271
|
ELEMENT_READY_TO_ERASE_OPACITY,
|
|
12712
13272
|
FRAME_STYLE,
|
|
12713
13273
|
DARK_THEME_FILTER,
|
|
12714
|
-
MIME_TYPES as
|
|
13274
|
+
MIME_TYPES as MIME_TYPES5,
|
|
12715
13275
|
THEME as THEME9,
|
|
12716
13276
|
distance,
|
|
12717
13277
|
getFontString as getFontString4,
|
|
@@ -12770,7 +13330,7 @@ import {
|
|
|
12770
13330
|
} from "@excalidraw/common";
|
|
12771
13331
|
import {
|
|
12772
13332
|
PRECISION as PRECISION2,
|
|
12773
|
-
clamp as
|
|
13333
|
+
clamp as clamp4,
|
|
12774
13334
|
lineSegment as lineSegment4,
|
|
12775
13335
|
pointDistance as pointDistance4,
|
|
12776
13336
|
pointDistanceSq,
|
|
@@ -12968,7 +13528,7 @@ var headingIsHorizontal = (a) => compareHeading(a, HEADING_RIGHT) || compareHead
|
|
|
12968
13528
|
|
|
12969
13529
|
// ../element/src/elbowArrow.ts
|
|
12970
13530
|
import {
|
|
12971
|
-
clamp as
|
|
13531
|
+
clamp as clamp3,
|
|
12972
13532
|
pointDistance as pointDistance3,
|
|
12973
13533
|
pointFrom as pointFrom9,
|
|
12974
13534
|
pointScaleFromOrigin as pointScaleFromOrigin2,
|
|
@@ -13005,6 +13565,7 @@ import { pointsEqual as pointsEqual6 } from "@excalidraw/math";
|
|
|
13005
13565
|
|
|
13006
13566
|
// ../element/src/zindex.ts
|
|
13007
13567
|
import { arrayToMap as arrayToMap20, findIndex, findLastIndex } from "@excalidraw/common";
|
|
13568
|
+
import { isFiniteNumber } from "@excalidraw/math";
|
|
13008
13569
|
|
|
13009
13570
|
// ../element/src/selection.ts
|
|
13010
13571
|
import { arrayToMap as arrayToMap19, isShallowEqual } from "@excalidraw/common";
|
|
@@ -13276,29 +13837,29 @@ var getArrowheadPoints = (element, shape, position, arrowhead, offsetMultiplier
|
|
|
13276
13837
|
const diameter = Math.hypot(ys - ty, xs - tx) + element.strokeWidth - 2;
|
|
13277
13838
|
return [tx, ty, diameter];
|
|
13278
13839
|
}
|
|
13279
|
-
const
|
|
13840
|
+
const angle2 = getArrowheadAngle(arrowhead);
|
|
13280
13841
|
if (arrowhead === "cardinality_many" || arrowhead === "cardinality_one_or_many") {
|
|
13281
13842
|
const [x32, y32] = pointRotateRads9(
|
|
13282
13843
|
pointFrom13(tx, ty),
|
|
13283
13844
|
pointFrom13(xs, ys),
|
|
13284
|
-
degreesToRadians(-
|
|
13845
|
+
degreesToRadians(-angle2)
|
|
13285
13846
|
);
|
|
13286
13847
|
const [x42, y42] = pointRotateRads9(
|
|
13287
13848
|
pointFrom13(tx, ty),
|
|
13288
13849
|
pointFrom13(xs, ys),
|
|
13289
|
-
degreesToRadians(
|
|
13850
|
+
degreesToRadians(angle2)
|
|
13290
13851
|
);
|
|
13291
13852
|
return [xs, ys, x32, y32, x42, y42];
|
|
13292
13853
|
}
|
|
13293
13854
|
const [x3, y3] = pointRotateRads9(
|
|
13294
13855
|
pointFrom13(xs, ys),
|
|
13295
13856
|
pointFrom13(tx, ty),
|
|
13296
|
-
-
|
|
13857
|
+
-angle2 * Math.PI / 180
|
|
13297
13858
|
);
|
|
13298
13859
|
const [x4, y4] = pointRotateRads9(
|
|
13299
13860
|
pointFrom13(xs, ys),
|
|
13300
13861
|
pointFrom13(tx, ty),
|
|
13301
|
-
degreesToRadians(
|
|
13862
|
+
degreesToRadians(angle2)
|
|
13302
13863
|
);
|
|
13303
13864
|
if (arrowhead === "diamond" || arrowhead === "diamond_outline") {
|
|
13304
13865
|
let ox;
|
|
@@ -13334,17 +13895,21 @@ import {
|
|
|
13334
13895
|
vectorAdd as vectorAdd2,
|
|
13335
13896
|
vectorScale as vectorScale7,
|
|
13336
13897
|
pointFromVector as pointFromVector6,
|
|
13337
|
-
clamp as
|
|
13898
|
+
clamp as clamp5,
|
|
13338
13899
|
isCloseTo
|
|
13339
13900
|
} from "@excalidraw/math";
|
|
13340
13901
|
|
|
13902
|
+
// ../element/src/image.ts
|
|
13903
|
+
import { MIME_TYPES as MIME_TYPES4, SVG_NS } from "@excalidraw/common";
|
|
13904
|
+
import { rgbaToThumbHash, thumbHashToRGBA } from "thumbhash";
|
|
13905
|
+
|
|
13341
13906
|
// ../element/src/renderElement.ts
|
|
13342
13907
|
var IMAGE_PLACEHOLDER_IMG = typeof document !== "undefined" ? document.createElement("img") : { src: "" };
|
|
13343
|
-
IMAGE_PLACEHOLDER_IMG.src = `data:${
|
|
13908
|
+
IMAGE_PLACEHOLDER_IMG.src = `data:${MIME_TYPES5.svg},${encodeURIComponent(
|
|
13344
13909
|
`<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
13910
|
)}`;
|
|
13346
13911
|
var IMAGE_ERROR_PLACEHOLDER_IMG = typeof document !== "undefined" ? document.createElement("img") : { src: "" };
|
|
13347
|
-
IMAGE_ERROR_PLACEHOLDER_IMG.src = `data:${
|
|
13912
|
+
IMAGE_ERROR_PLACEHOLDER_IMG.src = `data:${MIME_TYPES5.svg},${encodeURIComponent(
|
|
13348
13913
|
`<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
13914
|
)}`;
|
|
13350
13915
|
var elementWithCanvasCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -13948,19 +14513,46 @@ var getFreeDrawSvgPath = (element) => {
|
|
|
13948
14513
|
getFreedrawOutlinePoints(element)
|
|
13949
14514
|
);
|
|
13950
14515
|
};
|
|
13951
|
-
var
|
|
13952
|
-
|
|
14516
|
+
var VARIABLE_WIDTH_FREEDRAW = {
|
|
14517
|
+
/** Stroke size relative to `strokeWidth` for pressure-sensitive strokes. */
|
|
14518
|
+
SIZE_FACTOR: 4.25,
|
|
14519
|
+
THINNING: 0.6,
|
|
14520
|
+
SMOOTHING: 0.5
|
|
14521
|
+
};
|
|
14522
|
+
var CONSTANT_WIDTH_FREEDRAW = {
|
|
14523
|
+
/** Stroke size relative to `strokeWidth` for uniform (laser) strokes. */
|
|
14524
|
+
SIZE_FACTOR: 1.4
|
|
14525
|
+
};
|
|
14526
|
+
var getFreedrawStreamline = (element) => element.strokeOptions?.streamline ?? DEFAULT_STROKE_STREAMLINE;
|
|
14527
|
+
var getVariableWidthFreedrawOutline = (element) => {
|
|
14528
|
+
const inputPoints = element.simulatePressure ? element.points : element.points.length ? element.points.map(
|
|
14529
|
+
([x, y], i) => [x, y, element.pressures[i]]
|
|
14530
|
+
) : [[0, 0, 0.5]];
|
|
13953
14531
|
return getStroke(inputPoints, {
|
|
13954
14532
|
simulatePressure: element.simulatePressure,
|
|
13955
|
-
size: element.strokeWidth *
|
|
13956
|
-
thinning:
|
|
13957
|
-
smoothing:
|
|
13958
|
-
streamline:
|
|
14533
|
+
size: element.strokeWidth * VARIABLE_WIDTH_FREEDRAW.SIZE_FACTOR,
|
|
14534
|
+
thinning: VARIABLE_WIDTH_FREEDRAW.THINNING,
|
|
14535
|
+
smoothing: VARIABLE_WIDTH_FREEDRAW.SMOOTHING,
|
|
14536
|
+
streamline: getFreedrawStreamline(element),
|
|
13959
14537
|
easing: (t2) => Math.sin(t2 * Math.PI / 2),
|
|
13960
14538
|
// https://easings.net/#easeOutSine
|
|
13961
14539
|
last: true
|
|
13962
14540
|
});
|
|
13963
14541
|
};
|
|
14542
|
+
var createLaserPointer = (element) => new LaserPointer({
|
|
14543
|
+
size: element.strokeWidth * CONSTANT_WIDTH_FREEDRAW.SIZE_FACTOR,
|
|
14544
|
+
streamline: getFreedrawStreamline(element),
|
|
14545
|
+
simplify: 0,
|
|
14546
|
+
sizeMapping: (details) => Math.max(0.1, details.pressure)
|
|
14547
|
+
});
|
|
14548
|
+
var getConstantWidthFreedrawOutline = (element) => {
|
|
14549
|
+
const laserPointer = createLaserPointer(element);
|
|
14550
|
+
element.points.map(([x, y]) => laserPointer.addPoint([x, y, 1]));
|
|
14551
|
+
return laserPointer.getStrokeOutline().map(([x, y]) => [x, y]);
|
|
14552
|
+
};
|
|
14553
|
+
var getFreedrawOutlinePoints = (element) => {
|
|
14554
|
+
return element.strokeOptions?.variability === "constant" ? getConstantWidthFreedrawOutline(element) : getVariableWidthFreedrawOutline(element);
|
|
14555
|
+
};
|
|
13964
14556
|
var med = (A, B) => {
|
|
13965
14557
|
return [(A[0] + B[0]) / 2, (A[1] + B[1]) / 2];
|
|
13966
14558
|
};
|
|
@@ -16170,56 +16762,9 @@ var Renderer = class {
|
|
|
16170
16762
|
}
|
|
16171
16763
|
};
|
|
16172
16764
|
|
|
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";
|
|
16765
|
+
// scroll.ts
|
|
16766
|
+
import { easeOut } from "@excalidraw/common";
|
|
16767
|
+
import { clamp as clamp6 } from "@excalidraw/math";
|
|
16223
16768
|
|
|
16224
16769
|
// reactUtils.ts
|
|
16225
16770
|
import { version as ReactVersion } from "react";
|
|
@@ -16345,12 +16890,139 @@ var _AnimationController = class _AnimationController {
|
|
|
16345
16890
|
_AnimationController.animations.delete(key);
|
|
16346
16891
|
_AnimationController.cancelScheduledFrameIfIdle();
|
|
16347
16892
|
}
|
|
16893
|
+
static reset() {
|
|
16894
|
+
_AnimationController.animations.clear();
|
|
16895
|
+
_AnimationController.cancelScheduledFrame();
|
|
16896
|
+
}
|
|
16348
16897
|
};
|
|
16349
16898
|
__publicField(_AnimationController, "scheduledFrame", null);
|
|
16350
16899
|
__publicField(_AnimationController, "animations", /* @__PURE__ */ new Map());
|
|
16351
16900
|
var AnimationController = _AnimationController;
|
|
16352
16901
|
|
|
16902
|
+
// scroll.ts
|
|
16903
|
+
var SCROLL_TO_CONTENT_ANIMATION_KEY = "animateScrollToContent";
|
|
16904
|
+
var DEFAULT_ANIMATION_DURATION = 500;
|
|
16905
|
+
var scrollToElements = (state, target, onFrame, opts) => {
|
|
16906
|
+
AnimationController.cancel(SCROLL_TO_CONTENT_ANIMATION_KEY);
|
|
16907
|
+
const viewport = getTargetViewport(state, target, opts);
|
|
16908
|
+
if (opts?.animate) {
|
|
16909
|
+
animateToViewport(
|
|
16910
|
+
state,
|
|
16911
|
+
viewport,
|
|
16912
|
+
opts.duration ?? DEFAULT_ANIMATION_DURATION,
|
|
16913
|
+
onFrame
|
|
16914
|
+
);
|
|
16915
|
+
} else {
|
|
16916
|
+
onFrame({ ...viewport, shouldCacheIgnoreZoom: false });
|
|
16917
|
+
}
|
|
16918
|
+
};
|
|
16919
|
+
var getTargetViewport = (state, targetElements, opts) => {
|
|
16920
|
+
if (opts?.fitToContent || opts?.fitToViewport) {
|
|
16921
|
+
const { appState } = zoomToFit({
|
|
16922
|
+
canvasOffsets: opts.canvasOffsets,
|
|
16923
|
+
targetElements,
|
|
16924
|
+
appState: state,
|
|
16925
|
+
fitToViewport: !!opts.fitToViewport,
|
|
16926
|
+
viewportZoomFactor: opts.viewportZoomFactor,
|
|
16927
|
+
minZoom: opts.minZoom,
|
|
16928
|
+
maxZoom: opts.maxZoom
|
|
16929
|
+
});
|
|
16930
|
+
return {
|
|
16931
|
+
scrollX: appState.scrollX,
|
|
16932
|
+
scrollY: appState.scrollY,
|
|
16933
|
+
zoom: appState.zoom
|
|
16934
|
+
};
|
|
16935
|
+
}
|
|
16936
|
+
const { scrollX, scrollY } = calculateScrollCenter(targetElements, state);
|
|
16937
|
+
return { scrollX, scrollY, zoom: state.zoom };
|
|
16938
|
+
};
|
|
16939
|
+
var interpolateViewport = ({
|
|
16940
|
+
from,
|
|
16941
|
+
target,
|
|
16942
|
+
factor
|
|
16943
|
+
}) => {
|
|
16944
|
+
const zoom = from.zoom.value * Math.pow(
|
|
16945
|
+
target.zoom.value / from.zoom.value,
|
|
16946
|
+
factor
|
|
16947
|
+
);
|
|
16948
|
+
const fromCenterX = from.width / 2 / from.zoom.value - from.scrollX;
|
|
16949
|
+
const fromCenterY = from.height / 2 / from.zoom.value - from.scrollY;
|
|
16950
|
+
const toCenterX = from.width / 2 / target.zoom.value - target.scrollX;
|
|
16951
|
+
const toCenterY = from.height / 2 / target.zoom.value - target.scrollY;
|
|
16952
|
+
const centerX = fromCenterX + (toCenterX - fromCenterX) * factor;
|
|
16953
|
+
const centerY = fromCenterY + (toCenterY - fromCenterY) * factor;
|
|
16954
|
+
return {
|
|
16955
|
+
scrollX: from.width / 2 / zoom - centerX,
|
|
16956
|
+
scrollY: from.height / 2 / zoom - centerY,
|
|
16957
|
+
zoom: { value: zoom }
|
|
16958
|
+
};
|
|
16959
|
+
};
|
|
16960
|
+
var animateToViewport = (from, target, duration, onFrame) => {
|
|
16961
|
+
AnimationController.start(
|
|
16962
|
+
SCROLL_TO_CONTENT_ANIMATION_KEY,
|
|
16963
|
+
({ deltaTime, state }) => {
|
|
16964
|
+
const elapsed = (state?.elapsed ?? 0) + deltaTime;
|
|
16965
|
+
const progress = Math.min(elapsed / duration, 1);
|
|
16966
|
+
const factor = easeOut(clamp6(progress, 0, 1));
|
|
16967
|
+
onFrame({
|
|
16968
|
+
...interpolateViewport({ from, target, factor }),
|
|
16969
|
+
shouldCacheIgnoreZoom: progress < 1
|
|
16970
|
+
// ignore zoom caching while animating
|
|
16971
|
+
});
|
|
16972
|
+
return progress < 1 ? { elapsed } : null;
|
|
16973
|
+
}
|
|
16974
|
+
);
|
|
16975
|
+
};
|
|
16976
|
+
|
|
16977
|
+
// components/ElementCanvasButtons.tsx
|
|
16978
|
+
import { sceneCoordsToViewportCoords as sceneCoordsToViewportCoords2 } from "@excalidraw/common";
|
|
16979
|
+
import { getElementAbsoluteCoords as getElementAbsoluteCoords5 } from "@excalidraw/element";
|
|
16980
|
+
import { jsx as jsx57 } from "react/jsx-runtime";
|
|
16981
|
+
var CONTAINER_PADDING = 5;
|
|
16982
|
+
var getContainerCoords2 = (element, appState, elementsMap) => {
|
|
16983
|
+
const [x1, y1] = getElementAbsoluteCoords5(element, elementsMap);
|
|
16984
|
+
const { x: viewportX, y: viewportY } = sceneCoordsToViewportCoords2(
|
|
16985
|
+
{ sceneX: x1 + element.width, sceneY: y1 },
|
|
16986
|
+
appState
|
|
16987
|
+
);
|
|
16988
|
+
const x = viewportX - appState.offsetLeft + 10;
|
|
16989
|
+
const y = viewportY - appState.offsetTop;
|
|
16990
|
+
return { x, y };
|
|
16991
|
+
};
|
|
16992
|
+
var ElementCanvasButtons = ({
|
|
16993
|
+
children,
|
|
16994
|
+
element,
|
|
16995
|
+
elementsMap
|
|
16996
|
+
}) => {
|
|
16997
|
+
const appState = useExcalidrawAppState();
|
|
16998
|
+
if (appState.contextMenu || appState.newElement || appState.resizingElement || appState.isRotating || appState.openMenu || appState.viewModeEnabled) {
|
|
16999
|
+
return null;
|
|
17000
|
+
}
|
|
17001
|
+
const { x, y } = getContainerCoords2(element, appState, elementsMap);
|
|
17002
|
+
return /* @__PURE__ */ jsx57(
|
|
17003
|
+
"div",
|
|
17004
|
+
{
|
|
17005
|
+
className: "excalidraw-canvas-buttons",
|
|
17006
|
+
style: {
|
|
17007
|
+
top: `${y}px`,
|
|
17008
|
+
left: `${x}px`,
|
|
17009
|
+
// width: CONTAINER_WIDTH,
|
|
17010
|
+
padding: CONTAINER_PADDING
|
|
17011
|
+
},
|
|
17012
|
+
children
|
|
17013
|
+
}
|
|
17014
|
+
);
|
|
17015
|
+
};
|
|
17016
|
+
|
|
17017
|
+
// laserTrails.ts
|
|
17018
|
+
import { DEFAULT_LASER_COLOR, easeOut as easeOut2 } from "@excalidraw/common";
|
|
17019
|
+
|
|
16353
17020
|
// animatedTrail.ts
|
|
17021
|
+
import {
|
|
17022
|
+
SVG_NS as SVG_NS2,
|
|
17023
|
+
getSvgPathFromStroke as getSvgPathFromStroke2,
|
|
17024
|
+
sceneCoordsToViewportCoords as sceneCoordsToViewportCoords3
|
|
17025
|
+
} from "@excalidraw/common";
|
|
16354
17026
|
var _AnimatedTrail = class _AnimatedTrail {
|
|
16355
17027
|
constructor(app, options) {
|
|
16356
17028
|
this.app = app;
|
|
@@ -16362,9 +17034,9 @@ var _AnimatedTrail = class _AnimatedTrail {
|
|
|
16362
17034
|
__publicField(this, "trailAnimation");
|
|
16363
17035
|
__publicField(this, "key");
|
|
16364
17036
|
this.key = `animated-trail-${_AnimatedTrail.counter++}`;
|
|
16365
|
-
this.trailElement = document.createElementNS(
|
|
17037
|
+
this.trailElement = document.createElementNS(SVG_NS2, "path");
|
|
16366
17038
|
if (this.options.animateTrail) {
|
|
16367
|
-
this.trailAnimation = document.createElementNS(
|
|
17039
|
+
this.trailAnimation = document.createElementNS(SVG_NS2, "animate");
|
|
16368
17040
|
this.trailAnimation.setAttribute("attributeName", "stroke-dashoffset");
|
|
16369
17041
|
this.trailElement.setAttribute("stroke-dasharray", "7 7");
|
|
16370
17042
|
this.trailElement.setAttribute("stroke-dashoffset", "10");
|
|
@@ -16522,7 +17194,7 @@ var LaserTrails = class {
|
|
|
16522
17194
|
1 - (performance.now() - c.pressure) / DECAY_TIME
|
|
16523
17195
|
);
|
|
16524
17196
|
const l = (DECAY_LENGTH - Math.min(DECAY_LENGTH, c.totalLength - c.currentIndex)) / DECAY_LENGTH;
|
|
16525
|
-
return Math.min(
|
|
17197
|
+
return Math.min(easeOut2(l), easeOut2(t2));
|
|
16526
17198
|
}
|
|
16527
17199
|
};
|
|
16528
17200
|
}
|
|
@@ -16662,7 +17334,7 @@ import {
|
|
|
16662
17334
|
getFontString as getFontString6,
|
|
16663
17335
|
getFontFamilyString as getFontFamilyString3,
|
|
16664
17336
|
isTestEnv as isTestEnv4,
|
|
16665
|
-
MIME_TYPES as
|
|
17337
|
+
MIME_TYPES as MIME_TYPES6,
|
|
16666
17338
|
applyDarkModeFilter as applyDarkModeFilter3,
|
|
16667
17339
|
isRTL as isRTL2
|
|
16668
17340
|
} from "@excalidraw/common";
|
|
@@ -16697,9 +17369,9 @@ import {
|
|
|
16697
17369
|
isBoundToContainer as isBoundToContainer7,
|
|
16698
17370
|
isTextElement as isTextElement8
|
|
16699
17371
|
} from "@excalidraw/element";
|
|
16700
|
-
var getTransform = (width, height,
|
|
17372
|
+
var getTransform = (width, height, angle2, appState, maxWidth, maxHeight) => {
|
|
16701
17373
|
const { zoom } = appState;
|
|
16702
|
-
const degree = 180 *
|
|
17374
|
+
const degree = 180 * angle2 / Math.PI;
|
|
16703
17375
|
let translateX = width * (zoom.value - 1) / 2;
|
|
16704
17376
|
let translateY = height * (zoom.value - 1) / 2;
|
|
16705
17377
|
if (width > maxWidth && zoom.value !== 1) {
|
|
@@ -16905,7 +17577,7 @@ var textWysiwyg = ({
|
|
|
16905
17577
|
}
|
|
16906
17578
|
height *= 1.05;
|
|
16907
17579
|
const font = getFontString6(updatedTextElement);
|
|
16908
|
-
const
|
|
17580
|
+
const angle2 = getTextElementAngle(updatedTextElement, container);
|
|
16909
17581
|
const editorMaxHeight = (appState.height - viewportY) / appState.zoom.value;
|
|
16910
17582
|
Object.assign(editable.style, {
|
|
16911
17583
|
font,
|
|
@@ -16918,7 +17590,7 @@ var textWysiwyg = ({
|
|
|
16918
17590
|
transform: getTransform(
|
|
16919
17591
|
width,
|
|
16920
17592
|
height,
|
|
16921
|
-
|
|
17593
|
+
angle2,
|
|
16922
17594
|
appState,
|
|
16923
17595
|
maxWidth,
|
|
16924
17596
|
editorMaxHeight
|
|
@@ -16933,7 +17605,7 @@ var textWysiwyg = ({
|
|
|
16933
17605
|
maxHeight: `${editorMaxHeight}px`
|
|
16934
17606
|
});
|
|
16935
17607
|
currentTextLayout = {
|
|
16936
|
-
angle,
|
|
17608
|
+
angle: angle2,
|
|
16937
17609
|
font,
|
|
16938
17610
|
height: updatedTextElement.height,
|
|
16939
17611
|
lineHeightPx: getLineHeightInPx2(
|
|
@@ -17042,7 +17714,7 @@ var textWysiwyg = ({
|
|
|
17042
17714
|
editable.onpaste = async (event) => {
|
|
17043
17715
|
const mimeTypes = parseDataTransferEventMimeTypes(event);
|
|
17044
17716
|
let dataList = null;
|
|
17045
|
-
if (mimeTypes.has(
|
|
17717
|
+
if (mimeTypes.has(MIME_TYPES6.excalidrawClipboard) || mimeTypes.has(MIME_TYPES6.excalidraw)) {
|
|
17046
17718
|
event.preventDefault();
|
|
17047
17719
|
dataList = await parseDataTransferEvent(event);
|
|
17048
17720
|
try {
|
|
@@ -17063,7 +17735,7 @@ var textWysiwyg = ({
|
|
|
17063
17735
|
}
|
|
17064
17736
|
}
|
|
17065
17737
|
dataList = dataList || await parseDataTransferEvent(event);
|
|
17066
|
-
const textItem = dataList.findByType(
|
|
17738
|
+
const textItem = dataList.findByType(MIME_TYPES6.text);
|
|
17067
17739
|
if (!textItem) {
|
|
17068
17740
|
return;
|
|
17069
17741
|
}
|
|
@@ -17455,7 +18127,7 @@ import {
|
|
|
17455
18127
|
import { getFrameChildren as getFrameChildren4 } from "@excalidraw/element";
|
|
17456
18128
|
import { selectGroupsForSelectedElements as selectGroupsForSelectedElements6 } from "@excalidraw/element";
|
|
17457
18129
|
import { getContainerElement as getContainerElement4 } from "@excalidraw/element";
|
|
17458
|
-
import { arrayToMap as arrayToMap25, easeOut as
|
|
18130
|
+
import { arrayToMap as arrayToMap25, easeOut as easeOut3, isShallowEqual as isShallowEqual3 } from "@excalidraw/common";
|
|
17459
18131
|
|
|
17460
18132
|
// lasso/utils.ts
|
|
17461
18133
|
import { simplify as simplify2 } from "points-on-curve";
|
|
@@ -17567,7 +18239,7 @@ var LassoTrail = class extends AnimatedTrail {
|
|
|
17567
18239
|
1 - (performance.now() - c.pressure) / DECAY_TIME
|
|
17568
18240
|
);
|
|
17569
18241
|
const l = (DECAY_LENGTH - Math.min(DECAY_LENGTH, c.totalLength - c.currentIndex)) / DECAY_LENGTH;
|
|
17570
|
-
return Math.min(
|
|
18242
|
+
return Math.min(easeOut3(l), easeOut3(t2));
|
|
17571
18243
|
},
|
|
17572
18244
|
fill: () => "rgba(105,101,219,0.05)",
|
|
17573
18245
|
stroke: () => "rgba(105,101,219)"
|
|
@@ -17735,7 +18407,7 @@ var actionSmartZoom = register({
|
|
|
17735
18407
|
});
|
|
17736
18408
|
|
|
17737
18409
|
// eraser/index.ts
|
|
17738
|
-
import { arrayToMap as arrayToMap26, easeOut as
|
|
18410
|
+
import { arrayToMap as arrayToMap26, easeOut as easeOut4, THEME as THEME12 } from "@excalidraw/common";
|
|
17739
18411
|
import {
|
|
17740
18412
|
computeBoundTextPosition as computeBoundTextPosition4,
|
|
17741
18413
|
doBoundsIntersect as doBoundsIntersect3,
|
|
@@ -17775,7 +18447,7 @@ var EraserTrail = class extends AnimatedTrail {
|
|
|
17775
18447
|
1 - (performance.now() - c.pressure) / DECAY_TIME
|
|
17776
18448
|
);
|
|
17777
18449
|
const l = (DECAY_LENGTH - Math.min(DECAY_LENGTH, c.totalLength - c.currentIndex)) / DECAY_LENGTH;
|
|
17778
|
-
return Math.min(
|
|
18450
|
+
return Math.min(easeOut4(l), easeOut4(t2));
|
|
17779
18451
|
},
|
|
17780
18452
|
fill: () => app.state.theme === THEME12.LIGHT ? "rgba(0, 0, 0, 0.2)" : "rgba(255, 255, 255, 0.2)"
|
|
17781
18453
|
});
|
|
@@ -18165,7 +18837,7 @@ var createRadarAxisLabels = (labels, angles, centerX, centerY, radius, backgroun
|
|
|
18165
18837
|
);
|
|
18166
18838
|
const minLabelWidth = getApproxMinLineWidth(fontString, lineHeight);
|
|
18167
18839
|
const axisLabels = labels.map((label, index) => {
|
|
18168
|
-
const
|
|
18840
|
+
const angle2 = angles[index];
|
|
18169
18841
|
const longestWordWidth = Math.max(
|
|
18170
18842
|
0,
|
|
18171
18843
|
...label.trim().split(/\s+/).filter(Boolean).map((word) => measureText4(word, fontString, lineHeight).width)
|
|
@@ -18177,8 +18849,8 @@ var createRadarAxisLabels = (labels, angles, centerX, centerY, radius, backgroun
|
|
|
18177
18849
|
);
|
|
18178
18850
|
const displayLabel = getRadarDisplayText(label, fontString, maxLabelWidth);
|
|
18179
18851
|
const metrics = measureText4(displayLabel, fontString, lineHeight);
|
|
18180
|
-
const cos = Math.cos(
|
|
18181
|
-
const sin = Math.sin(
|
|
18852
|
+
const cos = Math.cos(angle2);
|
|
18853
|
+
const sin = Math.sin(angle2);
|
|
18182
18854
|
const textAlign = cos > RADAR_AXIS_LABEL_ALIGNMENT_THRESHOLD ? "left" : cos < -RADAR_AXIS_LABEL_ALIGNMENT_THRESHOLD ? "right" : "center";
|
|
18183
18855
|
const centerAlignedXExtent = textAlign === "center" ? metrics.width / 2 : 0;
|
|
18184
18856
|
const projectedExtent = Math.abs(cos) * centerAlignedXExtent + Math.abs(sin) * (metrics.height / 2);
|
|
@@ -18324,9 +18996,9 @@ var wrapOrEllipsifyTextToWidth = (text, maxWidth, fontString, lineHeight) => {
|
|
|
18324
18996
|
text: ellipsifyTextToWidth(text, maxWidth, fontString, lineHeight)
|
|
18325
18997
|
};
|
|
18326
18998
|
};
|
|
18327
|
-
var getRotatedBoundingBox = (width, height,
|
|
18328
|
-
const cos = Math.abs(Math.cos(
|
|
18329
|
-
const sin = Math.abs(Math.sin(
|
|
18999
|
+
var getRotatedBoundingBox = (width, height, angle2) => {
|
|
19000
|
+
const cos = Math.abs(Math.cos(angle2));
|
|
19001
|
+
const sin = Math.abs(Math.sin(angle2));
|
|
18330
19002
|
return {
|
|
18331
19003
|
width: width * cos + height * sin,
|
|
18332
19004
|
height: width * sin + height * cos
|
|
@@ -18900,9 +19572,9 @@ var renderRadarChart = (spreadsheet, x, y, colorSeed) => {
|
|
|
18900
19572
|
const levelRatio = (levelIndex + 1) / RADAR_GRID_LEVELS;
|
|
18901
19573
|
const levelRadius = radius * levelRatio;
|
|
18902
19574
|
const points = angles.map(
|
|
18903
|
-
(
|
|
18904
|
-
Math.cos(
|
|
18905
|
-
Math.sin(
|
|
19575
|
+
(angle2) => pointFrom24(
|
|
19576
|
+
Math.cos(angle2) * levelRadius,
|
|
19577
|
+
Math.sin(angle2) * levelRadius
|
|
18906
19578
|
)
|
|
18907
19579
|
);
|
|
18908
19580
|
points.push(pointFrom24(points[0][0], points[0][1]));
|
|
@@ -18921,9 +19593,9 @@ var renderRadarChart = (spreadsheet, x, y, colorSeed) => {
|
|
|
18921
19593
|
points
|
|
18922
19594
|
});
|
|
18923
19595
|
}) : [];
|
|
18924
|
-
const spokes = angles.map((
|
|
18925
|
-
const px = Math.cos(
|
|
18926
|
-
const py = Math.sin(
|
|
19596
|
+
const spokes = angles.map((angle2) => {
|
|
19597
|
+
const px = Math.cos(angle2) * radius;
|
|
19598
|
+
const py = Math.sin(angle2) * radius;
|
|
18927
19599
|
return newLinearElement3({
|
|
18928
19600
|
backgroundColor: "transparent",
|
|
18929
19601
|
...commonProps,
|
|
@@ -18939,12 +19611,12 @@ var renderRadarChart = (spreadsheet, x, y, colorSeed) => {
|
|
|
18939
19611
|
});
|
|
18940
19612
|
});
|
|
18941
19613
|
const seriesPolygons = series.map((seriesData, index) => {
|
|
18942
|
-
const points = angles.map((
|
|
19614
|
+
const points = angles.map((angle2, axisIndex) => {
|
|
18943
19615
|
const value = seriesData.values[axisIndex] ?? 0;
|
|
18944
19616
|
const pointRadius = normalize(value, axisIndex) * radius;
|
|
18945
19617
|
return pointFrom24(
|
|
18946
|
-
Math.cos(
|
|
18947
|
-
Math.sin(
|
|
19618
|
+
Math.cos(angle2) * pointRadius,
|
|
19619
|
+
Math.sin(angle2) * pointRadius
|
|
18948
19620
|
);
|
|
18949
19621
|
});
|
|
18950
19622
|
points.push(pointFrom24(points[0][0], points[0][1]));
|
|
@@ -19430,7 +20102,7 @@ var filterLinearConvertibleElements = (elements) => elements.filter(
|
|
|
19430
20102
|
var THRESHOLD = 20;
|
|
19431
20103
|
var isVert = (a, b) => a[0] === b[0];
|
|
19432
20104
|
var isHorz = (a, b) => a[1] === b[1];
|
|
19433
|
-
var
|
|
20105
|
+
var dist2 = (a, b) => isVert(a, b) ? Math.abs(a[1] - b[1]) : Math.abs(a[0] - b[0]);
|
|
19434
20106
|
var convertLineToElbow = (line) => {
|
|
19435
20107
|
const ortho = [line.points[0]];
|
|
19436
20108
|
const src = sanitizePoints(line.points);
|
|
@@ -19464,8 +20136,8 @@ var convertLineToElbow = (line) => {
|
|
|
19464
20136
|
const v1 = isVert(a, b);
|
|
19465
20137
|
const v2 = isVert(b, c);
|
|
19466
20138
|
if (v1 !== v2) {
|
|
19467
|
-
const d1 =
|
|
19468
|
-
const d2 =
|
|
20139
|
+
const d1 = dist2(a, b);
|
|
20140
|
+
const d2 = dist2(b, c);
|
|
19469
20141
|
if (d1 < THRESHOLD || d2 < THRESHOLD) {
|
|
19470
20142
|
if (d2 < d1) {
|
|
19471
20143
|
if (v1) {
|
|
@@ -19522,7 +20194,7 @@ var convertElementType = (element, targetType, app) => {
|
|
|
19522
20194
|
newElement5({
|
|
19523
20195
|
...element,
|
|
19524
20196
|
type: targetType,
|
|
19525
|
-
roundness:
|
|
20197
|
+
roundness: element.roundness ? {
|
|
19526
20198
|
type: isUsingAdaptiveRadius3(targetType) ? ROUNDNESS6.ADAPTIVE_RADIUS : ROUNDNESS6.PROPORTIONAL_RADIUS
|
|
19527
20199
|
} : element.roundness
|
|
19528
20200
|
})
|
|
@@ -20645,7 +21317,7 @@ var SelectedShapeActions = ({
|
|
|
20645
21317
|
canChangeBackgroundColor(appState, targetElements) && /* @__PURE__ */ jsx75("div", { children: renderAction("changeBackgroundColor") }),
|
|
20646
21318
|
showFillIcons && renderAction("changeFillStyle"),
|
|
20647
21319
|
(hasStrokeWidth(appState.activeTool.type) || targetElements.some((element) => hasStrokeWidth(element.type))) && renderAction("changeStrokeWidth"),
|
|
20648
|
-
(appState.activeTool.type
|
|
21320
|
+
(hasFreedrawMode(appState.activeTool.type) || targetElements.some((element) => hasFreedrawMode(element.type))) && renderAction("changeFreedrawMode"),
|
|
20649
21321
|
(hasStrokeStyle(appState.activeTool.type) || targetElements.some((element) => hasStrokeStyle(element.type))) && /* @__PURE__ */ jsxs35(Fragment8, { children: [
|
|
20650
21322
|
renderAction("changeStrokeStyle"),
|
|
20651
21323
|
renderAction("changeSloppiness")
|
|
@@ -20778,6 +21450,13 @@ var CombinedShapeProperties = ({
|
|
|
20778
21450
|
(hasStrokeWidth(appState.activeTool.type) || targetElements.some(
|
|
20779
21451
|
(element) => hasStrokeWidth(element.type)
|
|
20780
21452
|
)) && renderAction("changeStrokeWidth"),
|
|
21453
|
+
/* in compact UI the freedraw pressure setting is rendered as a
|
|
21454
|
+
standalone cycle button in the compact actions list; we render
|
|
21455
|
+
it in the combined properties popup as well for clarity
|
|
21456
|
+
*/
|
|
21457
|
+
(hasFreedrawMode(appState.activeTool.type) || targetElements.some(
|
|
21458
|
+
(element) => hasFreedrawMode(element.type)
|
|
21459
|
+
)) && renderAction("changeFreedrawMode"),
|
|
20781
21460
|
(hasStrokeStyle(appState.activeTool.type) || targetElements.some(
|
|
20782
21461
|
(element) => hasStrokeStyle(element.type)
|
|
20783
21462
|
)) && /* @__PURE__ */ jsxs35(Fragment8, { children: [
|
|
@@ -21105,6 +21784,7 @@ var CompactShapeActions = ({
|
|
|
21105
21784
|
return /* @__PURE__ */ jsxs35("div", { className: "compact-shape-actions", children: [
|
|
21106
21785
|
canChangeStrokeColor(appState, targetElements) && /* @__PURE__ */ jsx75("div", { className: clsx29("compact-action-item"), children: renderAction("changeStrokeColor") }),
|
|
21107
21786
|
canChangeBackgroundColor(appState, targetElements) && /* @__PURE__ */ jsx75("div", { className: "compact-action-item", children: renderAction("changeBackgroundColor") }),
|
|
21787
|
+
(hasFreedrawMode(appState.activeTool.type) || targetElements.some((element) => hasFreedrawMode(element.type))) && /* @__PURE__ */ jsx75("div", { className: "compact-action-item", children: renderAction("changeFreedrawMode", { cycle: true }) }),
|
|
21108
21788
|
/* @__PURE__ */ jsx75(
|
|
21109
21789
|
CombinedShapeProperties,
|
|
21110
21790
|
{
|
|
@@ -21293,6 +21973,7 @@ var ShapesSwitcher = ({
|
|
|
21293
21973
|
const stylesPanelMode = useStylesPanelMode();
|
|
21294
21974
|
const isFullStylesPanel = stylesPanelMode === "full";
|
|
21295
21975
|
const isCompactStylesPanel = stylesPanelMode === "compact";
|
|
21976
|
+
const pendingPenDetectionRef = useRef16(false);
|
|
21296
21977
|
const SELECTION_TOOLS2 = [
|
|
21297
21978
|
{
|
|
21298
21979
|
type: "selection",
|
|
@@ -21418,7 +22099,7 @@ var ShapesSwitcher = ({
|
|
|
21418
22099
|
"data-testid": `toolbar-${value}`,
|
|
21419
22100
|
onPointerDown: ({ pointerType }) => {
|
|
21420
22101
|
if (!app.state.penDetected && pointerType === "pen") {
|
|
21421
|
-
|
|
22102
|
+
pendingPenDetectionRef.current = true;
|
|
21422
22103
|
}
|
|
21423
22104
|
if (value === "selection") {
|
|
21424
22105
|
if (app.state.activeTool.type === "selection") {
|
|
@@ -21428,16 +22109,14 @@ var ShapesSwitcher = ({
|
|
|
21428
22109
|
}
|
|
21429
22110
|
}
|
|
21430
22111
|
},
|
|
21431
|
-
onChange: (
|
|
22112
|
+
onChange: () => {
|
|
21432
22113
|
if (app.state.activeTool.type !== value) {
|
|
21433
22114
|
trackEvent("toolbar", value, "ui");
|
|
21434
22115
|
}
|
|
21435
|
-
|
|
21436
|
-
|
|
21437
|
-
|
|
21438
|
-
|
|
21439
|
-
} else {
|
|
21440
|
-
app.setActiveTool({ type: value });
|
|
22116
|
+
app.setActiveTool({ type: value });
|
|
22117
|
+
if (pendingPenDetectionRef.current) {
|
|
22118
|
+
pendingPenDetectionRef.current = false;
|
|
22119
|
+
requestAnimationFrame(() => app.togglePenMode(true));
|
|
21441
22120
|
}
|
|
21442
22121
|
}
|
|
21443
22122
|
},
|
|
@@ -25250,7 +25929,7 @@ var CanvasGrid = ({
|
|
|
25250
25929
|
var CanvasGrid_default = CanvasGrid;
|
|
25251
25930
|
|
|
25252
25931
|
// components/Stats/Dimension.tsx
|
|
25253
|
-
import { clamp as
|
|
25932
|
+
import { clamp as clamp7, round as round3 } from "@excalidraw/math";
|
|
25254
25933
|
import { MIN_WIDTH_OR_HEIGHT } from "@excalidraw/common";
|
|
25255
25934
|
import {
|
|
25256
25935
|
MINIMAL_CROP_SIZE,
|
|
@@ -25305,7 +25984,7 @@ var handleDimensionChange = ({
|
|
|
25305
25984
|
if (nextValue !== void 0) {
|
|
25306
25985
|
if (property === "width") {
|
|
25307
25986
|
const nextValueInNatural = nextValue * naturalToUncroppedWidthRatio;
|
|
25308
|
-
const nextCropWidth2 =
|
|
25987
|
+
const nextCropWidth2 = clamp7(
|
|
25309
25988
|
nextValueInNatural,
|
|
25310
25989
|
MIN_WIDTH,
|
|
25311
25990
|
MAX_POSSIBLE_WIDTH
|
|
@@ -25317,7 +25996,7 @@ var handleDimensionChange = ({
|
|
|
25317
25996
|
};
|
|
25318
25997
|
} else if (property === "height") {
|
|
25319
25998
|
const nextValueInNatural = nextValue * naturalToUncroppedHeightRatio;
|
|
25320
|
-
const nextCropHeight2 =
|
|
25999
|
+
const nextCropHeight2 = clamp7(
|
|
25321
26000
|
nextValueInNatural,
|
|
25322
26001
|
MIN_HEIGHT,
|
|
25323
26002
|
MAX_POSSIBLE_HEIGHT
|
|
@@ -25337,12 +26016,12 @@ var handleDimensionChange = ({
|
|
|
25337
26016
|
}
|
|
25338
26017
|
const changeInWidth = property === "width" ? instantChange : 0;
|
|
25339
26018
|
const changeInHeight = property === "height" ? instantChange : 0;
|
|
25340
|
-
const nextCropWidth =
|
|
26019
|
+
const nextCropWidth = clamp7(
|
|
25341
26020
|
crop.width + changeInWidth,
|
|
25342
26021
|
MIN_WIDTH,
|
|
25343
26022
|
MAX_POSSIBLE_WIDTH
|
|
25344
26023
|
);
|
|
25345
|
-
const nextCropHeight =
|
|
26024
|
+
const nextCropHeight = clamp7(
|
|
25346
26025
|
crop.height + changeInHeight,
|
|
25347
26026
|
MIN_WIDTH,
|
|
25348
26027
|
MAX_POSSIBLE_HEIGHT
|
|
@@ -25696,7 +26375,7 @@ import { getBoundTextElement as getBoundTextElement13, handleBindTextResize as h
|
|
|
25696
26375
|
import { isTextElement as isTextElement13 } from "@excalidraw/element";
|
|
25697
26376
|
|
|
25698
26377
|
// ../utils/src/export.ts
|
|
25699
|
-
import { MIME_TYPES as
|
|
26378
|
+
import { MIME_TYPES as MIME_TYPES7 } from "@excalidraw/common";
|
|
25700
26379
|
var exportToCanvas2 = ({
|
|
25701
26380
|
elements,
|
|
25702
26381
|
appState,
|
|
@@ -25744,16 +26423,16 @@ var exportToCanvas2 = ({
|
|
|
25744
26423
|
);
|
|
25745
26424
|
};
|
|
25746
26425
|
var exportToBlob = async (opts) => {
|
|
25747
|
-
let { mimeType =
|
|
25748
|
-
if (mimeType ===
|
|
25749
|
-
console.warn(`"quality" will be ignored for "${
|
|
26426
|
+
let { mimeType = MIME_TYPES7.png, quality } = opts;
|
|
26427
|
+
if (mimeType === MIME_TYPES7.png && typeof quality === "number") {
|
|
26428
|
+
console.warn(`"quality" will be ignored for "${MIME_TYPES7.png}" mimeType`);
|
|
25750
26429
|
}
|
|
25751
26430
|
if (mimeType === "image/jpg") {
|
|
25752
|
-
mimeType =
|
|
26431
|
+
mimeType = MIME_TYPES7.jpg;
|
|
25753
26432
|
}
|
|
25754
|
-
if (mimeType ===
|
|
26433
|
+
if (mimeType === MIME_TYPES7.jpg && !opts.appState?.exportBackground) {
|
|
25755
26434
|
console.warn(
|
|
25756
|
-
`Defaulting "exportBackground" to "true" for "${
|
|
26435
|
+
`Defaulting "exportBackground" to "true" for "${MIME_TYPES7.jpg}" mimeType`
|
|
25757
26436
|
);
|
|
25758
26437
|
opts = {
|
|
25759
26438
|
...opts,
|
|
@@ -25768,7 +26447,7 @@ var exportToBlob = async (opts) => {
|
|
|
25768
26447
|
if (!blob) {
|
|
25769
26448
|
return reject(new Error("couldn't export to blob"));
|
|
25770
26449
|
}
|
|
25771
|
-
if (blob && mimeType ===
|
|
26450
|
+
if (blob && mimeType === MIME_TYPES7.png && opts.appState?.exportEmbedScene) {
|
|
25772
26451
|
blob = await encodePngMetadata({
|
|
25773
26452
|
blob,
|
|
25774
26453
|
metadata: serializeAsJSON(
|
|
@@ -26469,7 +27148,7 @@ var MultiPosition = ({
|
|
|
26469
27148
|
var MultiPosition_default = MultiPosition;
|
|
26470
27149
|
|
|
26471
27150
|
// components/Stats/Position.tsx
|
|
26472
|
-
import { clamp as
|
|
27151
|
+
import { clamp as clamp8, pointFrom as pointFrom29, pointRotateRads as pointRotateRads19, round as round4 } from "@excalidraw/math";
|
|
26473
27152
|
import {
|
|
26474
27153
|
getFlipAdjustedCropPosition,
|
|
26475
27154
|
getUncroppedWidthAndHeight as getUncroppedWidthAndHeight2
|
|
@@ -26515,7 +27194,7 @@ var handlePositionChange2 = ({
|
|
|
26515
27194
|
if (isFlippedByX) {
|
|
26516
27195
|
nextCrop = {
|
|
26517
27196
|
...crop,
|
|
26518
|
-
x:
|
|
27197
|
+
x: clamp8(
|
|
26519
27198
|
crop.naturalWidth - nextValueInNatural - crop.width,
|
|
26520
27199
|
0,
|
|
26521
27200
|
crop.naturalWidth - crop.width
|
|
@@ -26524,7 +27203,7 @@ var handlePositionChange2 = ({
|
|
|
26524
27203
|
} else {
|
|
26525
27204
|
nextCrop = {
|
|
26526
27205
|
...crop,
|
|
26527
|
-
x:
|
|
27206
|
+
x: clamp8(
|
|
26528
27207
|
nextValue * (crop.naturalWidth / uncroppedWidth),
|
|
26529
27208
|
0,
|
|
26530
27209
|
crop.naturalWidth - crop.width
|
|
@@ -26535,7 +27214,7 @@ var handlePositionChange2 = ({
|
|
|
26535
27214
|
if (property === "y") {
|
|
26536
27215
|
nextCrop = {
|
|
26537
27216
|
...crop,
|
|
26538
|
-
y:
|
|
27217
|
+
y: clamp8(
|
|
26539
27218
|
nextValue * (crop.naturalHeight / uncroppedHeight),
|
|
26540
27219
|
0,
|
|
26541
27220
|
crop.naturalHeight - crop.height
|
|
@@ -26551,8 +27230,8 @@ var handlePositionChange2 = ({
|
|
|
26551
27230
|
const changeInY = (property === "y" ? instantChange : 0) * (isFlippedByY ? -1 : 1);
|
|
26552
27231
|
nextCrop = {
|
|
26553
27232
|
...crop,
|
|
26554
|
-
x:
|
|
26555
|
-
y:
|
|
27233
|
+
x: clamp8(crop.x + changeInX, 0, crop.naturalWidth - crop.width),
|
|
27234
|
+
y: clamp8(crop.y + changeInY, 0, crop.naturalHeight - crop.height)
|
|
26556
27235
|
};
|
|
26557
27236
|
scene.mutateElement(element, {
|
|
26558
27237
|
crop: nextCrop
|
|
@@ -28794,7 +29473,6 @@ var LayerUI = ({
|
|
|
28794
29473
|
renderWelcomeScreen && /* @__PURE__ */ jsx130(tunnels.WelcomeScreenMenuHintTunnel.Out, {})
|
|
28795
29474
|
] });
|
|
28796
29475
|
const renderSelectedShapeActions = () => {
|
|
28797
|
-
const isCompactMode = isCompactStylesPanel;
|
|
28798
29476
|
return /* @__PURE__ */ jsx130(
|
|
28799
29477
|
Section,
|
|
28800
29478
|
{
|
|
@@ -28802,7 +29480,7 @@ var LayerUI = ({
|
|
|
28802
29480
|
className: clsx55("selected-shape-actions zen-mode-transition", {
|
|
28803
29481
|
"transition-left": appState.zenModeEnabled
|
|
28804
29482
|
}),
|
|
28805
|
-
children:
|
|
29483
|
+
children: isCompactStylesPanel ? /* @__PURE__ */ jsx130(
|
|
28806
29484
|
Island,
|
|
28807
29485
|
{
|
|
28808
29486
|
className: clsx55("compact-shape-actions-island"),
|
|
@@ -28873,6 +29551,17 @@ var LayerUI = ({
|
|
|
28873
29551
|
}),
|
|
28874
29552
|
children: shouldRenderSelectedShapeActions && renderSelectedShapeActions()
|
|
28875
29553
|
}
|
|
29554
|
+
),
|
|
29555
|
+
isCompactStylesPanel && !appState.viewModeEnabled && shouldRenderSelectedShapeActions && /* @__PURE__ */ jsx130(
|
|
29556
|
+
PenModeButton,
|
|
29557
|
+
{
|
|
29558
|
+
zenModeEnabled: appState.zenModeEnabled,
|
|
29559
|
+
checked: appState.penMode,
|
|
29560
|
+
onChange: () => onPenModeToggle(null),
|
|
29561
|
+
title: t("toolBar.penMode"),
|
|
29562
|
+
isMobile: true,
|
|
29563
|
+
penDetected: appState.penDetected
|
|
29564
|
+
}
|
|
28876
29565
|
)
|
|
28877
29566
|
]
|
|
28878
29567
|
}
|
|
@@ -28907,7 +29596,7 @@ var LayerUI = ({
|
|
|
28907
29596
|
),
|
|
28908
29597
|
heading,
|
|
28909
29598
|
/* @__PURE__ */ jsxs67(Stack_default.Row, { gap: spacing.toolbarInnerRowGap, children: [
|
|
28910
|
-
/* @__PURE__ */ jsx130(
|
|
29599
|
+
!isCompactStylesPanel && /* @__PURE__ */ jsx130(
|
|
28911
29600
|
PenModeButton,
|
|
28912
29601
|
{
|
|
28913
29602
|
zenModeEnabled: appState.zenModeEnabled,
|
|
@@ -29295,7 +29984,7 @@ import {
|
|
|
29295
29984
|
|
|
29296
29985
|
// renderer/interactiveScene.ts
|
|
29297
29986
|
import {
|
|
29298
|
-
clamp as
|
|
29987
|
+
clamp as clamp9,
|
|
29299
29988
|
pointFrom as pointFrom31,
|
|
29300
29989
|
pointsEqual as pointsEqual8,
|
|
29301
29990
|
bezierEquation as bezierEquation2,
|
|
@@ -29601,7 +30290,7 @@ var renderBindingHighlightForBindableElement_simple = (context, suggestedBinding
|
|
|
29601
30290
|
context.rotate(suggestedBinding.element.angle);
|
|
29602
30291
|
context.translate(-center[0], -center[1]);
|
|
29603
30292
|
context.translate(suggestedBinding.element.x, suggestedBinding.element.y);
|
|
29604
|
-
context.lineWidth =
|
|
30293
|
+
context.lineWidth = clamp9(1.75, suggestedBinding.element.strokeWidth, 4) / Math.max(0.25, appState.zoom.value);
|
|
29605
30294
|
context.strokeStyle = appState.theme === THEME16.DARK ? `rgba(3, 93, 161, 1)` : `rgba(106, 189, 252, 1)`;
|
|
29606
30295
|
switch (suggestedBinding.element.type) {
|
|
29607
30296
|
case "ellipse":
|
|
@@ -29792,7 +30481,7 @@ var renderBindingHighlightForBindableElement_simple = (context, suggestedBinding
|
|
|
29792
30481
|
var renderBindingHighlightForBindableElement_complex = (app, context, element, allElementsMap, appState, deltaTime, state) => {
|
|
29793
30482
|
const countdownInProgress = app.state.bindMode === "orbit" && app.bindModeHandler !== null;
|
|
29794
30483
|
const remainingTime = BIND_MODE_TIMEOUT - (state?.runtime ?? (countdownInProgress ? 0 : BIND_MODE_TIMEOUT));
|
|
29795
|
-
const opacity =
|
|
30484
|
+
const opacity = clamp9(1 / BIND_MODE_TIMEOUT * remainingTime, 1e-4, 1);
|
|
29796
30485
|
const offset = element.strokeWidth / 2;
|
|
29797
30486
|
const enclosingFrame = element.frameId && allElementsMap.get(element.frameId);
|
|
29798
30487
|
if (enclosingFrame && isFrameLikeElement14(enclosingFrame)) {
|
|
@@ -29847,7 +30536,7 @@ var renderBindingHighlightForBindableElement_complex = (app, context, element, a
|
|
|
29847
30536
|
element.x + appState.scrollX - offset,
|
|
29848
30537
|
element.y + appState.scrollY - offset
|
|
29849
30538
|
);
|
|
29850
|
-
context.lineWidth =
|
|
30539
|
+
context.lineWidth = clamp9(2.5, element.strokeWidth * 1.75, 4) / Math.max(0.25, appState.zoom.value);
|
|
29851
30540
|
context.strokeStyle = appState.theme === THEME16.DARK ? `rgba(3, 93, 161, ${opacity / 2})` : `rgba(106, 189, 252, ${opacity / 2})`;
|
|
29852
30541
|
switch (element.type) {
|
|
29853
30542
|
case "ellipse":
|
|
@@ -30083,7 +30772,7 @@ var renderBindingHighlightForBindableElement = (app, context, suggestedBinding,
|
|
|
30083
30772
|
};
|
|
30084
30773
|
var renderSelectionBorder = (context, appState, elementProperties) => {
|
|
30085
30774
|
const {
|
|
30086
|
-
angle,
|
|
30775
|
+
angle: angle2,
|
|
30087
30776
|
x1,
|
|
30088
30777
|
y1,
|
|
30089
30778
|
x2,
|
|
@@ -30121,7 +30810,7 @@ var renderSelectionBorder = (context, appState, elementProperties) => {
|
|
|
30121
30810
|
elementHeight + linePadding * 2,
|
|
30122
30811
|
cx,
|
|
30123
30812
|
cy,
|
|
30124
|
-
|
|
30813
|
+
angle2
|
|
30125
30814
|
);
|
|
30126
30815
|
}
|
|
30127
30816
|
context.restore();
|
|
@@ -30353,7 +31042,7 @@ var renderFocusPointIndicator = ({
|
|
|
30353
31042
|
);
|
|
30354
31043
|
}
|
|
30355
31044
|
};
|
|
30356
|
-
var renderTransformHandles = (context, renderConfig, appState, transformHandles,
|
|
31045
|
+
var renderTransformHandles = (context, renderConfig, appState, transformHandles, angle2) => {
|
|
30357
31046
|
Object.keys(transformHandles).forEach((key) => {
|
|
30358
31047
|
const transformHandle = transformHandles[key];
|
|
30359
31048
|
if (transformHandle !== void 0) {
|
|
@@ -30379,7 +31068,7 @@ var renderTransformHandles = (context, renderConfig, appState, transformHandles,
|
|
|
30379
31068
|
height,
|
|
30380
31069
|
x + width / 2,
|
|
30381
31070
|
y + height / 2,
|
|
30382
|
-
|
|
31071
|
+
angle2,
|
|
30383
31072
|
true
|
|
30384
31073
|
// fill before stroke
|
|
30385
31074
|
);
|
|
@@ -30511,6 +31200,46 @@ var renderResetAutoResizeHandle = (text, context, appState, selectionColor, form
|
|
|
30511
31200
|
context.stroke();
|
|
30512
31201
|
context.restore();
|
|
30513
31202
|
};
|
|
31203
|
+
var renderImageLoadingProgress = (context, visibleElements, elementsMap, app, appState, selectionColor) => {
|
|
31204
|
+
for (const element of visibleElements) {
|
|
31205
|
+
if (!isImageElement8(element) || !element.fileId || element.status === "error") {
|
|
31206
|
+
continue;
|
|
31207
|
+
}
|
|
31208
|
+
const progress = app.imageLoadingProgress.get(element.fileId);
|
|
31209
|
+
if (progress === void 0) {
|
|
31210
|
+
continue;
|
|
31211
|
+
}
|
|
31212
|
+
const [x1, y1, x2, y2] = getElementAbsoluteCoords7(element, elementsMap);
|
|
31213
|
+
const centerX = (x1 + x2) / 2 + appState.scrollX;
|
|
31214
|
+
const centerY = (y1 + y2) / 2 + appState.scrollY;
|
|
31215
|
+
const zoom = appState.zoom.value;
|
|
31216
|
+
const radius = Math.min(14, Math.min(x2 - x1, y2 - y1) * zoom / 4) / zoom;
|
|
31217
|
+
const lineWidth = Math.min(3 / zoom, radius / 2);
|
|
31218
|
+
if (radius <= 0 || lineWidth <= 0) {
|
|
31219
|
+
continue;
|
|
31220
|
+
}
|
|
31221
|
+
context.save();
|
|
31222
|
+
context.lineWidth = lineWidth;
|
|
31223
|
+
context.lineCap = "round";
|
|
31224
|
+
context.strokeStyle = appState.theme === THEME16.DARK ? "rgba(255, 255, 255, 0.35)" : "rgba(0, 0, 0, 0.25)";
|
|
31225
|
+
context.beginPath();
|
|
31226
|
+
context.arc(centerX, centerY, radius, 0, Math.PI * 2);
|
|
31227
|
+
context.stroke();
|
|
31228
|
+
if (progress > 0) {
|
|
31229
|
+
context.strokeStyle = selectionColor;
|
|
31230
|
+
context.beginPath();
|
|
31231
|
+
context.arc(
|
|
31232
|
+
centerX,
|
|
31233
|
+
centerY,
|
|
31234
|
+
radius,
|
|
31235
|
+
-Math.PI / 2,
|
|
31236
|
+
-Math.PI / 2 + Math.PI * 2 * progress
|
|
31237
|
+
);
|
|
31238
|
+
context.stroke();
|
|
31239
|
+
}
|
|
31240
|
+
context.restore();
|
|
31241
|
+
}
|
|
31242
|
+
};
|
|
30514
31243
|
var _renderInteractiveScene = ({
|
|
30515
31244
|
app,
|
|
30516
31245
|
canvas,
|
|
@@ -30868,6 +31597,14 @@ var _renderInteractiveScene = ({
|
|
|
30868
31597
|
}
|
|
30869
31598
|
});
|
|
30870
31599
|
renderSnaps(context, appState);
|
|
31600
|
+
renderImageLoadingProgress(
|
|
31601
|
+
context,
|
|
31602
|
+
visibleElements,
|
|
31603
|
+
elementsMap,
|
|
31604
|
+
app,
|
|
31605
|
+
appState,
|
|
31606
|
+
renderConfig.selectionColor
|
|
31607
|
+
);
|
|
30871
31608
|
context.restore();
|
|
30872
31609
|
renderRemoteCursors({
|
|
30873
31610
|
context,
|
|
@@ -30920,6 +31657,31 @@ var INTERACTIVE_SCENE_ANIMATION_KEY = "animateInteractiveScene";
|
|
|
30920
31657
|
var InteractiveCanvas = (props) => {
|
|
30921
31658
|
const isComponentMounted = useRef27(false);
|
|
30922
31659
|
const rendererParams = useRef27(null);
|
|
31660
|
+
useEffect31(() => {
|
|
31661
|
+
let scheduledFrame = null;
|
|
31662
|
+
const unsubscribe = props.app.imageLoadingProgressEmitter.on(() => {
|
|
31663
|
+
if (scheduledFrame !== null) {
|
|
31664
|
+
return;
|
|
31665
|
+
}
|
|
31666
|
+
scheduledFrame = requestAnimationFrame(() => {
|
|
31667
|
+
scheduledFrame = null;
|
|
31668
|
+
if (!rendererParams.current) {
|
|
31669
|
+
return;
|
|
31670
|
+
}
|
|
31671
|
+
renderInteractiveScene({
|
|
31672
|
+
...rendererParams.current,
|
|
31673
|
+
callback: () => {
|
|
31674
|
+
}
|
|
31675
|
+
});
|
|
31676
|
+
});
|
|
31677
|
+
});
|
|
31678
|
+
return () => {
|
|
31679
|
+
unsubscribe();
|
|
31680
|
+
if (scheduledFrame !== null) {
|
|
31681
|
+
cancelAnimationFrame(scheduledFrame);
|
|
31682
|
+
}
|
|
31683
|
+
};
|
|
31684
|
+
}, [props.app]);
|
|
30923
31685
|
useEffect31(() => {
|
|
30924
31686
|
if (!isComponentMounted.current) {
|
|
30925
31687
|
isComponentMounted.current = true;
|
|
@@ -31099,6 +31861,54 @@ import { jsx as jsx134 } from "react/jsx-runtime";
|
|
|
31099
31861
|
var StaticCanvas = (props) => {
|
|
31100
31862
|
const wrapperRef = useRef28(null);
|
|
31101
31863
|
const isComponentMounted = useRef28(false);
|
|
31864
|
+
const propsRef = useRef28(props);
|
|
31865
|
+
const renderCanvasRef = useRef28(() => {
|
|
31866
|
+
});
|
|
31867
|
+
const transitionFrameRef = useRef28(null);
|
|
31868
|
+
propsRef.current = props;
|
|
31869
|
+
const renderCanvas = React39.useCallback(() => {
|
|
31870
|
+
const currentProps = propsRef.current;
|
|
31871
|
+
const wrapper = wrapperRef.current;
|
|
31872
|
+
if (!wrapper) {
|
|
31873
|
+
return;
|
|
31874
|
+
}
|
|
31875
|
+
const gridColorBold = getComputedStyle(wrapper).getPropertyValue("--color-grid-bold").trim();
|
|
31876
|
+
const gridColorRegular = getComputedStyle(wrapper).getPropertyValue("--color-grid-regular").trim();
|
|
31877
|
+
renderStaticScene(
|
|
31878
|
+
{
|
|
31879
|
+
canvas: currentProps.canvas,
|
|
31880
|
+
rc: currentProps.rc,
|
|
31881
|
+
scale: currentProps.scale,
|
|
31882
|
+
elementsMap: currentProps.elementsMap,
|
|
31883
|
+
allElementsMap: currentProps.allElementsMap,
|
|
31884
|
+
visibleElements: currentProps.visibleElements,
|
|
31885
|
+
appState: currentProps.appState,
|
|
31886
|
+
renderConfig: {
|
|
31887
|
+
...currentProps.renderConfig,
|
|
31888
|
+
gridColorBold,
|
|
31889
|
+
gridColorRegular
|
|
31890
|
+
}
|
|
31891
|
+
},
|
|
31892
|
+
isRenderThrottlingEnabled()
|
|
31893
|
+
);
|
|
31894
|
+
const transitionDuration = currentProps.renderConfig.imageTransitionDuration ?? 0;
|
|
31895
|
+
const hasActiveTransition = transitionDuration > 0 && currentProps.visibleElements.some((element) => {
|
|
31896
|
+
if (element.type !== "image" || !element.fileId) {
|
|
31897
|
+
return false;
|
|
31898
|
+
}
|
|
31899
|
+
const transitionStart = currentProps.renderConfig.imageCache.get(
|
|
31900
|
+
element.fileId
|
|
31901
|
+
)?.transitionStart;
|
|
31902
|
+
return transitionStart !== void 0 && performance.now() - transitionStart < transitionDuration;
|
|
31903
|
+
});
|
|
31904
|
+
if (hasActiveTransition && transitionFrameRef.current === null) {
|
|
31905
|
+
transitionFrameRef.current = requestAnimationFrame(() => {
|
|
31906
|
+
transitionFrameRef.current = null;
|
|
31907
|
+
renderCanvasRef.current();
|
|
31908
|
+
});
|
|
31909
|
+
}
|
|
31910
|
+
}, []);
|
|
31911
|
+
renderCanvasRef.current = renderCanvas;
|
|
31102
31912
|
useEffect32(() => {
|
|
31103
31913
|
props.canvas.style.width = `${props.appState.width}px`;
|
|
31104
31914
|
props.canvas.style.height = `${props.appState.height}px`;
|
|
@@ -31116,26 +31926,34 @@ var StaticCanvas = (props) => {
|
|
|
31116
31926
|
wrapper.replaceChildren(canvas);
|
|
31117
31927
|
canvas.classList.add("excalidraw__canvas", "static");
|
|
31118
31928
|
}
|
|
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
|
-
);
|
|
31929
|
+
renderCanvas();
|
|
31138
31930
|
});
|
|
31931
|
+
useEffect32(() => {
|
|
31932
|
+
let scheduledFrame = null;
|
|
31933
|
+
const unsubscribe = props.app.imagePlaceholderUpdateEmitter.on(() => {
|
|
31934
|
+
if (scheduledFrame !== null) {
|
|
31935
|
+
return;
|
|
31936
|
+
}
|
|
31937
|
+
scheduledFrame = requestAnimationFrame(() => {
|
|
31938
|
+
scheduledFrame = null;
|
|
31939
|
+
renderCanvas();
|
|
31940
|
+
});
|
|
31941
|
+
});
|
|
31942
|
+
return () => {
|
|
31943
|
+
unsubscribe();
|
|
31944
|
+
if (scheduledFrame !== null) {
|
|
31945
|
+
cancelAnimationFrame(scheduledFrame);
|
|
31946
|
+
}
|
|
31947
|
+
};
|
|
31948
|
+
}, [props.app, renderCanvas]);
|
|
31949
|
+
useEffect32(
|
|
31950
|
+
() => () => {
|
|
31951
|
+
if (transitionFrameRef.current !== null) {
|
|
31952
|
+
cancelAnimationFrame(transitionFrameRef.current);
|
|
31953
|
+
}
|
|
31954
|
+
},
|
|
31955
|
+
[]
|
|
31956
|
+
);
|
|
31139
31957
|
return /* @__PURE__ */ jsx134("div", { className: "excalidraw__canvas-wrapper", ref: wrapperRef });
|
|
31140
31958
|
};
|
|
31141
31959
|
var getRelevantAppStateProps2 = (appState) => {
|
|
@@ -31571,6 +32389,10 @@ var App = class _App extends React40.Component {
|
|
|
31571
32389
|
__publicField(this, "excalidrawContainerValue");
|
|
31572
32390
|
__publicField(this, "files", {});
|
|
31573
32391
|
__publicField(this, "imageCache", /* @__PURE__ */ new Map());
|
|
32392
|
+
__publicField(this, "imageLoadingProgress", /* @__PURE__ */ new Map());
|
|
32393
|
+
__publicField(this, "imageLoadingProgressEmitter", new Emitter2());
|
|
32394
|
+
__publicField(this, "imagePlaceholderUpdateEmitter", new Emitter2());
|
|
32395
|
+
__publicField(this, "imageTransitionPlaceholders", /* @__PURE__ */ new Map());
|
|
31574
32396
|
__publicField(this, "iFrameRefs", /* @__PURE__ */ new Map());
|
|
31575
32397
|
/**
|
|
31576
32398
|
* Indicates whether the embeddable's url has been validated for rendering.
|
|
@@ -32610,7 +33432,8 @@ var App = class _App extends React40.Component {
|
|
|
32610
33432
|
this.setState((prevState) => {
|
|
32611
33433
|
return {
|
|
32612
33434
|
penMode: force ?? !prevState.penMode,
|
|
32613
|
-
penDetected: true
|
|
33435
|
+
penDetected: true,
|
|
33436
|
+
currentItemStrokeVariability: !prevState.penDetected ? "variable" : prevState.currentItemStrokeVariability
|
|
32614
33437
|
};
|
|
32615
33438
|
});
|
|
32616
33439
|
});
|
|
@@ -32635,120 +33458,92 @@ var App = class _App extends React40.Component {
|
|
|
32635
33458
|
__publicField(this, "cancelInProgressAnimation", null);
|
|
32636
33459
|
__publicField(this, "scrollToViewport", (target, opts) => {
|
|
32637
33460
|
this.cancelInProgressAnimation?.();
|
|
33461
|
+
AnimationController.cancel(SCROLL_TO_CONTENT_ANIMATION_KEY);
|
|
32638
33462
|
const zoom = { value: getNormalizedZoom(target.zoom) };
|
|
32639
33463
|
const animateDuration = opts?.duration ?? 500;
|
|
32640
33464
|
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: () => {
|
|
33465
|
+
const from = this.state;
|
|
33466
|
+
let startTime = null;
|
|
33467
|
+
let frameId = null;
|
|
33468
|
+
let cancelled = false;
|
|
33469
|
+
const targetViewport = {
|
|
33470
|
+
scrollX: target.scrollX,
|
|
33471
|
+
scrollY: target.scrollY,
|
|
33472
|
+
zoom
|
|
33473
|
+
};
|
|
33474
|
+
const step = (timestamp) => {
|
|
33475
|
+
if (cancelled) {
|
|
33476
|
+
return;
|
|
33477
|
+
}
|
|
33478
|
+
startTime ?? (startTime = timestamp);
|
|
33479
|
+
const progress = Math.min((timestamp - startTime) / animateDuration, 1);
|
|
33480
|
+
this.setState({
|
|
33481
|
+
...interpolateViewport({
|
|
33482
|
+
from,
|
|
33483
|
+
target: targetViewport,
|
|
33484
|
+
factor: easeOut5(progress)
|
|
33485
|
+
}),
|
|
33486
|
+
shouldCacheIgnoreZoom: progress < 1
|
|
33487
|
+
});
|
|
33488
|
+
if (progress < 1) {
|
|
33489
|
+
frameId = requestAnimationFrame(step);
|
|
33490
|
+
} else {
|
|
32676
33491
|
this.cancelInProgressAnimation = null;
|
|
32677
|
-
|
|
32678
|
-
|
|
32679
|
-
duration: animateDuration
|
|
32680
|
-
});
|
|
33492
|
+
}
|
|
33493
|
+
};
|
|
32681
33494
|
this.cancelInProgressAnimation = () => {
|
|
32682
|
-
|
|
33495
|
+
cancelled = true;
|
|
33496
|
+
if (frameId !== null) {
|
|
33497
|
+
cancelAnimationFrame(frameId);
|
|
33498
|
+
}
|
|
32683
33499
|
this.cancelInProgressAnimation = null;
|
|
33500
|
+
this.setState({ shouldCacheIgnoreZoom: false });
|
|
32684
33501
|
};
|
|
33502
|
+
frameId = requestAnimationFrame(step);
|
|
32685
33503
|
} else {
|
|
32686
33504
|
this.setState({
|
|
32687
33505
|
scrollX: target.scrollX,
|
|
32688
33506
|
scrollY: target.scrollY,
|
|
32689
|
-
zoom
|
|
33507
|
+
zoom,
|
|
33508
|
+
shouldCacheIgnoreZoom: false
|
|
32690
33509
|
});
|
|
32691
33510
|
}
|
|
32692
33511
|
});
|
|
32693
|
-
__publicField(this, "scrollToContent", (target
|
|
33512
|
+
__publicField(this, "scrollToContent", (target, opts) => {
|
|
33513
|
+
let elements;
|
|
32694
33514
|
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;
|
|
33515
|
+
const id = isElementLink2(target) ? parseElementLinkFromURL(target) : target;
|
|
33516
|
+
elements = id ? this.scene.getElementsFromId(id) : [];
|
|
33517
|
+
} else if (Array.isArray(target)) {
|
|
33518
|
+
elements = target;
|
|
33519
|
+
} else if (target) {
|
|
33520
|
+
elements = [target];
|
|
32737
33521
|
} else {
|
|
32738
|
-
|
|
32739
|
-
scrollX = scroll.scrollX;
|
|
32740
|
-
scrollY = scroll.scrollY;
|
|
33522
|
+
elements = this.scene.getNonDeletedElements();
|
|
32741
33523
|
}
|
|
32742
|
-
|
|
32743
|
-
{
|
|
32744
|
-
|
|
32745
|
-
|
|
32746
|
-
|
|
32747
|
-
|
|
32748
|
-
|
|
32749
|
-
|
|
32750
|
-
|
|
33524
|
+
if (!elements.length) {
|
|
33525
|
+
if (typeof target === "string" && isElementLink2(target)) {
|
|
33526
|
+
this.setState({
|
|
33527
|
+
toast: {
|
|
33528
|
+
message: t("elementLink.notFound"),
|
|
33529
|
+
duration: 3e3,
|
|
33530
|
+
closable: true
|
|
33531
|
+
}
|
|
33532
|
+
});
|
|
32751
33533
|
}
|
|
33534
|
+
return;
|
|
33535
|
+
}
|
|
33536
|
+
const resolvedOpts = typeof target === "string" ? {
|
|
33537
|
+
...opts,
|
|
33538
|
+
fitToViewport: void 0,
|
|
33539
|
+
fitToContent: opts?.fitToContent ?? true,
|
|
33540
|
+
animate: opts?.animate ?? true
|
|
33541
|
+
} : opts;
|
|
33542
|
+
scrollToElements(
|
|
33543
|
+
this.state,
|
|
33544
|
+
elements,
|
|
33545
|
+
this.setState.bind(this),
|
|
33546
|
+
resolvedOpts
|
|
32752
33547
|
);
|
|
32753
33548
|
});
|
|
32754
33549
|
__publicField(this, "maybeUnfollowRemoteUser", () => {
|
|
@@ -32759,6 +33554,8 @@ var App = class _App extends React40.Component {
|
|
|
32759
33554
|
/** use when changing scrollX/scrollY/zoom based on user interaction */
|
|
32760
33555
|
__publicField(this, "translateCanvas", (state) => {
|
|
32761
33556
|
this.cancelInProgressAnimation?.();
|
|
33557
|
+
AnimationController.cancel(SCROLL_TO_CONTENT_ANIMATION_KEY);
|
|
33558
|
+
this.setState({ shouldCacheIgnoreZoom: false });
|
|
32762
33559
|
this.maybeUnfollowRemoteUser();
|
|
32763
33560
|
this.setState(state);
|
|
32764
33561
|
});
|
|
@@ -32790,11 +33587,93 @@ var App = class _App extends React40.Component {
|
|
|
32790
33587
|
__publicField(this, "addFiles", withBatchedUpdates(
|
|
32791
33588
|
(files) => {
|
|
32792
33589
|
const { addedFiles } = this.addMissingFiles(files);
|
|
33590
|
+
for (const fileId of Object.keys(addedFiles)) {
|
|
33591
|
+
const cacheEntry = this.imageCache.get(fileId);
|
|
33592
|
+
if (cacheEntry?.isPlaceholder && !(cacheEntry.image instanceof Promise)) {
|
|
33593
|
+
this.imageTransitionPlaceholders.set(fileId, cacheEntry.image);
|
|
33594
|
+
}
|
|
33595
|
+
}
|
|
32793
33596
|
this.clearImageShapeCache(addedFiles);
|
|
32794
33597
|
this.scene.triggerUpdate();
|
|
32795
|
-
this.addNewImagesToImageCache()
|
|
33598
|
+
this.addNewImagesToImageCache().then(() => {
|
|
33599
|
+
for (const fileId of Object.keys(addedFiles)) {
|
|
33600
|
+
const cacheEntry = this.imageCache.get(fileId);
|
|
33601
|
+
if (cacheEntry && !(cacheEntry.image instanceof Promise)) {
|
|
33602
|
+
this.clearImageLoadingProgress(fileId);
|
|
33603
|
+
}
|
|
33604
|
+
this.imageTransitionPlaceholders.delete(fileId);
|
|
33605
|
+
}
|
|
33606
|
+
});
|
|
32796
33607
|
}
|
|
32797
33608
|
));
|
|
33609
|
+
__publicField(this, "addImagePlaceholder", async (fileId, file2) => {
|
|
33610
|
+
if (this.files[fileId]) {
|
|
33611
|
+
return;
|
|
33612
|
+
}
|
|
33613
|
+
let normalizedFile = await normalizeFile(file2);
|
|
33614
|
+
if (!isSupportedImageFile(normalizedFile)) {
|
|
33615
|
+
throw new Error(t("errors.unsupportedFileType"));
|
|
33616
|
+
}
|
|
33617
|
+
if (normalizedFile.type === MIME_TYPES8.svg) {
|
|
33618
|
+
normalizedFile = SVGStringToFile(
|
|
33619
|
+
normalizeSVG(await normalizedFile.text()),
|
|
33620
|
+
normalizedFile.name
|
|
33621
|
+
);
|
|
33622
|
+
}
|
|
33623
|
+
const dataURL = await getDataURL(normalizedFile);
|
|
33624
|
+
if (this.files[fileId]) {
|
|
33625
|
+
return;
|
|
33626
|
+
}
|
|
33627
|
+
const imagePromise = loadHTMLImageElement(dataURL);
|
|
33628
|
+
const placeholderEntry = {
|
|
33629
|
+
image: imagePromise,
|
|
33630
|
+
mimeType: normalizedFile.type,
|
|
33631
|
+
isPlaceholder: true
|
|
33632
|
+
};
|
|
33633
|
+
this.imageCache.set(fileId, placeholderEntry);
|
|
33634
|
+
try {
|
|
33635
|
+
const image = await imagePromise;
|
|
33636
|
+
if (this.imageCache.get(fileId) !== placeholderEntry || this.files[fileId]) {
|
|
33637
|
+
return;
|
|
33638
|
+
}
|
|
33639
|
+
this.imageCache.set(fileId, { ...placeholderEntry, image });
|
|
33640
|
+
this.clearImageShapeCacheForFileId(fileId);
|
|
33641
|
+
this.imagePlaceholderUpdateEmitter.trigger();
|
|
33642
|
+
} catch (error) {
|
|
33643
|
+
if (this.imageCache.get(fileId) === placeholderEntry) {
|
|
33644
|
+
this.imageCache.delete(fileId);
|
|
33645
|
+
this.imagePlaceholderUpdateEmitter.trigger();
|
|
33646
|
+
}
|
|
33647
|
+
throw error;
|
|
33648
|
+
}
|
|
33649
|
+
});
|
|
33650
|
+
__publicField(this, "setImageLoadingProgress", (fileId, progress) => {
|
|
33651
|
+
if (progress === null) {
|
|
33652
|
+
this.clearImageLoadingProgress(fileId);
|
|
33653
|
+
return;
|
|
33654
|
+
}
|
|
33655
|
+
if (!Number.isFinite(progress)) {
|
|
33656
|
+
return;
|
|
33657
|
+
}
|
|
33658
|
+
const nextProgress = clamp10(progress, 0, 1);
|
|
33659
|
+
if (this.imageLoadingProgress.get(fileId) === nextProgress) {
|
|
33660
|
+
return;
|
|
33661
|
+
}
|
|
33662
|
+
this.imageLoadingProgress.set(fileId, nextProgress);
|
|
33663
|
+
this.imageLoadingProgressEmitter.trigger();
|
|
33664
|
+
});
|
|
33665
|
+
__publicField(this, "clearImageLoadingProgress", (fileId) => {
|
|
33666
|
+
if (this.imageLoadingProgress.delete(fileId)) {
|
|
33667
|
+
this.imageLoadingProgressEmitter.trigger();
|
|
33668
|
+
}
|
|
33669
|
+
});
|
|
33670
|
+
__publicField(this, "clearImageShapeCacheForFileId", (fileId) => {
|
|
33671
|
+
for (const element of this.scene.getNonDeletedElements()) {
|
|
33672
|
+
if (isInitializedImageElement3(element) && element.fileId === fileId) {
|
|
33673
|
+
ShapeCache4.delete(element);
|
|
33674
|
+
}
|
|
33675
|
+
}
|
|
33676
|
+
});
|
|
32798
33677
|
__publicField(this, "addMissingFiles", (files, replace = false) => {
|
|
32799
33678
|
const nextFiles = replace ? {} : { ...this.files };
|
|
32800
33679
|
const addedFiles = {};
|
|
@@ -32805,11 +33684,11 @@ var App = class _App extends React40.Component {
|
|
|
32805
33684
|
}
|
|
32806
33685
|
addedFiles[fileData.id] = fileData;
|
|
32807
33686
|
nextFiles[fileData.id] = fileData;
|
|
32808
|
-
if (fileData.mimeType ===
|
|
33687
|
+
if (fileData.mimeType === MIME_TYPES8.svg) {
|
|
32809
33688
|
try {
|
|
32810
33689
|
const restoredDataURL = getDataURL_sync(
|
|
32811
33690
|
normalizeSVG(dataURLToString(fileData.dataURL)),
|
|
32812
|
-
|
|
33691
|
+
MIME_TYPES8.svg
|
|
32813
33692
|
);
|
|
32814
33693
|
if (fileData.dataURL !== restoredDataURL) {
|
|
32815
33694
|
fileData.version = (fileData.version ?? 1) + 1;
|
|
@@ -33719,7 +34598,7 @@ var App = class _App extends React40.Component {
|
|
|
33719
34598
|
strokeColor: this.state.currentItemStrokeColor,
|
|
33720
34599
|
backgroundColor: this.state.currentItemBackgroundColor,
|
|
33721
34600
|
fillStyle: this.state.currentItemFillStyle,
|
|
33722
|
-
strokeWidth: this.
|
|
34601
|
+
strokeWidth: this.getCurrentItemStrokeWidth("text"),
|
|
33723
34602
|
strokeStyle: this.state.currentItemStrokeStyle,
|
|
33724
34603
|
roughness: this.state.currentItemRoughness,
|
|
33725
34604
|
opacity: this.state.currentItemOpacity,
|
|
@@ -34278,42 +35157,7 @@ var App = class _App extends React40.Component {
|
|
|
34278
35157
|
const { lastCommittedPoint } = selectedLinearElement;
|
|
34279
35158
|
setCursorForShape(this.interactiveCanvas, this.state);
|
|
34280
35159
|
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 (
|
|
35160
|
+
if (
|
|
34317
35161
|
// if we haven't yet created a temp point and we're beyond commit-zone
|
|
34318
35162
|
// threshold, add a point
|
|
34319
35163
|
pointDistance9(
|
|
@@ -34321,6 +35165,24 @@ var App = class _App extends React40.Component {
|
|
|
34321
35165
|
lastPoint
|
|
34322
35166
|
) >= LINE_CONFIRM_THRESHOLD2
|
|
34323
35167
|
) {
|
|
35168
|
+
this.store.scheduleCapture();
|
|
35169
|
+
flushSync2(() => {
|
|
35170
|
+
invariant16(
|
|
35171
|
+
this.state.selectedLinearElement?.initialState,
|
|
35172
|
+
"initialState must be set"
|
|
35173
|
+
);
|
|
35174
|
+
this.setState({
|
|
35175
|
+
selectedLinearElement: {
|
|
35176
|
+
...this.state.selectedLinearElement,
|
|
35177
|
+
lastCommittedPoint: points[points.length - 1],
|
|
35178
|
+
selectedPointsIndices: [multiElement.points.length],
|
|
35179
|
+
initialState: {
|
|
35180
|
+
...this.state.selectedLinearElement.initialState,
|
|
35181
|
+
lastClickedPoint: multiElement.points.length
|
|
35182
|
+
}
|
|
35183
|
+
}
|
|
35184
|
+
});
|
|
35185
|
+
});
|
|
34324
35186
|
this.scene.mutateElement(
|
|
34325
35187
|
multiElement,
|
|
34326
35188
|
{
|
|
@@ -34331,21 +35193,6 @@ var App = class _App extends React40.Component {
|
|
|
34331
35193
|
},
|
|
34332
35194
|
{ informMutation: false, isDragging: false }
|
|
34333
35195
|
);
|
|
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
35196
|
} else {
|
|
34350
35197
|
setCursor(this.interactiveCanvas, CURSOR_TYPE4.POINTER);
|
|
34351
35198
|
}
|
|
@@ -34693,7 +35540,8 @@ var App = class _App extends React40.Component {
|
|
|
34693
35540
|
this.setState((prevState) => {
|
|
34694
35541
|
return {
|
|
34695
35542
|
penMode: true,
|
|
34696
|
-
penDetected: true
|
|
35543
|
+
penDetected: true,
|
|
35544
|
+
currentItemStrokeVariability: "variable"
|
|
34697
35545
|
};
|
|
34698
35546
|
});
|
|
34699
35547
|
}
|
|
@@ -35466,6 +36314,7 @@ var App = class _App extends React40.Component {
|
|
|
35466
36314
|
y: gridY
|
|
35467
36315
|
});
|
|
35468
36316
|
const simulatePressure = event.pressure === 0.5;
|
|
36317
|
+
const strokeVariability = this.state.currentItemStrokeVariability;
|
|
35469
36318
|
const element = newFreeDrawElement({
|
|
35470
36319
|
type: elementType,
|
|
35471
36320
|
x: gridX,
|
|
@@ -35473,15 +36322,21 @@ var App = class _App extends React40.Component {
|
|
|
35473
36322
|
strokeColor: this.state.currentItemStrokeColor,
|
|
35474
36323
|
backgroundColor: this.state.currentItemBackgroundColor,
|
|
35475
36324
|
fillStyle: this.state.currentItemFillStyle,
|
|
35476
|
-
strokeWidth: this.
|
|
36325
|
+
strokeWidth: this.getCurrentItemStrokeWidth("freedraw"),
|
|
35477
36326
|
strokeStyle: this.state.currentItemStrokeStyle,
|
|
35478
36327
|
roughness: this.state.currentItemRoughness,
|
|
35479
36328
|
opacity: this.state.currentItemOpacity,
|
|
35480
36329
|
roundness: null,
|
|
35481
36330
|
simulatePressure,
|
|
36331
|
+
strokeOptions: {
|
|
36332
|
+
variability: strokeVariability,
|
|
36333
|
+
streamline: event.pointerType !== "mouse" ? DEFAULT_STROKE_STREAMLINE_PRECISE : DEFAULT_STROKE_STREAMLINE2
|
|
36334
|
+
},
|
|
35482
36335
|
locked: false,
|
|
35483
36336
|
frameId: topLayerFrame ? topLayerFrame.id : null,
|
|
35484
36337
|
points: [pointFrom32(0, 0)],
|
|
36338
|
+
// pressures are only consumed when rendering a real-pressure stroke, so
|
|
36339
|
+
// skip persisting them while pressure is being simulated
|
|
35485
36340
|
pressures: simulatePressure ? [] : [event.pressure]
|
|
35486
36341
|
});
|
|
35487
36342
|
this.insertNewElement(element);
|
|
@@ -35520,7 +36375,7 @@ var App = class _App extends React40.Component {
|
|
|
35520
36375
|
strokeColor: "transparent",
|
|
35521
36376
|
backgroundColor: "transparent",
|
|
35522
36377
|
fillStyle: this.state.currentItemFillStyle,
|
|
35523
|
-
strokeWidth: this.
|
|
36378
|
+
strokeWidth: this.getCurrentItemStrokeWidth("iframe"),
|
|
35524
36379
|
strokeStyle: this.state.currentItemStrokeStyle,
|
|
35525
36380
|
roughness: this.state.currentItemRoughness,
|
|
35526
36381
|
roundness: this.getCurrentItemRoundness("iframe"),
|
|
@@ -35560,7 +36415,7 @@ var App = class _App extends React40.Component {
|
|
|
35560
36415
|
strokeColor: "transparent",
|
|
35561
36416
|
backgroundColor: "transparent",
|
|
35562
36417
|
fillStyle: this.state.currentItemFillStyle,
|
|
35563
|
-
strokeWidth: this.
|
|
36418
|
+
strokeWidth: this.getCurrentItemStrokeWidth("embeddable"),
|
|
35564
36419
|
strokeStyle: this.state.currentItemStrokeStyle,
|
|
35565
36420
|
roughness: this.state.currentItemRoughness,
|
|
35566
36421
|
roundness: this.getCurrentItemRoundness("embeddable"),
|
|
@@ -35594,7 +36449,7 @@ var App = class _App extends React40.Component {
|
|
|
35594
36449
|
strokeColor: this.state.currentItemStrokeColor,
|
|
35595
36450
|
backgroundColor: this.state.currentItemBackgroundColor,
|
|
35596
36451
|
fillStyle: this.state.currentItemFillStyle,
|
|
35597
|
-
strokeWidth: this.
|
|
36452
|
+
strokeWidth: this.getCurrentItemStrokeWidth("image"),
|
|
35598
36453
|
strokeStyle: this.state.currentItemStrokeStyle,
|
|
35599
36454
|
roughness: this.state.currentItemRoughness,
|
|
35600
36455
|
roundness: null,
|
|
@@ -35651,21 +36506,41 @@ var App = class _App extends React40.Component {
|
|
|
35651
36506
|
}
|
|
35652
36507
|
const { x: rx, y: ry } = multiElement;
|
|
35653
36508
|
const { lastCommittedPoint } = selectedLinearElement;
|
|
35654
|
-
const
|
|
35655
|
-
|
|
35656
|
-
|
|
35657
|
-
|
|
35658
|
-
|
|
36509
|
+
const sceneCoords = viewportCoordsToSceneCoords3(event, this.state);
|
|
36510
|
+
const { start: start2, end } = isBindingElement4(multiElement) && isBindingEnabled2(this.state) ? getBindingStrategyForDraggingBindingElementEndpoints2(
|
|
36511
|
+
multiElement,
|
|
36512
|
+
/* @__PURE__ */ new Map([
|
|
36513
|
+
[
|
|
36514
|
+
multiElement.points.length - 1,
|
|
36515
|
+
{
|
|
36516
|
+
point: multiElement.points[multiElement.points.length - 1],
|
|
36517
|
+
isDragging: false
|
|
36518
|
+
}
|
|
36519
|
+
]
|
|
36520
|
+
]),
|
|
36521
|
+
sceneCoords.x,
|
|
36522
|
+
sceneCoords.y,
|
|
36523
|
+
this.scene.getNonDeletedElementsMap(),
|
|
35659
36524
|
this.scene.getNonDeletedElements(),
|
|
35660
|
-
this.
|
|
35661
|
-
|
|
35662
|
-
|
|
36525
|
+
this.state,
|
|
36526
|
+
{
|
|
36527
|
+
newArrow: Boolean(this.state.newElement),
|
|
36528
|
+
zoom: this.state.zoom
|
|
36529
|
+
}
|
|
36530
|
+
) : { end: { mode: void 0 } };
|
|
36531
|
+
const elementsMap = this.scene.getNonDeletedElementsMap();
|
|
36532
|
+
const endOutsideSameElement = start2?.mode != null && end.mode != null && start2.element.id === end.element.id && !isPointInElement3(end.focusPoint, end.element, elementsMap);
|
|
36533
|
+
const boundOutsideFromElsewhere = end.mode === "orbit" && multiElement.startBinding?.elementId !== end.element?.id;
|
|
36534
|
+
const lastCommittedPointIsInsideCommitZone = lastCommittedPoint && pointDistance9(
|
|
35663
36535
|
pointFrom32(
|
|
35664
36536
|
pointerDownState.origin.x - rx,
|
|
35665
36537
|
pointerDownState.origin.y - ry
|
|
35666
36538
|
),
|
|
35667
36539
|
lastCommittedPoint
|
|
35668
|
-
) < LINE_CONFIRM_THRESHOLD2
|
|
36540
|
+
) < LINE_CONFIRM_THRESHOLD2;
|
|
36541
|
+
if (boundOutsideFromElsewhere || // Outside -> orbit: Bind immediately
|
|
36542
|
+
endOutsideSameElement || // End outside the start's element: Bind immediately
|
|
36543
|
+
multiElement.points.length > 1 && lastCommittedPointIsInsideCommitZone) {
|
|
35669
36544
|
this.actionManager.executeAction(actionFinalize, "ui", {
|
|
35670
36545
|
event: event.nativeEvent,
|
|
35671
36546
|
sceneCoords: {
|
|
@@ -35704,7 +36579,7 @@ var App = class _App extends React40.Component {
|
|
|
35704
36579
|
strokeColor: this.state.currentItemStrokeColor,
|
|
35705
36580
|
backgroundColor: this.state.currentItemBackgroundColor,
|
|
35706
36581
|
fillStyle: this.state.currentItemFillStyle,
|
|
35707
|
-
strokeWidth: this.
|
|
36582
|
+
strokeWidth: this.getCurrentItemStrokeWidth(elementType),
|
|
35708
36583
|
strokeStyle: this.state.currentItemStrokeStyle,
|
|
35709
36584
|
roughness: this.state.currentItemRoughness,
|
|
35710
36585
|
opacity: this.state.currentItemOpacity,
|
|
@@ -35726,7 +36601,7 @@ var App = class _App extends React40.Component {
|
|
|
35726
36601
|
strokeColor: this.state.currentItemStrokeColor,
|
|
35727
36602
|
backgroundColor: this.state.currentItemBackgroundColor,
|
|
35728
36603
|
fillStyle: this.state.currentItemFillStyle,
|
|
35729
|
-
strokeWidth: this.
|
|
36604
|
+
strokeWidth: this.getCurrentItemStrokeWidth(elementType),
|
|
35730
36605
|
strokeStyle: this.state.currentItemStrokeStyle,
|
|
35731
36606
|
roughness: this.state.currentItemRoughness,
|
|
35732
36607
|
opacity: this.state.currentItemOpacity,
|
|
@@ -35837,7 +36712,7 @@ var App = class _App extends React40.Component {
|
|
|
35837
36712
|
strokeColor: this.state.currentItemStrokeColor,
|
|
35838
36713
|
backgroundColor: this.state.currentItemBackgroundColor,
|
|
35839
36714
|
fillStyle: this.state.currentItemFillStyle,
|
|
35840
|
-
strokeWidth: this.
|
|
36715
|
+
strokeWidth: this.getCurrentItemStrokeWidth(elementType),
|
|
35841
36716
|
strokeStyle: this.state.currentItemStrokeStyle,
|
|
35842
36717
|
roughness: this.state.currentItemRoughness,
|
|
35843
36718
|
opacity: this.state.currentItemOpacity,
|
|
@@ -35965,7 +36840,7 @@ var App = class _App extends React40.Component {
|
|
|
35965
36840
|
let fileName = imageFile.name;
|
|
35966
36841
|
const fileNeedsResizing = imageFile.size >= this.state.dontResizeLimitMBs * 1024 * 1024;
|
|
35967
36842
|
setCursor(this.interactiveCanvas, "wait");
|
|
35968
|
-
if (mimeType ===
|
|
36843
|
+
if (mimeType === MIME_TYPES8.svg) {
|
|
35969
36844
|
try {
|
|
35970
36845
|
imageFile = SVGStringToFile(
|
|
35971
36846
|
normalizeSVG(await imageFile.text()),
|
|
@@ -36030,8 +36905,15 @@ var App = class _App extends React40.Component {
|
|
|
36030
36905
|
lastRetrieved: Date.now()
|
|
36031
36906
|
}
|
|
36032
36907
|
]);
|
|
36908
|
+
if (this.imageCache.get(fileId)?.isPlaceholder) {
|
|
36909
|
+
const cacheEntry = this.imageCache.get(fileId);
|
|
36910
|
+
if (cacheEntry && !(cacheEntry.image instanceof Promise)) {
|
|
36911
|
+
this.imageTransitionPlaceholders.set(fileId, cacheEntry.image);
|
|
36912
|
+
}
|
|
36913
|
+
this.imageCache.delete(fileId);
|
|
36914
|
+
this.clearImageShapeCacheForFileId(fileId);
|
|
36915
|
+
}
|
|
36033
36916
|
if (!this.imageCache.get(fileId)) {
|
|
36034
|
-
this.addNewImagesToImageCache();
|
|
36035
36917
|
const { erroredFiles } = await this.updateImageCache([
|
|
36036
36918
|
initializedImageElement
|
|
36037
36919
|
]);
|
|
@@ -36040,18 +36922,33 @@ var App = class _App extends React40.Component {
|
|
|
36040
36922
|
}
|
|
36041
36923
|
}
|
|
36042
36924
|
const imageHTML = await this.imageCache.get(fileId)?.image;
|
|
36043
|
-
|
|
36925
|
+
let thumbHash = null;
|
|
36926
|
+
if (imageHTML) {
|
|
36927
|
+
try {
|
|
36928
|
+
thumbHash = generateThumbHash(imageHTML);
|
|
36929
|
+
} catch (error) {
|
|
36930
|
+
console.warn("Failed to generate image ThumbHash", error);
|
|
36931
|
+
}
|
|
36932
|
+
}
|
|
36933
|
+
if (thumbHash && this.files[fileId]) {
|
|
36934
|
+
this.files[fileId].thumbHash = thumbHash;
|
|
36935
|
+
}
|
|
36936
|
+
if (imageHTML) {
|
|
36044
36937
|
initializedImageElement = this.getLatestInitializedImageElement(
|
|
36045
36938
|
placeholderImageElement,
|
|
36046
36939
|
fileId,
|
|
36047
|
-
fileName
|
|
36048
|
-
|
|
36049
|
-
const naturalDimensions = this.getImageNaturalDimensions(
|
|
36050
|
-
initializedImageElement,
|
|
36051
|
-
imageHTML
|
|
36940
|
+
fileName,
|
|
36941
|
+
thumbHash
|
|
36052
36942
|
);
|
|
36053
|
-
|
|
36943
|
+
if (this.state.newElement?.id !== initializedImageElement.id) {
|
|
36944
|
+
const naturalDimensions = this.getImageNaturalDimensions(
|
|
36945
|
+
initializedImageElement,
|
|
36946
|
+
imageHTML
|
|
36947
|
+
);
|
|
36948
|
+
Object.assign(initializedImageElement, naturalDimensions);
|
|
36949
|
+
}
|
|
36054
36950
|
}
|
|
36951
|
+
this.clearImageLoadingProgress(fileId);
|
|
36055
36952
|
resolve(initializedImageElement);
|
|
36056
36953
|
} catch (error) {
|
|
36057
36954
|
console.error(error);
|
|
@@ -36065,13 +36962,14 @@ var App = class _App extends React40.Component {
|
|
|
36065
36962
|
* when the placeholder image could have been modified in the meantime,
|
|
36066
36963
|
* and when you don't want to loose those modifications
|
|
36067
36964
|
*/
|
|
36068
|
-
__publicField(this, "getLatestInitializedImageElement", (imagePlaceholder, fileId, fileName) => {
|
|
36965
|
+
__publicField(this, "getLatestInitializedImageElement", (imagePlaceholder, fileId, fileName, thumbHash = null) => {
|
|
36069
36966
|
const latestImageElement = this.scene.getElement(imagePlaceholder.id) ?? imagePlaceholder;
|
|
36070
36967
|
return newElementWith10(
|
|
36071
36968
|
latestImageElement,
|
|
36072
36969
|
{
|
|
36073
36970
|
fileId,
|
|
36074
|
-
fileName
|
|
36971
|
+
fileName,
|
|
36972
|
+
thumbHash
|
|
36075
36973
|
}
|
|
36076
36974
|
);
|
|
36077
36975
|
});
|
|
@@ -36142,7 +37040,23 @@ var App = class _App extends React40.Component {
|
|
|
36142
37040
|
fileIds: elements.map((element) => element.fileId),
|
|
36143
37041
|
files
|
|
36144
37042
|
});
|
|
37043
|
+
const transitionStart = performance.now();
|
|
37044
|
+
for (const fileId of updatedFiles.keys()) {
|
|
37045
|
+
const cacheEntry = this.imageCache.get(fileId);
|
|
37046
|
+
if (cacheEntry && !(cacheEntry.image instanceof Promise)) {
|
|
37047
|
+
this.imageCache.set(fileId, {
|
|
37048
|
+
...cacheEntry,
|
|
37049
|
+
placeholderImage: this.imageTransitionPlaceholders.get(fileId),
|
|
37050
|
+
transitionStart
|
|
37051
|
+
});
|
|
37052
|
+
}
|
|
37053
|
+
this.imageTransitionPlaceholders.delete(fileId);
|
|
37054
|
+
}
|
|
36145
37055
|
if (erroredFiles.size) {
|
|
37056
|
+
for (const fileId of erroredFiles.keys()) {
|
|
37057
|
+
this.imageTransitionPlaceholders.delete(fileId);
|
|
37058
|
+
this.clearImageLoadingProgress(fileId);
|
|
37059
|
+
}
|
|
36146
37060
|
this.store.scheduleAction(CaptureUpdateAction41.NEVER);
|
|
36147
37061
|
this.scene.replaceAllElements(
|
|
36148
37062
|
this.scene.getElementsIncludingDeleted().map((element) => {
|
|
@@ -36264,7 +37178,7 @@ var App = class _App extends React40.Component {
|
|
|
36264
37178
|
const fileItems = dataTransferList.getFiles();
|
|
36265
37179
|
if (fileItems.length === 1) {
|
|
36266
37180
|
const { file: file2, fileHandle } = fileItems[0];
|
|
36267
|
-
if (file2 && (file2.type ===
|
|
37181
|
+
if (file2 && (file2.type === MIME_TYPES8.png || file2.type === MIME_TYPES8.svg)) {
|
|
36268
37182
|
try {
|
|
36269
37183
|
const scene = await loadFromBlob(
|
|
36270
37184
|
file2,
|
|
@@ -36306,11 +37220,11 @@ var App = class _App extends React40.Component {
|
|
|
36306
37220
|
if (item.kind !== "string") {
|
|
36307
37221
|
return;
|
|
36308
37222
|
}
|
|
36309
|
-
if (item.type ===
|
|
37223
|
+
if (item.type === MIME_TYPES8.html) {
|
|
36310
37224
|
try {
|
|
36311
37225
|
const doc = new DOMParser().parseFromString(
|
|
36312
37226
|
item.value,
|
|
36313
|
-
|
|
37227
|
+
MIME_TYPES8.html
|
|
36314
37228
|
);
|
|
36315
37229
|
for (const img of Array.from(
|
|
36316
37230
|
doc.body.querySelectorAll("img")
|
|
@@ -36320,7 +37234,7 @@ var App = class _App extends React40.Component {
|
|
|
36320
37234
|
}
|
|
36321
37235
|
} catch {
|
|
36322
37236
|
}
|
|
36323
|
-
} else if (item.type ===
|
|
37237
|
+
} else if (item.type === MIME_TYPES8.text) {
|
|
36324
37238
|
pushUnique(textImageSources, item.value);
|
|
36325
37239
|
}
|
|
36326
37240
|
});
|
|
@@ -36369,7 +37283,7 @@ var App = class _App extends React40.Component {
|
|
|
36369
37283
|
await this.loadFileToCanvas(file2, fileHandle);
|
|
36370
37284
|
}
|
|
36371
37285
|
}
|
|
36372
|
-
const textItem = dataTransferList.findByType(
|
|
37286
|
+
const textItem = dataTransferList.findByType(MIME_TYPES8.text);
|
|
36373
37287
|
if (textItem) {
|
|
36374
37288
|
const text = textItem.value;
|
|
36375
37289
|
if (text && embeddableURLValidator2(text, this.props.validateEmbeddable) && (/^(http|https):\/\/[^\s/$.?#].[^\s]*$/.test(text) || getEmbedLink2(text)?.type === "video")) {
|
|
@@ -37013,6 +37927,8 @@ var App = class _App extends React40.Component {
|
|
|
37013
37927
|
applyDeltas: this.applyDeltas,
|
|
37014
37928
|
mutateElement: this.mutateElement,
|
|
37015
37929
|
addFiles: this.addFiles,
|
|
37930
|
+
addImagePlaceholder: this.addImagePlaceholder,
|
|
37931
|
+
setImageLoadingProgress: this.setImageLoadingProgress,
|
|
37016
37932
|
addImageElementsToScene: this.addImageElementsToScene,
|
|
37017
37933
|
resetScene: this.resetScene,
|
|
37018
37934
|
getSceneElementsIncludingDeleted: this.getSceneElementsIncludingDeleted,
|
|
@@ -37592,7 +38508,7 @@ var App = class _App extends React40.Component {
|
|
|
37592
38508
|
const isActive = this.state.activeEmbeddable?.element === el && this.state.activeEmbeddable?.state === "active";
|
|
37593
38509
|
const isHovered = this.state.activeEmbeddable?.element === el && this.state.activeEmbeddable?.state === "hover";
|
|
37594
38510
|
const shouldScaleEmbeddableViewport = src?.type === "video";
|
|
37595
|
-
const embeddableViewportScale =
|
|
38511
|
+
const embeddableViewportScale = clamp10(
|
|
37596
38512
|
shouldScaleEmbeddableViewport ? scale : 1,
|
|
37597
38513
|
0.75,
|
|
37598
38514
|
MAX_EMBEDDABLE_VIEWPORT_SCALE
|
|
@@ -37878,6 +38794,7 @@ var App = class _App extends React40.Component {
|
|
|
37878
38794
|
/* @__PURE__ */ jsx137(
|
|
37879
38795
|
StaticCanvas_default,
|
|
37880
38796
|
{
|
|
38797
|
+
app: this,
|
|
37881
38798
|
canvas: this.canvas,
|
|
37882
38799
|
rc: this.rc,
|
|
37883
38800
|
elementsMap,
|
|
@@ -37889,6 +38806,7 @@ var App = class _App extends React40.Component {
|
|
|
37889
38806
|
appState: this.state,
|
|
37890
38807
|
renderConfig: {
|
|
37891
38808
|
imageCache: this.imageCache,
|
|
38809
|
+
imageTransitionDuration: this.props.imageOptions.placeholderTransitionDuration,
|
|
37892
38810
|
isExporting: false,
|
|
37893
38811
|
renderGrid: isGridModeEnabled(this),
|
|
37894
38812
|
canvasBackgroundColor: this.state.viewBackgroundColor,
|
|
@@ -37910,6 +38828,7 @@ var App = class _App extends React40.Component {
|
|
|
37910
38828
|
allElementsMap,
|
|
37911
38829
|
renderConfig: {
|
|
37912
38830
|
imageCache: this.imageCache,
|
|
38831
|
+
imageTransitionDuration: this.props.imageOptions.placeholderTransitionDuration,
|
|
37913
38832
|
isExporting: false,
|
|
37914
38833
|
renderGrid: false,
|
|
37915
38834
|
canvasBackgroundColor: this.state.viewBackgroundColor,
|
|
@@ -38177,6 +39096,10 @@ var App = class _App extends React40.Component {
|
|
|
38177
39096
|
this.renderer = new Renderer(this.scene);
|
|
38178
39097
|
this.files = {};
|
|
38179
39098
|
this.imageCache.clear();
|
|
39099
|
+
this.imageLoadingProgress.clear();
|
|
39100
|
+
this.imageTransitionPlaceholders.clear();
|
|
39101
|
+
this.imageLoadingProgressEmitter.clear();
|
|
39102
|
+
this.imagePlaceholderUpdateEmitter.clear();
|
|
38180
39103
|
this.resizeObserver?.disconnect();
|
|
38181
39104
|
this.unmounted = true;
|
|
38182
39105
|
this.removeEventListeners();
|
|
@@ -38581,7 +39504,7 @@ var App = class _App extends React40.Component {
|
|
|
38581
39504
|
strokeColor: this.state.currentItemStrokeColor,
|
|
38582
39505
|
backgroundColor: this.state.currentItemBackgroundColor,
|
|
38583
39506
|
fillStyle: this.state.currentItemFillStyle,
|
|
38584
|
-
strokeWidth: this.
|
|
39507
|
+
strokeWidth: this.getCurrentItemStrokeWidth("text"),
|
|
38585
39508
|
strokeStyle: this.state.currentItemStrokeStyle,
|
|
38586
39509
|
roundness: null,
|
|
38587
39510
|
roughness: this.state.currentItemRoughness,
|
|
@@ -39160,6 +40083,12 @@ var App = class _App extends React40.Component {
|
|
|
39160
40083
|
type: isUsingAdaptiveRadius4(elementType) ? ROUNDNESS7.ADAPTIVE_RADIUS : ROUNDNESS7.PROPORTIONAL_RADIUS
|
|
39161
40084
|
} : null;
|
|
39162
40085
|
}
|
|
40086
|
+
getCurrentItemStrokeWidth(elementType) {
|
|
40087
|
+
return getStrokeWidthByKey3(
|
|
40088
|
+
elementType,
|
|
40089
|
+
this.state.currentItemStrokeWidthKey
|
|
40090
|
+
);
|
|
40091
|
+
}
|
|
39163
40092
|
maybeCacheReferenceSnapPoints(event, selectedElements, recomputeAnyways = false) {
|
|
39164
40093
|
if (isSnappingEnabled({
|
|
39165
40094
|
event,
|
|
@@ -39498,12 +40427,12 @@ var App = class _App extends React40.Component {
|
|
|
39498
40427
|
);
|
|
39499
40428
|
const nextCrop = {
|
|
39500
40429
|
...crop,
|
|
39501
|
-
x:
|
|
40430
|
+
x: clamp10(
|
|
39502
40431
|
crop.x - offsetVector[0] * Math.sign(croppingElement.scale[0]),
|
|
39503
40432
|
0,
|
|
39504
40433
|
image.naturalWidth - crop.width
|
|
39505
40434
|
),
|
|
39506
|
-
y:
|
|
40435
|
+
y: clamp10(
|
|
39507
40436
|
crop.y - offsetVector[1] * Math.sign(croppingElement.scale[1]),
|
|
39508
40437
|
0,
|
|
39509
40438
|
image.naturalHeight - crop.height
|
|
@@ -40056,9 +40985,6 @@ var App = class _App extends React40.Component {
|
|
|
40056
40985
|
return;
|
|
40057
40986
|
}
|
|
40058
40987
|
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
40988
|
const pointerCoords = viewportCoordsToSceneCoords3(
|
|
40063
40989
|
childEvent,
|
|
40064
40990
|
this.state
|
|
@@ -40086,21 +41012,13 @@ var App = class _App extends React40.Component {
|
|
|
40086
41012
|
);
|
|
40087
41013
|
this.actionManager.executeAction(actionFinalize);
|
|
40088
41014
|
} 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
41015
|
this.setState({
|
|
40099
41016
|
multiElement: newElement7,
|
|
40100
41017
|
newElement: newElement7
|
|
40101
41018
|
});
|
|
40102
41019
|
}
|
|
40103
41020
|
} else if (pointerDownState.drag.hasOccurred && !multiElement) {
|
|
41021
|
+
this.store.scheduleCapture();
|
|
40104
41022
|
if (isLinearElement11(newElement7)) {
|
|
40105
41023
|
this.actionManager.executeAction(actionFinalize, "ui", {
|
|
40106
41024
|
event: childEvent,
|
|
@@ -41220,7 +42138,7 @@ import { isLinearElement as isLinearElement12 } from "@excalidraw/element";
|
|
|
41220
42138
|
import {
|
|
41221
42139
|
FONT_FAMILY as FONT_FAMILY7,
|
|
41222
42140
|
THEME as THEME18,
|
|
41223
|
-
MIME_TYPES as
|
|
42141
|
+
MIME_TYPES as MIME_TYPES9,
|
|
41224
42142
|
ROUNDNESS as ROUNDNESS8,
|
|
41225
42143
|
DEFAULT_LASER_COLOR as DEFAULT_LASER_COLOR2,
|
|
41226
42144
|
UserIdleState as UserIdleState2,
|
|
@@ -41333,7 +42251,8 @@ var ExcalidrawBase = (props) => {
|
|
|
41333
42251
|
}
|
|
41334
42252
|
const normalizedImageOptions = {
|
|
41335
42253
|
maxFileSizeBytes: imageOptions?.maxFileSizeBytes ?? DEFAULT_IMAGE_OPTIONS.maxFileSizeBytes,
|
|
41336
|
-
maxWidthOrHeight: imageOptions?.maxWidthOrHeight ?? DEFAULT_IMAGE_OPTIONS.maxWidthOrHeight
|
|
42254
|
+
maxWidthOrHeight: imageOptions?.maxWidthOrHeight ?? DEFAULT_IMAGE_OPTIONS.maxWidthOrHeight,
|
|
42255
|
+
placeholderTransitionDuration: imageOptions?.placeholderTransitionDuration ?? DEFAULT_IMAGE_OPTIONS.placeholderTransitionDuration
|
|
41337
42256
|
};
|
|
41338
42257
|
const setExcalidrawAPI = useContext4(ExcalidrawAPISetContext);
|
|
41339
42258
|
const onExcalidrawAPIRef = useRef31(onExcalidrawAPI);
|
|
@@ -41452,7 +42371,7 @@ var areEqual5 = (prevProps, nextProps) => {
|
|
|
41452
42371
|
}
|
|
41453
42372
|
return prevUIOptions[key] === nextUIOptions[key];
|
|
41454
42373
|
});
|
|
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);
|
|
42374
|
+
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
42375
|
return isUIOptionsSame && isImageOptionsSame && isShallowEqual9(prev, next);
|
|
41457
42376
|
};
|
|
41458
42377
|
var Excalidraw = React42.memo(ExcalidrawBase, areEqual5);
|
|
@@ -41474,7 +42393,7 @@ export {
|
|
|
41474
42393
|
Fonts,
|
|
41475
42394
|
FooterCenter_default as Footer,
|
|
41476
42395
|
LiveCollaborationTrigger_default as LiveCollaborationTrigger,
|
|
41477
|
-
|
|
42396
|
+
MIME_TYPES9 as MIME_TYPES,
|
|
41478
42397
|
MainMenu_default as MainMenu,
|
|
41479
42398
|
ROUNDNESS8 as ROUNDNESS,
|
|
41480
42399
|
Sidebar,
|
|
@@ -41496,6 +42415,7 @@ export {
|
|
|
41496
42415
|
getFormFactor2 as getFormFactor,
|
|
41497
42416
|
getNonDeletedElements13 as getNonDeletedElements,
|
|
41498
42417
|
getSceneVersion,
|
|
42418
|
+
getStrokeWidthByKey4 as getStrokeWidthByKey,
|
|
41499
42419
|
getTextFromElements3 as getTextFromElements,
|
|
41500
42420
|
getVisibleSceneBounds2 as getVisibleSceneBounds,
|
|
41501
42421
|
hashElementsVersion,
|