ef-workbench is a CSS grid shell for a composition. Put an ef-timegroup (or an ef-configuration or ef-canvas) in its default slot and the workbench creates the hierarchy, fitted canvas, timeline, transport, zoom, theme, and export controls around it. Use toolbar-start and toolbar-end for additions to the built-in toolbar. Pan/zoom state and theme preference are persisted to localStorage.
<ef-workbench style="width: 100%; height: 100vh; display: block;">
<span slot="toolbar-start">My editor</span>
<button slot="toolbar-end" type="button">Save</button>
<ef-timegroup id="root" mode="fixed" duration="10s" class="w-[1920px] h-[1080px] bg-slate-900">
<!-- composition content -->
</ef-timegroup>
</ef-workbench>The workbench discovers the root timegroup and wires its internal hierarchy and timeline to #root. The timeline includes its ruler, rows, playhead, and zoom controls; playback controls live in the workbench transport bar.
Alternatively, set the workbench attribute directly on a root ef-timegroup to auto-wrap:
<ef-timegroup workbench mode="fixed" duration="10s" class="w-[1920px] h-[1080px]">
<!-- workbench is created automatically -->
</ef-timegroup>Set the preview mode as a property when you need the canvas comparison view:
document.querySelector("ef-workbench").previewMode = "canvas";Preview modes:
| Mode | Description |
|---|---|
dom | Live DOM rendering through the fitted composition slot. |
canvas | A continuously repainted canvas view of the live composition. |
Attributes
rendering
- React prop
rendering- Type
boolean- Default
false- Description
- True while a native render host (
EF_FRAMEGEN) owns frame capture — collapses the workbench to just the bare.stage(no toolbar/sidebar/ transport/timeline chrome).
resolution
- React prop
resolution- Type
string- Default
"1920x1080"- Description
- Composition's true rendered resolution, as
"WIDTHxHEIGHT"(e.g."1920x1080","1080x1920").
Slots
| Slot | Description |
|---|---|
| (default) | This slot holds the composition. The composition is a light-DOM <ef-configuration>, <ef-canvas>, or <ef-timegroup> element, and the workbench auto-wraps it as needed. |
toolbar-end | Extension point at the right end of the header toolbar, after the built-in theme/export controls. Assign elements with slot="toolbar-end". |
toolbar-start | Extension point at the left end of the header toolbar. Assign elements with slot="toolbar-start". They stay light-DOM children of <ef-workbench> (so page CSS and the theme's --ef-color-* custom properties still reach them), and hide with the rest of the editor chrome in render mode. |
CSS Custom Properties
| Property | Default | Description |
|---|---|---|
--ef-color-danger | #dc2626 | Color for destructive actions and error states. |
--ef-color-hover | #333 | Hover background color for toolbar and zoom buttons. |
--ef-color-success | #059669 | Color for success states in the export popover. |
--ef-color-text-subtle | var(--ef-color-text-muted) | Secondary text color for export popover labels. |
--ef-color-warning | #d97706 | Color for warning and cancelled states. |
--ef-workbench-sidebar-width | 260px | Width of the left hierarchy panel. |
--ef-workbench-timeline-height | 260px | Height of the bottom timeline panel. |
Events
| Event | Detail | Description |
|---|---|---|
export-complete | {
/** Omitted when a custom `target` was supplied. */
buffer?: ArrayBuffer;
mimeType: string;
} | This event fires once, when an export finishes successfully, with a RenderTimegroupToVideoResult detail value. |
export-error | — | This event fires if an export throws an error. Its detail value holds the thrown error. |
export-progress | {
frame: number;
totalFrames: number;
/** Composition time (seconds) just rendered. */
time: number;
/** Total exported duration (seconds), i.e. `to - from`. */
duration: number;
/** Wall-clock milliseconds since the render started. */
elapsedMs: number;
/**
* Estimated wall-clock milliseconds remaining, from the mean per-frame
* cost so far. `0` before the first frame lands.
*/
estimatedRemainingMs: number;
/**
* Composition seconds rendered per wall-clock second. Above `1` means
* the export is running faster than realtime. `0` before the first
* frame lands.
*/
speedMultiplier: number;
/**
* Live thumbnail of the last captured frame, redrawn in place every
* {@link RenderTimegroupToVideoOptions.progressPreviewInterval} frames.
* The same canvas instance is passed on every progress callback — embed
* it directly (e.g. append it to a status popover) rather than copying.
* Omitted when `progressPreviewInterval` is `0`.
*/
framePreviewCanvas?: HTMLCanvasElement;
} | This event fires repeatedly during an export, with a RenderProgress detail value that holds the frame count and the total frame count. |
export-start | — | This event fires once, when EFWorkbenchElement#exportVideo begins. |
Methods
| Method | Description |
|---|---|
exportVideo(options?: RenderTimegroupToVideoOptions): Promise<RenderTimegroupToVideoResult> | Renders the composition to an MP4, through an offscreen
createRenderClone and renderTimegroupToVideo call. By
default it renders at this workbench's resolution. The live,
interactive preview stays untouched. It dispatches bubbling
export-start, export-progress, export-complete, and
export-error events, so surrounding UI can show progress with no
polling.
This method returns the encoded buffer. The toolbar Export button
also downloads the buffer as an .mp4 file. See
#runToolbarExport for that download logic. |