mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Co-authored-by: dwelle <luzar.david@gmail.com>
This commit is contained in:
parent
5c26bd19d7
commit
fc58e51ab3
10 changed files with 193 additions and 118 deletions
|
@ -1022,12 +1022,12 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
copyToClipboard(this.scene.getElements(), this.state);
|
||||
};
|
||||
|
||||
private copyToClipboardAsPng = () => {
|
||||
private copyToClipboardAsPng = async () => {
|
||||
const elements = this.scene.getElements();
|
||||
|
||||
const selectedElements = getSelectedElements(elements, this.state);
|
||||
try {
|
||||
exportCanvas(
|
||||
await exportCanvas(
|
||||
"clipboard",
|
||||
selectedElements.length ? selectedElements : elements,
|
||||
this.state,
|
||||
|
@ -1040,13 +1040,13 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
}
|
||||
};
|
||||
|
||||
private copyToClipboardAsSvg = () => {
|
||||
private copyToClipboardAsSvg = async () => {
|
||||
const selectedElements = getSelectedElements(
|
||||
this.scene.getElements(),
|
||||
this.state,
|
||||
);
|
||||
try {
|
||||
exportCanvas(
|
||||
await exportCanvas(
|
||||
"clipboard-svg",
|
||||
selectedElements.length ? selectedElements : this.scene.getElements(),
|
||||
this.state,
|
||||
|
|
|
@ -15,10 +15,24 @@ import { probablySupportsClipboardBlob } from "../clipboard";
|
|||
import { getSelectedElements, isSomeElementSelected } from "../scene";
|
||||
import useIsMobile from "../is-mobile";
|
||||
import { Dialog } from "./Dialog";
|
||||
import { canvasToBlob } from "../data/blob";
|
||||
import { CanvasError } from "../errors";
|
||||
|
||||
const scales = [1, 2, 3];
|
||||
const defaultScale = scales.includes(devicePixelRatio) ? devicePixelRatio : 1;
|
||||
|
||||
export const ErrorCanvasPreview = () => {
|
||||
return (
|
||||
<div>
|
||||
<h3>{t("canvasError.cannotShowPreview")}</h3>
|
||||
<p>
|
||||
<span>{t("canvasError.canvasTooBig")}</span>
|
||||
</p>
|
||||
<em>({t("canvasError.canvasTooBigTip")})</em>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export type ExportCB = (
|
||||
elements: readonly NonDeletedExcalidrawElement[],
|
||||
scale?: number,
|
||||
|
@ -47,6 +61,7 @@ const ExportModal = ({
|
|||
const someElementIsSelected = isSomeElementSelected(elements, appState);
|
||||
const [scale, setScale] = useState(defaultScale);
|
||||
const [exportSelected, setExportSelected] = useState(someElementIsSelected);
|
||||
const [previewError, setPreviewError] = useState<Error | null>(null);
|
||||
const previewRef = useRef<HTMLDivElement>(null);
|
||||
const {
|
||||
exportBackground,
|
||||
|
@ -64,17 +79,42 @@ const ExportModal = ({
|
|||
|
||||
useEffect(() => {
|
||||
const previewNode = previewRef.current;
|
||||
const canvas = exportToCanvas(exportedElements, appState, {
|
||||
exportBackground,
|
||||
viewBackgroundColor,
|
||||
exportPadding,
|
||||
scale,
|
||||
shouldAddWatermark,
|
||||
});
|
||||
previewNode?.appendChild(canvas);
|
||||
return () => {
|
||||
previewNode?.removeChild(canvas);
|
||||
};
|
||||
if (!previewNode) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const canvas = exportToCanvas(exportedElements, appState, {
|
||||
exportBackground,
|
||||
viewBackgroundColor,
|
||||
exportPadding,
|
||||
scale,
|
||||
shouldAddWatermark,
|
||||
});
|
||||
|
||||
let isRemoved = false;
|
||||
// if converting to blob fails, there's some problem that will
|
||||
// likely prevent preview and export (e.g. canvas too big)
|
||||
canvasToBlob(canvas)
|
||||
.then(() => {
|
||||
if (isRemoved) {
|
||||
return;
|
||||
}
|
||||
setPreviewError(null);
|
||||
previewNode.appendChild(canvas);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
setPreviewError(new CanvasError());
|
||||
});
|
||||
|
||||
return () => {
|
||||
isRemoved = true;
|
||||
canvas.remove();
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
setPreviewError(new CanvasError());
|
||||
}
|
||||
}, [
|
||||
appState,
|
||||
exportedElements,
|
||||
|
@ -87,7 +127,9 @@ const ExportModal = ({
|
|||
|
||||
return (
|
||||
<div className="ExportDialog">
|
||||
<div className="ExportDialog__preview" ref={previewRef}></div>
|
||||
<div className="ExportDialog__preview" ref={previewRef}>
|
||||
{previewError && <ErrorCanvasPreview />}
|
||||
</div>
|
||||
<Stack.Col gap={2} align="center">
|
||||
<div className="ExportDialog__actions">
|
||||
<Stack.Row gap={2}>
|
||||
|
|
|
@ -315,18 +315,18 @@ const LayerUI = ({
|
|||
scale,
|
||||
) => {
|
||||
if (canvas) {
|
||||
try {
|
||||
await exportCanvas(type, exportedElements, appState, canvas, {
|
||||
exportBackground: appState.exportBackground,
|
||||
name: appState.name,
|
||||
viewBackgroundColor: appState.viewBackgroundColor,
|
||||
scale,
|
||||
shouldAddWatermark: appState.shouldAddWatermark,
|
||||
await exportCanvas(type, exportedElements, appState, canvas, {
|
||||
exportBackground: appState.exportBackground,
|
||||
name: appState.name,
|
||||
viewBackgroundColor: appState.viewBackgroundColor,
|
||||
scale,
|
||||
shouldAddWatermark: appState.shouldAddWatermark,
|
||||
})
|
||||
.catch(muteFSAbortError)
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
setAppState({ errorMessage: error.message });
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
setAppState({ errorMessage: error.message });
|
||||
}
|
||||
}
|
||||
};
|
||||
return (
|
||||
|
@ -351,8 +351,11 @@ const LayerUI = ({
|
|||
appState,
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
setAppState({ errorMessage: error.message });
|
||||
if (error.name !== "AbortError") {
|
||||
const { width, height } = canvas;
|
||||
console.error(error, { width, height });
|
||||
setAppState({ errorMessage: error.message });
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
|
|
@ -73,7 +73,7 @@ export class TopErrorBoundary extends React.Component<
|
|||
|
||||
private errorSplash() {
|
||||
return (
|
||||
<div className="ErrorSplash">
|
||||
<div className="ErrorSplash excalidraw">
|
||||
<div className="ErrorSplash-messageContainer">
|
||||
<div className="ErrorSplash-paragraph bigger align-center">
|
||||
{t("errorSplash.headingMain_pre")}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue