diff --git a/src/components/MermaidToExcalidraw.tsx b/src/components/MermaidToExcalidraw.tsx index 28ac409f9..1422b5f6b 100644 --- a/src/components/MermaidToExcalidraw.tsx +++ b/src/components/MermaidToExcalidraw.tsx @@ -114,7 +114,7 @@ const MermaidToExcalidraw = ({ }, [loading]); useEffect(() => { - const convertMermaidToExcal = async () => { + const renderExcalidrawPreview = async () => { let mermaidGraphData; const canvasNode = canvasRef.current; if (!canvasNode) { @@ -140,7 +140,10 @@ const MermaidToExcalidraw = ({ mermaidToExcalidrawLib.current.graphToExcalidraw(mermaidGraphData); data.current = { - elements: convertToExcalidrawElements(elements, true), + elements: convertToExcalidrawElements(elements, appState, { + regenerateIds: true, + transformViewportToSceneCoords: true, + }), files, }; const parent = canvasNode.parentElement!; @@ -150,23 +153,21 @@ const MermaidToExcalidraw = ({ dimension = Math.min(dimension, parent.offsetWidth - 10); dimension = Math.min(dimension, parent.offsetHeight - 10); - exportToCanvas({ + const canvas = await exportToCanvas({ elements: data.current.elements, files: data.current.files, exportPadding: DEFAULT_EXPORT_PADDING, maxWidthOrHeight: dimension, - }).then((canvas) => { - // if converting to blob fails, there's some problem that will - // likely prevent preview and export (e.g. canvas too big) - return canvasToBlob(canvas).then(() => { - parent.style.background = "#fff"; - canvasNode.replaceChildren(canvas); - }); }); + // if converting to blob fails, there's some problem that will + // likely prevent preview and export (e.g. canvas too big) + await canvasToBlob(canvas); + parent.style.background = "#fff"; + canvasNode.replaceChildren(canvas); } }; - convertMermaidToExcal(); - }, [text]); + renderExcalidrawPreview(); + }, [text, appState]); const setAppState = useExcalidrawSetAppState(); diff --git a/src/data/transform.ts b/src/data/transform.ts index 806710f23..f3be0377c 100644 --- a/src/data/transform.ts +++ b/src/data/transform.ts @@ -38,9 +38,14 @@ import { VerticalAlign, } from "../element/types"; import { MarkOptional } from "../utility-types"; -import { assertNever, getFontString } from "../utils"; +import { + assertNever, + getFontString, + viewportCoordsToSceneCoords, +} from "../utils"; import { getSizeFromPoints } from "../points"; import { nanoid } from "nanoid"; +import { AppState } from "../types"; export type ValidLinearElement = { type: "arrow" | "line"; @@ -387,7 +392,8 @@ class ElementStore { export const convertToExcalidrawElements = ( elements: ExcalidrawElementSkeleton[] | null, - regenerateIds = false, + appState: AppState, + { regenerateIds = false, transformViewportToSceneCoords = false }, ) => { if (!elements) { return []; @@ -404,6 +410,20 @@ export const convertToExcalidrawElements = ( if (regenerateIds) { Object.assign(element, { id: nanoid() }); } + + // transform viewport coords to scene coordinates + if (transformViewportToSceneCoords) { + const { x, y } = viewportCoordsToSceneCoords( + { + clientX: element.x, + clientY: element.y, + }, + appState, + ); + + Object.assign(element, { x, y }); + } + switch (element.type) { case "rectangle": case "ellipse":