@pixerate/flair 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/LICENSE +21 -0
- package/README.md +254 -2
- package/dist/catalog/index.d.ts +74 -0
- package/dist/catalog/index.js +47 -0
- package/dist/catalog/index.js.map +1 -0
- package/dist/chunk-36DTNSHU.js +160 -0
- package/dist/chunk-36DTNSHU.js.map +1 -0
- package/dist/chunk-3FAUZOGL.js +331 -0
- package/dist/chunk-3FAUZOGL.js.map +1 -0
- package/dist/chunk-CFCLT2XL.js +1 -0
- package/dist/chunk-CFCLT2XL.js.map +1 -0
- package/dist/chunk-EHDJ3CPJ.js +327 -0
- package/dist/chunk-EHDJ3CPJ.js.map +1 -0
- package/dist/chunk-G5FNZDTA.js +536 -0
- package/dist/chunk-G5FNZDTA.js.map +1 -0
- package/dist/chunk-HKXOHRCD.js +763 -0
- package/dist/chunk-HKXOHRCD.js.map +1 -0
- package/dist/chunk-J55UBNAT.js +164 -0
- package/dist/chunk-J55UBNAT.js.map +1 -0
- package/dist/chunk-JWZCPMFG.js +2074 -0
- package/dist/chunk-JWZCPMFG.js.map +1 -0
- package/dist/chunk-MWVTQFV5.js +1894 -0
- package/dist/chunk-MWVTQFV5.js.map +1 -0
- package/dist/chunk-UQQNZSYL.js +594 -0
- package/dist/chunk-UQQNZSYL.js.map +1 -0
- package/dist/chunk-WMZQCUFJ.js +73 -0
- package/dist/chunk-WMZQCUFJ.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +331 -0
- package/dist/cli.js.map +1 -0
- package/dist/clock-BhdXWH-n.d.ts +47 -0
- package/dist/controls-DdXMbovi.d.ts +97 -0
- package/dist/editor/index.d.ts +413 -0
- package/dist/editor/index.js +1009 -0
- package/dist/editor/index.js.map +1 -0
- package/dist/export-FEBPEEO7.js +22 -0
- package/dist/export-FEBPEEO7.js.map +1 -0
- package/dist/index.d.ts +1431 -0
- package/dist/index.js +1263 -0
- package/dist/index.js.map +1 -0
- package/dist/motion-D0TVv2CF.d.ts +148 -0
- package/dist/node.d.ts +24 -0
- package/dist/node.js +10 -0
- package/dist/node.js.map +1 -0
- package/dist/recorder-WJTWMEQN.js +10 -0
- package/dist/recorder-WJTWMEQN.js.map +1 -0
- package/dist/renderer-Oyynz-fs.d.ts +293 -0
- package/dist/types-CkKkavvB.d.ts +71 -0
- package/dist/vector/index.d.ts +83 -0
- package/dist/vector/index.js +39 -0
- package/dist/vector/index.js.map +1 -0
- package/package.json +96 -4
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1431 @@
|
|
|
1
|
+
import { C as ControlValue, a as ControlDef } from './controls-DdXMbovi.js';
|
|
2
|
+
export { c as ControlCheck, b as ControlType, T as TextureSettings, d as checkControlValue, e as coerceControlValue, f as componentCount, g as controlValue, h as describeValue, i as hexToRgb, j as humanise, k as imageUrls, l as isImageUrl, p as parseControls, r as rgbToHex } from './controls-DdXMbovi.js';
|
|
3
|
+
export { B as BUILTIN_UNIFORMS, C as CompileError, b as CompileResult, a as CompileStatus, c as CompiledShader, F as FrameState, I as ImageLoadError, R as RendererStats, S as SVG_EDGE, d as ShaderCompileError, e as ShaderRenderer, T as TextureCache, f as TextureSource, V as VERTEX_SOURCE, g as applyTextureSettings, h as compileShader, i as createContext, j as drawFrame, k as formatCompileError, l as isSvgUrl, m as loadImage, p as parseCompileLog, n as preloadImages, r as releaseImages, o as resetGlCaches, s as sizeSvg, w as wrapSource } from './renderer-Oyynz-fs.js';
|
|
4
|
+
import { C as Clock } from './clock-BhdXWH-n.js';
|
|
5
|
+
export { M as ManualClock, j as jitter, p as pageHidden, r as realClock } from './clock-BhdXWH-n.js';
|
|
6
|
+
export { D as DataKey, E as EASES, a as EaseName, b as STEP_MS, c as SVG_PICTURE, d as SvgAnimation, e as SvgBox, f as SvgElementFrame, S as SvgMotion, g as defaultDataKey, l as lerpAttr, h as lerpData, s as stepData, i as stepProgress, j as stepStart, k as svgFrame, m as svgMotionIssues, n as svgOpeningTag } from './motion-D0TVv2CF.js';
|
|
7
|
+
export { SvgPlayer, SvgPlayerOptions, SvgView, SvgViewOptions, parseSvg, svgDuration, svgView } from './vector/index.js';
|
|
8
|
+
|
|
9
|
+
/** Controls a registered thumbnail. */
|
|
10
|
+
interface ThumbnailHandle {
|
|
11
|
+
/** Shows another source or other values. A new source is recompiled; new values only redraw. */
|
|
12
|
+
update(source: string, values?: Record<string, ControlValue>): void;
|
|
13
|
+
/** With reduced motion, a hovered thumbnail animates and the others hold a still frame. */
|
|
14
|
+
setHovered(hovered: boolean): void;
|
|
15
|
+
/** Stops drawing into the canvas and frees its program. */
|
|
16
|
+
dispose(): void;
|
|
17
|
+
}
|
|
18
|
+
interface ThumbnailPoolOptions {
|
|
19
|
+
/** Size of the shared render canvas (default 480 × 270). Thumbnails are drawn at most this large, then scaled. */
|
|
20
|
+
renderWidth?: number;
|
|
21
|
+
renderHeight?: number;
|
|
22
|
+
/** Animation rate (default 30). */
|
|
23
|
+
fps?: number;
|
|
24
|
+
/** `iTime` of the still frame shown with reduced motion (default 2). */
|
|
25
|
+
stillTime?: number;
|
|
26
|
+
/** Hold still frames unless hovered (default: the `prefers-reduced-motion` media query). */
|
|
27
|
+
reducedMotion?: boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Animated thumbnails from a single WebGL context. Browsers cap live WebGL
|
|
31
|
+
* contexts (about 16), so a gallery cannot give every card its own: the pool
|
|
32
|
+
* renders each visible thumbnail in turn on one hidden canvas and copies the
|
|
33
|
+
* frame into the thumbnail's own 2D canvas, cropped to its aspect ratio like
|
|
34
|
+
* `object-fit: cover`. Thumbnails off screen (by `IntersectionObserver`) cost
|
|
35
|
+
* nothing, and programs compile once per source.
|
|
36
|
+
*
|
|
37
|
+
* Nothing is created until the first `register`.
|
|
38
|
+
*/
|
|
39
|
+
declare class ThumbnailPool {
|
|
40
|
+
private readonly renderWidth;
|
|
41
|
+
private readonly renderHeight;
|
|
42
|
+
private readonly interval;
|
|
43
|
+
private readonly fps;
|
|
44
|
+
private readonly stillTime;
|
|
45
|
+
private readonly reducedMotion;
|
|
46
|
+
private readonly entries;
|
|
47
|
+
private readonly byCanvas;
|
|
48
|
+
private observer;
|
|
49
|
+
private glCanvas;
|
|
50
|
+
private gl;
|
|
51
|
+
private textures;
|
|
52
|
+
private raf;
|
|
53
|
+
private last;
|
|
54
|
+
private start;
|
|
55
|
+
constructor(options?: ThumbnailPoolOptions);
|
|
56
|
+
/**
|
|
57
|
+
* Starts drawing `source` into `canvas`, which should be sized with CSS; its
|
|
58
|
+
* drawing buffer follows its CSS size and the device pixel ratio (up to 2).
|
|
59
|
+
* `onStatus` hears whether the source compiled (and `false` without WebGL2).
|
|
60
|
+
*/
|
|
61
|
+
register(canvas: HTMLCanvasElement, source: string, values?: Record<string, ControlValue>, onStatus?: (ok: boolean) => void): ThumbnailHandle;
|
|
62
|
+
/** The number of registered thumbnails. */
|
|
63
|
+
get size(): number;
|
|
64
|
+
private intersection;
|
|
65
|
+
private context;
|
|
66
|
+
private textureCache;
|
|
67
|
+
/** Frees the textures no thumbnail shows any more. */
|
|
68
|
+
private retainTextures;
|
|
69
|
+
private release;
|
|
70
|
+
private compile;
|
|
71
|
+
private renderEntry;
|
|
72
|
+
private schedule;
|
|
73
|
+
private tick;
|
|
74
|
+
}
|
|
75
|
+
/** The pool `registerThumbnail` uses, created on first use. */
|
|
76
|
+
declare function sharedThumbnailPool(): ThumbnailPool;
|
|
77
|
+
/** Registers a thumbnail with the shared pool. See {@link ThumbnailPool.register}. */
|
|
78
|
+
declare function registerThumbnail(canvas: HTMLCanvasElement, source: string, values?: Record<string, ControlValue>, onStatus?: (ok: boolean) => void): ThumbnailHandle;
|
|
79
|
+
|
|
80
|
+
interface ShaderFramesOptions {
|
|
81
|
+
source: string;
|
|
82
|
+
values?: Record<string, ControlValue>;
|
|
83
|
+
width: number;
|
|
84
|
+
height: number;
|
|
85
|
+
/** Draw on this canvas instead of a new, detached one. It is resized to `width` × `height`. */
|
|
86
|
+
canvas?: HTMLCanvasElement;
|
|
87
|
+
}
|
|
88
|
+
interface RenderOptions {
|
|
89
|
+
/** `iFrame` (default: the number of frames rendered so far). */
|
|
90
|
+
frame?: number;
|
|
91
|
+
/** `iTimeDelta` in seconds (default: the time since the previous `render`, else 0). */
|
|
92
|
+
delta?: number;
|
|
93
|
+
/** `iMouse` (default: all zero, as on a page nobody has touched). */
|
|
94
|
+
mouse?: [number, number, number, number];
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Renders a shader at exact times you choose, off screen. There is no
|
|
98
|
+
* animation loop and no clock: frame `n` of a recording at `fps` is
|
|
99
|
+
* `render(start + n / fps)`, so the output is the same on any machine. It
|
|
100
|
+
* suits recorders, video pipelines and anything else stepped by its own
|
|
101
|
+
* clock. The constructor throws a {@link ShaderCompileError} when the source
|
|
102
|
+
* does not compile.
|
|
103
|
+
*
|
|
104
|
+
* Image controls load in the background: `await frames.ready()` before the
|
|
105
|
+
* first `render`, or the frames show black where the images go.
|
|
106
|
+
*/
|
|
107
|
+
declare class ShaderFrames {
|
|
108
|
+
readonly canvas: HTMLCanvasElement;
|
|
109
|
+
readonly width: number;
|
|
110
|
+
readonly height: number;
|
|
111
|
+
readonly controls: ControlDef[];
|
|
112
|
+
private gl;
|
|
113
|
+
private shader;
|
|
114
|
+
private textures;
|
|
115
|
+
private values;
|
|
116
|
+
private rendered;
|
|
117
|
+
private lastTime;
|
|
118
|
+
private pixels;
|
|
119
|
+
constructor(options: ShaderFramesOptions);
|
|
120
|
+
/** Changes control values for the frames that follow. */
|
|
121
|
+
setValues(values: Record<string, ControlValue> | undefined): void;
|
|
122
|
+
/**
|
|
123
|
+
* Settles once every image the controls show has loaded. Rejects with an
|
|
124
|
+
* {@link ImageLoadError} when one cannot be.
|
|
125
|
+
*/
|
|
126
|
+
ready(): Promise<void>;
|
|
127
|
+
/** Draws the frame at `time` seconds onto `canvas`. */
|
|
128
|
+
render(time: number, options?: RenderOptions): void;
|
|
129
|
+
/**
|
|
130
|
+
* The last rendered frame as RGBA bytes, rows top down (as in `ImageData`;
|
|
131
|
+
* WebGL itself reads bottom up). Pass `out` to reuse a buffer of
|
|
132
|
+
* `width * height * 4` bytes.
|
|
133
|
+
*/
|
|
134
|
+
readPixels(out?: Uint8Array | Uint8ClampedArray): Uint8Array | Uint8ClampedArray;
|
|
135
|
+
/** Releases the GL context now rather than at garbage collection (browsers cap live contexts). */
|
|
136
|
+
dispose(): void;
|
|
137
|
+
private syncTextures;
|
|
138
|
+
private context;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
interface GifOptions {
|
|
142
|
+
source: string;
|
|
143
|
+
values?: Record<string, ControlValue>;
|
|
144
|
+
width: number;
|
|
145
|
+
height: number;
|
|
146
|
+
/** Frames per second. GIF delays are whole hundredths of a second, so 10, 20, 25 and 50 play back exactly. */
|
|
147
|
+
fps: number;
|
|
148
|
+
/** Seconds of animation to record. */
|
|
149
|
+
duration: number;
|
|
150
|
+
/** `iTime` of the first frame (default 0). */
|
|
151
|
+
start?: number;
|
|
152
|
+
/** Called after each frame with the frames done and the total. */
|
|
153
|
+
onProgress?: (done: number, total: number) => void;
|
|
154
|
+
/** Aborting rejects with an `AbortError` `DOMException`. */
|
|
155
|
+
signal?: AbortSignal;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Records a shader as an animated GIF that loops forever. Frames are rendered
|
|
159
|
+
* off screen at exact time steps (`start + i / fps`), so the result is smooth
|
|
160
|
+
* whatever the page's frame rate, and nothing on screen is disturbed. Each
|
|
161
|
+
* frame gets its own 256-colour palette. The encoder,
|
|
162
|
+
* [gifenc](https://github.com/mattdesl/gifenc), is loaded on first use.
|
|
163
|
+
*
|
|
164
|
+
* Image controls are loaded before the first frame. Rejects with a
|
|
165
|
+
* `ShaderCompileError` when the source does not compile, and an
|
|
166
|
+
* `ImageLoadError` when an image cannot be loaded.
|
|
167
|
+
*/
|
|
168
|
+
declare function recordGif(options: GifOptions): Promise<Blob>;
|
|
169
|
+
|
|
170
|
+
interface StandaloneOptions {
|
|
171
|
+
/** The comment at the top of the script, saying where the page came from. */
|
|
172
|
+
credit?: string;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* A self-contained HTML page that runs the shader full-window, with the
|
|
176
|
+
* control values baked in. It has no dependencies and opens from disk. Like
|
|
177
|
+
* the live preview, it feeds `iMouse` from pointer drags and caps the pixel
|
|
178
|
+
* ratio at 2.
|
|
179
|
+
*
|
|
180
|
+
* Images are loaded by URL when the page opens: a `data:` URL travels with
|
|
181
|
+
* the page, an `https:` one needs the network and CORS, and a `blob:` one
|
|
182
|
+
* only lives as long as the page that made it. SVGs are sized to
|
|
183
|
+
* {@link SVG_EDGE} pixels before they are decoded, as `loadImage` does.
|
|
184
|
+
*/
|
|
185
|
+
declare function standaloneHtml(title: string, source: string, values?: Record<string, ControlValue>, options?: StandaloneOptions): string;
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* 38 Layer Blend Modes for Compositing and WebGL Shader Generation.
|
|
189
|
+
* Mathematically matching Adobe After Effects & EffectCraft blending standards.
|
|
190
|
+
*/
|
|
191
|
+
type BlendMode = 'normal' | 'dissolve' | 'dancingDissolve' | 'darken' | 'multiply' | 'colorBurn' | 'classicColorBurn' | 'linearBurn' | 'darkerColor' | 'add' | 'lighten' | 'screen' | 'colorDodge' | 'classicColorDodge' | 'linearDodge' | 'lighterColor' | 'overlay' | 'softLight' | 'hardLight' | 'linearLight' | 'vividLight' | 'pinLight' | 'hardMix' | 'difference' | 'classicDifference' | 'exclusion' | 'subtract' | 'divide' | 'hue' | 'saturation' | 'color' | 'luminosity' | 'stencilAlpha' | 'stencilLuma' | 'silhouetteAlpha' | 'silhouetteLuma' | 'alphaAdd' | 'luminescentPremul';
|
|
192
|
+
declare const ALL_BLEND_MODES: readonly BlendMode[];
|
|
193
|
+
type ColorRgba = [number, number, number, number];
|
|
194
|
+
/**
|
|
195
|
+
* Evaluates CPU compositing of premultiplied RGBA source onto premultiplied RGBA destination.
|
|
196
|
+
*
|
|
197
|
+
* @param mode Blend mode to apply.
|
|
198
|
+
* @param dst Destination premultiplied RGBA [r, g, b, a] in [0, 1].
|
|
199
|
+
* @param src Source premultiplied RGBA [r, g, b, a] in [0, 1].
|
|
200
|
+
* @param noise Per-pixel noise parameter in [0, 1] for Dissolve modes (default: 0).
|
|
201
|
+
*/
|
|
202
|
+
declare function blendRgba(mode: BlendMode, dst: ColorRgba, src: ColorRgba, noise?: number): ColorRgba;
|
|
203
|
+
/**
|
|
204
|
+
* Returns a self-contained GLSL shader function for blending two vec4 colors.
|
|
205
|
+
* Useful for runtime GPU compositing across multiple shader layers or passes.
|
|
206
|
+
*/
|
|
207
|
+
declare function getGlslBlendFunction(mode: BlendMode): string;
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Procedural WebGL Fragment Shader Transitions & CPU Compositing.
|
|
211
|
+
* Inspired by professional NLE/After Effects/EffectCraft transitions:
|
|
212
|
+
* Linear Wipe, Radial Iris, Block Dissolve, Grid Wipe, Glass Wipe,
|
|
213
|
+
* Twister, Light Leak, and Cross Zoom.
|
|
214
|
+
*/
|
|
215
|
+
type TransitionType = 'linearWipe' | 'radialIris' | 'blockDissolve' | 'gridWipe' | 'glassWipe' | 'twister' | 'lightLeak' | 'crossZoom';
|
|
216
|
+
declare const ALL_TRANSITION_TYPES: readonly TransitionType[];
|
|
217
|
+
interface LinearWipeOptions {
|
|
218
|
+
/** Angle in degrees clockwise from right (0 = left-to-right, 90 = top-to-bottom). Default: 0 */
|
|
219
|
+
angle?: number;
|
|
220
|
+
/** Feather softness width [0..1]. Default: 0.1 */
|
|
221
|
+
feather?: number;
|
|
222
|
+
}
|
|
223
|
+
interface RadialIrisOptions {
|
|
224
|
+
/** Center point in normalized UV coordinates [0..1]. Default: [0.5, 0.5] */
|
|
225
|
+
center?: [number, number];
|
|
226
|
+
/** Geometric iris shape. Default: 'circle' */
|
|
227
|
+
shape?: 'circle' | 'box' | 'diamond';
|
|
228
|
+
/** Feather softness [0..1]. Default: 0.1 */
|
|
229
|
+
feather?: number;
|
|
230
|
+
}
|
|
231
|
+
interface BlockDissolveOptions {
|
|
232
|
+
/** Block cell count along width. Default: 32 */
|
|
233
|
+
blockCount?: number;
|
|
234
|
+
/** Pseudo-random seed integer. Default: 1337 */
|
|
235
|
+
seed?: number;
|
|
236
|
+
/** Softness of dissolve per block. Default: 0.05 */
|
|
237
|
+
feather?: number;
|
|
238
|
+
}
|
|
239
|
+
interface GridWipeOptions {
|
|
240
|
+
/** Number of grid cells [x, y]. Default: [16, 10] */
|
|
241
|
+
gridSize?: [number, number];
|
|
242
|
+
/** Order in which cells wipe: 'ltr' | 'diagonal' | 'radial' | 'random'. Default: 'diagonal' */
|
|
243
|
+
order?: 'ltr' | 'diagonal' | 'radial' | 'random';
|
|
244
|
+
}
|
|
245
|
+
interface GlassWipeOptions {
|
|
246
|
+
/** Angle in degrees. Default: 45 */
|
|
247
|
+
angle?: number;
|
|
248
|
+
/** Wave displacement amplitude. Default: 0.08 */
|
|
249
|
+
amplitude?: number;
|
|
250
|
+
/** Wave frequency. Default: 12.0 */
|
|
251
|
+
frequency?: number;
|
|
252
|
+
}
|
|
253
|
+
interface TwisterOptions {
|
|
254
|
+
/** Maximum twist angle in radians. Default: Math.PI * 2 */
|
|
255
|
+
twist?: number;
|
|
256
|
+
/** Center of swirl. Default: [0.5, 0.5] */
|
|
257
|
+
center?: [number, number];
|
|
258
|
+
}
|
|
259
|
+
interface LightLeakOptions {
|
|
260
|
+
/** Leak tint RGB [0..1]. Default: [1.0, 0.85, 0.6] (warm golden light) */
|
|
261
|
+
color?: [number, number, number];
|
|
262
|
+
/** Peak intensity of light bloom at progress 0.5. Default: 1.5 */
|
|
263
|
+
intensity?: number;
|
|
264
|
+
}
|
|
265
|
+
interface CrossZoomOptions {
|
|
266
|
+
/** Zoom strength. Default: 0.3 */
|
|
267
|
+
strength?: number;
|
|
268
|
+
/** Center of zoom. Default: [0.5, 0.5] */
|
|
269
|
+
center?: [number, number];
|
|
270
|
+
}
|
|
271
|
+
type TransitionOptions = LinearWipeOptions | RadialIrisOptions | BlockDissolveOptions | GridWipeOptions | GlassWipeOptions | TwisterOptions | LightLeakOptions | CrossZoomOptions;
|
|
272
|
+
interface TransitionSample {
|
|
273
|
+
/** Weight of scene B in [0..1] (0 = fully A, 1 = fully B). */
|
|
274
|
+
weight: number;
|
|
275
|
+
/** Sample coordinate for scene A [u, v]. */
|
|
276
|
+
uvA: [number, number];
|
|
277
|
+
/** Sample coordinate for scene B [u, v]. */
|
|
278
|
+
uvB: [number, number];
|
|
279
|
+
/** Additive color light bloom [r, g, b]. */
|
|
280
|
+
additive: [number, number, number];
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Evaluates the transition at a given UV coordinate and progress [0..1].
|
|
284
|
+
* Returns displaced UVs, B weight, and any additive optical bloom.
|
|
285
|
+
*/
|
|
286
|
+
declare function sampleTransition(type: TransitionType, uv: [number, number], progress: number, options?: TransitionOptions): TransitionSample;
|
|
287
|
+
/**
|
|
288
|
+
* CPU Compositing: blends two RGBA pixels across a transition.
|
|
289
|
+
*/
|
|
290
|
+
declare function blendTransitionPixel(colA: [number, number, number, number], colB: [number, number, number, number], sample: TransitionSample): [number, number, number, number];
|
|
291
|
+
/**
|
|
292
|
+
* Returns self-contained WebGL GLSL fragment shader code implementing
|
|
293
|
+
* the selected transition function.
|
|
294
|
+
* Signature: `vec4 flair_transition(sampler2D texA, sampler2D texB, vec2 uv, float progress)`
|
|
295
|
+
*/
|
|
296
|
+
declare function getTransitionGLSL(type: TransitionType): string;
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Perceptual Color Science & Film Grading Engine.
|
|
300
|
+
*
|
|
301
|
+
* Implements:
|
|
302
|
+
* - Oklab & Oklch: Perceptually uniform color spaces that eliminate hue shifts and gray dead zones.
|
|
303
|
+
* - Standard Color Spaces: sRGB, Linear sRGB, Rec.709, Display P3, and ACEScg.
|
|
304
|
+
* - Film Color Grading: ASC CDL (Slope, Offset, Power), Lift/Gamma/Gain, Vibrance (skin tone protection),
|
|
305
|
+
* and White Balance (Kelvin color temperature & tint).
|
|
306
|
+
* - GLSL code generators for real-time WebGL fragment shader execution.
|
|
307
|
+
*/
|
|
308
|
+
type ColorRGB = [number, number, number];
|
|
309
|
+
type ColorRGBA = [number, number, number, number];
|
|
310
|
+
declare function srgbToLinear(c: number): number;
|
|
311
|
+
declare function linearToSrgb(c: number): number;
|
|
312
|
+
declare function srgbToLinearRgb(rgb: ColorRGB): ColorRGB;
|
|
313
|
+
declare function linearRgbToSrgb(rgb: ColorRGB): ColorRGB;
|
|
314
|
+
declare function linearSrgbToOklab(rgb: ColorRGB): [number, number, number];
|
|
315
|
+
declare function oklabToLinearSrgb(lab: [number, number, number]): ColorRGB;
|
|
316
|
+
declare function srgbToOklab(rgb: ColorRGB): [number, number, number];
|
|
317
|
+
declare function oklabToSrgb(lab: [number, number, number]): ColorRGB;
|
|
318
|
+
declare function oklabToOklch(lab: [number, number, number]): [number, number, number];
|
|
319
|
+
declare function oklchToOklab(lch: [number, number, number]): [number, number, number];
|
|
320
|
+
/**
|
|
321
|
+
* Perceptually uniform color interpolation using Oklab space.
|
|
322
|
+
* Prevents intermediate grayish dead spots.
|
|
323
|
+
*/
|
|
324
|
+
declare function interpolateOklab(c1: ColorRGB, c2: ColorRGB, t: number): ColorRGB;
|
|
325
|
+
/**
|
|
326
|
+
* Perceptually uniform color interpolation using Oklch cylindrical space.
|
|
327
|
+
* Interpolates along the shortest hue arc for vibrant gradients.
|
|
328
|
+
*/
|
|
329
|
+
declare function interpolateOklch(c1: ColorRGB, c2: ColorRGB, t: number): ColorRGB;
|
|
330
|
+
type ColorSpace = 'srgb' | 'linear-srgb' | 'rec709' | 'display-p3' | 'acescg';
|
|
331
|
+
/**
|
|
332
|
+
* Converts a color between standard imaging color spaces.
|
|
333
|
+
*/
|
|
334
|
+
declare function convertColorSpace(color: ColorRGB, from: ColorSpace, to: ColorSpace): ColorRGB;
|
|
335
|
+
interface AscCdl {
|
|
336
|
+
/** Multiplicative scaling (default [1, 1, 1]) */
|
|
337
|
+
slope?: ColorRGB;
|
|
338
|
+
/** Additive offset (default [0, 0, 0]) */
|
|
339
|
+
offset?: ColorRGB;
|
|
340
|
+
/** Exponential power (default [1, 1, 1]) */
|
|
341
|
+
power?: ColorRGB;
|
|
342
|
+
/** Master saturation (default 1.0) */
|
|
343
|
+
saturation?: number;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Standard ASC CDL (American Society of Cinematographers Color Decision List).
|
|
347
|
+
* Formula: out = (in * slope + offset)^power, followed by Rec.709 luma-weighted saturation.
|
|
348
|
+
*/
|
|
349
|
+
declare function applyAscCdl(color: ColorRGB, cdl: AscCdl): ColorRGB;
|
|
350
|
+
interface LiftGammaGain {
|
|
351
|
+
/** Shadows adjustment (default [0, 0, 0]) */
|
|
352
|
+
lift?: ColorRGB;
|
|
353
|
+
/** Midtones gamma adjustment (default [1, 1, 1]) */
|
|
354
|
+
gamma?: ColorRGB;
|
|
355
|
+
/** Highlights gain adjustment (default [1, 1, 1]) */
|
|
356
|
+
gain?: ColorRGB;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Three-way Lift / Gamma / Gain film color grading.
|
|
360
|
+
* Formula: out = (gain * (in + lift * (1 - in)))^(1 / gamma)
|
|
361
|
+
*/
|
|
362
|
+
declare function applyLiftGammaGain(color: ColorRGB, lgg: LiftGammaGain): ColorRGB;
|
|
363
|
+
/**
|
|
364
|
+
* Vibrance adjustment with skin tone protection.
|
|
365
|
+
* Selectively boosts muted colors while preventing already saturated colors and skin tones
|
|
366
|
+
* from clipping.
|
|
367
|
+
* @param amount Vibrance delta in [-1..1]
|
|
368
|
+
*/
|
|
369
|
+
declare function applyVibrance(color: ColorRGB, amount: number): ColorRGB;
|
|
370
|
+
/**
|
|
371
|
+
* Calculates RGB multiplier from Kelvin blackbody color temperature and green/magenta tint.
|
|
372
|
+
* @param kelvin Temperature in Kelvin [2000..12000], D65 neutral is 6500K.
|
|
373
|
+
* @param tint Green/magenta shift in [-100..100] (0 = neutral).
|
|
374
|
+
*/
|
|
375
|
+
declare function getWhiteBalanceGains(kelvin: number, tint?: number): ColorRGB;
|
|
376
|
+
/**
|
|
377
|
+
* Self-contained GLSL functions for fast Oklab <-> Linear sRGB transforms.
|
|
378
|
+
*/
|
|
379
|
+
declare function getOklabGLSL(): string;
|
|
380
|
+
/**
|
|
381
|
+
* Self-contained GLSL functions for ASC CDL and Lift/Gamma/Gain grading.
|
|
382
|
+
*/
|
|
383
|
+
declare function getColorGradingGLSL(): string;
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Retiming math engine inspired by Apple Motion's RetimingMath framework.
|
|
387
|
+
* Provides deterministic time transformation functors for looping, bouncing (ping-pong),
|
|
388
|
+
* freezing (hold), posterizing/stepping (strobe), and non-linear speed ramps.
|
|
389
|
+
*/
|
|
390
|
+
type EasingCurve = 'linear' | 'easeIn' | 'easeOut' | 'easeInOut';
|
|
391
|
+
/**
|
|
392
|
+
* Loops time within [start, start + duration).
|
|
393
|
+
* Handles negative time values smoothly.
|
|
394
|
+
*/
|
|
395
|
+
declare function loopTime(t: number, duration: number, start?: number): number;
|
|
396
|
+
/**
|
|
397
|
+
* Reflects time back and forth (triangle wave) between start and start + duration.
|
|
398
|
+
*/
|
|
399
|
+
declare function pingPongTime(t: number, duration: number, start?: number): number;
|
|
400
|
+
/**
|
|
401
|
+
* Freezes time at a specified timestamp.
|
|
402
|
+
*/
|
|
403
|
+
declare function holdTime(_t: number, holdAt: number): number;
|
|
404
|
+
/**
|
|
405
|
+
* Quantizes continuous time into discrete intervals matching a target frame rate (posterize time).
|
|
406
|
+
* @param t Current timestamp.
|
|
407
|
+
* @param fps Target stepped frame rate (e.g. 12 for stop-motion).
|
|
408
|
+
* @param unit 'ms' (default) if t is in milliseconds, or 'sec' if t is in seconds.
|
|
409
|
+
*/
|
|
410
|
+
declare function strobeTime(t: number, fps: number, unit?: 'ms' | 'sec'): number;
|
|
411
|
+
/**
|
|
412
|
+
* Applies a non-linear speed ramp curve to time progression within an interval [start, start + duration].
|
|
413
|
+
*/
|
|
414
|
+
declare function speedRampTime(t: number, start: number, duration: number, ease?: EasingCurve): number;
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Keyframe velocity and cubic Bezier easing engine matching Adobe After Effects interpolation semantics.
|
|
418
|
+
*
|
|
419
|
+
* Temporal interpolation between two keyframes is characterized by:
|
|
420
|
+
* - Speed (units / second)
|
|
421
|
+
* - Influence (fraction 0..1, corresponding to 0.1%..100% in the Keyframe Velocity dialog)
|
|
422
|
+
*
|
|
423
|
+
* For normalized values going from 0 to 1 over a segment, easeProgress(outSpeedNorm, outInf, inSpeedNorm, inInf, x)
|
|
424
|
+
* solves the monotone cubic Bezier root x(u) = x and computes value y(u).
|
|
425
|
+
*/
|
|
426
|
+
interface KeyframeEase {
|
|
427
|
+
/** Speed in value units per second (or normalized speed if evaluating normalized segment). */
|
|
428
|
+
speed: number;
|
|
429
|
+
/** Influence as a fraction between 0.0 and 1.0 (e.g. 0.3333 for 33.33%). */
|
|
430
|
+
influence: number;
|
|
431
|
+
}
|
|
432
|
+
/** Easy Ease preset: 0 speed, 33.333% influence. */
|
|
433
|
+
declare const EASY_EASE: KeyframeEase;
|
|
434
|
+
/** Evaluates a 1D cubic Bezier polynomial at parameter u in [0, 1]. */
|
|
435
|
+
declare function bez1d(p0: number, p1: number, p2: number, p3: number, u: number): number;
|
|
436
|
+
/** Evaluates the first derivative of a 1D cubic Bezier polynomial at parameter u. */
|
|
437
|
+
declare function bez1dDerivative(p0: number, p1: number, p2: number, p3: number, u: number): number;
|
|
438
|
+
/**
|
|
439
|
+
* Solves bez1d(x0, x1, x2, x3, u) = x for u in [0, 1] assuming x(u) is monotone.
|
|
440
|
+
* Uses closed-form inverse for 100% influence midpoint, Newton-Raphson iteration,
|
|
441
|
+
* and high-precision bisection fallback.
|
|
442
|
+
*/
|
|
443
|
+
declare function solveBezierU(x0: number, x1: number, x2: number, x3: number, x: number): number;
|
|
444
|
+
/**
|
|
445
|
+
* Fraction of progress 0..1 through a 1D Bezier temporal segment whose value goes from 0 to 1,
|
|
446
|
+
* with normalized out/in speeds (speed * duration / deltaValue) and influences.
|
|
447
|
+
*
|
|
448
|
+
* @param outSpeedNorm Normalized outgoing speed (speed * duration / deltaValue).
|
|
449
|
+
* @param outInfluence Outgoing influence fraction [0, 1].
|
|
450
|
+
* @param inSpeedNorm Normalized incoming speed (speed * duration / deltaValue).
|
|
451
|
+
* @param inInfluence Incoming influence fraction [0, 1].
|
|
452
|
+
* @param x Normalized time progress in segment [0, 1].
|
|
453
|
+
*/
|
|
454
|
+
declare function easeProgress(outSpeedNorm: number, outInfluence: number, inSpeedNorm: number, inInfluence: number, x: number): number;
|
|
455
|
+
/**
|
|
456
|
+
* Evaluates an interpolated keyframe segment between two values over duration.
|
|
457
|
+
*
|
|
458
|
+
* @param from Starting value at t = 0.
|
|
459
|
+
* @param to Ending value at t = duration.
|
|
460
|
+
* @param duration Duration of the keyframe segment in seconds.
|
|
461
|
+
* @param t Current elapsed time in seconds (0 <= t <= duration).
|
|
462
|
+
* @param outEase Outgoing ease specification at start keyframe.
|
|
463
|
+
* @param inEase Incoming ease specification at end keyframe.
|
|
464
|
+
*/
|
|
465
|
+
declare function evaluateKeyframeSegment(from: number, to: number, duration: number, t: number, outEase?: KeyframeEase, inEase?: KeyframeEase): number;
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Deterministic pseudo-random number generator, hash mixing, and C2-continuous smooth value noise.
|
|
469
|
+
* Based on 64-bit SplitMix64 mixing and quintic Hermite interpolation.
|
|
470
|
+
*
|
|
471
|
+
* Produces deterministic, platform-independent outputs for wiggle, organic turbulence, and camera shake.
|
|
472
|
+
*/
|
|
473
|
+
/**
|
|
474
|
+
* SplitMix64 mixing finalizer: maps any 64-bit integer to a high-quality pseudorandom 64-bit integer.
|
|
475
|
+
*/
|
|
476
|
+
declare function hash64(x: bigint): bigint;
|
|
477
|
+
/**
|
|
478
|
+
* Combines multiple seed numbers/bigints into a single mixed 64-bit seed.
|
|
479
|
+
*/
|
|
480
|
+
declare function mixSeeds(parts: (bigint | number)[]): bigint;
|
|
481
|
+
/**
|
|
482
|
+
* Maps a 64-bit seed to a uniform float in [0, 1).
|
|
483
|
+
*/
|
|
484
|
+
declare function unitFloat(seed: bigint | number): number;
|
|
485
|
+
/**
|
|
486
|
+
* Quintic Hermite interpolant fade function: 6t^5 - 15t^4 + 10t^3.
|
|
487
|
+
* First and second derivatives are zero at t = 0 and t = 1, ensuring C2 continuity.
|
|
488
|
+
*/
|
|
489
|
+
declare function quinticFade(t: number): number;
|
|
490
|
+
/**
|
|
491
|
+
* 1D C2-continuous smooth value noise in [-1, 1].
|
|
492
|
+
* Guaranteed bounded by lattice values, smooth without sudden velocity spikes.
|
|
493
|
+
*/
|
|
494
|
+
declare function noise1d(seed: bigint | number, x: number): number;
|
|
495
|
+
/**
|
|
496
|
+
* 3D C2-continuous smooth value noise in [-1, 1].
|
|
497
|
+
*/
|
|
498
|
+
declare function noise3d(x: number, y: number, z: number, seed?: bigint | number): number;
|
|
499
|
+
/**
|
|
500
|
+
* Evaluates multi-octave fractal noise wiggle:
|
|
501
|
+
* sum_{k=0}^{octaves-1} amp * (ampMult^k) * noise1d(freq * (2^k) * t)
|
|
502
|
+
*
|
|
503
|
+
* Matches the mathematical formulation of After Effects / EffectCraft wiggle().
|
|
504
|
+
*
|
|
505
|
+
* @param freq Oscillation frequency in Hz (cycles per second).
|
|
506
|
+
* @param amp Maximum deviation amplitude.
|
|
507
|
+
* @param octaves Number of noise detail octaves (default: 3).
|
|
508
|
+
* @param ampMult Amplitude multiplier per octave (default: 0.5).
|
|
509
|
+
* @param t Elapsed time in seconds.
|
|
510
|
+
* @param seed Random seed (default: 42).
|
|
511
|
+
* @param dimension Dimension index (0, 1, 2) to ensure decorrelated multi-axis wiggle.
|
|
512
|
+
*/
|
|
513
|
+
declare function fractalWiggle(freq: number, amp: number, octaves?: number, ampMult?: number, t?: number, seed?: number, dimension?: number): number;
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* SMPTE 12M Timecode engine and broadcast frame-rate converter.
|
|
517
|
+
*
|
|
518
|
+
* Supports non-drop-frame (NDF) and drop-frame (DF) timecode for broadcast standards
|
|
519
|
+
* (23.976, 24, 25, 29.97, 30, 48, 50, 59.94, 60, 120 fps).
|
|
520
|
+
*
|
|
521
|
+
* Drop-frame timecode drops frames 00 and 01 at the start of each minute,
|
|
522
|
+
* except every 10th minute (e.g. 00:01:00;02 instead of 00:01:00;00).
|
|
523
|
+
*/
|
|
524
|
+
interface RationalFrameRate {
|
|
525
|
+
readonly num: number;
|
|
526
|
+
readonly den: number;
|
|
527
|
+
}
|
|
528
|
+
declare const COMMON_FRAME_RATES: {
|
|
529
|
+
readonly FPS_23_976: {
|
|
530
|
+
readonly num: 24000;
|
|
531
|
+
readonly den: 1001;
|
|
532
|
+
};
|
|
533
|
+
readonly FPS_24: {
|
|
534
|
+
readonly num: 24;
|
|
535
|
+
readonly den: 1;
|
|
536
|
+
};
|
|
537
|
+
readonly FPS_25: {
|
|
538
|
+
readonly num: 25;
|
|
539
|
+
readonly den: 1;
|
|
540
|
+
};
|
|
541
|
+
readonly FPS_29_97: {
|
|
542
|
+
readonly num: 30000;
|
|
543
|
+
readonly den: 1001;
|
|
544
|
+
};
|
|
545
|
+
readonly FPS_30: {
|
|
546
|
+
readonly num: 30;
|
|
547
|
+
readonly den: 1;
|
|
548
|
+
};
|
|
549
|
+
readonly FPS_48: {
|
|
550
|
+
readonly num: 48;
|
|
551
|
+
readonly den: 1;
|
|
552
|
+
};
|
|
553
|
+
readonly FPS_50: {
|
|
554
|
+
readonly num: 50;
|
|
555
|
+
readonly den: 1;
|
|
556
|
+
};
|
|
557
|
+
readonly FPS_59_94: {
|
|
558
|
+
readonly num: 60000;
|
|
559
|
+
readonly den: 1001;
|
|
560
|
+
};
|
|
561
|
+
readonly FPS_60: {
|
|
562
|
+
readonly num: 60;
|
|
563
|
+
readonly den: 1;
|
|
564
|
+
};
|
|
565
|
+
readonly FPS_120: {
|
|
566
|
+
readonly num: 120;
|
|
567
|
+
readonly den: 1;
|
|
568
|
+
};
|
|
569
|
+
};
|
|
570
|
+
type StandardFrameRateKey = keyof typeof COMMON_FRAME_RATES;
|
|
571
|
+
/** Creates a reduced rational frame rate. */
|
|
572
|
+
declare function createFrameRate(num: number, den?: number): RationalFrameRate;
|
|
573
|
+
/** Returns the timecode base (frames counted per second in timecode display). */
|
|
574
|
+
declare function getTimecodeBase(rate: RationalFrameRate): number;
|
|
575
|
+
/** Whether a given frame rate supports drop-frame counting (29.97, 59.94, etc.). */
|
|
576
|
+
declare function supportsDropFrame(rate: RationalFrameRate): boolean;
|
|
577
|
+
/** Number of dropped frames per minute (e.g. 2 for 29.97, 4 for 59.94). */
|
|
578
|
+
declare function getDropFrameCount(rate: RationalFrameRate): number;
|
|
579
|
+
interface SMPTEFields {
|
|
580
|
+
negative: boolean;
|
|
581
|
+
hours: number;
|
|
582
|
+
minutes: number;
|
|
583
|
+
seconds: number;
|
|
584
|
+
frames: number;
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Converts a continuous frame count to SMPTE fields (hours, minutes, seconds, frames).
|
|
588
|
+
*/
|
|
589
|
+
declare function framesToSMPTE(frame: number, rate?: RationalFrameRate, dropFrame?: boolean): SMPTEFields;
|
|
590
|
+
/**
|
|
591
|
+
* Converts SMPTE fields back to a continuous frame number.
|
|
592
|
+
*/
|
|
593
|
+
declare function smpteToFrames(fields: {
|
|
594
|
+
hours: number;
|
|
595
|
+
minutes: number;
|
|
596
|
+
seconds: number;
|
|
597
|
+
frames: number;
|
|
598
|
+
}, rate?: RationalFrameRate, dropFrame?: boolean): number;
|
|
599
|
+
/**
|
|
600
|
+
* Formats a frame number as standard SMPTE timecode (HH:MM:SS:FF or HH;MM;SS;FF).
|
|
601
|
+
*/
|
|
602
|
+
declare function formatTimecode(frame: number, rate?: RationalFrameRate, dropFrame?: boolean): string;
|
|
603
|
+
/**
|
|
604
|
+
* Parses user or NLE input into a frame number.
|
|
605
|
+
* Supports:
|
|
606
|
+
* - Standard timecodes: `01:00:00:00`, `01;00;00;00`, `00.01.20.15`
|
|
607
|
+
* - Right-aligned numbers: `1000` -> `00:00:10:00`
|
|
608
|
+
* - Relative offsets: `+15` (+15 frames), `-1.00` (-1 second)
|
|
609
|
+
*
|
|
610
|
+
* @param input The timecode string to parse.
|
|
611
|
+
* @param rate Rational frame rate (default: 30 fps).
|
|
612
|
+
* @param dropFrame Whether drop-frame arithmetic applies.
|
|
613
|
+
* @param currentFrame Current playhead position for relative additions.
|
|
614
|
+
*/
|
|
615
|
+
declare function parseTimecode(input: string, rate?: RationalFrameRate, dropFrame?: boolean, currentFrame?: number): number;
|
|
616
|
+
|
|
617
|
+
type Point = [number, number];
|
|
618
|
+
interface Rect {
|
|
619
|
+
x: number;
|
|
620
|
+
y: number;
|
|
621
|
+
width: number;
|
|
622
|
+
height: number;
|
|
623
|
+
}
|
|
624
|
+
/** An element placed or animated in a scene. */
|
|
625
|
+
interface SceneElement {
|
|
626
|
+
id: string;
|
|
627
|
+
type: string;
|
|
628
|
+
x: number;
|
|
629
|
+
y: number;
|
|
630
|
+
width: number;
|
|
631
|
+
height: number;
|
|
632
|
+
points?: readonly (readonly [number, number])[];
|
|
633
|
+
fontSize?: number;
|
|
634
|
+
text?: string;
|
|
635
|
+
containerId?: string | null;
|
|
636
|
+
isDeleted?: boolean;
|
|
637
|
+
opacity?: number;
|
|
638
|
+
}
|
|
639
|
+
/** Bounds in scene units, ignoring rotation. */
|
|
640
|
+
declare function boundsOf(e: SceneElement): Rect;
|
|
641
|
+
/** Area of the overlap of two rectangles (0 when they do not meet). */
|
|
642
|
+
declare function overlapArea(a: Rect, b: Rect): number;
|
|
643
|
+
declare const areaOf: (r: Rect) => number;
|
|
644
|
+
|
|
645
|
+
interface Stage {
|
|
646
|
+
width: number;
|
|
647
|
+
height: number;
|
|
648
|
+
caption?: number;
|
|
649
|
+
}
|
|
650
|
+
declare const DEFAULT_STAGE: Stage;
|
|
651
|
+
declare const CAMERA_MS = 600;
|
|
652
|
+
/** Camera view into the scene: drawn at (point + scroll) × zoom. */
|
|
653
|
+
interface View {
|
|
654
|
+
zoom: number;
|
|
655
|
+
scrollX: number;
|
|
656
|
+
scrollY: number;
|
|
657
|
+
}
|
|
658
|
+
declare const boardHeight: (stage: Stage) => number;
|
|
659
|
+
/** View with `(cx, cy)` in the middle of the board at `zoom`. */
|
|
660
|
+
declare function viewAt(cx: number, cy: number, zoom: number, stage: Stage): View;
|
|
661
|
+
/** Scene point in the middle of the board. */
|
|
662
|
+
declare function centreOf(view: View, stage: Stage): [number, number];
|
|
663
|
+
/** The view that fits `rect` on the board, centred and with its aspect kept. */
|
|
664
|
+
declare function frame(rect: Rect, stage: Stage): View;
|
|
665
|
+
interface FramingOptions {
|
|
666
|
+
/** Proportional padding added to all sides (e.g., 0.15 for 15%). Default: 0.15 */
|
|
667
|
+
padding?: number;
|
|
668
|
+
/** Minimum width in scene units. */
|
|
669
|
+
minWidth?: number;
|
|
670
|
+
/** Minimum height in scene units. */
|
|
671
|
+
minHeight?: number;
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
674
|
+
* Calculates a camera framing rectangle that encloses target elements
|
|
675
|
+
* while preserving the stage aspect ratio and applying optional margin padding.
|
|
676
|
+
*/
|
|
677
|
+
declare function calculateFramingRect(elements: readonly SceneElement[], stage: Stage, options?: FramingOptions): Rect;
|
|
678
|
+
/**
|
|
679
|
+
* The view part-way (`t` from 0 to 1) from one view to another.
|
|
680
|
+
* Centre moves linearly and zoom scales exponentially for smooth motion.
|
|
681
|
+
*/
|
|
682
|
+
declare function between(from: View, to: View, t: number, stage: Stage): View;
|
|
683
|
+
/** The part of the scene the camera currently shows. */
|
|
684
|
+
declare function visibleRect(view: View, stage: Stage): Rect;
|
|
685
|
+
/** Smooth cubic ease in / ease out. */
|
|
686
|
+
declare const easeInOutCubic: (t: number) => number;
|
|
687
|
+
|
|
688
|
+
interface EffectBase {
|
|
689
|
+
/** Unique identifier for the effect so it can be stopped or updated. */
|
|
690
|
+
id: string;
|
|
691
|
+
/** End the effect when this many subsequent shots begin. */
|
|
692
|
+
shots?: number;
|
|
693
|
+
/** Duration in milliseconds after which the effect stops automatically. */
|
|
694
|
+
duration?: number;
|
|
695
|
+
/** When to start: 'start' of shot or after commands are 'drawn'. Default: 'drawn'. */
|
|
696
|
+
at?: 'start' | 'drawn';
|
|
697
|
+
}
|
|
698
|
+
interface GradientEffect extends EffectBase {
|
|
699
|
+
type: 'gradient';
|
|
700
|
+
colors: string[];
|
|
701
|
+
rect?: Rect;
|
|
702
|
+
ids?: string[];
|
|
703
|
+
angle?: number;
|
|
704
|
+
period?: number;
|
|
705
|
+
opacity?: number;
|
|
706
|
+
}
|
|
707
|
+
interface FlowEffect extends EffectBase {
|
|
708
|
+
type: 'flow';
|
|
709
|
+
along: string;
|
|
710
|
+
color?: string;
|
|
711
|
+
dots?: number;
|
|
712
|
+
period?: number;
|
|
713
|
+
size?: number;
|
|
714
|
+
direction?: 'forward' | 'back' | 'both';
|
|
715
|
+
label?: string;
|
|
716
|
+
}
|
|
717
|
+
interface GlowEffect extends EffectBase {
|
|
718
|
+
type: 'glow';
|
|
719
|
+
ids: string[];
|
|
720
|
+
color?: string;
|
|
721
|
+
size?: number;
|
|
722
|
+
pulse?: boolean;
|
|
723
|
+
}
|
|
724
|
+
interface SpotlightEffect extends EffectBase {
|
|
725
|
+
type: 'spotlight';
|
|
726
|
+
ids: string[];
|
|
727
|
+
dim?: number;
|
|
728
|
+
padding?: number;
|
|
729
|
+
}
|
|
730
|
+
interface ShimmerEffect extends EffectBase {
|
|
731
|
+
type: 'shimmer';
|
|
732
|
+
ids: string[];
|
|
733
|
+
color?: string;
|
|
734
|
+
period?: number;
|
|
735
|
+
}
|
|
736
|
+
interface RippleEffect extends EffectBase {
|
|
737
|
+
type: 'ripple';
|
|
738
|
+
ids: string[];
|
|
739
|
+
color?: string;
|
|
740
|
+
period?: number;
|
|
741
|
+
size?: number;
|
|
742
|
+
times?: number;
|
|
743
|
+
}
|
|
744
|
+
interface TimerEffect extends EffectBase {
|
|
745
|
+
type: 'timer';
|
|
746
|
+
ids: string[];
|
|
747
|
+
time?: number;
|
|
748
|
+
fill?: boolean;
|
|
749
|
+
repeat?: boolean;
|
|
750
|
+
color?: string;
|
|
751
|
+
size?: number;
|
|
752
|
+
}
|
|
753
|
+
interface CounterEffect extends EffectBase {
|
|
754
|
+
type: 'counter';
|
|
755
|
+
to: number;
|
|
756
|
+
from?: number;
|
|
757
|
+
time?: number;
|
|
758
|
+
text?: string;
|
|
759
|
+
decimals?: number;
|
|
760
|
+
near?: string;
|
|
761
|
+
x?: number;
|
|
762
|
+
y?: number;
|
|
763
|
+
color?: string;
|
|
764
|
+
size?: number;
|
|
765
|
+
}
|
|
766
|
+
interface HighlightEffect extends EffectBase {
|
|
767
|
+
type: 'highlight';
|
|
768
|
+
ids: string[];
|
|
769
|
+
style?: 'marker' | 'underline';
|
|
770
|
+
color?: string;
|
|
771
|
+
}
|
|
772
|
+
interface BlurEffect extends EffectBase {
|
|
773
|
+
type: 'blur';
|
|
774
|
+
ids: string[];
|
|
775
|
+
amount?: number;
|
|
776
|
+
padding?: number;
|
|
777
|
+
}
|
|
778
|
+
interface BurstEffect extends EffectBase {
|
|
779
|
+
type: 'burst';
|
|
780
|
+
ids: string[];
|
|
781
|
+
color?: string;
|
|
782
|
+
sparks?: number;
|
|
783
|
+
size?: number;
|
|
784
|
+
}
|
|
785
|
+
/** Media layer effect driving a WebGL shader (or other media stream) under or over the scene. */
|
|
786
|
+
interface MediaEffect extends EffectBase {
|
|
787
|
+
type: 'media';
|
|
788
|
+
/** ID in Scene.media. */
|
|
789
|
+
media: string;
|
|
790
|
+
rect?: Rect;
|
|
791
|
+
ids?: string[];
|
|
792
|
+
padding?: number;
|
|
793
|
+
layer?: 'under' | 'over';
|
|
794
|
+
opacity?: number;
|
|
795
|
+
}
|
|
796
|
+
type Effect = GradientEffect | FlowEffect | GlowEffect | SpotlightEffect | ShimmerEffect | RippleEffect | TimerEffect | CounterEffect | HighlightEffect | BlurEffect | BurstEffect | MediaEffect;
|
|
797
|
+
declare const EFFECT_TYPES: readonly ["gradient", "flow", "glow", "spotlight", "shimmer", "ripple", "timer", "counter", "highlight", "blur", "burst", "media"];
|
|
798
|
+
declare const EFFECT_FADE_MS = 300;
|
|
799
|
+
interface RunningEffect {
|
|
800
|
+
effect: Effect;
|
|
801
|
+
/** Timestamp when started (ms). */
|
|
802
|
+
from: number;
|
|
803
|
+
/** Timestamp when stopping/fading begins (ms). */
|
|
804
|
+
until?: number;
|
|
805
|
+
}
|
|
806
|
+
/** Returns true if the effect has completely expired and finished fading out. */
|
|
807
|
+
declare function effectGone(running: RunningEffect, now: number): boolean;
|
|
808
|
+
/** Returns current opacity multiplier (0 to 1) accounting for fade in / fade out. */
|
|
809
|
+
declare function effectOpacity(running: RunningEffect, now: number): number;
|
|
810
|
+
|
|
811
|
+
interface BehaviorBase {
|
|
812
|
+
id?: string;
|
|
813
|
+
/** Target element ID or media ID. */
|
|
814
|
+
target: string;
|
|
815
|
+
/** Property on element (e.g. 'x', 'y', 'scale', 'rotation', 'opacity') or uniform on media. */
|
|
816
|
+
property: string;
|
|
817
|
+
}
|
|
818
|
+
interface OscillateBehavior extends BehaviorBase {
|
|
819
|
+
type: 'oscillate';
|
|
820
|
+
wave?: 'sine' | 'square' | 'triangle' | 'sawtooth';
|
|
821
|
+
amplitude: number;
|
|
822
|
+
/** Frequency in Hz (cycles per second). */
|
|
823
|
+
frequency: number;
|
|
824
|
+
/** Phase offset in radians (default 0). */
|
|
825
|
+
phase?: number;
|
|
826
|
+
/** Base center value. If undefined, treated as relative offset added to current base value. */
|
|
827
|
+
center?: number;
|
|
828
|
+
}
|
|
829
|
+
interface RampBehavior extends BehaviorBase {
|
|
830
|
+
type: 'ramp';
|
|
831
|
+
from?: number;
|
|
832
|
+
to: number;
|
|
833
|
+
ease?: EasingCurve;
|
|
834
|
+
}
|
|
835
|
+
interface RateBehavior extends BehaviorBase {
|
|
836
|
+
type: 'rate';
|
|
837
|
+
/** Rate of change per second (e.g. degrees/sec or units/sec). */
|
|
838
|
+
rate: number;
|
|
839
|
+
}
|
|
840
|
+
interface WriggleBehavior extends BehaviorBase {
|
|
841
|
+
type: 'wriggle';
|
|
842
|
+
/** Maximum amplitude of deviation. */
|
|
843
|
+
amount: number;
|
|
844
|
+
/** Speed / frequency of variation in Hz. */
|
|
845
|
+
frequency: number;
|
|
846
|
+
/** Number of noise octaves for organic complexity (default: 3). */
|
|
847
|
+
octaves?: number;
|
|
848
|
+
/** Deterministic random seed. */
|
|
849
|
+
seed?: number;
|
|
850
|
+
}
|
|
851
|
+
interface OvershootBehavior extends BehaviorBase {
|
|
852
|
+
type: 'overshoot';
|
|
853
|
+
targetValue: number;
|
|
854
|
+
startValue?: number;
|
|
855
|
+
/** Oscillation frequency / cycles (default: 3). */
|
|
856
|
+
cycles?: number;
|
|
857
|
+
/** Damping factor (higher settles faster, default: 4.0). */
|
|
858
|
+
damping?: number;
|
|
859
|
+
}
|
|
860
|
+
interface ThrowBehavior extends BehaviorBase {
|
|
861
|
+
type: 'throw';
|
|
862
|
+
/** Initial speed in units per second. */
|
|
863
|
+
initialVelocity: number;
|
|
864
|
+
/** Friction / deceleration factor (default: 2.0). */
|
|
865
|
+
friction?: number;
|
|
866
|
+
}
|
|
867
|
+
type Behavior = OscillateBehavior | RampBehavior | RateBehavior | WriggleBehavior | OvershootBehavior | ThrowBehavior;
|
|
868
|
+
/**
|
|
869
|
+
* Evaluates the new numeric value for a behavior at a given elapsed time.
|
|
870
|
+
* @param behavior The behavior specification.
|
|
871
|
+
* @param elapsedSec Elapsed time within the shot/behavior duration (in seconds).
|
|
872
|
+
* @param durationSec Total duration of the shot/behavior (in seconds).
|
|
873
|
+
* @param baseValue Initial or fallback value before behavior was applied.
|
|
874
|
+
*/
|
|
875
|
+
declare function evaluateBehavior(behavior: Behavior, elapsedSec: number, durationSec: number, baseValue?: number): number;
|
|
876
|
+
|
|
877
|
+
interface SliderSnapshot {
|
|
878
|
+
at: number;
|
|
879
|
+
values: Record<string, number | string>;
|
|
880
|
+
}
|
|
881
|
+
interface SliderWidget {
|
|
882
|
+
type: 'slider';
|
|
883
|
+
name: string;
|
|
884
|
+
value: number;
|
|
885
|
+
snapshots: SliderSnapshot[];
|
|
886
|
+
}
|
|
887
|
+
interface PopupWidget {
|
|
888
|
+
type: 'popup';
|
|
889
|
+
name: string;
|
|
890
|
+
selected: string;
|
|
891
|
+
options: Record<string, Record<string, number | string>>;
|
|
892
|
+
}
|
|
893
|
+
interface ToggleWidget {
|
|
894
|
+
type: 'toggle';
|
|
895
|
+
name: string;
|
|
896
|
+
enabled: boolean;
|
|
897
|
+
on: Record<string, number | string>;
|
|
898
|
+
off: Record<string, number | string>;
|
|
899
|
+
}
|
|
900
|
+
type RigWidget = SliderWidget | PopupWidget | ToggleWidget;
|
|
901
|
+
interface SceneRig {
|
|
902
|
+
widgets: Record<string, RigWidget>;
|
|
903
|
+
}
|
|
904
|
+
/**
|
|
905
|
+
* Updates a widget within a SceneRig and returns the updated SceneRig.
|
|
906
|
+
*/
|
|
907
|
+
declare function setRigWidget(rig: SceneRig, widgetName: string, value: number | string | boolean): SceneRig;
|
|
908
|
+
/**
|
|
909
|
+
* Propagates rig widget state into the scene's shader uniforms and elements.
|
|
910
|
+
*/
|
|
911
|
+
declare function applyRig(rig: SceneRig, scene: Scene): Scene;
|
|
912
|
+
|
|
913
|
+
/** Shader or external visual stream in the scene. */
|
|
914
|
+
interface SceneMedia {
|
|
915
|
+
type: 'shader' | string;
|
|
916
|
+
source?: string;
|
|
917
|
+
values?: Record<string, unknown>;
|
|
918
|
+
[field: string]: unknown;
|
|
919
|
+
}
|
|
920
|
+
interface ElementCommand {
|
|
921
|
+
type: 'element';
|
|
922
|
+
element: SceneElement;
|
|
923
|
+
}
|
|
924
|
+
interface UpdateCommand {
|
|
925
|
+
type: 'update';
|
|
926
|
+
id: string;
|
|
927
|
+
props: Partial<SceneElement>;
|
|
928
|
+
}
|
|
929
|
+
interface DeleteCommand {
|
|
930
|
+
type: 'delete';
|
|
931
|
+
id: string;
|
|
932
|
+
}
|
|
933
|
+
interface ClearCommand {
|
|
934
|
+
type: 'clear';
|
|
935
|
+
}
|
|
936
|
+
interface CustomCommand {
|
|
937
|
+
type: string;
|
|
938
|
+
[key: string]: unknown;
|
|
939
|
+
}
|
|
940
|
+
/** A command to add, move, or style elements in a shot. */
|
|
941
|
+
type SceneCommand = ElementCommand | UpdateCommand | DeleteCommand | ClearCommand | CustomCommand;
|
|
942
|
+
declare function isElementCommand(cmd: SceneCommand): cmd is ElementCommand;
|
|
943
|
+
declare function isUpdateCommand(cmd: SceneCommand): cmd is UpdateCommand;
|
|
944
|
+
declare function isDeleteCommand(cmd: SceneCommand): cmd is DeleteCommand;
|
|
945
|
+
interface DynamicFraming {
|
|
946
|
+
/** Element IDs to frame. */
|
|
947
|
+
frame: string[];
|
|
948
|
+
/** Proportional padding (default 0.15 for 15%). */
|
|
949
|
+
padding?: number;
|
|
950
|
+
/** Minimum width in scene units. */
|
|
951
|
+
minWidth?: number;
|
|
952
|
+
/** Minimum height in scene units. */
|
|
953
|
+
minHeight?: number;
|
|
954
|
+
}
|
|
955
|
+
type ShotCamera = Rect | DynamicFraming;
|
|
956
|
+
/** One beat of a scene: camera framing, title, narration/caption, commands, and procedural effects. */
|
|
957
|
+
interface Shot {
|
|
958
|
+
/** Narration / caption spoken or displayed during this beat. */
|
|
959
|
+
caption?: string;
|
|
960
|
+
/** High-level title or callout displayed on screen. */
|
|
961
|
+
title?: string;
|
|
962
|
+
/** Camera framing box in scene units, or dynamic auto-framing target. */
|
|
963
|
+
camera?: ShotCamera;
|
|
964
|
+
/** Pause/dwell duration after this shot's actions run (in milliseconds). Default: 800ms. */
|
|
965
|
+
hold?: number;
|
|
966
|
+
/** Drawing or state change commands played during this shot. */
|
|
967
|
+
run?: SceneCommand[];
|
|
968
|
+
/** Procedural visual effects started in this shot. */
|
|
969
|
+
effects?: Effect[];
|
|
970
|
+
/** IDs of active effects to stop/fade at the start of this shot. */
|
|
971
|
+
stopEffects?: string[];
|
|
972
|
+
/** Continuous procedural parameter and physics behaviors played during this shot. */
|
|
973
|
+
behaviors?: Behavior[];
|
|
974
|
+
}
|
|
975
|
+
/** Complete animated scene specification. */
|
|
976
|
+
interface Scene {
|
|
977
|
+
name: string;
|
|
978
|
+
title?: string;
|
|
979
|
+
description?: string;
|
|
980
|
+
stage?: Partial<Stage>;
|
|
981
|
+
/** Embedded media (e.g. bespoke WebGL fragment shaders). */
|
|
982
|
+
media?: Record<string, SceneMedia>;
|
|
983
|
+
/** Target duration [minSeconds, maxSeconds]. */
|
|
984
|
+
target?: [number, number];
|
|
985
|
+
/** Interactive macro rigs binding high-level controls to uniforms or element properties. */
|
|
986
|
+
rig?: SceneRig;
|
|
987
|
+
shots: Shot[];
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
interface ShotCheck {
|
|
991
|
+
/** Elements this shot drew or changed that the camera frame leaves out ("outside") or cuts ("cut"). */
|
|
992
|
+
framing: {
|
|
993
|
+
id: string;
|
|
994
|
+
how: 'outside' | 'cut';
|
|
995
|
+
}[];
|
|
996
|
+
/** Elements this shot drew that overlap each other significantly. */
|
|
997
|
+
overlaps: [string, string][];
|
|
998
|
+
/** Smallest text size on screen in CSS px. */
|
|
999
|
+
smallestText?: {
|
|
1000
|
+
id: string;
|
|
1001
|
+
text: string;
|
|
1002
|
+
px: number;
|
|
1003
|
+
};
|
|
1004
|
+
/** Any text smaller than min readable threshold (e.g. 18px). */
|
|
1005
|
+
smallTexts?: {
|
|
1006
|
+
id: string;
|
|
1007
|
+
text: string;
|
|
1008
|
+
px: number;
|
|
1009
|
+
}[];
|
|
1010
|
+
/** Elements clipped by the screen edges. */
|
|
1011
|
+
edges: string[];
|
|
1012
|
+
/** Elements covered by the title bar. */
|
|
1013
|
+
underTitle: string[];
|
|
1014
|
+
}
|
|
1015
|
+
declare const NO_CHECK: ShotCheck;
|
|
1016
|
+
declare const SMALL_TEXT_PX = 24;
|
|
1017
|
+
declare function titleBox(title: string, stage: Stage): Rect;
|
|
1018
|
+
declare function touchedIds(shot: Shot): string[];
|
|
1019
|
+
/** Evaluates the elements on stage against the current camera view and shot settings. */
|
|
1020
|
+
declare function checkShot(shot: Shot, elements: readonly SceneElement[], view: View, stage: Stage, title?: string): ShotCheck;
|
|
1021
|
+
|
|
1022
|
+
interface SceneIssue {
|
|
1023
|
+
/** 1-based shot index (0 indicates whole scene level). */
|
|
1024
|
+
shot: number;
|
|
1025
|
+
message: string;
|
|
1026
|
+
}
|
|
1027
|
+
/** Validates a Scene before running or rendering it. */
|
|
1028
|
+
declare function validateScene(scene: Scene): SceneIssue[];
|
|
1029
|
+
|
|
1030
|
+
interface ShotLog extends ShotCheck {
|
|
1031
|
+
index: number;
|
|
1032
|
+
start: number;
|
|
1033
|
+
drawn: number;
|
|
1034
|
+
end: number;
|
|
1035
|
+
caption?: string;
|
|
1036
|
+
title?: string;
|
|
1037
|
+
failed: string[];
|
|
1038
|
+
effects?: string[];
|
|
1039
|
+
}
|
|
1040
|
+
interface ReviewOptions {
|
|
1041
|
+
target?: [number, number];
|
|
1042
|
+
minTextPx?: number;
|
|
1043
|
+
}
|
|
1044
|
+
interface Review {
|
|
1045
|
+
totalMs: number;
|
|
1046
|
+
warnings: string[];
|
|
1047
|
+
notes: string[];
|
|
1048
|
+
markdown: string;
|
|
1049
|
+
}
|
|
1050
|
+
/** Formats a structured diagnostic report of scene playback. */
|
|
1051
|
+
declare function reviewScene(scene: Scene, logs: readonly ShotLog[], options?: ReviewOptions): Review;
|
|
1052
|
+
|
|
1053
|
+
interface SceneBoard {
|
|
1054
|
+
getView(): View;
|
|
1055
|
+
setView(view: View): void;
|
|
1056
|
+
elements(): readonly SceneElement[];
|
|
1057
|
+
runCommand(cmd: SceneCommand): void | Promise<void>;
|
|
1058
|
+
setTitle?(text: string, opacity: number): void;
|
|
1059
|
+
setCaption?(text: string): void;
|
|
1060
|
+
setEffects?(effects: readonly RunningEffect[]): void;
|
|
1061
|
+
setMediaTime?(mediaId: string, timeSeconds: number): void;
|
|
1062
|
+
}
|
|
1063
|
+
/** Pure in-memory board implementation suitable for headless simulation, testing, and SSR. */
|
|
1064
|
+
declare class MemorySceneBoard implements SceneBoard {
|
|
1065
|
+
private view;
|
|
1066
|
+
private elMap;
|
|
1067
|
+
private currentTitle;
|
|
1068
|
+
private currentCaption;
|
|
1069
|
+
private runningEffects;
|
|
1070
|
+
constructor(stage?: Stage);
|
|
1071
|
+
getView(): View;
|
|
1072
|
+
setView(view: View): void;
|
|
1073
|
+
elements(): readonly SceneElement[];
|
|
1074
|
+
runCommand(cmd: SceneCommand): void;
|
|
1075
|
+
setTitle(text: string): void;
|
|
1076
|
+
setCaption(text: string): void;
|
|
1077
|
+
setEffects(effects: readonly RunningEffect[]): void;
|
|
1078
|
+
}
|
|
1079
|
+
interface PlayOptions {
|
|
1080
|
+
check?: boolean;
|
|
1081
|
+
afterShot?: (log: ShotLog) => void | Promise<void>;
|
|
1082
|
+
}
|
|
1083
|
+
interface PlayResult {
|
|
1084
|
+
ok: boolean;
|
|
1085
|
+
duration: number;
|
|
1086
|
+
shots: ShotLog[];
|
|
1087
|
+
}
|
|
1088
|
+
/**
|
|
1089
|
+
* Plays a scene's shots sequentially on `board` driven by `clock`.
|
|
1090
|
+
* When using a `ManualClock`, the execution is completely deterministic and stepped.
|
|
1091
|
+
*/
|
|
1092
|
+
declare function playScene(scene: Scene, board: SceneBoard, clock: Clock, options?: PlayOptions): Promise<PlayResult>;
|
|
1093
|
+
/**
|
|
1094
|
+
* Simulates a scene instantaneously using a ManualClock and MemorySceneBoard,
|
|
1095
|
+
* returning full timing details, layout checks, and diagnostic report.
|
|
1096
|
+
*/
|
|
1097
|
+
declare function simulateScene(scene: Scene, options?: {
|
|
1098
|
+
minTextPx?: number;
|
|
1099
|
+
}): Promise<{
|
|
1100
|
+
result: PlayResult;
|
|
1101
|
+
review: Review;
|
|
1102
|
+
}>;
|
|
1103
|
+
|
|
1104
|
+
/**
|
|
1105
|
+
* Generates a self-contained, standalone HTML player for an animated scene.
|
|
1106
|
+
* Includes interactive playback controls, camera panning/zooming, title and caption rendering,
|
|
1107
|
+
* and embedded WebGL fragment shaders for bespoke motion graphics.
|
|
1108
|
+
*/
|
|
1109
|
+
declare function standaloneSceneHtml(scene: Scene): string;
|
|
1110
|
+
|
|
1111
|
+
type ReplicatorPattern = 'grid' | 'line' | 'circle' | 'spiral';
|
|
1112
|
+
interface ReplicatorSequence {
|
|
1113
|
+
/** Property to modulate per item. */
|
|
1114
|
+
property?: 'opacity' | 'rotation' | 'scale' | 'x' | 'y';
|
|
1115
|
+
/** Incremental offset or delta added per instance. */
|
|
1116
|
+
offset?: number;
|
|
1117
|
+
/** Milliseconds delay per instance for staggered triggers. */
|
|
1118
|
+
delayPerItem?: number;
|
|
1119
|
+
}
|
|
1120
|
+
interface ReplicatorConfig {
|
|
1121
|
+
pattern: ReplicatorPattern;
|
|
1122
|
+
count: number;
|
|
1123
|
+
/** Origin point [x, y] to anchor the layout (defaults to prototype.x, prototype.y). */
|
|
1124
|
+
origin?: [number, number];
|
|
1125
|
+
columns?: number;
|
|
1126
|
+
rows?: number;
|
|
1127
|
+
columnSpacing?: number;
|
|
1128
|
+
rowSpacing?: number;
|
|
1129
|
+
startPoint?: [number, number];
|
|
1130
|
+
endPoint?: [number, number];
|
|
1131
|
+
spacing?: number;
|
|
1132
|
+
radius?: number;
|
|
1133
|
+
startAngle?: number;
|
|
1134
|
+
spiralTightness?: number;
|
|
1135
|
+
sequence?: ReplicatorSequence;
|
|
1136
|
+
}
|
|
1137
|
+
/**
|
|
1138
|
+
* Procedurally replicates a prototype SceneElement into an array of positioned
|
|
1139
|
+
* and sequenced instances (grid, circular array, line, or spiral).
|
|
1140
|
+
*/
|
|
1141
|
+
declare function expandReplicator(prototype: SceneElement, config: ReplicatorConfig): SceneElement[];
|
|
1142
|
+
|
|
1143
|
+
/**
|
|
1144
|
+
* Constant-Velocity Spatial Motion Paths & Arc-Length Parameterization.
|
|
1145
|
+
*
|
|
1146
|
+
* Implements multi-segment cubic Bezier spatial trajectories with numerical
|
|
1147
|
+
* arc-length integration, ensuring constant pixel-speed traversal, tangent heading,
|
|
1148
|
+
* normal vectors, curvature, and seamless combination with temporal AE keyframe easing.
|
|
1149
|
+
*/
|
|
1150
|
+
|
|
1151
|
+
type Vec2 = [number, number];
|
|
1152
|
+
type Vec3 = [number, number, number];
|
|
1153
|
+
interface PathWaypoint {
|
|
1154
|
+
/** Anchor position in 2D or 3D scene coordinates [x, y] or [x, y, z]. */
|
|
1155
|
+
point: Vec2 | Vec3;
|
|
1156
|
+
/** In-tangent handle relative to anchor point (vector pointing from handle to anchor or vice-versa). Default: [0, 0, 0] */
|
|
1157
|
+
inTangent?: Vec2 | Vec3;
|
|
1158
|
+
/** Out-tangent handle relative to anchor point (vector pointing from anchor toward next handle). Default: [0, 0, 0] */
|
|
1159
|
+
outTangent?: Vec2 | Vec3;
|
|
1160
|
+
}
|
|
1161
|
+
interface SpatialPathSample {
|
|
1162
|
+
/** Position on curve [x, y, z]. */
|
|
1163
|
+
position: Vec3;
|
|
1164
|
+
/** Normalized unit tangent vector [dx, dy, dz]. */
|
|
1165
|
+
tangent: Vec3;
|
|
1166
|
+
/** 2D heading angle in radians (atan2(dy, dx)). */
|
|
1167
|
+
heading: number;
|
|
1168
|
+
/** 2D unit normal vector [-dy, dx, 0]. */
|
|
1169
|
+
normal: Vec3;
|
|
1170
|
+
/** Instantaneous curvature kappa (1 / radius of curvature). */
|
|
1171
|
+
curvature: number;
|
|
1172
|
+
/** Distance traversed along the path in absolute units. */
|
|
1173
|
+
distance: number;
|
|
1174
|
+
}
|
|
1175
|
+
interface SegmentSample {
|
|
1176
|
+
t: number;
|
|
1177
|
+
s: number;
|
|
1178
|
+
pos: Vec3;
|
|
1179
|
+
}
|
|
1180
|
+
interface PathSegment {
|
|
1181
|
+
p0: Vec3;
|
|
1182
|
+
p1: Vec3;
|
|
1183
|
+
p2: Vec3;
|
|
1184
|
+
p3: Vec3;
|
|
1185
|
+
length: number;
|
|
1186
|
+
samples: SegmentSample[];
|
|
1187
|
+
}
|
|
1188
|
+
interface SpatialMotionPath {
|
|
1189
|
+
waypoints: PathWaypoint[];
|
|
1190
|
+
closed: boolean;
|
|
1191
|
+
totalLength: number;
|
|
1192
|
+
segments: PathSegment[];
|
|
1193
|
+
}
|
|
1194
|
+
/**
|
|
1195
|
+
* Creates and compiles a constant-velocity SpatialMotionPath from a sequence of waypoints.
|
|
1196
|
+
* Computes fine-grained arc-length tables along all Bezier segments.
|
|
1197
|
+
*/
|
|
1198
|
+
declare function createMotionPath(waypoints: PathWaypoint[], options?: {
|
|
1199
|
+
closed?: boolean;
|
|
1200
|
+
resolution?: number;
|
|
1201
|
+
}): SpatialMotionPath;
|
|
1202
|
+
/**
|
|
1203
|
+
* Samples the spatial motion path at a normalized distance fraction [0..1].
|
|
1204
|
+
* Guarantees strictly constant pixel speed regardless of control handle asymmetry.
|
|
1205
|
+
*/
|
|
1206
|
+
declare function sampleMotionPath(path: SpatialMotionPath, distanceFraction: number): SpatialPathSample;
|
|
1207
|
+
/**
|
|
1208
|
+
* Samples a spatial motion path driven by elapsed time and AE keyframe velocity easing.
|
|
1209
|
+
* Combines spatial arc-length constancy with temporal speed curves.
|
|
1210
|
+
*/
|
|
1211
|
+
declare function sampleMotionPathAtTime(path: SpatialMotionPath, time: number, duration: number, ease?: {
|
|
1212
|
+
easeIn?: KeyframeEase;
|
|
1213
|
+
easeOut?: KeyframeEase;
|
|
1214
|
+
}): SpatialPathSample;
|
|
1215
|
+
|
|
1216
|
+
interface AgentToolDefinition {
|
|
1217
|
+
name: string;
|
|
1218
|
+
description: string;
|
|
1219
|
+
input_schema: Record<string, unknown>;
|
|
1220
|
+
}
|
|
1221
|
+
declare const FLAIR_AGENT_TOOLS: AgentToolDefinition[];
|
|
1222
|
+
type SceneToolResult = {
|
|
1223
|
+
ok: true;
|
|
1224
|
+
scene: Scene;
|
|
1225
|
+
issues: SceneIssue[];
|
|
1226
|
+
review?: Review;
|
|
1227
|
+
} | {
|
|
1228
|
+
ok: false;
|
|
1229
|
+
error: string;
|
|
1230
|
+
};
|
|
1231
|
+
/**
|
|
1232
|
+
* Pure state machine that applies tool operations to a Scene.
|
|
1233
|
+
*/
|
|
1234
|
+
declare function applySceneTool(scene: Scene, toolName: string, input?: Record<string, any>): Promise<SceneToolResult>;
|
|
1235
|
+
|
|
1236
|
+
/**
|
|
1237
|
+
* Atomic Agent Multi-Tool Batching with Result Variable Substitution.
|
|
1238
|
+
* Inspired by EffectCraft's atomic batch execution protocol.
|
|
1239
|
+
*
|
|
1240
|
+
* Allows AI agents to execute multi-step modifications to a Scene in a single turn,
|
|
1241
|
+
* with atomic rollback on failure and cross-step variable substitution ($1.prop, $2.prop).
|
|
1242
|
+
*/
|
|
1243
|
+
|
|
1244
|
+
interface BatchCommand {
|
|
1245
|
+
/** Name of the tool to execute (e.g. 'update_shot', 'insert_shots', 'set_rig_widget'). */
|
|
1246
|
+
tool: string;
|
|
1247
|
+
/** Parameters for the tool call. */
|
|
1248
|
+
params?: Record<string, any>;
|
|
1249
|
+
}
|
|
1250
|
+
interface BatchExecutionStepResult {
|
|
1251
|
+
step: number;
|
|
1252
|
+
tool: string;
|
|
1253
|
+
result: SceneToolResult;
|
|
1254
|
+
}
|
|
1255
|
+
interface BatchExecutionResult {
|
|
1256
|
+
ok: boolean;
|
|
1257
|
+
scene: Scene;
|
|
1258
|
+
steps: BatchExecutionStepResult[];
|
|
1259
|
+
error?: string;
|
|
1260
|
+
failedStep?: number;
|
|
1261
|
+
}
|
|
1262
|
+
/**
|
|
1263
|
+
* Recursively substitutes `$stepIndex.path` references in parameters using previous step results.
|
|
1264
|
+
* E.g., "$1.scene.shots[0].duration" -> substituted with the duration value from step 1 result.
|
|
1265
|
+
*/
|
|
1266
|
+
declare function substituteVariables(value: any, stepResults: Map<number, SceneToolResult>): any;
|
|
1267
|
+
/**
|
|
1268
|
+
* Executes an atomic batch of scene tools with transactional rollback.
|
|
1269
|
+
* If any step fails, the scene rolls back to the initial state and returns the failure.
|
|
1270
|
+
*
|
|
1271
|
+
* @param scene Initial scene state before batch.
|
|
1272
|
+
* @param commands Ordered array of tool commands to execute.
|
|
1273
|
+
*/
|
|
1274
|
+
declare function applySceneBatch(scene: Scene, commands: BatchCommand[]): Promise<BatchExecutionResult>;
|
|
1275
|
+
|
|
1276
|
+
interface MotnExportOptions {
|
|
1277
|
+
frameRate?: number;
|
|
1278
|
+
}
|
|
1279
|
+
/**
|
|
1280
|
+
* Serializes a Flair Scene into Apple Motion ozml 4.0 XML document format (.motn).
|
|
1281
|
+
*/
|
|
1282
|
+
declare function exportMotn(scene: Scene, options?: MotnExportOptions): string;
|
|
1283
|
+
|
|
1284
|
+
/**
|
|
1285
|
+
* Lottie JSON Vector Animation Exporter.
|
|
1286
|
+
*
|
|
1287
|
+
* Converts Flair scenes, elements, shapes, transforms, and keyframes into
|
|
1288
|
+
* official Lottie JSON format (v5.5.2) compatible with Airbnb Lottie-Web,
|
|
1289
|
+
* iOS/Android Lottie, Figma, and Telegram.
|
|
1290
|
+
*/
|
|
1291
|
+
|
|
1292
|
+
interface LottieExportOptions {
|
|
1293
|
+
/** Target framerate in fps. Default: 30 */
|
|
1294
|
+
frameRate?: number;
|
|
1295
|
+
}
|
|
1296
|
+
interface LottieKeyframe<T> {
|
|
1297
|
+
t: number;
|
|
1298
|
+
s: T;
|
|
1299
|
+
e?: T;
|
|
1300
|
+
o?: {
|
|
1301
|
+
x: number | number[];
|
|
1302
|
+
y: number | number[];
|
|
1303
|
+
};
|
|
1304
|
+
i?: {
|
|
1305
|
+
x: number | number[];
|
|
1306
|
+
y: number | number[];
|
|
1307
|
+
};
|
|
1308
|
+
h?: number;
|
|
1309
|
+
}
|
|
1310
|
+
interface LottieAnimatable<T, K = T> {
|
|
1311
|
+
a: 0 | 1;
|
|
1312
|
+
k: T | LottieKeyframe<K>[];
|
|
1313
|
+
}
|
|
1314
|
+
interface LottieTransform {
|
|
1315
|
+
p: LottieAnimatable<[number, number, number], [number, number, number]>;
|
|
1316
|
+
a: LottieAnimatable<[number, number, number], [number, number, number]>;
|
|
1317
|
+
s: LottieAnimatable<[number, number, number], [number, number, number]>;
|
|
1318
|
+
r: LottieAnimatable<number, [number]>;
|
|
1319
|
+
o: LottieAnimatable<number, [number]>;
|
|
1320
|
+
}
|
|
1321
|
+
interface LottieShapeItem {
|
|
1322
|
+
ty: string;
|
|
1323
|
+
nm?: string;
|
|
1324
|
+
[key: string]: unknown;
|
|
1325
|
+
}
|
|
1326
|
+
interface LottieLayer {
|
|
1327
|
+
ddd: 0 | 1;
|
|
1328
|
+
ind: number;
|
|
1329
|
+
ty: number;
|
|
1330
|
+
nm: string;
|
|
1331
|
+
sr: number;
|
|
1332
|
+
ks: LottieTransform;
|
|
1333
|
+
ao: 0 | 1;
|
|
1334
|
+
ip: number;
|
|
1335
|
+
op: number;
|
|
1336
|
+
st: number;
|
|
1337
|
+
bm: number;
|
|
1338
|
+
shapes?: LottieShapeItem[];
|
|
1339
|
+
sw?: number;
|
|
1340
|
+
sh?: number;
|
|
1341
|
+
sc?: string;
|
|
1342
|
+
}
|
|
1343
|
+
interface LottieAnimation {
|
|
1344
|
+
v: string;
|
|
1345
|
+
fr: number;
|
|
1346
|
+
ip: number;
|
|
1347
|
+
op: number;
|
|
1348
|
+
w: number;
|
|
1349
|
+
h: number;
|
|
1350
|
+
nm: string;
|
|
1351
|
+
ddd: 0;
|
|
1352
|
+
assets: unknown[];
|
|
1353
|
+
layers: LottieLayer[];
|
|
1354
|
+
}
|
|
1355
|
+
/**
|
|
1356
|
+
* Maps AE speed and influence into normalized Lottie Bezier ease control points (o.x, o.y, i.x, i.y).
|
|
1357
|
+
*/
|
|
1358
|
+
declare function createLottieEase(durationFrames: number, deltaVal: number, outEase?: KeyframeEase, inEase?: KeyframeEase): {
|
|
1359
|
+
o: {
|
|
1360
|
+
x: number;
|
|
1361
|
+
y: number;
|
|
1362
|
+
};
|
|
1363
|
+
i: {
|
|
1364
|
+
x: number;
|
|
1365
|
+
y: number;
|
|
1366
|
+
};
|
|
1367
|
+
};
|
|
1368
|
+
/**
|
|
1369
|
+
* Serializes a Flair Scene into standard Lottie JSON animation.
|
|
1370
|
+
*/
|
|
1371
|
+
declare function exportLottie(scene: Scene, options?: LottieExportOptions): LottieAnimation;
|
|
1372
|
+
|
|
1373
|
+
interface Fcp7ExportOptions {
|
|
1374
|
+
/** Timeline timebase / frame rate (default 30). */
|
|
1375
|
+
frameRate?: number;
|
|
1376
|
+
/** NTSC flag (default false, or true if 29.97 / 59.94). */
|
|
1377
|
+
ntsc?: boolean;
|
|
1378
|
+
/** Starting timecode (default "00:00:00:00"). */
|
|
1379
|
+
timecodeStart?: string;
|
|
1380
|
+
/** Sequence name override. */
|
|
1381
|
+
sequenceName?: string;
|
|
1382
|
+
/** Media path prefix or file base URL (default "file://localhost/media/"). */
|
|
1383
|
+
mediaPathPrefix?: string;
|
|
1384
|
+
/** Include text generator overlay track for titles/captions (default true). */
|
|
1385
|
+
includeTextTrack?: boolean;
|
|
1386
|
+
/** Include timeline sequence markers (default true). */
|
|
1387
|
+
includeMarkers?: boolean;
|
|
1388
|
+
}
|
|
1389
|
+
interface EdlExportOptions {
|
|
1390
|
+
/** Timeline timebase / frame rate (default 30). */
|
|
1391
|
+
frameRate?: number;
|
|
1392
|
+
/** Drop frame flag (default false). */
|
|
1393
|
+
dropFrame?: boolean;
|
|
1394
|
+
/** Starting timecode (default "01:00:00:00" as per standard broadcast EDL practice). */
|
|
1395
|
+
timecodeStart?: string;
|
|
1396
|
+
/** Reel name identifier (default "AX", max 8 chars). */
|
|
1397
|
+
reel?: string;
|
|
1398
|
+
}
|
|
1399
|
+
interface ShotTiming {
|
|
1400
|
+
shot: Shot;
|
|
1401
|
+
index: number;
|
|
1402
|
+
startFrame: number;
|
|
1403
|
+
endFrame: number;
|
|
1404
|
+
durationFrames: number;
|
|
1405
|
+
startMs: number;
|
|
1406
|
+
durationMs: number;
|
|
1407
|
+
}
|
|
1408
|
+
/**
|
|
1409
|
+
* Calculates start and duration frame boundaries for each shot in a scene.
|
|
1410
|
+
*/
|
|
1411
|
+
declare function calculateShotTimings(scene: Scene, frameRate?: number): ShotTiming[];
|
|
1412
|
+
/**
|
|
1413
|
+
* Converts frame count to standard SMPTE timecode HH:MM:SS:FF.
|
|
1414
|
+
*/
|
|
1415
|
+
declare function framesToTimecode(frame: number, timebase?: number, dropFrame?: boolean): string;
|
|
1416
|
+
/**
|
|
1417
|
+
* Converts standard SMPTE timecode HH:MM:SS:FF to frame count.
|
|
1418
|
+
*/
|
|
1419
|
+
declare function timecodeToFrames(timecode: string, timebase?: number, dropFrame?: boolean): number;
|
|
1420
|
+
/**
|
|
1421
|
+
* Serializes a Flair Scene into Apple Final Cut Pro 7 XML Interchange Format (xmeml v4).
|
|
1422
|
+
* Compatible with Premiere Pro, DaVinci Resolve, and Final Cut Pro.
|
|
1423
|
+
*/
|
|
1424
|
+
declare function exportFcp7Xml(scene: Scene, options?: Fcp7ExportOptions): string;
|
|
1425
|
+
/**
|
|
1426
|
+
* Serializes a Flair Scene into standard CMX 3600 Edit Decision List (EDL).
|
|
1427
|
+
* Fully readable by DaVinci Resolve, Premiere Pro, Avid, and Lightworks.
|
|
1428
|
+
*/
|
|
1429
|
+
declare function exportCmx3600Edl(scene: Scene, options?: EdlExportOptions): string;
|
|
1430
|
+
|
|
1431
|
+
export { ALL_BLEND_MODES, ALL_TRANSITION_TYPES, type AgentToolDefinition, type AscCdl, type BatchCommand, type BatchExecutionResult, type BatchExecutionStepResult, type Behavior, type BehaviorBase, type BlendMode, type BlockDissolveOptions, type BlurEffect, type BurstEffect, CAMERA_MS, COMMON_FRAME_RATES, type ClearCommand, Clock, type ColorRGB, type ColorRGBA, type ColorRgba, type ColorSpace, ControlDef, ControlValue, type CounterEffect, type CrossZoomOptions, type CustomCommand, DEFAULT_STAGE, type DeleteCommand, type DynamicFraming, EASY_EASE, EFFECT_FADE_MS, EFFECT_TYPES, type EasingCurve, type EdlExportOptions, type Effect, type EffectBase, type ElementCommand, FLAIR_AGENT_TOOLS, type Fcp7ExportOptions, type FlowEffect, type FramingOptions, type GifOptions, type GlassWipeOptions, type GlowEffect, type GradientEffect, type GridWipeOptions, type HighlightEffect, type KeyframeEase, type LiftGammaGain, type LightLeakOptions, type LinearWipeOptions, type LottieAnimatable, type LottieAnimation, type LottieExportOptions, type LottieKeyframe, type LottieLayer, type LottieShapeItem, type LottieTransform, type MediaEffect, MemorySceneBoard, type MotnExportOptions, NO_CHECK, type OscillateBehavior, type OvershootBehavior, type PathWaypoint, type PlayOptions, type PlayResult, type Point, type PopupWidget, type RadialIrisOptions, type RampBehavior, type RateBehavior, type RationalFrameRate, type Rect, type RenderOptions, type ReplicatorConfig, type ReplicatorPattern, type ReplicatorSequence, type Review, type ReviewOptions, type RigWidget, type RippleEffect, type RunningEffect, SMALL_TEXT_PX, type SMPTEFields, type Scene, type SceneBoard, type SceneCommand, type SceneElement, type SceneIssue, type SceneMedia, type SceneRig, type SceneToolResult, ShaderFrames, type ShaderFramesOptions, type ShimmerEffect, type Shot, type ShotCamera, type ShotCheck, type ShotLog, type ShotTiming, type SliderSnapshot, type SliderWidget, type SpatialMotionPath, type SpatialPathSample, type SpotlightEffect, type Stage, type StandaloneOptions, type StandardFrameRateKey, type ThrowBehavior, type ThumbnailHandle, ThumbnailPool, type ThumbnailPoolOptions, type TimerEffect, type ToggleWidget, type TransitionOptions, type TransitionSample, type TransitionType, type TwisterOptions, type UpdateCommand, type Vec2, type Vec3, type View, type WriggleBehavior, applyAscCdl, applyLiftGammaGain, applyRig, applySceneBatch, applySceneTool, applyVibrance, areaOf, between, bez1d, bez1dDerivative, blendRgba, blendTransitionPixel, boardHeight, boundsOf, calculateFramingRect, calculateShotTimings, centreOf, checkShot, convertColorSpace, createFrameRate, createLottieEase, createMotionPath, easeInOutCubic, easeProgress, effectGone, effectOpacity, evaluateBehavior, evaluateKeyframeSegment, expandReplicator, exportCmx3600Edl, exportFcp7Xml, exportLottie, exportMotn, formatTimecode, fractalWiggle, frame, framesToSMPTE, framesToTimecode, getColorGradingGLSL, getDropFrameCount, getGlslBlendFunction, getOklabGLSL, getTimecodeBase, getTransitionGLSL, getWhiteBalanceGains, hash64, holdTime, interpolateOklab, interpolateOklch, isDeleteCommand, isElementCommand, isUpdateCommand, linearRgbToSrgb, linearSrgbToOklab, linearToSrgb, loopTime, mixSeeds, noise1d, noise3d, oklabToLinearSrgb, oklabToOklch, oklabToSrgb, oklchToOklab, overlapArea, parseTimecode, pingPongTime, playScene, quinticFade, recordGif, registerThumbnail, reviewScene, sampleMotionPath, sampleMotionPathAtTime, sampleTransition, setRigWidget, sharedThumbnailPool, simulateScene, smpteToFrames, solveBezierU, speedRampTime, srgbToLinear, srgbToLinearRgb, srgbToOklab, standaloneHtml, standaloneSceneHtml, strobeTime, substituteVariables, supportsDropFrame, timecodeToFrames, titleBox, touchedIds, unitFloat, validateScene, viewAt, visibleRect };
|