UNPKG

tldraw

Version:

A tiny little drawing editor.

131 lines (130 loc) 4.03 kB
import { jsx } from "react/jsx-runtime"; import { DefaultSpinner, Editor, ErrorScreen, LoadingScreen, useShallowArrayIdentity, useTLStore } from "@tldraw/editor"; import { memo, useLayoutEffect, useMemo, useState } from "react"; import { defaultBindingUtils } from "./defaultBindingUtils.mjs"; import { defaultShapeUtils } from "./defaultShapeUtils.mjs"; import { usePreloadAssets } from "./ui/hooks/usePreloadAssets.mjs"; import { getSvgAsImage } from "./utils/export/export.mjs"; import { useDefaultEditorAssetsWithOverrides } from "./utils/static-assets/assetUrls.mjs"; const TldrawImage = memo(function TldrawImage2(props) { const [url, setUrl] = useState(null); const [container, setContainer] = useState(null); const shapeUtils = useShallowArrayIdentity(props.shapeUtils ?? []); const shapeUtilsWithDefaults = useMemo(() => [...defaultShapeUtils, ...shapeUtils], [shapeUtils]); const bindingUtils = useShallowArrayIdentity(props.bindingUtils ?? []); const bindingUtilsWithDefaults = useMemo( () => [...defaultBindingUtils, ...bindingUtils], [bindingUtils] ); const store = useTLStore({ snapshot: props.snapshot, shapeUtils: shapeUtilsWithDefaults }); const assets = useDefaultEditorAssetsWithOverrides(props.assetUrls); const { done: preloadingComplete, error: preloadingError } = usePreloadAssets(assets); const { pageId, bounds, scale, pixelRatio, background, padding, darkMode, preserveAspectRatio, format = "svg", licenseKey } = props; useLayoutEffect(() => { if (!container) return; if (!store) return; if (!preloadingComplete) return; let isCancelled = false; const tempElm = document.createElement("div"); container.appendChild(tempElm); container.classList.add("tl-container", "tl-theme__light"); const editor = new Editor({ store, shapeUtils: shapeUtilsWithDefaults, bindingUtils: bindingUtilsWithDefaults, tools: [], getContainer: () => tempElm, licenseKey }); if (pageId) editor.setCurrentPage(pageId); const shapeIds = editor.getCurrentPageShapeIds(); async function setSvg() { const svgResult = await editor.getSvgString([...shapeIds], { bounds, scale, background, padding, darkMode, preserveAspectRatio }); if (svgResult && !isCancelled) { if (format === "svg") { if (!isCancelled) { const blob = new Blob([svgResult.svg], { type: "image/svg+xml" }); const url2 = URL.createObjectURL(blob); setUrl(url2); } } else if (format === "png") { const blob = await getSvgAsImage(editor, svgResult.svg, { type: format, width: svgResult.width, height: svgResult.height, pixelRatio }); if (blob && !isCancelled) { const url2 = URL.createObjectURL(blob); setUrl(url2); } } } editor.dispose(); } setSvg(); return () => { isCancelled = true; }; }, [ format, container, store, shapeUtilsWithDefaults, bindingUtilsWithDefaults, pageId, bounds, scale, background, padding, darkMode, preserveAspectRatio, preloadingComplete, preloadingError, licenseKey, pixelRatio ]); if (preloadingError) { return /* @__PURE__ */ jsx(ErrorScreen, { children: "Could not load assets." }); } if (!preloadingComplete) { return /* @__PURE__ */ jsx(LoadingScreen, { children: /* @__PURE__ */ jsx(DefaultSpinner, {}) }); } return /* @__PURE__ */ jsx("div", { ref: setContainer, style: { position: "relative", width: "100%", height: "100%" }, children: url && /* @__PURE__ */ jsx( "img", { src: url, referrerPolicy: "strict-origin-when-cross-origin", style: { width: "100%", height: "100%" } } ) }); }); export { TldrawImage }; //# sourceMappingURL=TldrawImage.mjs.map