Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BC-6431 - Fix tldraw export to image functionality #53

Merged
merged 13 commits into from
Feb 12, 2024
3 changes: 2 additions & 1 deletion src/components/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function Editor({
focusModeHandler: (isFocusMode: boolean) => void;
}) {
const { onOpenMedia, onOpenProject } = useFileSystem();
const { onMount, onSave, onAssetCreate, onPatch, ...events } =
const { onMount, onSave, onAssetCreate, onPatch, onExport, ...events } =
useMultiplayerState({
roomId,
setIsDarkMode: darkModeHandler,
Expand All @@ -42,6 +42,7 @@ function Editor({
disableAssets={false}
onMount={onMount}
onPatch={onPatch}
onExport={onExport}
darkMode={isDarkMode}
{...events}
onOpenProject={onOpenProject}
Expand Down
36 changes: 33 additions & 3 deletions src/hooks/useMultiplayerState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import lodash from "lodash";
import {
TDAsset,
TDBinding,
TDExport,
TDShape,
TDUser,
TldrawApp,
Expand Down Expand Up @@ -29,6 +30,7 @@ import {
} from "../utils/boardImportUtils";
import { saveToFileSystem } from "../utils/boardExportUtils";
import { uploadFileToStorage } from "../utils/fileUpload";
import { getImageBlob } from "../utils/tldrawImageExportUtils";

declare const window: Window & { app: TldrawApp };

Expand Down Expand Up @@ -64,7 +66,7 @@ export function useMultiplayerState({
app.fileSystemHandle = handle;
}
} catch (error) {
console.error("Error while exporting project");
console.error("Error while exporting project", error);
toast.error("An error occurred while exporting project");
}
app.setIsLoading(false);
Expand All @@ -86,7 +88,7 @@ export function useMultiplayerState({
app.fileSystemHandle = handle;
}
} catch (error) {
console.error("Error while exporting project");
console.error("Error while exporting project", error);
toast.error("An error occurred while exporting project");
}
app.setIsLoading(false);
Expand Down Expand Up @@ -155,7 +157,7 @@ export function useMultiplayerState({
if (file.size > envs!.TLDRAW__ASSETS_MAX_SIZE) {
toast.info(
`Asset is too big - max. ${
envs!.TLDRAW__ASSETS_MAX_SIZE / 1000000
envs!.TLDRAW__ASSETS_MAX_SIZE / 1048576
davwas marked this conversation as resolved.
Show resolved Hide resolved
}MB`,
);
return false;
Expand Down Expand Up @@ -241,6 +243,33 @@ export function useMultiplayerState({
room.updatePresence({ tdUser });
}, []);

const onExport = useCallback(
async (app: TldrawApp, info: TDExport) => {
app.setIsLoading(true);
undoManager.stopCapturing();
syncAssets(app);
try {
const blob = await getImageBlob(app, info.type);

if (!blob) {
app.setIsLoading(false);
return;
}

const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.download = `${roomId}_export.${info.type}`;
link.click();
} catch (error) {
console.error("Error while exporting project as image", error);
davwas marked this conversation as resolved.
Show resolved Hide resolved
toast.error("An error occurred while exporting project as image");
}
app.setIsLoading(false);
},
[roomId],
);

// Document Changes --------

// Update app users whenever there is a change in the room users
Expand Down Expand Up @@ -332,6 +361,7 @@ export function useMultiplayerState({
onMount,
onSave,
onSaveAs,
onExport,
onChangePage,
onChangePresence,
loading,
Expand Down
14 changes: 14 additions & 0 deletions src/utils/imageExportUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Custom function for exporting images stored in external storage correctly.
**/

export const serializeImage = (id: string): string => {
const image = document.getElementById(id + "_image") as HTMLImageElement;
if (image) {
const canvas = document.createElement("canvas");
canvas.width = image.naturalWidth;
canvas.height = image.naturalHeight;
canvas.getContext("2d")!.drawImage(image, 0, 0);
return canvas.toDataURL("image/png");
} else throw new Error("Image with id " + id + " not found");
};
Loading
Loading