diff --git a/src/components/LibraryUnit.tsx b/src/components/LibraryUnit.tsx index 6723ac80..749877cd 100644 --- a/src/components/LibraryUnit.tsx +++ b/src/components/LibraryUnit.tsx @@ -2,7 +2,7 @@ import clsx from "clsx"; import oc from "open-color"; import { useEffect, useRef, useState } from "react"; import { useDevice } from "../components/App"; -import { exportToSvg } from "../scene/export"; +import { exportToSvg } from "../packages/utils"; import { LibraryItem } from "../types"; import "./LibraryUnit.scss"; import { CheckboxItem } from "./CheckboxItem"; @@ -36,14 +36,14 @@ export const LibraryUnit = ({ if (!elements) { return; } - const svg = await exportToSvg( + const svg = await exportToSvg({ elements, - { + appState: { exportBackground: false, viewBackgroundColor: oc.white, }, - null, - ); + files: null, + }); svg.querySelector(".style-fonts")?.remove(); node.innerHTML = svg.outerHTML; })(); diff --git a/src/packages/excalidraw/CHANGELOG.md b/src/packages/excalidraw/CHANGELOG.md index 628177a4..c36883b8 100644 --- a/src/packages/excalidraw/CHANGELOG.md +++ b/src/packages/excalidraw/CHANGELOG.md @@ -33,6 +33,10 @@ For more details refer to the [docs](https://docs.excalidraw.com) - The optional parameter `refreshDimensions` in [`restoreElements`](https://docs.excalidraw.com/docs/@excalidraw/excalidraw/api/utils/restore#restoreelements) has been removed and can be enabled via `opts` +### Fixes + +- Exporting labelled arrows via export utils [#6443](https://github.com/excalidraw/excalidraw/pull/6443) + ## 0.14.2 (2023-02-01) ### Features diff --git a/src/packages/utils.ts b/src/packages/utils.ts index d8199508..5161e0ca 100644 --- a/src/packages/utils.ts +++ b/src/packages/utils.ts @@ -5,7 +5,6 @@ import { import { getDefaultAppState } from "../appState"; import { AppState, BinaryFiles } from "../types"; import { ExcalidrawElement, NonDeleted } from "../element/types"; -import { getNonDeletedElements } from "../element"; import { restore } from "../data/restore"; import { MIME_TYPES } from "../constants"; import { encodePngMetadata } from "../data/image"; @@ -15,6 +14,7 @@ import { copyTextToSystemClipboard, copyToClipboard, } from "../clipboard"; +import Scene from "../scene/Scene"; export { MIME_TYPES }; @@ -44,9 +44,17 @@ export const exportToCanvas = ({ null, null, ); + // The helper methods getContainerElement and getBoundTextElement are + // dependent on Scene which will not be available + // when these pure utils are called outside Excalidraw or even if called + // from inside Excalidraw when Scene isn't available eg when using library items from store, as a result the element cannot be extracted + // hence initailizing a new scene with the elements + // so its always available to helper methods + const scene = new Scene(); + scene.replaceAllElements(restoredElements); const { exportBackground, viewBackgroundColor } = restoredAppState; return _exportToCanvas( - getNonDeletedElements(restoredElements), + scene.getNonDeletedElements(), { ...restoredAppState, offsetTop: 0, offsetLeft: 0, width: 0, height: 0 }, files || {}, { exportBackground, exportPadding, viewBackgroundColor }, @@ -114,8 +122,18 @@ export const exportToBlob = async ( }; } - const canvas = await exportToCanvas(opts); - + // The helper methods getContainerElement and getBoundTextElement are + // dependent on Scene which will not be available + // when these pure utils are called outside Excalidraw or even if called + // from inside Excalidraw when Scene isn't available eg when using library items from store, as a result the element cannot be extracted + // hence initailizing a new scene with the elements + // so its always available to helper methods + const scene = new Scene(); + scene.replaceAllElements(opts.elements); + const canvas = await exportToCanvas({ + ...opts, + elements: scene.getNonDeletedElements(), + }); quality = quality ? quality : /image\/jpe?g/.test(mimeType) ? 0.92 : 0.8; return new Promise((resolve, reject) => { @@ -132,7 +150,7 @@ export const exportToBlob = async ( blob = await encodePngMetadata({ blob, metadata: serializeAsJSON( - opts.elements, + scene.getNonDeletedElements(), opts.appState, opts.files || {}, "local", @@ -160,8 +178,16 @@ export const exportToSvg = async ({ null, null, ); + // The helper methods getContainerElement and getBoundTextElement are + // dependent on Scene which will not be available + // when these pure utils are called outside Excalidraw or even if called + // from inside Excalidraw when Scene isn't available eg when using library items from store, as a result the element cannot be extracted + // hence initailizing a new scene with the elements + // so its always available to helper methods + const scene = new Scene(); + scene.replaceAllElements(restoredElements); return _exportToSvg( - getNonDeletedElements(restoredElements), + scene.getNonDeletedElements(), { ...restoredAppState, exportPadding, @@ -177,6 +203,14 @@ export const exportToClipboard = async ( type: "png" | "svg" | "json"; }, ) => { + // The helper methods getContainerElement and getBoundTextElement are + // dependent on Scene which will not be available + // when these pure utils are called outside Excalidraw or even if called + // from inside Excalidraw when Scene isn't available eg when using library items from store, as a result the element cannot be extracted + // hence initailizing a new scene with the elements + // so its always available to helper methods + const scene = new Scene(); + scene.replaceAllElements(opts.elements); if (opts.type === "svg") { const svg = await exportToSvg(opts); await copyTextToSystemClipboard(svg.outerHTML); @@ -191,7 +225,7 @@ export const exportToClipboard = async ( ...getDefaultAppState(), ...opts.appState, }; - await copyToClipboard(opts.elements, appState, opts.files); + await copyToClipboard(scene.getNonDeletedElements(), appState, opts.files); } else { throw new Error("Invalid export type"); }