Excalidraw
Excalidraw exported as a component to directly embed in your projects
Installation
You can use npm
npm install react react-dom @excalidraw/excalidraw
or via yarn
yarn add react react-dom @excalidraw/excalidraw
After installation you will see a folder excalidraw-assets
in dist
directory which contains the assets needed for this app.
Move the folder excalidraw-assets
to the path where your assets are served. In the example its served from public/excalidraw-assets
Demo
Usage
import React, { useEffect, useState, createRef } from "react";
import Excalidraw from "@excalidraw/excalidraw";
import InitialData from "./initialData";
import "@excalidraw/excalidraw/dist/excalidraw.min.css";
import "@excalidraw/excalidraw/dist/fonts.min.css";
import "./styles.css";
export default function App() {
const excalidrawRef = createRef();
const onChange = (elements, state) => {
console.log(excalidrawRef.current);
console.log("Elements :", elements, "State : ", state);
};
const [dimensions, setDimensions] = useState({
width: window.innerWidth,
height: window.innerHeight,
});
const onResize = () => {
setDimensions({
width: window.innerWidth,
height: window.innerHeight,
});
};
useEffect(() => {
window.addEventListener("resize", onResize);
return () => window.removeEventListener("resize", onResize);
}, []);
const updateScene = () => {
const sceneData = {
elements: [
{
type: "rectangle",
version: 141,
versionNonce: 361174001,
isDeleted: false,
id: "oDVXy8D6rom3H1-LLH2-f",
fillStyle: "hachure",
strokeWidth: 1,
strokeStyle: "solid",
roughness: 1,
opacity: 100,
angle: 0,
x: 100.50390625,
y: 93.67578125,
strokeColor: "#c92a2a",
backgroundColor: "transparent",
width: 186.47265625,
height: 141.9765625,
seed: 1968410350,
groupIds: [],
},
],
appState: {
viewBackgroundColor: "#edf2ff",
},
};
excalidrawRef.current.updateScene(sceneData);
};
const { width, height } = dimensions;
return (
<div className="App">
<button className="update-scene" onClick={updateScene}>
Update Scene
</button>
<button
className="reset-scene"
onClick={() => {
excalidrawRef.current.resetScene();
}}
>
Reset Scene
</button>
<div className="excalidraw-wrapper">
<Excalidraw
ref={excalidrawRef}
width={width}
height={height}
initialData={InitialData}
onChange={onChange}
user={{ name: "Excalidraw User" }}
onPointerUpdate={(payload) => console.log(payload)}
/>
</div>
</div>
);
}
Props
Name | Type | Default | Description |
---|---|---|---|
width |
Number | window.innerWidth |
The width of Excalidraw component |
height |
Number | window.innerHeight |
The height of Excalidraw component |
offsetLeft |
Number | 0 |
left position relative to which Excalidraw should be rendered |
offsetTop |
Number | 0 |
top position relative to which Excalidraw should render |
onChange |
Function | This callback is triggered whenever the component updates due to any change. This callback will receive the excalidraw elements and the current app state. | |
initialData |
ExcalidrawElement[] |
[] | The initial data with which app loads. |
user |
{ name?: string } |
User details. The name refers to the name of the user to be shown | |
excalidrawRef |
createRef or callbackRef or { current: { readyPromise: resolvablePromise } } |
Ref to be passed to Excalidraw | |
onCollabButtonClick |
Function | Callback to be triggered when the collab button is clicked | |
isCollaborating |
boolean |
This implies if the app is in collaboration mode | |
onPointerUpdate |
Function | Callback triggered when mouse pointer is updated. |
width
This props defines the width
of the Excalidraw component. Defaults to window.innerWidth
if not passed.
height
This props defines the height
of the Excalidraw component. Defaults to window.innerHeight
if not passed.
offsetLeft
This prop defines left
position relative to which Excalidraw should be rendered. Defaults to 0
if not passed.
offsetTop
This prop defines top
position relative to which Excalidraw should be rendered. Defaults to 0
if not passed.
onChange
Every time component updates, this callback if passed will get triggered and has the below signature.
(excalidrawElements, appState) => void;
1.excalidrawElements
: Array of excalidrawElements in the scene.
2.appState
: AppState of the scene
Here you can try saving the data to your backend or local storage for example.
initialData
This helps to load Excalidraw with initialData
.
It must be an object or a promise which resolves to an object containing the below optional fields.
name | type |
---|---|
elements | ExcalidrawElement [] |
appState | AppState |
{
"elements": [
{
"type": "rectangle",
"version": 141,
"versionNonce": 361174001,
"isDeleted": false,
"id": "oDVXy8D6rom3H1-LLH2-f",
"fillStyle": "hachure",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"angle": 0,
"x": 100.50390625,
"y": 93.67578125,
"strokeColor": "#000000",
"backgroundColor": "transparent",
"width": 186.47265625,
"height": 141.9765625,
"seed": 1968410350,
"groupIds": []
}
],
"appState": { "zenModeEnabled": true, "viewBackgroundColor": "#AFEEEE" }
}
You might want to use this when you want to load excalidraw with some initial elements and app state.
user
This is the user name which shows during collaboration. Defaults to {name: ''}
.
excalidrawRef
You can pass a ref when you want to access some excalidraw API's. We expose the below API's
API | signature | Usage |
---|---|---|
ready | boolean |
This is set to true once Excalidraw is rendered |
readyPromise | resolvablePromise | This promise will be resolved with the api once excalidraw has rendered. This will be helpful when you want do some action on the host app once this promise resolves. For this to work you will have to pass ref as shown here |
updateScene | (sceneData)) => void |
updates the scene with the sceneData |
resetScene | ({ resetLoadingState: boolean }) => void |
Resets the scene. If resetLoadingState is passed as true then it will also force set the loading state to false. |
getSceneElementsIncludingDeleted | () => ExcalidrawElement [] |
Returns all the elements including the deleted in the scene |
getSceneElements | () => ExcalidrawElement [] |
Returns all the elements excluding the deleted in the scene |
history | { clear: () => void } |
This is the history API. history.clear() will clear the history |
setScrollToCenter | (ExcalidrawElement[]) => void |
sets the elements to center |
readyPromise
const excalidrawRef = { current: { readyPromise: resolvablePromise}}
onCollabButtonClick
This callback is triggered when clicked on the collab button in excalidraw
isCollaborating
This props implies if the app is in collaboration mode
onPointerUpdate
This callback is triggered when mouse pointer is updated
({ x, y }, button, pointersMap}) => void;
1.{x, y}
: Pointer coordinates
2.button
: The position of the button. This will be one of ["down", "up"]
3.pointersMap
: pointers map
of the scene