The core and editor packages
The framework-free engine (@opendrawjs/core) and editor (@opendrawjs/editor): scene document, history, export, commands and persistence.
@opendrawjs/core
The engine has no framework or DOM requirement. OpenDrawDocument holds the elements, the app state and history; every change goes through it, so undo, redo and change events always agree. Elements are plain, immutable objects, the shapes of the whiteboard (rectangle, diamond, ellipse, arrow, line, freedraw, text, image, frame, sticky note).
import {
OpenDrawDocument,
newRectangleElement,
exportToSvg,
parseFile,
serializeToJSON,
} from '@opendrawjs/core'
const doc = new OpenDrawDocument()
doc.addElement(newRectangleElement({ x: 0, y: 0, width: 160, height: 90 }))
// Every write is one undoable step; listeners hear each change.
doc.subscribe((state) => console.log(state.elements.length))
doc.undo()
// Export without a browser canvas:
const svg = exportToSvg(doc.getElements(), '#ffffff', { padding: 16 })
const json = serializeToJSON(doc.serialize())
const restored = parseFile(JSON.parse(json))- Factories:
newRectangleElement,newLinearElement,newTextElement,newStickyNoteElement,newFrameElement, … - Export:
exportToSvg,exportToDataURL(PNG), with padding, scale, theme and background options. - Files:
parseFilevalidates untrusted JSON and drops malformed elements;serializeToJSONwrites the.opendrawformat. - Rendering:
renderSceneandrenderOverlaypaint onto any 2D canvas context.
@opendrawjs/editor
The whole interactive editor without a UI framework: createEditor() returns a controller (state getters plus commands), and mountCanvas() wires every gesture, shortcut, the text editor and rendering onto three DOM elements. subscribe() announces each change, that is all a UI layer needs.
import { createEditor, mountCanvas, runAction } from '@opendrawjs/editor'
const editor = createEditor({ appState: { theme: 'light' } })
const session = mountCanvas(editor, {
host, // a positioned element the canvases fill
staticCanvas, // the scene
overlayCanvas, // selection chrome, stacked on top
})
editor.subscribe((ed) => renderMyToolbar(ed.activeTool, ed.canUndo))
editor.setActiveTool('rectangle')
runAction(editor, 'undo')
// later
session.dispose()- Tools:
TOOLSlists every tool with its icon name, label and keys, render your toolbar from it. - Actions:
ACTIONS/runAction/isActionEnabled, the commands behind menus and shortcuts, with labels and key hints. - Icons: actions and tools name a semantic
IconName; your adapter maps each name to any icon set.
Persistence
import { attachScenePersistence } from '@opendrawjs/editor'
const persistence = attachScenePersistence(editor, { storageKey: 'my-board' })
persistence.restore() // load the saved scene, if any
// ...
persistence.dispose() // flushes the last save