@excalidraw/excalidraw 0.17.1-c0b80a0 → 0.17.1-c329470
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-JGDL4H2X.js → chunk-3DLVY5XU.js} +8272 -6864
- package/dist/browser/dev/excalidraw-assets-dev/chunk-3DLVY5XU.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-V7NFEZA6.js → chunk-NOAEU4NM.js} +9 -2
- package/dist/browser/dev/excalidraw-assets-dev/chunk-NOAEU4NM.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{en-ZSVWGT55.js → en-7IBTMWBG.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{image-RJG3J34Y.js → image-N5AC7SEK.js} +2 -6
- package/dist/browser/dev/index.css +85 -50
- package/dist/browser/dev/index.css.map +3 -3
- package/dist/browser/dev/index.js +4375 -3766
- package/dist/browser/dev/index.js.map +4 -4
- package/dist/browser/prod/excalidraw-assets/{chunk-LDVEIXGO.js → chunk-7CSIPVOW.js} +2 -2
- package/dist/browser/prod/excalidraw-assets/chunk-TX3BU7T2.js +47 -0
- package/dist/browser/prod/excalidraw-assets/{en-UPNEHLDS.js → en-LOGQBETY.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/image-3V4U7GZE.js +1 -0
- package/dist/browser/prod/index.css +1 -1
- package/dist/browser/prod/index.js +40 -40
- package/dist/dev/index.css +85 -50
- package/dist/dev/index.css.map +3 -3
- package/dist/dev/index.js +8688 -6706
- package/dist/dev/index.js.map +4 -4
- package/dist/{prod/locales/en-ZXYG7GCR.json → dev/locales/en-V6KXFSCK.json} +8 -1
- package/dist/excalidraw/actions/actionAlign.d.ts +7 -6
- package/dist/excalidraw/actions/actionAlign.js +14 -14
- package/dist/excalidraw/actions/actionClipboard.d.ts +7 -3
- package/dist/excalidraw/actions/actionDeleteSelected.d.ts +7 -3
- package/dist/excalidraw/actions/actionDeleteSelected.js +103 -34
- package/dist/excalidraw/actions/actionDuplicateSelection.js +105 -95
- package/dist/excalidraw/actions/actionFlip.js +16 -7
- package/dist/excalidraw/actions/actionFrame.d.ts +493 -0
- package/dist/excalidraw/actions/actionFrame.js +45 -2
- package/dist/excalidraw/actions/actionGroup.js +6 -4
- package/dist/excalidraw/actions/actionProperties.js +145 -116
- package/dist/excalidraw/actions/actionSelectAll.js +4 -3
- package/dist/excalidraw/actions/shortcuts.d.ts +1 -1
- package/dist/excalidraw/actions/shortcuts.js +1 -0
- package/dist/excalidraw/actions/types.d.ts +1 -1
- package/dist/excalidraw/align.d.ts +2 -1
- package/dist/excalidraw/align.js +15 -6
- package/dist/excalidraw/clipboard.d.ts +27 -5
- package/dist/excalidraw/clipboard.js +55 -28
- package/dist/excalidraw/components/Actions.d.ts +2 -1
- package/dist/excalidraw/components/Actions.js +4 -2
- package/dist/excalidraw/components/ActiveConfirmDialog.d.ts +1 -1
- package/dist/excalidraw/components/ActiveConfirmDialog.js +2 -3
- package/dist/excalidraw/components/App.d.ts +1 -0
- package/dist/excalidraw/components/App.js +216 -111
- package/dist/excalidraw/components/ColorPicker/ColorInput.js +2 -3
- package/dist/excalidraw/components/ColorPicker/ColorPicker.js +2 -3
- package/dist/excalidraw/components/ColorPicker/CustomColorList.js +1 -1
- package/dist/excalidraw/components/ColorPicker/Picker.js +1 -1
- package/dist/excalidraw/components/ColorPicker/PickerColorList.js +1 -1
- package/dist/excalidraw/components/ColorPicker/ShadeList.js +1 -1
- package/dist/excalidraw/components/ColorPicker/colorPickerUtils.d.ts +1 -1
- package/dist/excalidraw/components/ColorPicker/colorPickerUtils.js +1 -1
- package/dist/excalidraw/components/CommandPalette/CommandPalette.js +3 -3
- package/dist/excalidraw/components/ConfirmDialog.js +17 -5
- package/dist/excalidraw/components/Dialog.js +2 -3
- package/dist/excalidraw/components/EyeDropper.d.ts +1 -1
- package/dist/excalidraw/components/EyeDropper.js +1 -1
- package/dist/excalidraw/components/IconPicker.d.ts +2 -2
- package/dist/excalidraw/components/IconPicker.js +56 -53
- package/dist/excalidraw/components/LayerUI.js +6 -6
- package/dist/excalidraw/components/LibraryMenu.d.ts +2 -16
- package/dist/excalidraw/components/LibraryMenu.js +70 -28
- package/dist/excalidraw/components/LibraryMenuHeaderContent.js +4 -5
- package/dist/excalidraw/components/MobileMenu.js +1 -1
- package/dist/excalidraw/components/OverwriteConfirm/OverwriteConfirm.js +2 -3
- package/dist/excalidraw/components/OverwriteConfirm/OverwriteConfirmState.d.ts +1 -1
- package/dist/excalidraw/components/OverwriteConfirm/OverwriteConfirmState.js +2 -3
- package/dist/excalidraw/components/Range.d.ts +9 -0
- package/dist/excalidraw/components/Range.js +24 -0
- package/dist/excalidraw/components/SearchMenu.d.ts +1 -1
- package/dist/excalidraw/components/SearchMenu.js +3 -4
- package/dist/excalidraw/components/Sidebar/Sidebar.d.ts +1 -1
- package/dist/excalidraw/components/Sidebar/Sidebar.js +2 -3
- package/dist/excalidraw/components/Stats/Collapsible.d.ts +2 -1
- package/dist/excalidraw/components/Stats/Collapsible.js +2 -2
- package/dist/excalidraw/components/Stats/Dimension.js +94 -8
- package/dist/excalidraw/components/Stats/MultiDimension.js +8 -5
- package/dist/excalidraw/components/Stats/Position.js +63 -3
- package/dist/excalidraw/components/Stats/index.js +21 -4
- package/dist/excalidraw/components/Stats/utils.d.ts +1 -1
- package/dist/excalidraw/components/Stats/utils.js +2 -55
- package/dist/excalidraw/components/TTDDialog/TTDDialog.js +1 -1
- package/dist/excalidraw/components/ToolButton.js +4 -9
- package/dist/excalidraw/components/hoc/withInternalFallback.js +3 -3
- package/dist/excalidraw/components/hyperlink/Hyperlink.js +6 -12
- package/dist/excalidraw/components/icons.d.ts +9 -0
- package/dist/excalidraw/components/icons.js +4 -4
- package/dist/excalidraw/components/main-menu/DefaultItems.js +2 -3
- package/dist/excalidraw/constants.d.ts +5 -1
- package/dist/excalidraw/constants.js +9 -1
- package/dist/excalidraw/context/tunnels.d.ts +2 -1
- package/dist/excalidraw/context/tunnels.js +3 -1
- package/dist/excalidraw/data/blob.d.ts +1 -0
- package/dist/excalidraw/data/blob.js +7 -3
- package/dist/excalidraw/data/filesystem.d.ts +2 -1
- package/dist/excalidraw/data/filesystem.js +1 -0
- package/dist/excalidraw/data/image.d.ts +0 -6
- package/dist/excalidraw/data/image.js +1 -43
- package/dist/excalidraw/data/index.js +6 -6
- package/dist/excalidraw/data/library.d.ts +9 -3
- package/dist/excalidraw/data/library.js +43 -6
- package/dist/excalidraw/data/restore.js +26 -8
- package/dist/excalidraw/data/url.d.ts +0 -1
- package/dist/excalidraw/data/url.js +2 -4
- package/dist/excalidraw/editor-jotai.d.ts +56 -0
- package/dist/excalidraw/editor-jotai.js +8 -0
- package/dist/excalidraw/element/binding.d.ts +9 -6
- package/dist/excalidraw/element/binding.js +124 -44
- package/dist/excalidraw/element/bounds.js +10 -0
- package/dist/excalidraw/element/cropElement.d.ts +5 -0
- package/dist/excalidraw/element/cropElement.js +28 -1
- package/dist/excalidraw/element/dragElements.js +13 -7
- package/dist/excalidraw/element/elbowArrow.d.ts +16 -0
- package/dist/excalidraw/element/elbowArrow.js +1268 -0
- package/dist/excalidraw/element/embeddable.js +4 -5
- package/dist/excalidraw/element/flowchart.d.ts +1 -1
- package/dist/excalidraw/element/flowchart.js +25 -9
- package/dist/excalidraw/element/heading.d.ts +5 -1
- package/dist/excalidraw/element/heading.js +5 -1
- package/dist/excalidraw/element/image.js +19 -5
- package/dist/excalidraw/element/linearElementEditor.d.ts +9 -10
- package/dist/excalidraw/element/linearElementEditor.js +97 -38
- package/dist/excalidraw/element/mutateElement.d.ts +3 -1
- package/dist/excalidraw/element/mutateElement.js +31 -4
- package/dist/excalidraw/element/newElement.d.ts +8 -12
- package/dist/excalidraw/element/newElement.js +36 -21
- package/dist/excalidraw/element/resizeElements.d.ts +20 -5
- package/dist/excalidraw/element/resizeElements.js +593 -361
- package/dist/excalidraw/element/sortElements.js +1 -4
- package/dist/excalidraw/element/types.d.ts +23 -1
- package/dist/excalidraw/fonts/Fonts.d.ts +0 -16
- package/dist/excalidraw/fonts/Fonts.js +6 -31
- package/dist/excalidraw/frame.d.ts +11 -5
- package/dist/excalidraw/frame.js +146 -35
- package/dist/excalidraw/groups.js +3 -0
- package/dist/excalidraw/hooks/useLibraryItemSvg.d.ts +1 -1
- package/dist/excalidraw/hooks/useLibraryItemSvg.js +2 -3
- package/dist/excalidraw/hooks/useScrollPosition.js +1 -1
- package/dist/excalidraw/i18n.js +3 -4
- package/dist/excalidraw/index.js +3 -4
- package/dist/excalidraw/locales/en.json +8 -1
- package/dist/excalidraw/renderer/interactiveScene.js +43 -32
- package/dist/excalidraw/renderer/staticScene.js +6 -4
- package/dist/excalidraw/renderer/staticSvgScene.js +1 -1
- package/dist/excalidraw/scene/Shape.js +40 -17
- package/dist/excalidraw/scene/comparisons.d.ts +0 -477
- package/dist/excalidraw/scene/comparisons.js +0 -37
- package/dist/excalidraw/scene/export.d.ts +7 -0
- package/dist/excalidraw/scene/export.js +107 -43
- package/dist/excalidraw/scene/index.d.ts +1 -1
- package/dist/excalidraw/scene/index.js +1 -1
- package/dist/excalidraw/scene/selection.js +4 -1
- package/dist/excalidraw/types.d.ts +15 -0
- package/dist/excalidraw/utility-types.d.ts +1 -0
- package/dist/excalidraw/utils.d.ts +8 -1
- package/dist/excalidraw/utils.js +9 -0
- package/dist/excalidraw/visualdebug.d.ts +8 -1
- package/dist/excalidraw/visualdebug.js +3 -0
- package/dist/math/line.d.ts +19 -0
- package/dist/math/line.js +32 -3
- package/dist/math/point.d.ts +10 -0
- package/dist/math/point.js +12 -1
- package/dist/prod/index.css +1 -1
- package/dist/prod/index.js +29 -44
- package/dist/{dev/locales/en-ZXYG7GCR.json → prod/locales/en-V6KXFSCK.json} +8 -1
- package/package.json +5 -2
- package/dist/browser/dev/excalidraw-assets-dev/chunk-JGDL4H2X.js.map +0 -7
- package/dist/browser/dev/excalidraw-assets-dev/chunk-V7NFEZA6.js.map +0 -7
- package/dist/browser/prod/excalidraw-assets/chunk-S2XKB3DE.js +0 -62
- package/dist/browser/prod/excalidraw-assets/image-OFI2YYMP.js +0 -1
- package/dist/excalidraw/element/routing.d.ts +0 -12
- package/dist/excalidraw/element/routing.js +0 -642
- package/dist/excalidraw/jotai.d.ts +0 -34
- package/dist/excalidraw/jotai.js +0 -18
- /package/dist/browser/dev/excalidraw-assets-dev/{en-ZSVWGT55.js.map → en-7IBTMWBG.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{image-RJG3J34Y.js.map → image-N5AC7SEK.js.map} +0 -0
|
@@ -2,7 +2,7 @@ import rough from "roughjs/bin/rough";
|
|
|
2
2
|
import { getCommonBounds, getElementAbsoluteCoords } from "../element/bounds";
|
|
3
3
|
import { renderSceneToSvg } from "../renderer/staticSvgScene";
|
|
4
4
|
import { arrayToMap, distance, getFontString, toBrandedType } from "../utils";
|
|
5
|
-
import { DEFAULT_EXPORT_PADDING, FRAME_STYLE, FONT_FAMILY, SVG_NS, THEME, THEME_FILTER, } from "../constants";
|
|
5
|
+
import { DEFAULT_EXPORT_PADDING, FRAME_STYLE, FONT_FAMILY, SVG_NS, THEME, THEME_FILTER, MIME_TYPES, EXPORT_DATA_TYPES, } from "../constants";
|
|
6
6
|
import { getDefaultAppState } from "../appState";
|
|
7
7
|
import { serializeAsJSON } from "../data/json";
|
|
8
8
|
import { getInitializedImageElements, updateImageCache, } from "../element/image";
|
|
@@ -13,7 +13,7 @@ import { isFrameLikeElement } from "../element/typeChecks";
|
|
|
13
13
|
import { syncInvalidIndices } from "../fractionalIndex";
|
|
14
14
|
import { renderStaticScene } from "../renderer/staticScene";
|
|
15
15
|
import { Fonts } from "../fonts";
|
|
16
|
-
|
|
16
|
+
import { base64ToString, decode, encode, stringToBase64 } from "../data/encode";
|
|
17
17
|
const truncateText = (element, maxWidth) => {
|
|
18
18
|
if (element.width <= maxWidth) {
|
|
19
19
|
return element;
|
|
@@ -157,6 +157,12 @@ export const exportToCanvas = async (elements, appState, files, { exportBackgrou
|
|
|
157
157
|
});
|
|
158
158
|
return canvas;
|
|
159
159
|
};
|
|
160
|
+
const createHTMLComment = (text) => {
|
|
161
|
+
// surrounding with spaces to maintain prettified consistency with previous
|
|
162
|
+
// iterations
|
|
163
|
+
// <!-- comment -->
|
|
164
|
+
return document.createComment(` ${text} `);
|
|
165
|
+
};
|
|
160
166
|
export const exportToSvg = async (elements, appState, files, opts) => {
|
|
161
167
|
const frameRendering = getFrameRenderingConfig(opts?.exportingFrame ?? null, appState.frameRendering ?? null);
|
|
162
168
|
let { exportPadding = DEFAULT_EXPORT_PADDING, exportWithDarkMode = false, viewBackgroundColor, exportScale = 1, exportEmbedScene, } = appState;
|
|
@@ -170,67 +176,84 @@ export const exportToSvg = async (elements, appState, files, opts) => {
|
|
|
170
176
|
if (exportingFrame) {
|
|
171
177
|
exportPadding = 0;
|
|
172
178
|
}
|
|
173
|
-
|
|
179
|
+
const [minX, minY, width, height] = getCanvasSize(exportingFrame ? [exportingFrame] : getRootElements(elementsForRender), exportPadding);
|
|
180
|
+
const offsetX = -minX + exportPadding;
|
|
181
|
+
const offsetY = -minY + exportPadding;
|
|
182
|
+
// ---------------------------------------------------------------------------
|
|
183
|
+
// initialize SVG root element
|
|
184
|
+
// ---------------------------------------------------------------------------
|
|
185
|
+
const svgRoot = document.createElementNS(SVG_NS, "svg");
|
|
186
|
+
svgRoot.setAttribute("version", "1.1");
|
|
187
|
+
svgRoot.setAttribute("xmlns", SVG_NS);
|
|
188
|
+
svgRoot.setAttribute("viewBox", `0 0 ${width} ${height}`);
|
|
189
|
+
svgRoot.setAttribute("width", `${width * exportScale}`);
|
|
190
|
+
svgRoot.setAttribute("height", `${height * exportScale}`);
|
|
191
|
+
if (exportWithDarkMode) {
|
|
192
|
+
svgRoot.setAttribute("filter", THEME_FILTER);
|
|
193
|
+
}
|
|
194
|
+
const defsElement = svgRoot.ownerDocument.createElementNS(SVG_NS, "defs");
|
|
195
|
+
const metadataElement = svgRoot.ownerDocument.createElementNS(SVG_NS, "metadata");
|
|
196
|
+
svgRoot.appendChild(createHTMLComment("svg-source:excalidraw"));
|
|
197
|
+
svgRoot.appendChild(metadataElement);
|
|
198
|
+
svgRoot.appendChild(defsElement);
|
|
199
|
+
// ---------------------------------------------------------------------------
|
|
200
|
+
// scene embed
|
|
201
|
+
// ---------------------------------------------------------------------------
|
|
174
202
|
// we need to serialize the "original" elements before we put them through
|
|
175
203
|
// the tempScene hack which duplicates and regenerates ids
|
|
176
204
|
if (exportEmbedScene) {
|
|
177
205
|
try {
|
|
178
|
-
|
|
206
|
+
encodeSvgBase64Payload({
|
|
207
|
+
metadataElement,
|
|
179
208
|
// when embedding scene, we want to embed the origionally supplied
|
|
180
209
|
// elements which don't contain the temp frame labels.
|
|
181
210
|
// But it also requires that the exportToSvg is being supplied with
|
|
182
211
|
// only the elements that we're exporting, and no extra.
|
|
183
|
-
|
|
212
|
+
payload: serializeAsJSON(elements, appState, files || {}, "local"),
|
|
184
213
|
});
|
|
185
214
|
}
|
|
186
215
|
catch (error) {
|
|
187
216
|
console.error(error);
|
|
188
217
|
}
|
|
189
218
|
}
|
|
190
|
-
|
|
191
|
-
//
|
|
192
|
-
|
|
193
|
-
svgRoot.setAttribute("version", "1.1");
|
|
194
|
-
svgRoot.setAttribute("xmlns", SVG_NS);
|
|
195
|
-
svgRoot.setAttribute("viewBox", `0 0 ${width} ${height}`);
|
|
196
|
-
svgRoot.setAttribute("width", `${width * exportScale}`);
|
|
197
|
-
svgRoot.setAttribute("height", `${height * exportScale}`);
|
|
198
|
-
if (exportWithDarkMode) {
|
|
199
|
-
svgRoot.setAttribute("filter", THEME_FILTER);
|
|
200
|
-
}
|
|
201
|
-
const offsetX = -minX + exportPadding;
|
|
202
|
-
const offsetY = -minY + exportPadding;
|
|
219
|
+
// ---------------------------------------------------------------------------
|
|
220
|
+
// frame clip paths
|
|
221
|
+
// ---------------------------------------------------------------------------
|
|
203
222
|
const frameElements = getFrameLikeElements(elements);
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
223
|
+
if (frameElements.length) {
|
|
224
|
+
const elementsMap = arrayToMap(elements);
|
|
225
|
+
for (const frame of frameElements) {
|
|
226
|
+
const clipPath = svgRoot.ownerDocument.createElementNS(SVG_NS, "clipPath");
|
|
227
|
+
clipPath.setAttribute("id", frame.id);
|
|
228
|
+
const [x1, y1, x2, y2] = getElementAbsoluteCoords(frame, elementsMap);
|
|
229
|
+
const cx = (x2 - x1) / 2 - (frame.x - x1);
|
|
230
|
+
const cy = (y2 - y1) / 2 - (frame.y - y1);
|
|
231
|
+
const rect = svgRoot.ownerDocument.createElementNS(SVG_NS, "rect");
|
|
232
|
+
rect.setAttribute("transform", `translate(${frame.x + offsetX} ${frame.y + offsetY}) rotate(${frame.angle} ${cx} ${cy})`);
|
|
233
|
+
rect.setAttribute("width", `${frame.width}`);
|
|
234
|
+
rect.setAttribute("height", `${frame.height}`);
|
|
235
|
+
if (!exportingFrame) {
|
|
236
|
+
rect.setAttribute("rx", `${FRAME_STYLE.radius}`);
|
|
237
|
+
rect.setAttribute("ry", `${FRAME_STYLE.radius}`);
|
|
238
|
+
}
|
|
239
|
+
clipPath.appendChild(rect);
|
|
240
|
+
defsElement.appendChild(clipPath);
|
|
241
|
+
}
|
|
220
242
|
}
|
|
243
|
+
// ---------------------------------------------------------------------------
|
|
244
|
+
// inline font faces
|
|
245
|
+
// ---------------------------------------------------------------------------
|
|
221
246
|
const fontFaces = !opts?.skipInliningFonts
|
|
222
247
|
? await Fonts.generateFontFaceDeclarations(elements)
|
|
223
248
|
: [];
|
|
224
249
|
const delimiter = "\n "; // 6 spaces
|
|
225
|
-
svgRoot.
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
</defs>
|
|
233
|
-
`;
|
|
250
|
+
const style = svgRoot.ownerDocument.createElementNS(SVG_NS, "style");
|
|
251
|
+
style.classList.add("style-fonts");
|
|
252
|
+
style.appendChild(document.createTextNode(`${delimiter}${fontFaces.join(delimiter)}`));
|
|
253
|
+
defsElement.appendChild(style);
|
|
254
|
+
// ---------------------------------------------------------------------------
|
|
255
|
+
// background
|
|
256
|
+
// ---------------------------------------------------------------------------
|
|
234
257
|
// render background rect
|
|
235
258
|
if (appState.exportBackground && viewBackgroundColor) {
|
|
236
259
|
const rect = svgRoot.ownerDocument.createElementNS(SVG_NS, "rect");
|
|
@@ -241,6 +264,9 @@ export const exportToSvg = async (elements, appState, files, opts) => {
|
|
|
241
264
|
rect.setAttribute("fill", viewBackgroundColor);
|
|
242
265
|
svgRoot.appendChild(rect);
|
|
243
266
|
}
|
|
267
|
+
// ---------------------------------------------------------------------------
|
|
268
|
+
// render elements
|
|
269
|
+
// ---------------------------------------------------------------------------
|
|
244
270
|
const rsvg = rough.svg(svgRoot);
|
|
245
271
|
const renderEmbeddables = opts?.renderEmbeddables ?? false;
|
|
246
272
|
renderSceneToSvg(elementsForRender, toBrandedType(arrayToMap(elementsForRender)), rsvg, svgRoot, files || {}, {
|
|
@@ -258,8 +284,46 @@ export const exportToSvg = async (elements, appState, files, opts) => {
|
|
|
258
284
|
: new Map(),
|
|
259
285
|
reuseImages: opts?.reuseImages ?? true,
|
|
260
286
|
});
|
|
287
|
+
// ---------------------------------------------------------------------------
|
|
261
288
|
return svgRoot;
|
|
262
289
|
};
|
|
290
|
+
export const encodeSvgBase64Payload = ({ payload, metadataElement, }) => {
|
|
291
|
+
const base64 = stringToBase64(JSON.stringify(encode({ text: payload })), true /* is already byte string */);
|
|
292
|
+
metadataElement.appendChild(createHTMLComment(`payload-type:${MIME_TYPES.excalidraw}`));
|
|
293
|
+
metadataElement.appendChild(createHTMLComment("payload-version:2"));
|
|
294
|
+
metadataElement.appendChild(createHTMLComment("payload-start"));
|
|
295
|
+
metadataElement.appendChild(document.createTextNode(base64));
|
|
296
|
+
metadataElement.appendChild(createHTMLComment("payload-end"));
|
|
297
|
+
};
|
|
298
|
+
export const decodeSvgBase64Payload = ({ svg }) => {
|
|
299
|
+
if (svg.includes(`payload-type:${MIME_TYPES.excalidraw}`)) {
|
|
300
|
+
const match = svg.match(/<!-- payload-start -->\s*(.+?)\s*<!-- payload-end -->/);
|
|
301
|
+
if (!match) {
|
|
302
|
+
throw new Error("INVALID");
|
|
303
|
+
}
|
|
304
|
+
const versionMatch = svg.match(/<!-- payload-version:(\d+) -->/);
|
|
305
|
+
const version = versionMatch?.[1] || "1";
|
|
306
|
+
const isByteString = version !== "1";
|
|
307
|
+
try {
|
|
308
|
+
const json = base64ToString(match[1], isByteString);
|
|
309
|
+
const encodedData = JSON.parse(json);
|
|
310
|
+
if (!("encoded" in encodedData)) {
|
|
311
|
+
// legacy, un-encoded scene JSON
|
|
312
|
+
if ("type" in encodedData &&
|
|
313
|
+
encodedData.type === EXPORT_DATA_TYPES.excalidraw) {
|
|
314
|
+
return json;
|
|
315
|
+
}
|
|
316
|
+
throw new Error("FAILED");
|
|
317
|
+
}
|
|
318
|
+
return decode(encodedData);
|
|
319
|
+
}
|
|
320
|
+
catch (error) {
|
|
321
|
+
console.error(error);
|
|
322
|
+
throw new Error("FAILED");
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
throw new Error("INVALID");
|
|
326
|
+
};
|
|
263
327
|
// calculate smallest area to fit the contents in
|
|
264
328
|
const getCanvasSize = (elements, exportPadding) => {
|
|
265
329
|
const [minX, minY, maxX, maxY] = getCommonBounds(elements);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { isSomeElementSelected, getElementsWithinSelection, getCommonAttributeOfSelectedElements, getSelectedElements, getTargetElements, } from "./selection";
|
|
2
2
|
export { calculateScrollCenter } from "./scroll";
|
|
3
|
-
export { hasBackground, hasStrokeWidth, hasStrokeStyle, canHaveArrowheads, canChangeRoundness,
|
|
3
|
+
export { hasBackground, hasStrokeWidth, hasStrokeStyle, canHaveArrowheads, canChangeRoundness, } from "./comparisons";
|
|
4
4
|
export { getNormalizedZoom, getNormalizedGridSize, getNormalizedGridStep, } from "./normalize";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { isSomeElementSelected, getElementsWithinSelection, getCommonAttributeOfSelectedElements, getSelectedElements, getTargetElements, } from "./selection";
|
|
2
2
|
export { calculateScrollCenter } from "./scroll";
|
|
3
|
-
export { hasBackground, hasStrokeWidth, hasStrokeStyle, canHaveArrowheads, canChangeRoundness,
|
|
3
|
+
export { hasBackground, hasStrokeWidth, hasStrokeStyle, canHaveArrowheads, canChangeRoundness, } from "./comparisons";
|
|
4
4
|
export { getNormalizedZoom, getNormalizedGridSize, getNormalizedGridStep, } from "./normalize";
|
|
@@ -94,16 +94,19 @@ export const getCommonAttributeOfSelectedElements = (elements, appState, getAttr
|
|
|
94
94
|
return attributes.length === 1 ? attributes[0] : null;
|
|
95
95
|
};
|
|
96
96
|
export const getSelectedElements = (elements, appState, opts) => {
|
|
97
|
+
const addedElements = new Set();
|
|
97
98
|
const selectedElements = [];
|
|
98
99
|
for (const element of elements.values()) {
|
|
99
100
|
if (appState.selectedElementIds[element.id]) {
|
|
100
101
|
selectedElements.push(element);
|
|
102
|
+
addedElements.add(element.id);
|
|
101
103
|
continue;
|
|
102
104
|
}
|
|
103
105
|
if (opts?.includeBoundTextElement &&
|
|
104
106
|
isBoundToContainer(element) &&
|
|
105
107
|
appState.selectedElementIds[element?.containerId]) {
|
|
106
108
|
selectedElements.push(element);
|
|
109
|
+
addedElements.add(element.id);
|
|
107
110
|
continue;
|
|
108
111
|
}
|
|
109
112
|
}
|
|
@@ -111,7 +114,7 @@ export const getSelectedElements = (elements, appState, opts) => {
|
|
|
111
114
|
const elementsToInclude = [];
|
|
112
115
|
selectedElements.forEach((element) => {
|
|
113
116
|
if (isFrameLikeElement(element)) {
|
|
114
|
-
getFrameChildren(elements, element.id).forEach((e) => elementsToInclude.push(e));
|
|
117
|
+
getFrameChildren(elements, element.id).forEach((e) => !addedElements.has(e.id) && elementsToInclude.push(e));
|
|
115
118
|
}
|
|
116
119
|
elementsToInclude.push(element);
|
|
117
120
|
});
|
|
@@ -415,6 +415,20 @@ export interface ExcalidrawProps {
|
|
|
415
415
|
pointersMap: Gesture["pointers"];
|
|
416
416
|
}) => void;
|
|
417
417
|
onPaste?: (data: ClipboardData, event: ClipboardEvent | null) => Promise<boolean> | boolean;
|
|
418
|
+
/**
|
|
419
|
+
* Called when element(s) are duplicated so you can listen or modify as
|
|
420
|
+
* needed.
|
|
421
|
+
*
|
|
422
|
+
* Called when duplicating via mouse-drag, keyboard, paste, library insert
|
|
423
|
+
* etc.
|
|
424
|
+
*
|
|
425
|
+
* Returned elements will be used in place of the next elements
|
|
426
|
+
* (you should return all elements, including deleted, and not mutate
|
|
427
|
+
* the element if changes are made)
|
|
428
|
+
*/
|
|
429
|
+
onDuplicate?: (nextElements: readonly ExcalidrawElement[],
|
|
430
|
+
/** excludes the duplicated elements */
|
|
431
|
+
prevElements: readonly ExcalidrawElement[]) => ExcalidrawElement[] | void;
|
|
418
432
|
renderTopRightUI?: (isMobile: boolean, appState: UIAppState) => JSX.Element | null;
|
|
419
433
|
langCode?: Language["code"];
|
|
420
434
|
viewModeEnabled?: boolean;
|
|
@@ -533,6 +547,7 @@ export type AppClassProperties = {
|
|
|
533
547
|
getEditorUIOffsets: App["getEditorUIOffsets"];
|
|
534
548
|
visibleElements: App["visibleElements"];
|
|
535
549
|
excalidrawContainerValue: App["excalidrawContainerValue"];
|
|
550
|
+
onPointerUpEmitter: App["onPointerUpEmitter"];
|
|
536
551
|
};
|
|
537
552
|
export type PointerDownState = Readonly<{
|
|
538
553
|
origin: Readonly<{
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EVENT } from "./constants";
|
|
2
|
-
import type { FontFamilyValues, FontString } from "./element/types";
|
|
2
|
+
import type { ExcalidrawBindableElement, FontFamilyValues, FontString } from "./element/types";
|
|
3
3
|
import type { ActiveTool, AppState, ToolType, UnsubscribeCallback, Zoom } from "./types";
|
|
4
4
|
import type { MaybePromise } from "./utility-types";
|
|
5
5
|
export declare const setDateTimeForTests: (dateTime: string) => void;
|
|
@@ -137,6 +137,7 @@ export declare const muteFSAbortError: (error?: Error) => void;
|
|
|
137
137
|
export declare const findIndex: <T>(array: readonly T[], cb: (element: T, index: number, array: readonly T[]) => boolean, fromIndex?: number) => number;
|
|
138
138
|
export declare const findLastIndex: <T>(array: readonly T[], cb: (element: T, index: number, array: readonly T[]) => boolean, fromIndex?: number) => number;
|
|
139
139
|
export declare const isTransparent: (color: string) => boolean;
|
|
140
|
+
export declare const isBindingFallthroughEnabled: (el: ExcalidrawBindableElement) => boolean;
|
|
140
141
|
export type ResolvablePromise<T> = Promise<T> & {
|
|
141
142
|
resolve: [T] extends [undefined] ? (value?: MaybePromise<Awaited<T>>) => void : (value: MaybePromise<Awaited<T>>) => void;
|
|
142
143
|
reject: (error: Error) => void;
|
|
@@ -246,4 +247,10 @@ export declare class PromisePool<T> {
|
|
|
246
247
|
constructor(source: IterableIterator<Promise<void | readonly [number, T]>>, concurrency: number);
|
|
247
248
|
all(): PromiseLike<T[]>;
|
|
248
249
|
}
|
|
250
|
+
/**
|
|
251
|
+
* use when you need to render unsafe string as HTML attribute, but MAKE SURE
|
|
252
|
+
* the attribute is double-quoted when constructing the HTML string
|
|
253
|
+
*/
|
|
254
|
+
export declare const escapeDoubleQuotes: (str: string) => string;
|
|
255
|
+
export declare const castArray: <T>(value: T | T[]) => T[];
|
|
249
256
|
export {};
|
package/dist/excalidraw/utils.js
CHANGED
|
@@ -346,6 +346,7 @@ export const isTransparent = (color) => {
|
|
|
346
346
|
isRRGGBBTransparent ||
|
|
347
347
|
color === COLOR_PALETTE.transparent);
|
|
348
348
|
};
|
|
349
|
+
export const isBindingFallthroughEnabled = (el) => el.fillStyle !== "solid" || isTransparent(el.backgroundColor);
|
|
349
350
|
export const resolvablePromise = () => {
|
|
350
351
|
let resolve;
|
|
351
352
|
let reject;
|
|
@@ -750,3 +751,11 @@ export class PromisePool {
|
|
|
750
751
|
});
|
|
751
752
|
}
|
|
752
753
|
}
|
|
754
|
+
/**
|
|
755
|
+
* use when you need to render unsafe string as HTML attribute, but MAKE SURE
|
|
756
|
+
* the attribute is double-quoted when constructing the HTML string
|
|
757
|
+
*/
|
|
758
|
+
export const escapeDoubleQuotes = (str) => {
|
|
759
|
+
return str.replace(/"/g, """);
|
|
760
|
+
};
|
|
761
|
+
export const castArray = (value) => Array.isArray(value) ? value : [value];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type GlobalPoint } from "../math";
|
|
1
|
+
import { type GlobalPoint, type LocalPoint } from "../math";
|
|
2
2
|
import type { LineSegment } from "../utils";
|
|
3
3
|
import type { BoundingBox, Bounds } from "./element/bounds";
|
|
4
4
|
declare global {
|
|
@@ -7,6 +7,8 @@ declare global {
|
|
|
7
7
|
data: DebugElement[][];
|
|
8
8
|
currentFrame?: number;
|
|
9
9
|
};
|
|
10
|
+
debugDrawPoint: typeof debugDrawPoint;
|
|
11
|
+
debugDrawLine: typeof debugDrawLine;
|
|
10
12
|
}
|
|
11
13
|
}
|
|
12
14
|
export type DebugElement = {
|
|
@@ -31,5 +33,10 @@ export declare const debugDrawBounds: (box: Bounds | Bounds[], opts?: {
|
|
|
31
33
|
color?: string;
|
|
32
34
|
permanent?: boolean;
|
|
33
35
|
}) => void;
|
|
36
|
+
export declare const debugDrawPoints: ({ x, y, points, }: {
|
|
37
|
+
x: number;
|
|
38
|
+
y: number;
|
|
39
|
+
points: LocalPoint[];
|
|
40
|
+
}, options?: any) => void;
|
|
34
41
|
export declare const debugCloseFrame: () => void;
|
|
35
42
|
export declare const debugClear: () => void;
|
|
@@ -42,6 +42,9 @@ export const debugDrawBounds = (box, opts) => {
|
|
|
42
42
|
permanent: !!opts?.permanent,
|
|
43
43
|
}));
|
|
44
44
|
};
|
|
45
|
+
export const debugDrawPoints = ({ x, y, points, }, options) => {
|
|
46
|
+
points.forEach((p) => debugDrawPoint(pointFrom(x + p[0], y + p[1]), options));
|
|
47
|
+
};
|
|
45
48
|
export const debugCloseFrame = () => {
|
|
46
49
|
window.visualDebug?.data.push([]);
|
|
47
50
|
};
|
package/dist/math/line.d.ts
CHANGED
|
@@ -23,4 +23,23 @@ export declare function lineFromPointPair<P extends GlobalPoint | LocalPoint>([a
|
|
|
23
23
|
* @returns
|
|
24
24
|
*/
|
|
25
25
|
export declare function lineFromPointArray<P extends GlobalPoint | LocalPoint>(pointArray: P[]): Line<P> | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Return the coordinates resulting from rotating the given line about an
|
|
28
|
+
* origin by an angle in degrees note that when the origin is not given,
|
|
29
|
+
* the midpoint of the given line is used as the origin
|
|
30
|
+
*
|
|
31
|
+
* @param l
|
|
32
|
+
* @param angle
|
|
33
|
+
* @param origin
|
|
34
|
+
* @returns
|
|
35
|
+
*/
|
|
26
36
|
export declare const lineRotate: <Point extends GlobalPoint | LocalPoint>(l: Line<Point>, angle: Radians, origin?: Point | undefined) => Line<Point>;
|
|
37
|
+
/**
|
|
38
|
+
* Determines the intersection point (unless the lines are parallel) of two
|
|
39
|
+
* lines
|
|
40
|
+
*
|
|
41
|
+
* @param a
|
|
42
|
+
* @param b
|
|
43
|
+
* @returns
|
|
44
|
+
*/
|
|
45
|
+
export declare const linesIntersectAt: <Point extends GlobalPoint | LocalPoint>(a: Line<Point>, b: Line<Point>) => Point | null;
|
package/dist/math/line.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { pointCenter, pointRotateRads } from "./point";
|
|
1
|
+
import { pointCenter, pointFrom, pointRotateRads } from "./point";
|
|
2
2
|
/**
|
|
3
3
|
* Create a line from two points.
|
|
4
4
|
*
|
|
@@ -28,8 +28,37 @@ export function lineFromPointArray(pointArray) {
|
|
|
28
28
|
? line(pointArray[0], pointArray[1])
|
|
29
29
|
: undefined;
|
|
30
30
|
}
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Return the coordinates resulting from rotating the given line about an
|
|
33
|
+
* origin by an angle in degrees note that when the origin is not given,
|
|
34
|
+
* the midpoint of the given line is used as the origin
|
|
35
|
+
*
|
|
36
|
+
* @param l
|
|
37
|
+
* @param angle
|
|
38
|
+
* @param origin
|
|
39
|
+
* @returns
|
|
40
|
+
*/
|
|
33
41
|
export const lineRotate = (l, angle, origin) => {
|
|
34
42
|
return line(pointRotateRads(l[0], origin || pointCenter(l[0], l[1]), angle), pointRotateRads(l[1], origin || pointCenter(l[0], l[1]), angle));
|
|
35
43
|
};
|
|
44
|
+
/**
|
|
45
|
+
* Determines the intersection point (unless the lines are parallel) of two
|
|
46
|
+
* lines
|
|
47
|
+
*
|
|
48
|
+
* @param a
|
|
49
|
+
* @param b
|
|
50
|
+
* @returns
|
|
51
|
+
*/
|
|
52
|
+
export const linesIntersectAt = (a, b) => {
|
|
53
|
+
const A1 = a[1][1] - a[0][1];
|
|
54
|
+
const B1 = a[0][0] - a[1][0];
|
|
55
|
+
const A2 = b[1][1] - b[0][1];
|
|
56
|
+
const B2 = b[0][0] - b[1][0];
|
|
57
|
+
const D = A1 * B2 - A2 * B1;
|
|
58
|
+
if (D !== 0) {
|
|
59
|
+
const C1 = A1 * a[0][0] + B1 * a[0][1];
|
|
60
|
+
const C2 = A2 * b[0][0] + B2 * b[0][1];
|
|
61
|
+
return pointFrom((C1 * B2 - C2 * B1) / D, (A1 * C2 - A2 * C1) / D);
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
};
|
package/dist/math/point.d.ts
CHANGED
|
@@ -28,6 +28,16 @@ export declare function pointFromPair<Point extends GlobalPoint | LocalPoint>(pa
|
|
|
28
28
|
* @returns The point the vector points at with origin 0,0
|
|
29
29
|
*/
|
|
30
30
|
export declare function pointFromVector<P extends GlobalPoint | LocalPoint>(v: Vector): P;
|
|
31
|
+
/**
|
|
32
|
+
* Convert the coordiante object to a point.
|
|
33
|
+
*
|
|
34
|
+
* @param coords The coordinate object with x and y properties
|
|
35
|
+
* @returns
|
|
36
|
+
*/
|
|
37
|
+
export declare function pointFromCoords<Point extends GlobalPoint | LocalPoint>({ x, y, }: {
|
|
38
|
+
x: number;
|
|
39
|
+
y: number;
|
|
40
|
+
}): Point;
|
|
31
41
|
/**
|
|
32
42
|
* Checks if the provided value has the shape of a Point.
|
|
33
43
|
*
|
package/dist/math/point.js
CHANGED
|
@@ -40,6 +40,15 @@ export function pointFromPair(pair) {
|
|
|
40
40
|
export function pointFromVector(v) {
|
|
41
41
|
return v;
|
|
42
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Convert the coordiante object to a point.
|
|
45
|
+
*
|
|
46
|
+
* @param coords The coordinate object with x and y properties
|
|
47
|
+
* @returns
|
|
48
|
+
*/
|
|
49
|
+
export function pointFromCoords({ x, y, }) {
|
|
50
|
+
return [x, y];
|
|
51
|
+
}
|
|
43
52
|
/**
|
|
44
53
|
* Checks if the provided value has the shape of a Point.
|
|
45
54
|
*
|
|
@@ -156,7 +165,9 @@ export function pointDistance(a, b) {
|
|
|
156
165
|
* @returns The euclidean distance between the two points.
|
|
157
166
|
*/
|
|
158
167
|
export function pointDistanceSq(a, b) {
|
|
159
|
-
|
|
168
|
+
const xDiff = b[0] - a[0];
|
|
169
|
+
const yDiff = b[1] - a[1];
|
|
170
|
+
return xDiff * xDiff + yDiff * yDiff;
|
|
160
171
|
}
|
|
161
172
|
/**
|
|
162
173
|
* Scale a point from a given origin by the multiplier.
|