mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
feat: export exportToClipboard util from package (#5103)
* feat: export copyToClipboard from package * use promise constructor for better browser supprt * add type to exportToClipboard * update docs * use json instead of text and use selected element in actionCopy * pass `files` in example `exportToClipboard` * fix bad access Co-authored-by: dwelle <luzar.david@gmail.com>
This commit is contained in:
parent
aee1e2451e
commit
6a0f800716
7 changed files with 111 additions and 18 deletions
|
@ -17,6 +17,7 @@ Please add the latest change on the top under the correct section.
|
|||
|
||||
#### Features
|
||||
|
||||
- Expose util `exportToClipboard`[https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#exportToClipboard] which allows to copy the scene contents to clipboard as `svg`, `png` or `json` [#5103](https://github.com/excalidraw/excalidraw/pull/5103).
|
||||
- Expose `window.EXCALIDRAW_EXPORT_SOURCE` which you can use to overwrite the `source` field in exported data [#5095](https://github.com/excalidraw/excalidraw/pull/5095).
|
||||
- The `exportToBlob` utility now supports the `exportEmbedScene` option when generating a png image [#5047](https://github.com/excalidraw/excalidraw/pull/5047).
|
||||
- Exported [`restoreLibraryItems`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#restoreLibraryItems) API [#4995](https://github.com/excalidraw/excalidraw/pull/4995).
|
||||
|
|
|
@ -857,7 +857,7 @@ This function returns the canvas with the exported elements, appState and dimens
|
|||
|
||||
<pre>
|
||||
exportToBlob(
|
||||
opts: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/packages/utils.ts#L10">ExportOpts</a> & {
|
||||
opts: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/packages/utils.ts#L14">ExportOpts</a> & {
|
||||
mimeType?: string,
|
||||
quality?: number;
|
||||
})
|
||||
|
@ -900,6 +900,34 @@ exportToSvg({
|
|||
|
||||
This function returns a promise which resolves to svg of the exported drawing.
|
||||
|
||||
#### `exportToClipboard`
|
||||
|
||||
**_Signature_**
|
||||
|
||||
<pre>
|
||||
exportToClipboard(
|
||||
opts: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/packages/utils.ts#L14">ExportOpts</a> & {
|
||||
mimeType?: string,
|
||||
quality?: number;
|
||||
type: 'png' | 'svg' |'json'
|
||||
})
|
||||
</pre>
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| opts | | | This param is same as the params passed to `exportToCanvas`. You can refer to [`exportToCanvas`](#exportToCanvas). |
|
||||
| mimeType | string | "image/png" | Indicates the image format, this will be used when exporting as `png`. |
|
||||
| quality | number | 0.92 | A value between 0 and 1 indicating the [image quality](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob#parameters). Applies only to `image/jpeg`/`image/webp` MIME types. This will be used when exporting as `png`. |
|
||||
| type | 'png' | 'svg' | 'json' | | This determines the format to which the scene data should be exported. |
|
||||
|
||||
**How to use**
|
||||
|
||||
```js
|
||||
import { exportToClipboard } from "@excalidraw/excalidraw-next";
|
||||
```
|
||||
|
||||
Copies the scene data in the specified format (determined by `type`) to clipboard.
|
||||
|
||||
##### Additional attributes of appState for `export\*` APIs
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|
|
|
@ -10,8 +10,13 @@ import { MIME_TYPES } from "../../../constants";
|
|||
// This is so that we use the bundled excalidraw.development.js file instead
|
||||
// of the actual source code
|
||||
|
||||
const { exportToCanvas, exportToSvg, exportToBlob, Excalidraw } =
|
||||
window.ExcalidrawLib;
|
||||
const {
|
||||
exportToCanvas,
|
||||
exportToSvg,
|
||||
exportToBlob,
|
||||
exportToClipboard,
|
||||
Excalidraw,
|
||||
} = window.ExcalidrawLib;
|
||||
const resolvablePromise = () => {
|
||||
let resolve;
|
||||
let reject;
|
||||
|
@ -141,6 +146,15 @@ export default function App() {
|
|||
}
|
||||
}, []);
|
||||
|
||||
const onCopy = async (type) => {
|
||||
await exportToClipboard({
|
||||
elements: excalidrawRef.current.getSceneElements(),
|
||||
appState: excalidrawRef.current.getAppState(),
|
||||
files: excalidrawRef.current.getFiles(),
|
||||
type,
|
||||
});
|
||||
window.alert(`Copied to clipboard as ${type} sucessfully`);
|
||||
};
|
||||
return (
|
||||
<div className="App">
|
||||
<h1> Excalidraw Example</h1>
|
||||
|
@ -175,6 +189,7 @@ export default function App() {
|
|||
>
|
||||
Update Library
|
||||
</button>
|
||||
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
|
@ -213,6 +228,17 @@ export default function App() {
|
|||
/>
|
||||
Switch to Dark Theme
|
||||
</label>
|
||||
<div>
|
||||
<button onClick={onCopy.bind(null, "png")}>
|
||||
Copy to Clipboard as PNG
|
||||
</button>
|
||||
<button onClick={onCopy.bind(null, "svg")}>
|
||||
Copy to Clipboard as SVG
|
||||
</button>
|
||||
<button onClick={onCopy.bind(null, "json")}>
|
||||
Copy to Clipboard as JSON
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="excalidraw-wrapper">
|
||||
<Excalidraw
|
||||
|
|
|
@ -197,6 +197,7 @@ export {
|
|||
loadLibraryFromBlob,
|
||||
loadFromBlob,
|
||||
getFreeDrawSvgPath,
|
||||
exportToClipboard,
|
||||
} from "../../packages/utils";
|
||||
export { isLinearElement } from "../../element/typeChecks";
|
||||
|
||||
|
|
|
@ -10,6 +10,11 @@ import { restore } from "../data/restore";
|
|||
import { MIME_TYPES } from "../constants";
|
||||
import { encodePngMetadata } from "../data/image";
|
||||
import { serializeAsJSON } from "../data/json";
|
||||
import {
|
||||
copyBlobToClipboardAsPng,
|
||||
copyTextToSystemClipboard,
|
||||
copyToClipboard,
|
||||
} from "../clipboard";
|
||||
|
||||
type ExportOpts = {
|
||||
elements: readonly NonDeleted<ExcalidrawElement>[];
|
||||
|
@ -81,7 +86,7 @@ export const exportToBlob = async (
|
|||
mimeType?: string;
|
||||
quality?: number;
|
||||
},
|
||||
): Promise<Blob | null> => {
|
||||
): Promise<Blob> => {
|
||||
let { mimeType = MIME_TYPES.png, quality } = opts;
|
||||
|
||||
if (mimeType === MIME_TYPES.png && typeof quality === "number") {
|
||||
|
@ -107,9 +112,12 @@ export const exportToBlob = async (
|
|||
|
||||
quality = quality ? quality : /image\/jpe?g/.test(mimeType) ? 0.92 : 0.8;
|
||||
|
||||
return new Promise((resolve) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
canvas.toBlob(
|
||||
async (blob: Blob | null) => {
|
||||
async (blob) => {
|
||||
if (!blob) {
|
||||
return reject(new Error("couldn't export to blob"));
|
||||
}
|
||||
if (
|
||||
blob &&
|
||||
mimeType === MIME_TYPES.png &&
|
||||
|
@ -156,6 +164,33 @@ export const exportToSvg = async ({
|
|||
);
|
||||
};
|
||||
|
||||
export const exportToClipboard = async (
|
||||
opts: ExportOpts & {
|
||||
mimeType?: string;
|
||||
quality?: number;
|
||||
type: "png" | "svg" | "json";
|
||||
},
|
||||
) => {
|
||||
if (opts.type === "svg") {
|
||||
const svg = await exportToSvg(opts);
|
||||
await copyTextToSystemClipboard(svg.outerHTML);
|
||||
} else if (opts.type === "png") {
|
||||
await copyBlobToClipboardAsPng(exportToBlob(opts));
|
||||
} else if (opts.type === "json") {
|
||||
const appState = {
|
||||
offsetTop: 0,
|
||||
offsetLeft: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
...getDefaultAppState(),
|
||||
...opts.appState,
|
||||
};
|
||||
await copyToClipboard(opts.elements, appState, opts.files);
|
||||
} else {
|
||||
throw new Error("Invalid export type");
|
||||
}
|
||||
};
|
||||
|
||||
export { serializeAsJSON, serializeLibraryAsJSON } from "../data/json";
|
||||
export { loadFromBlob, loadLibraryFromBlob } from "../data/blob";
|
||||
export { getFreeDrawSvgPath } from "../renderer/renderElement";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue