Skip to main content
Commands flow from the driver to Drawdy. Each entry below lists the type, its request req, and its response res.value. A dash means none. Each section also names the permission its commands need; a command issued without it fails with an unauthorized error.

Typing a command

Every command is a member of a discriminated union keyed by type, so you can pull a single command’s request or response out with Extract:

Camera

No permission is required for the commands in this section.
fly-to-rect’s zoom is the maximum zoom; the camera fits the rect. get-viewport-rect returns the visible canvas area in canvas coordinates.

Scene: elements

The commands in this section require the scene permission.
  • line and arrow elements can bind either end to another element instead of a fixed point — see LineBinding. Bindings resolve against elements already on the canvas and ones created earlier in the same add-drawdy-elements batch, so add the targets before the connector.
  • add-drawdy-elements is all or nothing on ids: if any drawdyElementId in the batch already exists on the canvas, nothing is added and the command fails with bad-argument, listing the taken ids in body.existingIds. The user sees an error toast.
  • When updating, meta is merged into the element’s existing meta; transform moves the element to an absolute x/y; width/height resize its bounding rect; every other property is set as given. See UpdateableProperties.
  • Elements that share a groupId form a group: the user selects, moves, resizes and rotates them as one. Set it on creation or later with update-drawdy-elements (null ungroups). Grouped elements are rejected by begin-preview.
  • A frame’s name is its name on creation, frameName when you read it back, and frameName again when you rename it with update-drawdy-elements. Renaming only applies to frames; on any other element the command fails with bad-argument.
  • An element’s frameId is the frame it belongs to: it moves, resizes and is clipped with that frame. Set it on creation or later with update-drawdy-elements (null removes it from the frame). Membership is explicit — dropping a frame on top of an element does not adopt it.
  • query-combined-rect returns the union of the elements’ bounding rects, or null when none of the ids exist.
  • The properties you pass to get-drawdy-elements and query-rect select which fields come back on each SubscribedDrawdyElement.
  • get-drawdy-elements returns the whole scene by default; pass drawdyElementIds to fetch only those elements (ids that don’t exist are silently skipped).

Scene: images

The commands in this section require the scene permission. Read the pixels behind an image element. This is the input side for drivers that transform images (background removal, filters, upscaling): the driver never needs a URL it can fetch itself, which matters because image sources can also be local file urls which the workers can’t access directly.
get-image-source returns the element’s source pixels at native resolution as a Blob (whatever the stored encoding is), not the cropped or scaled rendering. Errors: not-found if the id doesn’t exist, bad-argument if it isn’t an image, runtime if the bytes couldn’t be loaded. To put pixels back on the canvas, add an image element whose source is a blob instead of a url (see DrawdyElementSchema) with command:scene:add-drawdy-elements. Blob-sourced images go through Drawdy’s own image pipeline (processing, local store, upload on cloud boards, one undo step).

Scene: preview elements

The commands in this section require the scene permission. Preview elements are ephemeral: they render but are not committed to the scene, so they never persist, sync, or survive a refresh.
update-drawdy-preview-elements replaces live preview elements in place: each schema is matched to an existing preview by drawdyElementId and swapped for the new geometry and style, keeping its previewId batch and hit-testability. Ids that aren’t a live preview are skipped (updated counts the ones that were). Use it for cheap per-frame adjustments — for example resizing screen-anchored controls on camera:moved-rapid so they hold a constant pixel size — instead of deleting and recreating them. By default preview elements are purely visual: the pointer passes through them and they never appear in scene:pointer or scene:click. Pass hitTestable: true to register them for hit-testing — they then report enter/out/down/up and clicks under their drawdyElementId like any scene element, while staying uncommitted. Pressing a hit-testable preview element does not select it or disturb the current selection, which makes them the right primitive for ephemeral on-canvas controls (handles, quick-add dots, hover targets).

Scene: preview transforms

The commands in this section require the scene permission. A separate lifecycle for animating existing elements without touching undo history or collaboration until you commit. begin-preview snapshots each element’s rest geometry and moves it onto the animation layer; preview-transforms bakes per-tick deltas from that rest pose into real local geometry silently (nothing syncs, enters undo, or echoes as a scene event — but hit-testing and selection follow); end-preview restores non-committed elements, optionally baking final deltas as one undo step and one sync.
  • began is the subset of ids that entered preview. Grouped elements are rejected — their rotation pivot is the group center.
  • In end-preview, elements listed in commits are baked as one undo step; elements absent are restored. dRotation is radians about the element’s bounding-box center.
See PreviewTransform.

Scene: text editing

The commands in this section require the scene permission.
update-text-edit replaces the text of the active text edit in place, keeping the editor open so the user can keep typing. updated is false when no text edit is in progress.

Tools

The commands in this section require the scene permission.
See ToolId, StyleableToolId, and ToolStyleState.

Context menus

The commands in this section require the dom permission.
Subscribe to subscription:context-menu:clicked to know when a menu item is chosen.

DOM

The commands in this section require the dom permission. Drawdy exposes a handful of host-DOM primitives for buttons, floating panels, and window geometry.
  • create-action-button currently accepts svg only; other formats may come later.
  • create-floating-element’s position is a fixed position in the DOM. When barrierDismissible is true, clicking outside dismisses it (same effect as dom:remove-floating-element); the driver is not notified — poll dom:element-rect if you need to know. Defaults to false. asPopover defaults to true (a collision-aware popover near position); set it to false to render at exactly position as a click-through overlay — clicks pass to the canvas — for a cursor-following decoration.
  • move-floating-element repositions an existing floating element by domId — cheaper than remove + recreate, e.g. an overlay that follows the cursor. Fails with not-found when no element has that domId.
  • update-floating-element replaces an existing floating element’s schema and position in place, keeping its barrierDismissible and asPopover from creation. Use it to change what an element shows, such as a status toast going from “Removing background…” to “Done”, instead of removing and recreating it. Fails with not-found when no floating element has that domId.
  • upsert-floating-element updates the floating element with that domId if there is one, and creates it otherwise; created says which happened. On update, barrierDismissible and asPopover keep their values from creation, as with update-floating-element.
  • enter-fullscreen returns entered: false when the browser refused or doesn’t support it; exit-fullscreen returns exited: false when the document wasn’t fullscreen.

Webviews

The commands in this section require the dom permission. A webview is an isolated HTML document Drawdy hosts for you. Two-way messaging goes through the webview API.
  • When keepStateWhenClosed is true, closing the webview only hides it — it stays active and dies with the tab, at the cost of resources. Prefer stateless webviews.
  • post-message returns posted: false when the webview doesn’t exist or isn’t connected yet.
  • Receive messages from the webview by subscribing to subscription:webview:message.

Storage

A key/value store scoped to your driver. kv-storage requires the storage permission.

History

The commands in this section require the scene permission.

Collaboration

The commands in this section require the collaboration permission.
users always has at least one entry: the user running the driver, first in the list, with isSelf: true. On a local board, or a cloud board nobody else has open, that is the only entry. Each other person on the board appears once, even if they have it open in several tabs. cursorPosition is in canvas space. It is null until the user has moved their pointer over the canvas. isHost is true for the board’s owner. On a local board the user running the driver is the host. To follow changes, subscribe to subscription:collaboration:presence-changed.

Auth

No permission is required for the commands in this section.
loggedIn is true when the user running the driver is signed in to a Drawdy account, and false for a guest. Drawdy checks the session each time the command is issued, so the answer reflects a sign-in or sign-out that happened after the driver started. If the session check itself fails, the command fails with a runtime error.

Subscription management

No permission is required for the commands in this section.
Pass the subscriptionId you received when you set the subscription up. See Subscriptions.