API types
Import exported types from codeboard-studio in TypeScript. JavaScript callers use the same object shapes. These declarations describe inputs and returned artwork; they are not instructions to hand-write a project container. Use handles and production methods to edit stored values.
Positions are canvas units; rotation is radians; pressure and opacity use 0–1; pen timestamps use milliseconds; timeline positions use integer frames. Inherited and helper structural types are included for reference; not every helper type is a named package export.
Id
export type Id = string;PageOptions
export interface PageOptions {
limit?: number;
offset?: number;
}ObjectQuery
export interface ObjectQuery extends PageOptions {
name?: string;
kind?: string;
panelId?: Id;
}ObjectSummary
export interface ObjectSummary {
id: Id;
kind: string;
name: string;
panelId?: Id;
parentId?: Id;
}AffineMatrix
export type AffineMatrix = [
number,
number,
number,
number,
number,
number
];ElementPlacement
interface ElementPlacement {
matrix?: AffineMatrix;
}Point
export interface Point {
x: number;
y: number;
pressure?: number;
time?: number;
tiltX?: number;
tiltY?: number;
rotation?: number;
}Transform
export interface Transform {
x: number;
y: number;
scaleX: number;
scaleY: number;
rotation: number;
}Pivot
export interface Pivot {
x: number;
y: number;
}BlendMode
export type BlendMode = "source-over" | "multiply" | "screen" | "overlay" | "darken" | "lighten";TextureKind
export type TextureKind = "none" | "graphite" | "charcoal" | "dry-brush";BrushDynamics
export interface BrushDynamics {
pressureSize: number;
pressureOpacity: number;
speedSize: number;
speedOpacity: number;
tiltShape: number;
pressureSpacing: number;
pressureHardness: number;
rotationJitter: number;
}BrushTip
export type BrushTip = {
kind: "round" | "ellipse" | "chisel" | "rake";
aspect: number;
angle: number;
rotationMode: "fixed" | "stroke" | "stylus";
} | {
kind: "bitmap";
width: number;
height: number;
alpha: number[];
angle: number;
rotationMode: "fixed" | "stroke" | "stylus";
sourceAssetId?: Id;
};BrushPreset
export interface BrushPreset {
provenance?: {
source: string;
author?: string;
license: string;
redistribution: "allowed" | "unknown" | "forbidden";
resourceChecksum: string;
};
paperTexture?: {
width: number;
height: number;
alpha: number[];
scale: number;
strength: number;
};
id: Id;
name: string;
version: number;
tip: BrushTip;
size: number;
opacity: number;
flow: number;
hardness: number;
spacing: number;
taperStart: number;
taperEnd: number;
texture: TextureKind;
textureStrength: number;
dynamics: BrushDynamics;
}RasterStroke
export interface RasterStroke extends ElementPlacement {
/** Global timeline frames: blank at startFrame, complete at endFrame. */
reveal?: {
startFrame: number;
endFrame: number;
};
kind: "raster-stroke";
id: Id;
name?: string;
points: Point[];
brush: BrushPreset;
color: string;
opacity: number;
erase: boolean;
seed: number;
visible: boolean;
}PixelBuffer
export interface PixelBuffer {
width: number;
height: number;
pixels: Uint8Array;
}PixelRegion
export interface PixelRegion {
x: number;
y: number;
width: number;
height: number;
}RasterSurface
/** Straight-alpha, sRGB RGBA8 pixels; matrix maps source pixels into layer coordinates. */
export interface RasterSurface extends PixelBuffer {
kind: "raster-surface";
id: Id;
name?: string;
matrix: AffineMatrix;
opacity: number;
visible: boolean;
}VectorStroke
export interface VectorStroke extends ElementPlacement {
kind: "vector-stroke";
id: Id;
name?: string;
points: Point[];
color: string;
width: number;
opacity: number;
taperStart: number;
taperEnd: number;
pressureSize: number;
closed: boolean;
fill?: string;
visible: boolean;
}VectorFill
export type VectorFill = string | {
kind: "linear";
from: {
x: number;
y: number;
};
to: {
x: number;
y: number;
};
stops: {
offset: number;
color: string;
}[];
} | {
kind: "radial";
from: {
x: number;
y: number;
radius: number;
};
to: {
x: number;
y: number;
radius: number;
};
stops: {
offset: number;
color: string;
}[];
};VectorPath
export interface VectorPath extends ElementPlacement {
kind: "vector-path";
id: Id;
name?: string;
commands: PathCommand[];
fill?: VectorFill;
stroke?: string;
strokeWidth: number;
opacity: number;
visible: boolean;
}TextElement
export interface TextElement extends ElementPlacement {
kind: "text";
id: Id;
name?: string;
x: number;
y: number;
text: string;
color: string;
font: string;
align: "left" | "center" | "right";
opacity: number;
visible: boolean;
}PathCommand
export type PathCommand = {
op: "M" | "L";
x: number;
y: number;
} | {
op: "C";
x1: number;
y1: number;
x2: number;
y2: number;
x: number;
y: number;
} | {
op: "Q";
x1: number;
y1: number;
x: number;
y: number;
} | {
op: "Z";
};DrawingElement
export type DrawingElement = RasterStroke | RasterSurface | VectorStroke | VectorPath | TextElement;NewDrawingElement
export type NewDrawingElement = (Omit<RasterStroke, "id"> & {
id?: Id;
}) | (Omit<RasterSurface, "id"> & {
id?: Id;
}) | (Omit<VectorStroke, "id"> & {
id?: Id;
}) | (Omit<VectorPath, "id"> & {
id?: Id;
}) | (Omit<TextElement, "id"> & {
id?: Id;
});LayerBase
interface LayerBase {
pivot?: Pivot;
componentSource?: {
id: Id;
version: number;
};
id: Id;
name: string;
visible: boolean;
opacity: number;
blendMode: BlendMode;
transform: Transform;
maskLayerId?: Id;
clipToBelow: boolean;
keyframes: LayerKeyframe[];
depth: number;
exposure: {
startFrame: number;
endFrame: number;
} | null;
}DrawingLayer
export interface DrawingLayer extends LayerBase {
kind: "raster" | "vector";
elements: DrawingElement[];
}GroupLayer
export interface GroupLayer extends LayerBase {
kind: "group";
children: Layer[];
drawingSequence?: DrawingExposure[];
twoBoneRig?: TwoBoneRig;
}TwoBoneRig
export interface TwoBoneRig {
elbowId: Id;
upperLength: number;
lowerLength: number;
}DrawingExposure
export interface DrawingExposure {
frame: number;
drawingId: Id | null;
}DrawingInterval
export interface DrawingInterval {
startFrame: number;
endFrame: number;
drawingId: Id | null;
}DrawingNeighbors
export interface DrawingNeighbors {
current: DrawingInterval;
previous: DrawingInterval | null;
next: DrawingInterval | null;
}Layer
export type Layer = DrawingLayer | GroupLayer;LayerChanges
export type LayerChanges = Partial<Pick<Layer, "name" | "visible" | "opacity" | "blendMode" | "transform" | "clipToBelow" | "pivot">> & {
maskLayerId?: Id | null;
};MotionAnnotation
export interface MotionAnnotation {
id: Id;
label: string;
from: Point;
to: Point;
color: string;
}Panel
export interface Panel {
id: Id;
shotId: Id;
number: string;
title: string;
width: number;
height: number;
durationFrames: number;
startFrame: number;
transition: Transition;
status: "working" | "review" | "approved";
action: string;
dialogue: string;
camera: string;
notes: string;
layers: Layer[];
motion: MotionAnnotation[];
revision: number;
}Shot
export interface Shot {
id: Id;
sceneId: Id;
name: string;
panelIds: Id[];
cameraKeyframes: CameraKeyframe[];
}Scene
export interface Scene {
sequenceId: Id;
id: Id;
name: string;
shotIds: Id[];
}Sequence
export interface Sequence {
id: Id;
name: string;
sceneIds: Id[];
}StoryboardDocument
export interface StoryboardDocument {
components: DrawingComponent[];
schemaVersion: 3;
version: number;
id: Id;
title: string;
author?: string;
createdAt: string;
updatedAt: string;
canvas: {
width: number;
height: number;
background: string;
};
seed: number;
frameRate: number;
idCounter: number;
scenes: Scene[];
sequences: Sequence[];
shots: Shot[];
panels: Panel[];
brushes: BrushPreset[];
assets: Asset[];
audioTracks: AudioTrack[];
comments: ReviewComment[];
locks: ProjectLock[];
changes: ChangeEntry[];
metadata: Record<string, string>;
}DrawingComponent
export interface DrawingComponent {
id: Id;
name: string;
version: number;
layers: Layer[];
}ProjectOptions
export interface ProjectOptions {
id?: Id;
title: string;
author?: string;
width?: number;
height?: number;
background?: string;
seed?: number;
frameRate?: number;
}PanelOptions
export interface PanelOptions {
id?: Id;
number?: string;
title?: string;
width?: number;
height?: number;
durationFrames?: number;
action?: string;
dialogue?: string;
camera?: string;
notes?: string;
}LayerOptions
export interface LayerOptions {
pivot?: Pivot;
depth?: number;
exposure?: {
startFrame: number;
endFrame: number;
};
id?: Id;
opacity?: number;
blendMode?: BlendMode;
transform?: Partial<Transform>;
maskLayerId?: Id;
clipToBelow?: boolean;
visible?: boolean;
}StrokeOptions
export interface StrokeOptions {
reveal?: {
startFrame: number;
endFrame: number;
};
id?: Id;
name?: string;
color?: string;
opacity?: number;
erase?: boolean;
seed?: number;
}VectorStrokeOptions
export interface VectorStrokeOptions extends StrokeOptions {
width?: number;
taperStart?: number;
taperEnd?: number;
pressureSize?: number;
closed?: boolean;
fill?: string;
}SheetOptions
export interface SheetOptions {
columns?: number;
rows?: number;
pageWidth?: number;
pageHeight?: number;
margin?: number;
gutter?: number;
captionHeight?: number;
}Transition
export interface Transition {
type: "cut" | "dissolve" | "wipe-left" | "wipe-right";
durationFrames: number;
}Easing
export type Easing = "linear" | "ease-in-out" | "hold" | {
type: "cubic-bezier";
x1: number;
y1: number;
x2: number;
y2: number;
};CameraChannel
export type CameraChannel = "x" | "y" | "zoom" | "rotation";CameraKeyframe
export interface CameraKeyframe {
id: Id;
frame: number;
x?: number;
y?: number;
zoom?: number;
rotation?: number;
easing: Easing;
channelEasing?: Partial<Record<CameraChannel, Easing>>;
}LayerKeyframe
export interface LayerKeyframe {
id: Id;
frame: number;
transform: Partial<Transform>;
opacity?: number;
depth?: number;
easing: Easing;
channelEasing?: Partial<Record<LayerChannel, Easing>>;
}LayerChannel
export type LayerChannel = keyof Transform | "opacity" | "depth";Asset
export interface Asset {
id: Id;
kind: "image" | "audio";
name: string;
path: string;
mimeType: string;
source: "linked" | "managed";
checksum?: string;
}AudioClip
export interface AudioClip {
id: Id;
assetId: Id;
name: string;
startFrame: number;
sourceInFrame: number;
durationFrames: number;
volume: number;
fadeInFrames: number;
fadeOutFrames: number;
}AudioTrack
export interface AudioTrack {
id: Id;
name: string;
muted: boolean;
locked: boolean;
clips: AudioClip[];
}AudioTrackSummary
export interface AudioTrackSummary extends Omit<AudioTrack, "clips"> {
clipCount: number;
}AudioClipQuery
export interface AudioClipQuery extends PageOptions {
frame?: number;
assetId?: Id;
}ReviewComment
export interface ReviewComment {
id: Id;
author: string;
body: string;
status: "open" | "resolved";
anchor: {
panelId?: Id;
layerId?: Id;
elementId?: Id;
frame?: number;
x?: number;
y?: number;
};
createdAt: string;
resolvedAt?: string;
}ProjectLock
export interface ProjectLock {
id: Id;
targetType: "project" | "panel" | "layer";
targetId: Id;
owner: string;
reason: string;
createdAt: string;
}ChangeEntry
export interface ChangeEntry {
id: Id;
version: number;
actor: string;
operation: string;
targetIds: Id[];
timestamp: string;
}ResourceOrigin
export interface ResourceOrigin {
source: string;
author?: string;
license: string;
redistribution: "allowed" | "unknown" | "forbidden";
}BrushResource
export interface BrushResource {
id: string;
name: string;
role: "tip" | "texture";
tip: Extract<BrushTip, {
kind: "bitmap";
}>;
originalWidth: number;
originalHeight: number;
checksum: string;
origin: ResourceOrigin;
}ImportedPreset
export interface ImportedPreset {
name: string;
engine: string;
parameters: Record<string, string>;
resourceIds: string[];
mapped: Partial<Pick<BrushPreset, "spacing" | "opacity" | "flow">>;
missingDependencies: string[];
unsupported: string[];
}BrushImportReport
export interface BrushImportReport {
format: string;
source: ResourceOrigin;
checksum: string;
resources: BrushResource[];
presets: ImportedPreset[];
mapped: string[];
missingDependencies: string[];
unsupported: string[];
warnings: string[];
}ImportOptions
export interface ImportOptions {
origin: ResourceOrigin;
maxTipSize?: number;
maskMode?: "alpha" | "luminance" | "inverse-luminance";
dependencies?: Record<string, Buffer>;
role?: "tip" | "texture";
}CompositionGuides
export interface CompositionGuides {
frame?: number;
thirds?: boolean;
/** Fraction of frame width/height inset on each edge; not a broadcast standard. */
safeInset?: number;
/** Output-frame pixel coordinates, after camera placement. */
horizonY?: number;
vanishingPoints?: readonly {
x: number;
y: number;
}[];
}OnionSkinSample
export interface OnionSkinSample {
panelId: string;
frame?: number;
layerIds?: readonly string[];
tint?: string;
opacity?: number;
}PathSamplingOptions
export interface PathSamplingOptions {
/** Maximum intended spacing in local canvas units; native curve measurement is approximate. */
step?: number;
/** Reject before native sampling if the control-polygon estimate exceeds this allocation budget. */
maxSamples?: number;
}PixelSelection
export interface PixelSelection {
width: number;
height: number;
coverage: Uint8Array;
}PixelColor
export type PixelColor = readonly [
number,
number,
number,
number
];PixelComparison
export interface PixelComparison {
width: number;
height: number;
changedPixels: number;
maxChannelDelta: number;
meanAbsoluteDelta: number;
bounds: PixelRegion | null;
}CoordinateOptions
export interface CoordinateOptions {
frame?: number;
camera?: boolean;
}CoordinateSpace
export interface CoordinateSpace {
panelId: string;
layerId: string;
rootLayerId: string;
targetId: string;
frame: number;
localToFrame: AffineMatrix;
frameToLocal: AffineMatrix | null;
}TwoBoneSolution
export interface TwoBoneSolution {
rootRotation: number;
elbowRotation: number;
elbow: {
x: number;
y: number;
};
end: {
x: number;
y: number;
};
reachable: boolean;
error: number;
}MutationOptions
export interface MutationOptions {
expectedVersion?: number;
}PointLike
type PointLike = Pick<Point, "x" | "y"> & Partial<Omit<Point, "x" | "y">>;PathBooleanOperation
export type PathBooleanOperation = "union" | "intersect" | "difference" | "xor";RenderSource
export type RenderSource = StoryboardProject | StoryboardDocument;PanelRenderSource
export type PanelRenderSource = StoryboardProject | Pick<StoryboardDocument, "canvas" | "panels" | "shots">;ToneOptions
export interface ToneOptions {
frequency?: number;
durationSeconds?: number;
sampleRate?: number;
volume?: number;
attackSeconds?: number;
releaseSeconds?: number;
}Header
type Header = Omit<StoryboardDocument, "panels" | "components" | "changes">;PanelInfo
type PanelInfo = Omit<Panel, "layers" | "motion">;EvaluatedCamera
export interface EvaluatedCamera {
x: number;
y: number;
zoom: number;
rotation: number;
}