2020-11-02 20:14:20 +01:00
|
|
|
import {
|
|
|
|
exportToCanvas as _exportToCanvas,
|
|
|
|
exportToSvg as _exportToSvg,
|
|
|
|
} from "../scene/export";
|
|
|
|
import { getDefaultAppState } from "../appState";
|
|
|
|
import { AppState } from "../types";
|
|
|
|
import { ExcalidrawElement } from "../element/types";
|
|
|
|
import { getNonDeletedElements } from "../element";
|
2021-03-16 22:21:56 +05:30
|
|
|
import { restore } from "../data/restore";
|
2020-11-02 20:14:20 +01:00
|
|
|
|
|
|
|
type ExportOpts = {
|
|
|
|
elements: readonly ExcalidrawElement[];
|
2021-03-16 22:21:56 +05:30
|
|
|
appState?: Partial<Omit<AppState, "offsetTop" | "offsetLeft">>;
|
2020-11-02 20:14:20 +01:00
|
|
|
getDimensions: (
|
|
|
|
width: number,
|
|
|
|
height: number,
|
|
|
|
) => { width: number; height: number; scale: number };
|
|
|
|
};
|
|
|
|
|
2020-12-14 22:11:48 +09:00
|
|
|
export const exportToCanvas = ({
|
2020-11-02 20:14:20 +01:00
|
|
|
elements,
|
2021-03-16 22:21:56 +05:30
|
|
|
appState,
|
2020-11-02 20:14:20 +01:00
|
|
|
getDimensions = (width, height) => ({ width, height, scale: 1 }),
|
|
|
|
}: ExportOpts) => {
|
2021-03-16 22:21:56 +05:30
|
|
|
const { elements: restoredElements, appState: restoredAppState } = restore(
|
|
|
|
{ elements, appState },
|
|
|
|
null,
|
|
|
|
);
|
|
|
|
const {
|
|
|
|
exportBackground,
|
|
|
|
viewBackgroundColor,
|
|
|
|
shouldAddWatermark,
|
|
|
|
} = restoredAppState;
|
2020-11-02 20:14:20 +01:00
|
|
|
return _exportToCanvas(
|
2021-03-16 22:21:56 +05:30
|
|
|
getNonDeletedElements(restoredElements),
|
|
|
|
{ ...restoredAppState, offsetTop: 0, offsetLeft: 0 },
|
|
|
|
{ exportBackground, viewBackgroundColor, shouldAddWatermark },
|
2020-11-02 20:14:20 +01:00
|
|
|
(width: number, height: number) => {
|
|
|
|
const canvas = document.createElement("canvas");
|
|
|
|
const ret = getDimensions(width, height);
|
|
|
|
|
|
|
|
canvas.width = ret.width;
|
|
|
|
canvas.height = ret.height;
|
|
|
|
|
2021-02-04 14:54:08 +01:00
|
|
|
return { canvas, scale: ret.scale };
|
2020-11-02 20:14:20 +01:00
|
|
|
},
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export const exportToBlob = (
|
|
|
|
opts: ExportOpts & {
|
|
|
|
mimeType?: string;
|
|
|
|
quality?: number;
|
|
|
|
},
|
|
|
|
): Promise<Blob | null> => {
|
|
|
|
const canvas = exportToCanvas(opts);
|
|
|
|
|
|
|
|
let { mimeType = "image/png", quality } = opts;
|
|
|
|
|
|
|
|
if (mimeType === "image/png" && typeof quality === "number") {
|
|
|
|
console.warn(`"quality" will be ignored for "image/png" mimeType`);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mimeType === "image/jpg") {
|
|
|
|
mimeType = "image/jpeg";
|
|
|
|
}
|
|
|
|
|
|
|
|
quality = quality ? quality : /image\/jpe?g/.test(mimeType) ? 0.92 : 0.8;
|
|
|
|
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
canvas.toBlob(
|
|
|
|
(blob: Blob | null) => {
|
|
|
|
resolve(blob);
|
|
|
|
},
|
|
|
|
mimeType,
|
|
|
|
quality,
|
|
|
|
);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
export const exportToSvg = ({
|
|
|
|
elements,
|
|
|
|
appState = getDefaultAppState(),
|
|
|
|
exportPadding,
|
|
|
|
metadata,
|
|
|
|
}: ExportOpts & {
|
|
|
|
exportPadding?: number;
|
|
|
|
metadata?: string;
|
|
|
|
}): SVGSVGElement => {
|
2021-03-16 22:21:56 +05:30
|
|
|
const { elements: restoredElements, appState: restoredAppState } = restore(
|
|
|
|
{ elements, appState },
|
|
|
|
null,
|
|
|
|
);
|
|
|
|
return _exportToSvg(getNonDeletedElements(restoredElements), {
|
|
|
|
...restoredAppState,
|
2020-11-02 20:14:20 +01:00
|
|
|
exportPadding,
|
|
|
|
metadata,
|
|
|
|
});
|
|
|
|
};
|