Storyboard

Plan visual shot sequences with editable frame cards, camera notes, and timing.

Plan a sequence as visual shot cards. Edit frame references, action or dialogue, camera notes, and duration. Drag the six-dot handle to reorder shots, use its arrow keys, or use the rounded icon buttons in each card footer. Every reorder can be undone.

Try the storyboard

Select a shot using its numbered header or focus one of its fields. Open “Frame & camera” to set its image URL, framing notes, and duration in seconds. Earlier and Later change the shot order; Duplicate preserves metadata with a new ID.

Changes stay in this browser session until exported.

Setup

Initialize explicitly after the host is in the document. Storyboard has no additional JavaScript dependency. Your application owns image upload and storage; pass the resulting URL to image.

<div id="shot-board"></div>
import { Storyboard, Toolbar } from "kmaterialize";
import "kmaterialize/dist/css/materialize.css";

// Create a visual sequence.
const board = Storyboard.init(document.querySelector("#shot-board"), {
    shots: [{
        id: "shot-1", title: "Establishing the lake",
        image: "/images/lake.jpg", description: "Hold on the first light.",
        camera: "Wide · locked off", duration: 5
    }]
});
// Initialize the standard Toolbar.
const toolbar = Toolbar.init(document.querySelector("#shot-toolbar"));
// Bind selection-aware shot commands.
board.connectToolbar(toolbar);

Toolbar connection

The demo uses Rodeo-style crazy-button controls: size="small", shape="round", Material icons, and variant="tonal". Related actions use toolbar-group with toolbar-separator between them. Narrow toolbars scroll horizontally.

Each card includes small, round crazy-button footer actions for Earlier, Later, Duplicate, and Delete. Drag the six-dot header handle to insert a card before or after another; the insertion marker previews the position. Focus the handle and press an arrow key to reorder with the keyboard. Earlier and Later remain available on touch devices. Read-only mode disables handles and editing actions.

Use data-editor-command with add, duplicate, remove, up, down, undo, or redo. Connected buttons follow selection, read-only mode, and history availability. A new connection replaces the previous binding.

<div id="shot-toolbar" class="toolbar">
  <div class="toolbar-group">
    <crazy-button data-editor-command="add" type="extended" label="Add shot" size="small" shape="round" depth="flat" icon-text="add_photo_alternate" icon-position="left" variant="tonal" color-secondary="var(--md-sys-color-primary)"></crazy-button>
    <crazy-button data-editor-command="duplicate" type="floating" label="Duplicate" size="small" shape="round" depth="flat" icon-text="content_copy" icon-position="left" variant="tonal" color-secondary="var(--md-sys-color-primary)"></crazy-button>
    <crazy-button data-editor-command="up" type="floating" label="Earlier" size="small" shape="round" depth="flat" icon-text="arrow_upward" icon-position="left" variant="tonal" color-secondary="var(--md-sys-color-primary)"></crazy-button>
    <crazy-button data-editor-command="down" type="floating" label="Later" size="small" shape="round" depth="flat" icon-text="arrow_downward" icon-position="left" variant="tonal" color-secondary="var(--md-sys-color-primary)"></crazy-button>
    <crazy-button data-editor-command="undo" type="floating" label="Undo" size="small" shape="round" depth="flat" icon-text="undo" icon-position="left" variant="tonal" color-secondary="var(--md-sys-color-primary)"></crazy-button>
  </div>
</div>

Shot data & export

Each shot stores an ID, title, image URL, description, camera notes, and a non-negative duration in seconds. Getters return detached copies. Imports validate the entire document before replacement. HTTP(S), relative, blob, and raster data image URLs are supported; blob URLs only last for their creating browser session.

// Append a shot and retain its generated ID.
const id = board.addShot({title: "The landing", duration: 4});
// Update metadata using literal text and an application-owned image URL.
board.updateShot(id, {image: "/images/landing.jpg", camera: "Medium · slow pan"});
// Move the shot to the start of the sequence.
board.moveShot(id, 0);
// Export and restore the complete versioned document.
const json = board.toJSON();
board.fromJSON(json);
{"version":1,"shots":[]}

Methods & options

Method / optionBehavior
getShots() / setShots(shots)Read a detached shot list or replace the complete board as an undoable operation.
addShot(fields?, index?)Insert a shot with defaults; returns a generated ID. Index defaults to the end.
updateShot(id, fields)Validate and update supported metadata without changing the shot ID.
selectShot(id) / getSelectedShot()Select a shot or read a detached selected shot; returns null for an empty board.
duplicateShot(id?) / removeShot(id?)Duplicate or remove the selected shot by default.
moveShot(id, index)Move to a zero-based final position in the sequence.
getTotalDuration()Return total duration in seconds.
toJSON() / fromJSON(json)Export or import a version 1 storyboard document.
undo() / redo()Restore bounded, 100-step shot history.
setReadOnly(boolean)Keep cards selectable while disabling edits and mutation commands. Explicit data loads remain available.
execute(command) / canExecute(command)Run or inspect toolbar commands.
destroy()Restore original host content and remove component listeners and toolbar bindings.
shots / label / readOnly / onChangeInitialization options; onChange(shots) receives detached shot data.
--storyboard-card-width / --storyboard-frame-ratioCSS properties for minimum card width and frame aspect ratio; defaults are 260px and 16 / 9.

storyboardchange bubbles with detail.shots. storyboardselectionchange bubbles with detail.shot. Try window.storyboard in the demo console.