|
|
|
@ -4,13 +4,17 @@ import { canvasToBlob } from "../data/blob";
|
|
|
|
|
import { NonDeletedExcalidrawElement } from "../element/types";
|
|
|
|
|
import { t } from "../i18n";
|
|
|
|
|
import { getSelectedElements, isSomeElementSelected } from "../scene";
|
|
|
|
|
import { BinaryFiles, UIAppState } from "../types";
|
|
|
|
|
import { AppClassProperties, BinaryFiles, UIAppState } from "../types";
|
|
|
|
|
import { Dialog } from "./Dialog";
|
|
|
|
|
import { clipboard } from "./icons";
|
|
|
|
|
import Stack from "./Stack";
|
|
|
|
|
import OpenColor from "open-color";
|
|
|
|
|
import { CheckboxItem } from "./CheckboxItem";
|
|
|
|
|
import { DEFAULT_EXPORT_PADDING, isFirefox } from "../constants";
|
|
|
|
|
import {
|
|
|
|
|
DEFAULT_EXPORT_PADDING,
|
|
|
|
|
EXPORT_IMAGE_TYPES,
|
|
|
|
|
isFirefox,
|
|
|
|
|
} from "../constants";
|
|
|
|
|
import { nativeFileSystemSupported } from "../data/filesystem";
|
|
|
|
|
import { ActionManager } from "../actions/manager";
|
|
|
|
|
import { exportToCanvas } from "../packages/utils";
|
|
|
|
@ -65,21 +69,14 @@ const ImageExportModal = ({
|
|
|
|
|
elements,
|
|
|
|
|
appState,
|
|
|
|
|
files,
|
|
|
|
|
exportPadding = DEFAULT_EXPORT_PADDING,
|
|
|
|
|
actionManager,
|
|
|
|
|
onExportToPng,
|
|
|
|
|
onExportToSvg,
|
|
|
|
|
onExportToClipboard,
|
|
|
|
|
onExportImage,
|
|
|
|
|
}: {
|
|
|
|
|
appState: UIAppState;
|
|
|
|
|
elements: readonly NonDeletedExcalidrawElement[];
|
|
|
|
|
files: BinaryFiles;
|
|
|
|
|
exportPadding?: number;
|
|
|
|
|
actionManager: ActionManager;
|
|
|
|
|
onExportToPng: ExportCB;
|
|
|
|
|
onExportToSvg: ExportCB;
|
|
|
|
|
onExportToClipboard: ExportCB;
|
|
|
|
|
onCloseRequest: () => void;
|
|
|
|
|
onExportImage: AppClassProperties["onExportImage"];
|
|
|
|
|
}) => {
|
|
|
|
|
const someElementIsSelected = isSomeElementSelected(elements, appState);
|
|
|
|
|
const [exportSelected, setExportSelected] = useState(someElementIsSelected);
|
|
|
|
@ -90,10 +87,6 @@ const ImageExportModal = ({
|
|
|
|
|
? getSelectedElements(elements, appState, true)
|
|
|
|
|
: elements;
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
setExportSelected(someElementIsSelected);
|
|
|
|
|
}, [someElementIsSelected]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const previewNode = previewRef.current;
|
|
|
|
|
if (!previewNode) {
|
|
|
|
@ -107,7 +100,7 @@ const ImageExportModal = ({
|
|
|
|
|
elements: exportedElements,
|
|
|
|
|
appState,
|
|
|
|
|
files,
|
|
|
|
|
exportPadding,
|
|
|
|
|
exportPadding: DEFAULT_EXPORT_PADDING,
|
|
|
|
|
maxWidthOrHeight: maxWidth,
|
|
|
|
|
})
|
|
|
|
|
.then((canvas) => {
|
|
|
|
@ -122,7 +115,7 @@ const ImageExportModal = ({
|
|
|
|
|
console.error(error);
|
|
|
|
|
setRenderError(error);
|
|
|
|
|
});
|
|
|
|
|
}, [appState, files, exportedElements, exportPadding]);
|
|
|
|
|
}, [appState, files, exportedElements]);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="ExportDialog">
|
|
|
|
@ -177,7 +170,9 @@ const ImageExportModal = ({
|
|
|
|
|
color="indigo"
|
|
|
|
|
title={t("buttons.exportToPng")}
|
|
|
|
|
aria-label={t("buttons.exportToPng")}
|
|
|
|
|
onClick={() => onExportToPng(exportedElements)}
|
|
|
|
|
onClick={() =>
|
|
|
|
|
onExportImage(EXPORT_IMAGE_TYPES.png, exportedElements)
|
|
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
PNG
|
|
|
|
|
</ExportButton>
|
|
|
|
@ -185,7 +180,9 @@ const ImageExportModal = ({
|
|
|
|
|
color="red"
|
|
|
|
|
title={t("buttons.exportToSvg")}
|
|
|
|
|
aria-label={t("buttons.exportToSvg")}
|
|
|
|
|
onClick={() => onExportToSvg(exportedElements)}
|
|
|
|
|
onClick={() =>
|
|
|
|
|
onExportImage(EXPORT_IMAGE_TYPES.svg, exportedElements)
|
|
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
SVG
|
|
|
|
|
</ExportButton>
|
|
|
|
@ -194,7 +191,9 @@ const ImageExportModal = ({
|
|
|
|
|
{(probablySupportsClipboardBlob || isFirefox) && (
|
|
|
|
|
<ExportButton
|
|
|
|
|
title={t("buttons.copyPngToClipboard")}
|
|
|
|
|
onClick={() => onExportToClipboard(exportedElements)}
|
|
|
|
|
onClick={() =>
|
|
|
|
|
onExportImage(EXPORT_IMAGE_TYPES.clipboard, exportedElements)
|
|
|
|
|
}
|
|
|
|
|
color="gray"
|
|
|
|
|
shade={7}
|
|
|
|
|
>
|
|
|
|
@ -209,45 +208,31 @@ const ImageExportModal = ({
|
|
|
|
|
export const ImageExportDialog = ({
|
|
|
|
|
elements,
|
|
|
|
|
appState,
|
|
|
|
|
setAppState,
|
|
|
|
|
files,
|
|
|
|
|
exportPadding = DEFAULT_EXPORT_PADDING,
|
|
|
|
|
actionManager,
|
|
|
|
|
onExportToPng,
|
|
|
|
|
onExportToSvg,
|
|
|
|
|
onExportToClipboard,
|
|
|
|
|
onExportImage,
|
|
|
|
|
onCloseRequest,
|
|
|
|
|
}: {
|
|
|
|
|
appState: UIAppState;
|
|
|
|
|
setAppState: React.Component<any, UIAppState>["setState"];
|
|
|
|
|
elements: readonly NonDeletedExcalidrawElement[];
|
|
|
|
|
files: BinaryFiles;
|
|
|
|
|
exportPadding?: number;
|
|
|
|
|
actionManager: ActionManager;
|
|
|
|
|
onExportToPng: ExportCB;
|
|
|
|
|
onExportToSvg: ExportCB;
|
|
|
|
|
onExportToClipboard: ExportCB;
|
|
|
|
|
onExportImage: AppClassProperties["onExportImage"];
|
|
|
|
|
onCloseRequest: () => void;
|
|
|
|
|
}) => {
|
|
|
|
|
const handleClose = React.useCallback(() => {
|
|
|
|
|
setAppState({ openDialog: null });
|
|
|
|
|
}, [setAppState]);
|
|
|
|
|
if (appState.openDialog !== "imageExport") {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
{appState.openDialog === "imageExport" && (
|
|
|
|
|
<Dialog onCloseRequest={handleClose} title={t("buttons.exportImage")}>
|
|
|
|
|
<ImageExportModal
|
|
|
|
|
elements={elements}
|
|
|
|
|
appState={appState}
|
|
|
|
|
files={files}
|
|
|
|
|
exportPadding={exportPadding}
|
|
|
|
|
actionManager={actionManager}
|
|
|
|
|
onExportToPng={onExportToPng}
|
|
|
|
|
onExportToSvg={onExportToSvg}
|
|
|
|
|
onExportToClipboard={onExportToClipboard}
|
|
|
|
|
onCloseRequest={handleClose}
|
|
|
|
|
/>
|
|
|
|
|
</Dialog>
|
|
|
|
|
)}
|
|
|
|
|
</>
|
|
|
|
|
<Dialog onCloseRequest={onCloseRequest} title={t("buttons.exportImage")}>
|
|
|
|
|
<ImageExportModal
|
|
|
|
|
elements={elements}
|
|
|
|
|
appState={appState}
|
|
|
|
|
files={files}
|
|
|
|
|
actionManager={actionManager}
|
|
|
|
|
onExportImage={onExportImage}
|
|
|
|
|
/>
|
|
|
|
|
</Dialog>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|