onda-engine 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/LICENSE +106 -0
- package/LICENSE-APACHE +202 -0
- package/README.md +84 -0
- package/dist/chunk-NCNYMPIQ.js +12763 -0
- package/dist/chunk-NCNYMPIQ.js.map +1 -0
- package/dist/cinema.d.ts +580 -0
- package/dist/cinema.js +1687 -0
- package/dist/cinema.js.map +1 -0
- package/dist/components-manifest.d.ts +2 -0
- package/dist/components-manifest.js +3 -0
- package/dist/components-manifest.js.map +1 -0
- package/dist/components.d.ts +3480 -0
- package/dist/components.js +11486 -0
- package/dist/components.js.map +1 -0
- package/dist/index.d.ts +101 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest-7N3yu9tB.d.ts +131 -0
- package/dist/player.d.ts +177 -0
- package/dist/player.js +1749 -0
- package/dist/player.js.map +1 -0
- package/dist/react.d.ts +2141 -0
- package/dist/react.js +2052 -0
- package/dist/react.js.map +1 -0
- package/dist/render.d.ts +42 -0
- package/dist/render.js +113 -0
- package/dist/render.js.map +1 -0
- package/dist/wasm/pkg/onda_wasm.js +598 -0
- package/dist/wasm/pkg/onda_wasm_bg.wasm +0 -0
- package/dist/wasm-audio/pkg/onda_wasm_audio.js +417 -0
- package/dist/wasm-audio/pkg/onda_wasm_audio_bg.wasm +0 -0
- package/dist/wasm-vello/index.js +32 -0
- package/dist/wasm-vello/pkg/onda_wasm_vello.js +1325 -0
- package/dist/wasm-vello/pkg/onda_wasm_vello_bg.wasm +0 -0
- package/package.json +112 -0
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,2141 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactElement, ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
type EasingFn = (t: number) => number;
|
|
5
|
+
/** Easing presets + factories. Remotion-compatible: use a preset as an `EasingFn`
|
|
6
|
+
* (`Easing.linear`, `Easing.cubic`, …) or call the `Easing.bezier(x1,y1,x2,y2)`
|
|
7
|
+
* factory. The Remotion-named curves (`quad`/`cubic`/`sin`/`ease`/`bezier`) exist
|
|
8
|
+
* so components authored against Remotion port without rewriting their easing. */
|
|
9
|
+
declare const Easing: {
|
|
10
|
+
linear: (t: number) => number;
|
|
11
|
+
quad: (t: number) => number;
|
|
12
|
+
cubic: (t: number) => number;
|
|
13
|
+
sin: (t: number) => number;
|
|
14
|
+
ease: EasingFn;
|
|
15
|
+
easeInQuad: (t: number) => number;
|
|
16
|
+
easeOutQuad: (t: number) => number;
|
|
17
|
+
easeInOutQuad: (t: number) => number;
|
|
18
|
+
easeInCubic: (t: number) => number;
|
|
19
|
+
easeOutCubic: (t: number) => number;
|
|
20
|
+
easeInOutCubic: (t: number) => number;
|
|
21
|
+
smoothStep: (t: number) => number;
|
|
22
|
+
easeInBack: (t: number) => number;
|
|
23
|
+
easeOutBack: (t: number) => number;
|
|
24
|
+
/** CSS cubic-bézier factory — Remotion's `Easing.bezier(x1,y1,x2,y2)`. */
|
|
25
|
+
bezier: (x1: number, y1: number, x2: number, y2: number) => EasingFn;
|
|
26
|
+
};
|
|
27
|
+
/** A CSS-style cubic-bézier ease with control points `(x1,y1)`, `(x2,y2)` and
|
|
28
|
+
* fixed endpoints `(0,0)`–`(1,1)`. Matches `onda-animation`'s `CubicBezier`. */
|
|
29
|
+
declare function cubicBezier(x1: number, y1: number, x2: number, y2: number): EasingFn;
|
|
30
|
+
interface InterpolateOptions {
|
|
31
|
+
easing?: EasingFn;
|
|
32
|
+
/** How to handle inputs below the range. Default `'clamp'`. */
|
|
33
|
+
extrapolateLeft?: 'clamp' | 'extend';
|
|
34
|
+
/** How to handle inputs above the range. Default `'clamp'`. */
|
|
35
|
+
extrapolateRight?: 'clamp' | 'extend';
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Map `input` from `inputRange` to `outputRange` (both ascending, equal length
|
|
39
|
+
* ≥ 2). Out-of-range inputs clamp by default. Example:
|
|
40
|
+
* `interpolate(frame, [0, 30], [0, 1])` fades in over 30 frames.
|
|
41
|
+
*/
|
|
42
|
+
declare function interpolate(input: number, inputRange: readonly number[], outputRange: readonly number[], options?: InterpolateOptions): number;
|
|
43
|
+
|
|
44
|
+
interface Vec2 {
|
|
45
|
+
x: number;
|
|
46
|
+
y: number;
|
|
47
|
+
}
|
|
48
|
+
interface Size {
|
|
49
|
+
width: number;
|
|
50
|
+
height: number;
|
|
51
|
+
}
|
|
52
|
+
/** Straight-alpha sRGB, components in 0..1. `a` defaults to 1 on the Rust side. */
|
|
53
|
+
interface Color {
|
|
54
|
+
r: number;
|
|
55
|
+
g: number;
|
|
56
|
+
b: number;
|
|
57
|
+
a?: number;
|
|
58
|
+
}
|
|
59
|
+
interface Transform {
|
|
60
|
+
translate?: Vec2;
|
|
61
|
+
scale?: Vec2;
|
|
62
|
+
/** Clockwise rotation in degrees about `origin` (default the local origin). */
|
|
63
|
+
rotate?: number;
|
|
64
|
+
/** Pivot for scale + rotation in local space (CSS transform-origin). Default (0,0). */
|
|
65
|
+
origin?: Vec2;
|
|
66
|
+
}
|
|
67
|
+
/** A drop shadow / glow behind a shape (mirrors onda-scene's `Shadow`). */
|
|
68
|
+
interface Shadow {
|
|
69
|
+
color: Color;
|
|
70
|
+
/** Gaussian blur std-dev in px. */
|
|
71
|
+
blur: number;
|
|
72
|
+
/** Shadow offset from the shape; default (0,0) = a centered glow. */
|
|
73
|
+
offset?: Vec2;
|
|
74
|
+
/** Grow the shadow box by this many px on every side. Default 0. */
|
|
75
|
+
spread?: number;
|
|
76
|
+
}
|
|
77
|
+
interface Stroke {
|
|
78
|
+
color: Color;
|
|
79
|
+
width: number;
|
|
80
|
+
/** End-cap style (CSS stroke-linecap). Default 'butt'. */
|
|
81
|
+
cap?: 'butt' | 'round' | 'square';
|
|
82
|
+
/** Corner-join style (CSS stroke-linejoin). Default 'miter'. */
|
|
83
|
+
join?: 'miter' | 'round' | 'bevel';
|
|
84
|
+
/** Dash pattern: alternating on/off lengths in px. Omit for a solid stroke. */
|
|
85
|
+
dash?: number[];
|
|
86
|
+
/** Phase offset into the dash pattern (px) — animate for a draw-on reveal. */
|
|
87
|
+
dash_offset?: number;
|
|
88
|
+
/** Trim paths: draw only the [start, end] arc-length slice of the stroke (0..1),
|
|
89
|
+
* rotated by offset. Animate end 0→1 for a line-draw. */
|
|
90
|
+
trim?: {
|
|
91
|
+
start?: number;
|
|
92
|
+
end?: number;
|
|
93
|
+
offset?: number;
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
interface Composition$1 {
|
|
97
|
+
width: number;
|
|
98
|
+
height: number;
|
|
99
|
+
fps: number;
|
|
100
|
+
duration_in_frames: number;
|
|
101
|
+
/** Opt-in cinematic LINEAR + ACES finishing pipeline (gpu/export only). */
|
|
102
|
+
linear?: boolean;
|
|
103
|
+
/** Composition-level cinematic finish: a linear-HDR finishing chain + ACES tone-map
|
|
104
|
+
* run after the comp rasterizes (gpu/export only). */
|
|
105
|
+
finish?: Finish;
|
|
106
|
+
}
|
|
107
|
+
/** Composition-level cinematic finish (linear HDR + ACES). See {@link Composition.finish}. */
|
|
108
|
+
interface Finish {
|
|
109
|
+
/** Linear exposure multiplier before the tone-map (1 = neutral). */
|
|
110
|
+
exposure?: number;
|
|
111
|
+
/** Comp-level bloom in linear HDR. */
|
|
112
|
+
bloom?: {
|
|
113
|
+
sigma: number;
|
|
114
|
+
threshold?: number;
|
|
115
|
+
intensity?: number;
|
|
116
|
+
};
|
|
117
|
+
/** Warm halation around highlights (0 = off). */
|
|
118
|
+
halation?: number;
|
|
119
|
+
/** Grade: white-balance (+ warm / − cool; 0 = neutral). */
|
|
120
|
+
temperature?: number;
|
|
121
|
+
/** Grade: contrast around mid-grey (1 = identity). */
|
|
122
|
+
contrast?: number;
|
|
123
|
+
/** Grade: saturation (1 = identity, 0 = greyscale). */
|
|
124
|
+
saturation?: number;
|
|
125
|
+
/** Vignette: radial edge darkening (0 = off). */
|
|
126
|
+
vignette?: number;
|
|
127
|
+
/** Film-grain intensity, added in linear (0 = off). */
|
|
128
|
+
grain?: number;
|
|
129
|
+
/** Grain animation seed (the reconciler injects the current frame). */
|
|
130
|
+
grain_seed?: number;
|
|
131
|
+
/** A cinematic 3D color LUT (`.cube`-style lookup table) applied as the FINAL
|
|
132
|
+
* finish step, in DISPLAY space (after the grade + ACES tone-map + sRGB encode),
|
|
133
|
+
* as a trilinear lookup. `table` holds `size³` RGB triples in 0..1, **red varying
|
|
134
|
+
* fastest, then green, then blue** (the entry for grid cell (r,g,b) is at
|
|
135
|
+
* `((b*size + g)*size + r) * 3`). Omitted = no LUT (identity). Honored by both the
|
|
136
|
+
* GPU (3D texture) and the CPU reference (software trilinear). */
|
|
137
|
+
lut?: {
|
|
138
|
+
size: number;
|
|
139
|
+
table: number[];
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
type ShapeGeometry = {
|
|
143
|
+
shape: 'rect';
|
|
144
|
+
size: Size;
|
|
145
|
+
corner_radius?: number;
|
|
146
|
+
} | {
|
|
147
|
+
shape: 'ellipse';
|
|
148
|
+
size: Size;
|
|
149
|
+
} | {
|
|
150
|
+
shape: 'path';
|
|
151
|
+
data: string;
|
|
152
|
+
} | {
|
|
153
|
+
shape: 'boolean';
|
|
154
|
+
op: BooleanOp;
|
|
155
|
+
operands: BooleanOperand[];
|
|
156
|
+
};
|
|
157
|
+
/** Boolean (merge-paths) operation for a {@link ShapeGeometry} of `shape: 'boolean'`. */
|
|
158
|
+
type BooleanOp = 'union' | 'difference' | 'intersect' | 'xor';
|
|
159
|
+
/** One input to a boolean geometry: a sub-geometry + the transform placing it. */
|
|
160
|
+
interface BooleanOperand {
|
|
161
|
+
geometry: ShapeGeometry;
|
|
162
|
+
transform: Transform;
|
|
163
|
+
}
|
|
164
|
+
/** A color stop of a {@link Gradient}: a color at offset 0..1. */
|
|
165
|
+
interface GradientStop {
|
|
166
|
+
offset: number;
|
|
167
|
+
color: Color;
|
|
168
|
+
}
|
|
169
|
+
/** A gradient paint, in the shape's local coordinate space. */
|
|
170
|
+
type Gradient = {
|
|
171
|
+
gradient: 'linear';
|
|
172
|
+
start: Vec2;
|
|
173
|
+
end: Vec2;
|
|
174
|
+
stops: GradientStop[];
|
|
175
|
+
} | {
|
|
176
|
+
gradient: 'radial';
|
|
177
|
+
center: Vec2;
|
|
178
|
+
radius: number;
|
|
179
|
+
stops: GradientStop[];
|
|
180
|
+
} | {
|
|
181
|
+
gradient: 'fbm';
|
|
182
|
+
stops: GradientStop[];
|
|
183
|
+
scale?: number;
|
|
184
|
+
time?: number;
|
|
185
|
+
warp?: number;
|
|
186
|
+
};
|
|
187
|
+
/** One styled run of rich text (mirrors onda-scene's `TextRun`). */
|
|
188
|
+
interface SceneTextRun {
|
|
189
|
+
text: string;
|
|
190
|
+
color?: Color;
|
|
191
|
+
font_size?: number;
|
|
192
|
+
font_family?: string;
|
|
193
|
+
weight?: number;
|
|
194
|
+
italic?: boolean;
|
|
195
|
+
}
|
|
196
|
+
type NodeKind = {
|
|
197
|
+
type: 'group';
|
|
198
|
+
} | {
|
|
199
|
+
type: 'text';
|
|
200
|
+
content: string;
|
|
201
|
+
font_size?: number;
|
|
202
|
+
color?: Color;
|
|
203
|
+
font_family?: string;
|
|
204
|
+
weight?: number;
|
|
205
|
+
italic?: boolean;
|
|
206
|
+
letter_spacing?: number;
|
|
207
|
+
runs?: SceneTextRun[];
|
|
208
|
+
} | {
|
|
209
|
+
type: 'image';
|
|
210
|
+
src: string;
|
|
211
|
+
width?: number;
|
|
212
|
+
height?: number;
|
|
213
|
+
fit?: ImageFit;
|
|
214
|
+
blur?: number;
|
|
215
|
+
} | {
|
|
216
|
+
type: 'video';
|
|
217
|
+
src: string;
|
|
218
|
+
/** Source position in seconds of the frame to display. */
|
|
219
|
+
time?: number;
|
|
220
|
+
width?: number;
|
|
221
|
+
height?: number;
|
|
222
|
+
fit?: ImageFit;
|
|
223
|
+
/** Preview-only hint (ignored by renderers + export): how the player should
|
|
224
|
+
* preview a source it can't composite (cross-origin without CORS).
|
|
225
|
+
* `'skip'` (default) leaves it blank + warns; `'element'` overlays a plain
|
|
226
|
+
* `<video>`. Never affects `onda export`. */
|
|
227
|
+
previewFallback?: 'skip' | 'element';
|
|
228
|
+
} | {
|
|
229
|
+
/** A non-visual audio clip (renderers skip it; the player plays it). */
|
|
230
|
+
type: 'audio';
|
|
231
|
+
src: string;
|
|
232
|
+
/** Composition time (seconds) the clip begins at. */
|
|
233
|
+
start?: number;
|
|
234
|
+
/** Seconds into the source to begin from (trim the head). */
|
|
235
|
+
start_at?: number;
|
|
236
|
+
/** Linear gain 0..1. */
|
|
237
|
+
volume?: number;
|
|
238
|
+
} | {
|
|
239
|
+
type: 'shape';
|
|
240
|
+
geometry: ShapeGeometry;
|
|
241
|
+
fill?: Color;
|
|
242
|
+
gradient?: Gradient;
|
|
243
|
+
stroke?: Stroke;
|
|
244
|
+
shadow?: Shadow;
|
|
245
|
+
} | {
|
|
246
|
+
type: 'svg';
|
|
247
|
+
src?: string;
|
|
248
|
+
markup?: string;
|
|
249
|
+
};
|
|
250
|
+
/** How a bitmap is fitted into its `width`×`height` box (mirrors onda-scene's
|
|
251
|
+
* `ImageFit`). The renderer measures the decoded image to compute the scale. */
|
|
252
|
+
type ImageFit = 'fill' | 'cover' | 'contain';
|
|
253
|
+
/** Flex layout for a node's direct children (mirrors onda-scene's `Layout`).
|
|
254
|
+
* Resolved to absolute child transforms by the engine's layout pass. */
|
|
255
|
+
interface Layout {
|
|
256
|
+
direction?: 'row' | 'column';
|
|
257
|
+
justify?: 'start' | 'center' | 'end' | 'space-between' | 'space-around';
|
|
258
|
+
align?: 'start' | 'center' | 'end';
|
|
259
|
+
gap?: number;
|
|
260
|
+
padding?: number;
|
|
261
|
+
/** Wrap children onto multiple lines when they overflow the main axis
|
|
262
|
+
* (CSS `flex-wrap`). Needs a fixed main-axis size (`width`/`height`). */
|
|
263
|
+
wrap?: boolean;
|
|
264
|
+
width?: number;
|
|
265
|
+
height?: number;
|
|
266
|
+
}
|
|
267
|
+
/** An ordered, screen-space effect applied to a node + its subtree via
|
|
268
|
+
* render-to-texture (mirrors onda-scene's internally-tagged `Effect` enum).
|
|
269
|
+
* The subtree renders to an offscreen surface, the chain runs, then the result
|
|
270
|
+
* composites back at the node's transform/opacity/blend/clip. */
|
|
271
|
+
type Effect =
|
|
272
|
+
/** Isolate / precomp: flatten the subtree to one layer (render-to-texture) so the
|
|
273
|
+
* node's opacity/blend apply to the composited result, not per-child. */
|
|
274
|
+
{
|
|
275
|
+
effect: 'isolate';
|
|
276
|
+
}
|
|
277
|
+
/** Gaussian blur; `sigma` = std-dev in OUTPUT px (CSS `blur()`). */
|
|
278
|
+
| {
|
|
279
|
+
effect: 'blur';
|
|
280
|
+
sigma: number;
|
|
281
|
+
}
|
|
282
|
+
/** Directional (motion) blur: a 1D blur of std-dev `sigma` (px) smeared along
|
|
283
|
+
* `angle` (radians, 0 = horizontal) — the cinematic "in-motion" tell. */
|
|
284
|
+
| {
|
|
285
|
+
effect: 'directional_blur';
|
|
286
|
+
sigma: number;
|
|
287
|
+
angle: number;
|
|
288
|
+
}
|
|
289
|
+
/** Chromatic aberration: R/B split by `amount` px radially from centre. */
|
|
290
|
+
| {
|
|
291
|
+
effect: 'chromatic_aberration';
|
|
292
|
+
amount: number;
|
|
293
|
+
}
|
|
294
|
+
/** Vignette: radial edge-darkening, `amount` (0..1) over `softness` (0..1). */
|
|
295
|
+
| {
|
|
296
|
+
effect: 'vignette';
|
|
297
|
+
amount: number;
|
|
298
|
+
softness: number;
|
|
299
|
+
}
|
|
300
|
+
/** Posterize: quantize each channel to `levels` (≥2) steps. */
|
|
301
|
+
| {
|
|
302
|
+
effect: 'posterize';
|
|
303
|
+
levels: number;
|
|
304
|
+
}
|
|
305
|
+
/** Duotone: luma → gradient from `shadow` to `highlight` (RGB, 0..1). */
|
|
306
|
+
| {
|
|
307
|
+
effect: 'duotone';
|
|
308
|
+
shadow: [number, number, number];
|
|
309
|
+
highlight: [number, number, number];
|
|
310
|
+
}
|
|
311
|
+
/** Chroma key: alpha-cut pixels within `threshold` of `key` (RGB 0..1), ramping
|
|
312
|
+
* over `smoothness`. */
|
|
313
|
+
| {
|
|
314
|
+
effect: 'chroma_key';
|
|
315
|
+
key: [number, number, number];
|
|
316
|
+
threshold: number;
|
|
317
|
+
smoothness: number;
|
|
318
|
+
}
|
|
319
|
+
/** Glow / bloom: bright regions (luminance above `threshold`, scaled by
|
|
320
|
+
* `intensity`) are blurred with `sigma` and composited *additively* over the
|
|
321
|
+
* sharp subtree — a bright accent glows a soft halo. */
|
|
322
|
+
| {
|
|
323
|
+
effect: 'bloom';
|
|
324
|
+
threshold: number;
|
|
325
|
+
intensity: number;
|
|
326
|
+
sigma: number;
|
|
327
|
+
}
|
|
328
|
+
/** Cinematic color grade: a per-pixel remap (no blur) — the "land AI media"
|
|
329
|
+
* wedge. `exposure` (linear gain, 0 = identity), `contrast` (1 = identity),
|
|
330
|
+
* `saturation` (1 = identity, 0 = grayscale), `temperature` (warm/cool on R/B,
|
|
331
|
+
* 0 = neutral) and `tint` (green/magenta on G, 0 = neutral). */
|
|
332
|
+
| {
|
|
333
|
+
effect: 'color_grade';
|
|
334
|
+
exposure: number;
|
|
335
|
+
contrast: number;
|
|
336
|
+
saturation: number;
|
|
337
|
+
temperature: number;
|
|
338
|
+
tint: number;
|
|
339
|
+
}
|
|
340
|
+
/** Gooey / liquid / metaball morph: the subtree is blurred with `sigma`, then
|
|
341
|
+
* its alpha is sharpened around `threshold` (0..1 cutoff) so overlapping shapes
|
|
342
|
+
* fuse into solid forms joined by smooth necks (the "drops coalescing" look). */
|
|
343
|
+
| {
|
|
344
|
+
effect: 'goo';
|
|
345
|
+
sigma: number;
|
|
346
|
+
threshold: number;
|
|
347
|
+
}
|
|
348
|
+
/** Film grain — luminance-banded, animated monochrome noise added late over the
|
|
349
|
+
* subtree (the compositing "glue" that unifies mismatched sources, and the dither
|
|
350
|
+
* that hides 8-bit banding on dark gradients). Peaks in the midtones, clean at
|
|
351
|
+
* pure black/white. `intensity` ~0.04–0.1 is filmic, `size` is the grain scale in
|
|
352
|
+
* px (~1 = fine), `seed` an animation offset — pass the frame for living grain. */
|
|
353
|
+
| {
|
|
354
|
+
effect: 'grain';
|
|
355
|
+
intensity: number;
|
|
356
|
+
size: number;
|
|
357
|
+
seed: number;
|
|
358
|
+
}
|
|
359
|
+
/** Frosted glass (CSS `backdrop-filter`). The ODD ONE OUT: instead of capturing
|
|
360
|
+
* this node's OWN subtree, it samples the already-composited BACKDROP *behind*
|
|
361
|
+
* the node, blurs it by `sigma` (output px, like CSS `blur()`), scales its
|
|
362
|
+
* `brightness`/`saturation` (CSS-style, `1` = identity), and tints it toward
|
|
363
|
+
* `tint` by that color's ALPHA (alpha 0 = no tint). The blurred backdrop is
|
|
364
|
+
* drawn as the node's backing; the node's own content composites on top. */
|
|
365
|
+
| {
|
|
366
|
+
effect: 'backdrop_blur';
|
|
367
|
+
sigma: number;
|
|
368
|
+
tint: Color;
|
|
369
|
+
brightness: number;
|
|
370
|
+
saturation: number;
|
|
371
|
+
}
|
|
372
|
+
/** Light-wrap — the #1 "integrated vs pasted" compositing tell. Like
|
|
373
|
+
* `backdrop_blur` it samples the already-composited BACKDROP *behind* the node,
|
|
374
|
+
* but instead of laying it under the node it bleeds that blurred light onto the
|
|
375
|
+
* node's own FEATHERED EDGES (a real lens spilling a bright background a few px
|
|
376
|
+
* onto a foreground subject), so a cut-out plate reads as *shot in* the scene.
|
|
377
|
+
* `sigma` is the backdrop blur / rim width, `strength` scales the added light
|
|
378
|
+
* (0 = off). Export/native only — the web preview draws the node un-wrapped. */
|
|
379
|
+
| {
|
|
380
|
+
effect: 'light_wrap';
|
|
381
|
+
sigma: number;
|
|
382
|
+
strength: number;
|
|
383
|
+
};
|
|
384
|
+
/** Which channel of a {@link Matte}'s rendered `source` subtree drives the reveal
|
|
385
|
+
* (CSS `mask-mode`). `'alpha'` (the default): content alpha ×= matte alpha — the
|
|
386
|
+
* signature media-through-type matte. `'luminance'`: content alpha ×= luma(matte
|
|
387
|
+
* rgb) × matte alpha (white reveals, black hides — gradient wipes / luma keys). */
|
|
388
|
+
type MatteMode = 'alpha' | 'luminance';
|
|
389
|
+
/** Compositing blend mode (CSS `mix-blend-mode`). Vello renders the full set;
|
|
390
|
+
* the CPU reference composites `normal` only. */
|
|
391
|
+
type BlendMode = 'normal' | 'multiply' | 'screen' | 'overlay' | 'darken' | 'lighten' | 'color-dodge' | 'color-burn' | 'hard-light' | 'soft-light' | 'difference' | 'exclusion' | 'hue' | 'saturation' | 'color' | 'luminosity';
|
|
392
|
+
interface SceneNode {
|
|
393
|
+
id?: number;
|
|
394
|
+
transform?: Transform;
|
|
395
|
+
opacity?: number;
|
|
396
|
+
/** Clip this node and its subtree to a geometry (local space). */
|
|
397
|
+
clip?: ShapeGeometry;
|
|
398
|
+
/** Matte (track matte / mask): reveal this node's content only through the
|
|
399
|
+
* `source` subtree's alpha — or luminance, per `mode` — multiplying the
|
|
400
|
+
* content's alpha by it. The strictly-more-powerful sibling of `clip` (a
|
|
401
|
+
* static geometry); `source` is a fully rendered subtree (animated text, a
|
|
402
|
+
* gradient, an image) — the "media-through-type" move. Omitted when absent. */
|
|
403
|
+
matte?: {
|
|
404
|
+
mode: MatteMode;
|
|
405
|
+
source: SceneNode;
|
|
406
|
+
};
|
|
407
|
+
/** Blend this node's subtree against the backdrop (CSS mix-blend-mode). */
|
|
408
|
+
blend?: BlendMode;
|
|
409
|
+
/** Ordered screen-space effects applied to this node + subtree (render-to-texture). */
|
|
410
|
+
effects?: Effect[];
|
|
411
|
+
/** 3D SCENE ROOT: makes this node's direct children 3D layers, placed in one
|
|
412
|
+
* shared 3D world by their `transform3d` and rendered through this perspective
|
|
413
|
+
* camera (depth-sorted, composited as one layer). GPU runs true perspective;
|
|
414
|
+
* the CPU reference degrades to a 2.5D depth-sorted composite. */
|
|
415
|
+
camera3d?: Camera3D;
|
|
416
|
+
/** This node's placement as a 3D layer (only meaningful inside a 3D scene). */
|
|
417
|
+
transform3d?: Transform3D;
|
|
418
|
+
/** Extrude this layer's 2D outline into a lit 3D solid (GPU only; CPU draws flat). */
|
|
419
|
+
extrude?: Extrude;
|
|
420
|
+
/** Flex-lay-out this node's direct children. */
|
|
421
|
+
layout?: Layout;
|
|
422
|
+
kind: NodeKind;
|
|
423
|
+
children?: SceneNode[];
|
|
424
|
+
}
|
|
425
|
+
/** Extrude a 3D layer's 2D outline into a lit solid — the "3D logo / title" move
|
|
426
|
+
* (mirrors scene-rs `Extrude`). Shape/text layer inside a `<Scene3D>` only. */
|
|
427
|
+
interface Extrude {
|
|
428
|
+
/** Thickness along z, in world units (the solid spans ±depth/2 about the plane). */
|
|
429
|
+
depth: number;
|
|
430
|
+
}
|
|
431
|
+
/** A perspective camera for a 3D scene (mirrors scene-rs `Camera3D`). World units
|
|
432
|
+
* are composition pixels (x→right, y→down); `+z` points away from the camera, into
|
|
433
|
+
* the screen (larger z = farther = smaller), the After Effects convention. Leaving
|
|
434
|
+
* fields default frames the `z = 0` plane to fill the comp, so a layer at `z = 0`
|
|
435
|
+
* with no rotation matches its 2D placement. */
|
|
436
|
+
interface Camera3D {
|
|
437
|
+
/** Eye position `[x, y, z]`. Omit to derive from `fov` (centered, looking at +z). */
|
|
438
|
+
position?: [number, number, number];
|
|
439
|
+
/** Look-at point `[x, y, z]`. Omit ⇒ comp center at z = 0. */
|
|
440
|
+
target?: [number, number, number];
|
|
441
|
+
/** Up vector. Omit ⇒ `[0, -1, 0]` (screen up). */
|
|
442
|
+
up?: [number, number, number];
|
|
443
|
+
/** Vertical field of view, degrees. Default 50. */
|
|
444
|
+
fov?: number;
|
|
445
|
+
near?: number;
|
|
446
|
+
far?: number;
|
|
447
|
+
}
|
|
448
|
+
/** The 3D placement of a layer inside a 3D scene (mirrors scene-rs `Transform3D`). */
|
|
449
|
+
interface Transform3D {
|
|
450
|
+
/** World position of the anchor `[x, y, z]` in comp pixels. z = 0 is the framing
|
|
451
|
+
* plane; larger z is farther into the screen (smaller), negative z nearer the camera. */
|
|
452
|
+
position?: [number, number, number];
|
|
453
|
+
/** Degrees about each axis (Z·Y·X order): X pitch, Y yaw, Z roll. */
|
|
454
|
+
rotation?: [number, number, number];
|
|
455
|
+
/** Pivot within the layer's content plane (comp px). Omit ⇒ layer center. */
|
|
456
|
+
anchor?: [number, number];
|
|
457
|
+
}
|
|
458
|
+
interface Scene {
|
|
459
|
+
composition: Composition$1;
|
|
460
|
+
root: SceneNode;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/** A color as a hex string (`#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`) or an
|
|
464
|
+
* explicit 0..1 {@link Color}. */
|
|
465
|
+
type ColorInput = string | Color;
|
|
466
|
+
/** Normalize a {@link ColorInput} into the engine's 0..1 sRGB {@link Color}. */
|
|
467
|
+
declare function parseColor(input: ColorInput): Color;
|
|
468
|
+
/**
|
|
469
|
+
* Interpolate between colors — like {@link interpolate}, but each output is a
|
|
470
|
+
* {@link ColorInput}. Channels are mixed in 0..1 sRGB and returned as a hex
|
|
471
|
+
* string (`#rrggbb`, or `#rrggbbaa` when any stop has alpha). Out-of-range
|
|
472
|
+
* inputs clamp by default. Mirrors Remotion's `interpolateColors`.
|
|
473
|
+
*
|
|
474
|
+
* @example `interpolateColors(frame, [0, 30], ['#d96b82', '#2974f2'])`
|
|
475
|
+
*/
|
|
476
|
+
declare function interpolateColors(input: number, inputRange: readonly number[], outputRange: readonly ColorInput[], options?: InterpolateOptions): string;
|
|
477
|
+
|
|
478
|
+
/** A clip region as authored: a rect (optionally rounded), ellipse, or path. */
|
|
479
|
+
type ClipInput = {
|
|
480
|
+
type: 'rect';
|
|
481
|
+
width: number;
|
|
482
|
+
height: number;
|
|
483
|
+
cornerRadius?: number;
|
|
484
|
+
} | {
|
|
485
|
+
type: 'ellipse';
|
|
486
|
+
width: number;
|
|
487
|
+
height: number;
|
|
488
|
+
} | {
|
|
489
|
+
type: 'path';
|
|
490
|
+
d: string;
|
|
491
|
+
};
|
|
492
|
+
/** Normalize a {@link ClipInput} into the engine's {@link ShapeGeometry}. */
|
|
493
|
+
declare function parseClip(input: ClipInput): ShapeGeometry;
|
|
494
|
+
/** A rounded/square rectangle clip. */
|
|
495
|
+
declare function clipRect(width: number, height: number, cornerRadius?: number): ClipInput;
|
|
496
|
+
/** An ellipse clip inscribed in `width`×`height`. */
|
|
497
|
+
declare function clipEllipse(width: number, height: number): ClipInput;
|
|
498
|
+
/** An arbitrary clip from SVG path data. */
|
|
499
|
+
declare function clipPath(d: string): ClipInput;
|
|
500
|
+
|
|
501
|
+
/** A point as an `{ x, y }` or a `[x, y]` tuple. */
|
|
502
|
+
type Point = Vec2 | [number, number];
|
|
503
|
+
/** A color stop: a color at a normalized position 0..1 along the gradient. */
|
|
504
|
+
interface GradientStopInput {
|
|
505
|
+
offset: number;
|
|
506
|
+
color: ColorInput;
|
|
507
|
+
}
|
|
508
|
+
/** A gradient as authored: hex/`Color` stops and tuple-or-`Vec2` points. */
|
|
509
|
+
type GradientInput = {
|
|
510
|
+
type: 'linear';
|
|
511
|
+
start: Point;
|
|
512
|
+
end: Point;
|
|
513
|
+
stops: GradientStopInput[];
|
|
514
|
+
} | {
|
|
515
|
+
type: 'radial';
|
|
516
|
+
center: Point;
|
|
517
|
+
radius: number;
|
|
518
|
+
stops: GradientStopInput[];
|
|
519
|
+
} | {
|
|
520
|
+
/** Fractal-noise ("expensive") gradient — fBm over Simplex noise. The field
|
|
521
|
+
* value 0..1 samples the stops; `scale` ~0.8–1.2 + `warp` ~0.4–0.6 gives the
|
|
522
|
+
* soft Stripe/Linear register (higher = busier turbulence). Animate `time`
|
|
523
|
+
* per frame for a living gradient. Rendered natively (full quality on
|
|
524
|
+
* `onda export`); the browser preview degrades to a smooth gradient. */
|
|
525
|
+
type: 'fbm';
|
|
526
|
+
stops: GradientStopInput[];
|
|
527
|
+
scale?: number;
|
|
528
|
+
time?: number;
|
|
529
|
+
warp?: number;
|
|
530
|
+
};
|
|
531
|
+
/** Normalize a {@link GradientInput} into the engine's {@link Gradient} JSON. */
|
|
532
|
+
declare function parseGradient(input: GradientInput): Gradient;
|
|
533
|
+
/** Build a linear gradient input from two points and color stops. */
|
|
534
|
+
declare function linearGradient(start: Point, end: Point, stops: GradientStopInput[]): GradientInput;
|
|
535
|
+
/** Build a radial gradient input from a center, radius, and color stops. */
|
|
536
|
+
declare function radialGradient(center: Point, radius: number, stops: GradientStopInput[]): GradientInput;
|
|
537
|
+
/** Build an fBm fractal-noise ("expensive") gradient — the soft, flowing
|
|
538
|
+
* Stripe/Linear backdrop. `scale` ~0.8–1.2 + `warp` ~0.4–0.6 reads premium;
|
|
539
|
+
* animate `time` (e.g. `frame / fps * speed`) for a living gradient. */
|
|
540
|
+
declare function fbmGradient(stops: GradientStopInput[], opts?: {
|
|
541
|
+
scale?: number;
|
|
542
|
+
time?: number;
|
|
543
|
+
warp?: number;
|
|
544
|
+
}): GradientInput;
|
|
545
|
+
|
|
546
|
+
interface MorphOptions {
|
|
547
|
+
/** Subdivide segments longer than this (user units) for a smoother morph.
|
|
548
|
+
* Lower = smoother + slower to build. Default `2`. */
|
|
549
|
+
maxSegmentLength?: number;
|
|
550
|
+
/** Wind both shapes the same way before interpolating (flubber default `true`). */
|
|
551
|
+
single?: boolean;
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* The in-between SVG path `d` morphing `from` → `to` at progress `t` (0..1).
|
|
555
|
+
* Pass two `<Path>` `d` strings (or any flubber-acceptable shape) and an animated
|
|
556
|
+
* `t`; feed the result to a `<Path d=...>`.
|
|
557
|
+
*
|
|
558
|
+
* @example
|
|
559
|
+
* const d = morphPath(CIRCLE, RULE, ramp(frame, 70, 95))
|
|
560
|
+
* return <Path d={d} fill="#fff" />
|
|
561
|
+
*/
|
|
562
|
+
declare function morphPath(from: string, to: string, t: number, options?: MorphOptions): string;
|
|
563
|
+
/**
|
|
564
|
+
* Morph through an ordered list of shapes as `t` runs 0..1 — `[A, B, C]` spends
|
|
565
|
+
* the first half on A→B and the second on B→C. Useful for a multi-stage magic
|
|
566
|
+
* move under one progress value.
|
|
567
|
+
*/
|
|
568
|
+
declare function morphPathSequence(shapes: string[], t: number, options?: MorphOptions): string;
|
|
569
|
+
|
|
570
|
+
/** Properties shared by every scene node: identity, placement, opacity, clip. */
|
|
571
|
+
interface NodeProps {
|
|
572
|
+
/** Stable id, required to target the node from an animation timeline. */
|
|
573
|
+
id?: number;
|
|
574
|
+
/** Translation in pixels. */
|
|
575
|
+
x?: number;
|
|
576
|
+
y?: number;
|
|
577
|
+
/** Scale factor (1 = identity). */
|
|
578
|
+
scaleX?: number;
|
|
579
|
+
scaleY?: number;
|
|
580
|
+
/** Clockwise rotation in degrees, about the transform origin (default (0,0)).
|
|
581
|
+
* Renders on the GPU (Vello) backend; the CPU reference rasterizer ignores it. */
|
|
582
|
+
rotation?: number;
|
|
583
|
+
/** Pivot for scale + rotation in local px (CSS transform-origin). Default (0,0).
|
|
584
|
+
* For "about the center", pass half the node's width/height. */
|
|
585
|
+
originX?: number;
|
|
586
|
+
originY?: number;
|
|
587
|
+
/** Opacity, 0..1. */
|
|
588
|
+
opacity?: number;
|
|
589
|
+
/** DEPTH (z) of this layer for depth-of-field, in the same arbitrary units as
|
|
590
|
+
* `<Composition dof={{ focus }}>`. Layers at the focus depth stay sharp; the
|
|
591
|
+
* farther a layer's `depth` is from `focus`, the more it defocuses (a blur the
|
|
592
|
+
* reconciler computes from the camera aperture). Animate the comp's `focus` for a
|
|
593
|
+
* rack-focus pull. No effect unless the comp sets `dof`. */
|
|
594
|
+
depth?: number;
|
|
595
|
+
/** 3D LAYER position `[x, y, z]` in world pixels — meaningful only inside a
|
|
596
|
+
* `<Scene3D>`. `z = 0` is the framing plane (matches the 2D placement); larger
|
|
597
|
+
* `z` is farther into the screen (smaller), negative `z` nearer the camera (After
|
|
598
|
+
* Effects convention). Animate for fly-throughs / parallax / exploded views. */
|
|
599
|
+
position3d?: [number, number, number];
|
|
600
|
+
/** 3D LAYER rotation `[x, y, z]` in degrees (Z·Y·X): X pitch (tilt toward/away),
|
|
601
|
+
* Y yaw (swing), Z roll (in-plane spin). Inside `<Scene3D>` only. GPU-only — the
|
|
602
|
+
* CPU reference degrades to a flat depth-sorted composite (no out-of-plane tilt). */
|
|
603
|
+
rotation3d?: [number, number, number];
|
|
604
|
+
/** Pivot within this layer's content plane (px) that `position3d`/`rotation3d`
|
|
605
|
+
* act about. Default: the layer's center. */
|
|
606
|
+
anchor3d?: [number, number];
|
|
607
|
+
/** EXTRUDE this layer's 2D outline into a lit 3D SOLID (the "3D logo / title"):
|
|
608
|
+
* inside a `<Scene3D>`, a shape or text layer becomes a mesh with `depth`
|
|
609
|
+
* thickness + side walls, shaded by a directional light so it catches the light
|
|
610
|
+
* as it rotates. GPU only — the CPU reference + live preview draw the flat outline. */
|
|
611
|
+
extrude?: number | {
|
|
612
|
+
depth: number;
|
|
613
|
+
};
|
|
614
|
+
/** Blend this node's subtree against the backdrop (CSS mix-blend-mode).
|
|
615
|
+
* GPU/Vello-rendered (e.g. `'screen'`, `'multiply'`, `'overlay'`). */
|
|
616
|
+
blendMode?: BlendMode;
|
|
617
|
+
/** Clip this node and its subtree to a region (local space). */
|
|
618
|
+
clip?: ClipInput;
|
|
619
|
+
/** Matte (track matte / mask): a stencil SUBTREE, passed as a React element,
|
|
620
|
+
* through which this node's content is revealed. The matte's alpha — or its
|
|
621
|
+
* luminance, per `matteMode` — multiplies the content's alpha, so the content
|
|
622
|
+
* (this node's children) shows only where the matte covers. The
|
|
623
|
+
* strictly-more-powerful sibling of `clip`: the matte is a fully rendered,
|
|
624
|
+
* animatable subtree (giant text, a gradient, a shape) — the signature
|
|
625
|
+
* "media-through-type" move (a photo seen only through animated type). */
|
|
626
|
+
matte?: ReactElement;
|
|
627
|
+
/** Which channel of the {@link NodeProps.matte} subtree drives the reveal (CSS
|
|
628
|
+
* `mask-mode`). `'alpha'` (default): content alpha ×= matte alpha. `'luminance'`:
|
|
629
|
+
* content alpha ×= luma(matte) × matte alpha (white reveals, black hides). */
|
|
630
|
+
matteMode?: MatteMode;
|
|
631
|
+
/** Ordered, low-level screen-space effects on this node + subtree (render-to-texture). */
|
|
632
|
+
effects?: Effect[];
|
|
633
|
+
/** Gaussian blur std-dev in output px; sugar for `effects: [{ effect: 'blur', sigma }]`.
|
|
634
|
+
* Honored by Vello AND the CPU reference once Phase 1 lands. */
|
|
635
|
+
blur?: number;
|
|
636
|
+
/** Directional (motion) blur sugar for `effects: [{ effect: 'directional_blur', … }]`:
|
|
637
|
+
* a 1D blur of std-dev `sigma` (px) along `angle` (radians, default 0 = horizontal) —
|
|
638
|
+
* the cinematic "in-motion" smear. Honored by Vello AND the CPU reference. */
|
|
639
|
+
directionalBlur?: {
|
|
640
|
+
sigma: number;
|
|
641
|
+
angle?: number;
|
|
642
|
+
};
|
|
643
|
+
/** Chromatic-aberration sugar: R/B split by `amount` px radially from centre. */
|
|
644
|
+
chromaticAberration?: number;
|
|
645
|
+
/** Vignette sugar — radial edge darkening. `amount` 0..1; `softness` 0..1 (default 0.5). */
|
|
646
|
+
vignette?: number | {
|
|
647
|
+
amount: number;
|
|
648
|
+
softness?: number;
|
|
649
|
+
};
|
|
650
|
+
/** Posterize sugar: quantize each channel to `levels` (≥2) discrete steps. */
|
|
651
|
+
posterize?: number;
|
|
652
|
+
/** Duotone sugar: map luminance to a gradient from `shadow` to `highlight`. */
|
|
653
|
+
duotone?: {
|
|
654
|
+
shadow: ColorInput;
|
|
655
|
+
highlight: ColorInput;
|
|
656
|
+
};
|
|
657
|
+
/** Chroma-key sugar: knock out `color`; `threshold` (default 0.4) + `smoothness`
|
|
658
|
+
* (default 0.1) shape the soft matte edge. */
|
|
659
|
+
chromaKey?: {
|
|
660
|
+
color: ColorInput;
|
|
661
|
+
threshold?: number;
|
|
662
|
+
smoothness?: number;
|
|
663
|
+
};
|
|
664
|
+
/** Glow / bloom sugar for `effects: [{ effect: 'bloom', ... }]`: bright regions
|
|
665
|
+
* (luminance above `threshold`, default 0.7; scaled by `intensity`, default 1)
|
|
666
|
+
* blur with `sigma` and composite additively over the sharp subtree. Honored by
|
|
667
|
+
* Vello AND the CPU reference. */
|
|
668
|
+
bloom?: number | {
|
|
669
|
+
sigma: number;
|
|
670
|
+
threshold?: number;
|
|
671
|
+
intensity?: number;
|
|
672
|
+
};
|
|
673
|
+
/** Cinematic color-grade sugar for `effects: [{ effect: 'color_grade', ... }]` —
|
|
674
|
+
* the "land AI media" wedge: one grade unifies mismatched clips into a single
|
|
675
|
+
* look. All five fields are optional and default to the neutral identity
|
|
676
|
+
* (`exposure` 0, `contrast` 1, `saturation` 1, `temperature` 0, `tint` 0), so
|
|
677
|
+
* `{}` is a no-op. Honored by Vello AND the CPU reference. */
|
|
678
|
+
grade?: {
|
|
679
|
+
/** Linear exposure gain (`2^exposure`); 0 = identity. */
|
|
680
|
+
exposure?: number;
|
|
681
|
+
/** Contrast around a 0.5 pivot; 1 = identity. */
|
|
682
|
+
contrast?: number;
|
|
683
|
+
/** Saturation; 1 = identity, 0 = grayscale, >1 = punchier. */
|
|
684
|
+
saturation?: number;
|
|
685
|
+
/** Warm/cool shift (R up / B down for positive); 0 = neutral. */
|
|
686
|
+
temperature?: number;
|
|
687
|
+
/** Green/magenta shift on G (positive = green); 0 = neutral. */
|
|
688
|
+
tint?: number;
|
|
689
|
+
};
|
|
690
|
+
/** Gooey / liquid / metaball-morph sugar for `effects: [{ effect: 'goo', ... }]`:
|
|
691
|
+
* the subtree is blurred with `sigma`, then its alpha is sharpened around
|
|
692
|
+
* `threshold` (the 0..1 cutoff, default 0.5) so overlapping shapes fuse into
|
|
693
|
+
* solid forms joined by smooth necks (the "drops of liquid coalescing" look).
|
|
694
|
+
* A bare number is the `sigma`. Honored by Vello AND the CPU reference. */
|
|
695
|
+
goo?: number | {
|
|
696
|
+
sigma: number;
|
|
697
|
+
threshold?: number;
|
|
698
|
+
};
|
|
699
|
+
/** Film-grain sugar for `effects: [{ effect: 'grain', ... }]`: luminance-banded,
|
|
700
|
+
* animated monochrome noise added late over the subtree — the compositing "glue"
|
|
701
|
+
* that makes mismatched sources read as one photographed image, and the dither
|
|
702
|
+
* that hides 8-bit banding on dark gradients. A bare number is the `intensity`
|
|
703
|
+
* (~0.04–0.1 is filmic); the object form adds `size` (grain scale in px, default
|
|
704
|
+
* 1) and `seed` (animation offset — pass the current frame for *living* grain,
|
|
705
|
+
* default 0 = static). Honored by Vello AND the CPU reference. */
|
|
706
|
+
grain?: number | {
|
|
707
|
+
intensity: number;
|
|
708
|
+
size?: number;
|
|
709
|
+
seed?: number;
|
|
710
|
+
};
|
|
711
|
+
/** Frosted-glass sugar for `effects: [{ effect: 'backdrop_blur', ... }]`: samples
|
|
712
|
+
* the already-composited BACKDROP *behind* this node (not its own subtree),
|
|
713
|
+
* blurs it by `sigma` (output px), and draws it as the node's backing — then the
|
|
714
|
+
* node's own content (e.g. a translucent panel `fill`) composites on top. A bare
|
|
715
|
+
* number is just the `sigma`; the object form adds a `tint` (its alpha = tint
|
|
716
|
+
* strength), a `brightness` and a `saturation` (CSS-style, `1` = identity).
|
|
717
|
+
* Honored by Vello AND the CPU reference. */
|
|
718
|
+
backdropBlur?: number | {
|
|
719
|
+
sigma: number;
|
|
720
|
+
tint?: ColorInput;
|
|
721
|
+
brightness?: number;
|
|
722
|
+
saturation?: number;
|
|
723
|
+
};
|
|
724
|
+
/** Light-wrap sugar for `effects: [{ effect: 'light_wrap', ... }]`: bleeds the
|
|
725
|
+
* blurred BACKDROP behind this node onto its own feathered EDGES — the #1
|
|
726
|
+
* "shot in, not pasted on" compositing tell for a cut-out plate. A bare number
|
|
727
|
+
* is the `sigma` (the backdrop blur / rim width); the object form adds a
|
|
728
|
+
* `strength` (0 = off, ~1 = a natural spill). EXPORT/NATIVE only — the live
|
|
729
|
+
* preview draws the node un-wrapped. */
|
|
730
|
+
lightWrap?: number | {
|
|
731
|
+
sigma: number;
|
|
732
|
+
strength?: number;
|
|
733
|
+
};
|
|
734
|
+
children?: ReactNode;
|
|
735
|
+
}
|
|
736
|
+
/** Paint props shared by shapes: a solid fill, a gradient (which takes
|
|
737
|
+
* precedence), and a stroke. */
|
|
738
|
+
interface PaintProps {
|
|
739
|
+
fill?: ColorInput;
|
|
740
|
+
gradient?: GradientInput;
|
|
741
|
+
stroke?: ColorInput;
|
|
742
|
+
strokeWidth?: number;
|
|
743
|
+
/** Stroke end-cap (CSS stroke-linecap). Default 'butt'. */
|
|
744
|
+
strokeCap?: 'butt' | 'round' | 'square';
|
|
745
|
+
/** Stroke corner-join (CSS stroke-linejoin). Default 'miter'. */
|
|
746
|
+
strokeJoin?: 'miter' | 'round' | 'bevel';
|
|
747
|
+
/** Dash pattern: alternating on/off px (e.g. [12, 8]). Omit for solid. */
|
|
748
|
+
strokeDash?: number[];
|
|
749
|
+
/** Phase offset into the dash pattern (px) — animate for a draw-on reveal. */
|
|
750
|
+
strokeDashOffset?: number;
|
|
751
|
+
/** TRIM PATHS (mograph line-draw): draw only a slice of the stroked outline.
|
|
752
|
+
* `trimStart`/`trimEnd` are fractions 0..1 of the path's length (default 0 / 1);
|
|
753
|
+
* `trimOffset` rotates the visible window around the path. Animate `trimEnd` 0→1
|
|
754
|
+
* for a draw-on reveal. Needs a `stroke`; length is measured by the engine. */
|
|
755
|
+
trimStart?: number;
|
|
756
|
+
trimEnd?: number;
|
|
757
|
+
trimOffset?: number;
|
|
758
|
+
/** Drop shadow / glow behind the shape (CSS box-shadow). `blur` is the gaussian
|
|
759
|
+
* std-dev; `(0,0)` offset reads as a centered glow. GPU/Vello-rendered. */
|
|
760
|
+
shadow?: {
|
|
761
|
+
color: ColorInput;
|
|
762
|
+
blur: number;
|
|
763
|
+
offsetX?: number;
|
|
764
|
+
offsetY?: number;
|
|
765
|
+
spread?: number;
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
interface CompositionProps {
|
|
769
|
+
width: number;
|
|
770
|
+
height: number;
|
|
771
|
+
fps: number;
|
|
772
|
+
durationInFrames: number;
|
|
773
|
+
/** Opt into the cinematic LINEAR + ACES finishing pipeline (correct bloom/light,
|
|
774
|
+
* light-wrap, halation). GPU/export only; off by default (gamma). */
|
|
775
|
+
linear?: boolean;
|
|
776
|
+
/** Composition-level cinematic FINISH: a linear-HDR finishing chain run after the
|
|
777
|
+
* comp rasterizes — bloom bleeding REAL light (highlights exceed 1.0 and roll off),
|
|
778
|
+
* warm halation — ending in one ACES film tone-map. The correct "looks shot" output
|
|
779
|
+
* transform (unlike per-node effects, no HDR is lost between passes). GPU/export only. */
|
|
780
|
+
finish?: {
|
|
781
|
+
/** Linear exposure multiplier before the tone-map (1 = neutral; >1 brightens). */
|
|
782
|
+
exposure?: number;
|
|
783
|
+
/** Comp-level bloom in linear HDR. `sigma` = halo blur radius (px). */
|
|
784
|
+
bloom?: {
|
|
785
|
+
sigma: number;
|
|
786
|
+
threshold?: number;
|
|
787
|
+
intensity?: number;
|
|
788
|
+
};
|
|
789
|
+
/** Warm red/orange halation around highlights (0 = off, ~0.6 filmic). */
|
|
790
|
+
halation?: number;
|
|
791
|
+
/** Grade — white balance: + warm (boost red/cut blue), − cool. 0 = neutral. */
|
|
792
|
+
temperature?: number;
|
|
793
|
+
/** Grade — contrast around mid-grey. 1 = identity, >1 punchier. */
|
|
794
|
+
contrast?: number;
|
|
795
|
+
/** Grade — saturation. 1 = identity, 0 = greyscale, >1 richer. */
|
|
796
|
+
saturation?: number;
|
|
797
|
+
/** Vignette — radial edge darkening of the finished frame. 0 = off. */
|
|
798
|
+
vignette?: number;
|
|
799
|
+
/** Film grain intensity added in linear light (luminance-banded). 0 = off; the
|
|
800
|
+
* current frame is used as the animation seed automatically. */
|
|
801
|
+
grain?: number;
|
|
802
|
+
/** A cinematic 3D color LUT applied as the FINAL finish step (after grade + ACES
|
|
803
|
+
* + sRGB), as a trilinear lookup. `table` holds `size³` RGB triples in 0..1 with
|
|
804
|
+
* RED varying fastest, then green, then blue. Honored by BOTH backends. */
|
|
805
|
+
lut?: {
|
|
806
|
+
size: number;
|
|
807
|
+
table: number[];
|
|
808
|
+
};
|
|
809
|
+
};
|
|
810
|
+
/** Per-object MOTION BLUR via temporal supersampling: each output frame is the
|
|
811
|
+
* average of `samples` sub-frames spread across the shutter window, so anything
|
|
812
|
+
* that MOVES smears by its own motion and static elements stay sharp — the
|
|
813
|
+
* shutter-angle blur every pro comp ships with. `true` = a 180° shutter, 16
|
|
814
|
+
* samples. Cost is `samples`× the render, so it's an EXPORT feature (the live
|
|
815
|
+
* preview shows the sharp frame). */
|
|
816
|
+
motionBlur?: boolean | {
|
|
817
|
+
/** Shutter angle in degrees: how much of the frame the shutter is open. 180 =
|
|
818
|
+
* half a frame (the film default); 360 = full-frame (heavier blur). */
|
|
819
|
+
shutter?: number;
|
|
820
|
+
/** Sub-frames averaged per output frame. More = smoother smear, linearly costlier. */
|
|
821
|
+
samples?: number;
|
|
822
|
+
};
|
|
823
|
+
/** DEPTH OF FIELD (2.5D rack focus): with this set, any layer carrying a `depth`
|
|
824
|
+
* prop defocuses by how far its `depth` is from `focus` — sharp at the focus plane,
|
|
825
|
+
* blurrier away from it. Animate `focus` for a focus pull. Resolved as a per-layer
|
|
826
|
+
* blur (reuses the blur effect), so it works on both backends. */
|
|
827
|
+
dof?: {
|
|
828
|
+
/** The `depth` value that is in sharp focus. */
|
|
829
|
+
focus: number;
|
|
830
|
+
/** How fast blur grows with depth distance (px of blur per unit of depth past the
|
|
831
|
+
* in-focus band). Bigger = shallower depth of field. Default 0.04. */
|
|
832
|
+
aperture?: number;
|
|
833
|
+
/** A sharp band (± in depth units) around `focus` that stays unblurred. Default 0. */
|
|
834
|
+
range?: number;
|
|
835
|
+
/** Clamp the blur σ (px) so far layers don't blur to mush. Default 40. */
|
|
836
|
+
maxBlur?: number;
|
|
837
|
+
};
|
|
838
|
+
children?: ReactNode;
|
|
839
|
+
}
|
|
840
|
+
/** The root of every ONDA tree: resolution + timing, like Remotion's. */
|
|
841
|
+
declare function Composition(props: CompositionProps): react.DOMElement<CompositionProps, Element>;
|
|
842
|
+
type GroupProps = NodeProps;
|
|
843
|
+
/** A transform/opacity container with no visual of its own. */
|
|
844
|
+
declare function Group(props: GroupProps): react.DOMElement<NodeProps, Element>;
|
|
845
|
+
/** Props for {@link Repeater} (After Effects' shape "Repeater"). */
|
|
846
|
+
interface RepeaterProps {
|
|
847
|
+
/** Number of copies (including the original). */
|
|
848
|
+
count: number;
|
|
849
|
+
/** Per-copy translation, applied cumulatively (copy i is offset i×). */
|
|
850
|
+
offsetX?: number;
|
|
851
|
+
offsetY?: number;
|
|
852
|
+
/** Per-copy rotation in degrees, applied cumulatively (a radial array / spiral). */
|
|
853
|
+
rotation?: number;
|
|
854
|
+
/** Per-copy scale factor, applied cumulatively (copy i is `scale**i`). 1 = none. */
|
|
855
|
+
scale?: number;
|
|
856
|
+
/** Pivot for the per-copy rotation/scale (local px). Default (0,0). */
|
|
857
|
+
originX?: number;
|
|
858
|
+
originY?: number;
|
|
859
|
+
/** Opacity of the first / last copy; the rest interpolate (a fade-out trail). */
|
|
860
|
+
startOpacity?: number;
|
|
861
|
+
endOpacity?: number;
|
|
862
|
+
children?: ReactNode;
|
|
863
|
+
}
|
|
864
|
+
/** REPEATER — stamp `children` `count` times, each copy COMPOUNDING one more step of
|
|
865
|
+
* the transform (offset / rotation / scale) and a step of the opacity ramp: grids,
|
|
866
|
+
* radial arrays, spirals, motion trails. Mirrors After Effects' shape Repeater.
|
|
867
|
+
*
|
|
868
|
+
* Implemented as `count` nested transform groups (each adds one increment on top of
|
|
869
|
+
* the previous, so the transforms truly compound into a spiral rather than a naive
|
|
870
|
+
* `i×` fan), with a copy of `children` drawn at every level. Pure composition — it
|
|
871
|
+
* renders identically on every backend. */
|
|
872
|
+
declare function Repeater({ count, offsetX, offsetY, rotation, scale, originX, originY, startOpacity, endOpacity, children, }: RepeaterProps): ReactElement;
|
|
873
|
+
/** Props for {@link Merge} (After Effects' shape "Merge Paths"). */
|
|
874
|
+
interface MergeProps extends PaintProps, Omit<NodeProps, 'children'> {
|
|
875
|
+
/** Boolean operation over the SHAPE children: `union` (add) / `difference` (the
|
|
876
|
+
* first minus the rest) / `intersect` (common area) / `xor` (symmetric difference).
|
|
877
|
+
* Default `union`. */
|
|
878
|
+
op?: 'union' | 'difference' | 'intersect' | 'xor';
|
|
879
|
+
children?: ReactNode;
|
|
880
|
+
}
|
|
881
|
+
/** MERGE PATHS — combine the SHAPE children into ONE outline via a boolean `op`
|
|
882
|
+
* (union / difference / intersect / xor). A ring = circle − circle; a lens =
|
|
883
|
+
* circle ∩ circle; a speech bubble = rect ∪ triangle. The children are folded into
|
|
884
|
+
* the result (not drawn separately), so fill/stroke the `<Merge>` itself. Curve
|
|
885
|
+
* outlines are flattened before the boolean; resolved on both backends (i_overlay). */
|
|
886
|
+
declare function Merge(props: MergeProps): react.DOMElement<MergeProps, Element>;
|
|
887
|
+
type PrecompProps = NodeProps;
|
|
888
|
+
/** PRECOMP — flatten this subtree to a SINGLE layer (render-to-texture) before its
|
|
889
|
+
* `opacity` / `blendMode` / effects apply, the way After Effects' precomp /
|
|
890
|
+
* collapse-transformations does. Reach for it when you fade or blend-mode a GROUP of
|
|
891
|
+
* overlapping layers and don't want the overlaps to double-up, or to treat a group as
|
|
892
|
+
* one unit. (It's a `<Group>` carrying the `isolate` effect.) */
|
|
893
|
+
declare function Precomp(props: PrecompProps): react.FunctionComponentElement<NodeProps>;
|
|
894
|
+
/** Flex layout props for {@link Flex} / {@link AbsoluteFill} (CSS-flexbox subset). */
|
|
895
|
+
interface FlexProps extends NodeProps, Layout {
|
|
896
|
+
}
|
|
897
|
+
/** A flex container: lays out its direct children (row/column, with
|
|
898
|
+
* justify/align/gap/padding) instead of requiring absolute x/y. Resolved to
|
|
899
|
+
* absolute positions by the engine's layout pass. */
|
|
900
|
+
declare function Flex(props: FlexProps): react.DOMElement<{
|
|
901
|
+
layout: Layout;
|
|
902
|
+
/** Stable id, required to target the node from an animation timeline. */
|
|
903
|
+
id?: number;
|
|
904
|
+
/** Translation in pixels. */
|
|
905
|
+
x?: number;
|
|
906
|
+
y?: number;
|
|
907
|
+
/** Scale factor (1 = identity). */
|
|
908
|
+
scaleX?: number;
|
|
909
|
+
scaleY?: number;
|
|
910
|
+
/** Clockwise rotation in degrees, about the transform origin (default (0,0)).
|
|
911
|
+
* Renders on the GPU (Vello) backend; the CPU reference rasterizer ignores it. */
|
|
912
|
+
rotation?: number;
|
|
913
|
+
/** Pivot for scale + rotation in local px (CSS transform-origin). Default (0,0).
|
|
914
|
+
* For "about the center", pass half the node's width/height. */
|
|
915
|
+
originX?: number;
|
|
916
|
+
originY?: number;
|
|
917
|
+
/** Opacity, 0..1. */
|
|
918
|
+
opacity?: number;
|
|
919
|
+
/** DEPTH (z) of this layer for depth-of-field, in the same arbitrary units as
|
|
920
|
+
* `<Composition dof={{ focus }}>`. Layers at the focus depth stay sharp; the
|
|
921
|
+
* farther a layer's `depth` is from `focus`, the more it defocuses (a blur the
|
|
922
|
+
* reconciler computes from the camera aperture). Animate the comp's `focus` for a
|
|
923
|
+
* rack-focus pull. No effect unless the comp sets `dof`. */
|
|
924
|
+
depth?: number;
|
|
925
|
+
/** 3D LAYER position `[x, y, z]` in world pixels — meaningful only inside a
|
|
926
|
+
* `<Scene3D>`. `z = 0` is the framing plane (matches the 2D placement); larger
|
|
927
|
+
* `z` is farther into the screen (smaller), negative `z` nearer the camera (After
|
|
928
|
+
* Effects convention). Animate for fly-throughs / parallax / exploded views. */
|
|
929
|
+
position3d?: [number, number, number];
|
|
930
|
+
/** 3D LAYER rotation `[x, y, z]` in degrees (Z·Y·X): X pitch (tilt toward/away),
|
|
931
|
+
* Y yaw (swing), Z roll (in-plane spin). Inside `<Scene3D>` only. GPU-only — the
|
|
932
|
+
* CPU reference degrades to a flat depth-sorted composite (no out-of-plane tilt). */
|
|
933
|
+
rotation3d?: [number, number, number];
|
|
934
|
+
/** Pivot within this layer's content plane (px) that `position3d`/`rotation3d`
|
|
935
|
+
* act about. Default: the layer's center. */
|
|
936
|
+
anchor3d?: [number, number];
|
|
937
|
+
/** EXTRUDE this layer's 2D outline into a lit 3D SOLID (the "3D logo / title"):
|
|
938
|
+
* inside a `<Scene3D>`, a shape or text layer becomes a mesh with `depth`
|
|
939
|
+
* thickness + side walls, shaded by a directional light so it catches the light
|
|
940
|
+
* as it rotates. GPU only — the CPU reference + live preview draw the flat outline. */
|
|
941
|
+
extrude?: number | {
|
|
942
|
+
depth: number;
|
|
943
|
+
};
|
|
944
|
+
/** Blend this node's subtree against the backdrop (CSS mix-blend-mode).
|
|
945
|
+
* GPU/Vello-rendered (e.g. `'screen'`, `'multiply'`, `'overlay'`). */
|
|
946
|
+
blendMode?: BlendMode;
|
|
947
|
+
/** Clip this node and its subtree to a region (local space). */
|
|
948
|
+
clip?: ClipInput;
|
|
949
|
+
/** Matte (track matte / mask): a stencil SUBTREE, passed as a React element,
|
|
950
|
+
* through which this node's content is revealed. The matte's alpha — or its
|
|
951
|
+
* luminance, per `matteMode` — multiplies the content's alpha, so the content
|
|
952
|
+
* (this node's children) shows only where the matte covers. The
|
|
953
|
+
* strictly-more-powerful sibling of `clip`: the matte is a fully rendered,
|
|
954
|
+
* animatable subtree (giant text, a gradient, a shape) — the signature
|
|
955
|
+
* "media-through-type" move (a photo seen only through animated type). */
|
|
956
|
+
matte?: ReactElement;
|
|
957
|
+
/** Which channel of the {@link NodeProps.matte} subtree drives the reveal (CSS
|
|
958
|
+
* `mask-mode`). `'alpha'` (default): content alpha ×= matte alpha. `'luminance'`:
|
|
959
|
+
* content alpha ×= luma(matte) × matte alpha (white reveals, black hides). */
|
|
960
|
+
matteMode?: MatteMode;
|
|
961
|
+
/** Ordered, low-level screen-space effects on this node + subtree (render-to-texture). */
|
|
962
|
+
effects?: Effect[];
|
|
963
|
+
/** Gaussian blur std-dev in output px; sugar for `effects: [{ effect: 'blur', sigma }]`.
|
|
964
|
+
* Honored by Vello AND the CPU reference once Phase 1 lands. */
|
|
965
|
+
blur?: number;
|
|
966
|
+
/** Directional (motion) blur sugar for `effects: [{ effect: 'directional_blur', … }]`:
|
|
967
|
+
* a 1D blur of std-dev `sigma` (px) along `angle` (radians, default 0 = horizontal) —
|
|
968
|
+
* the cinematic "in-motion" smear. Honored by Vello AND the CPU reference. */
|
|
969
|
+
directionalBlur?: {
|
|
970
|
+
sigma: number;
|
|
971
|
+
angle?: number;
|
|
972
|
+
};
|
|
973
|
+
/** Chromatic-aberration sugar: R/B split by `amount` px radially from centre. */
|
|
974
|
+
chromaticAberration?: number;
|
|
975
|
+
/** Vignette sugar — radial edge darkening. `amount` 0..1; `softness` 0..1 (default 0.5). */
|
|
976
|
+
vignette?: number | {
|
|
977
|
+
amount: number;
|
|
978
|
+
softness?: number;
|
|
979
|
+
};
|
|
980
|
+
/** Posterize sugar: quantize each channel to `levels` (≥2) discrete steps. */
|
|
981
|
+
posterize?: number;
|
|
982
|
+
/** Duotone sugar: map luminance to a gradient from `shadow` to `highlight`. */
|
|
983
|
+
duotone?: {
|
|
984
|
+
shadow: ColorInput;
|
|
985
|
+
highlight: ColorInput;
|
|
986
|
+
};
|
|
987
|
+
/** Chroma-key sugar: knock out `color`; `threshold` (default 0.4) + `smoothness`
|
|
988
|
+
* (default 0.1) shape the soft matte edge. */
|
|
989
|
+
chromaKey?: {
|
|
990
|
+
color: ColorInput;
|
|
991
|
+
threshold?: number;
|
|
992
|
+
smoothness?: number;
|
|
993
|
+
};
|
|
994
|
+
/** Glow / bloom sugar for `effects: [{ effect: 'bloom', ... }]`: bright regions
|
|
995
|
+
* (luminance above `threshold`, default 0.7; scaled by `intensity`, default 1)
|
|
996
|
+
* blur with `sigma` and composite additively over the sharp subtree. Honored by
|
|
997
|
+
* Vello AND the CPU reference. */
|
|
998
|
+
bloom?: number | {
|
|
999
|
+
sigma: number;
|
|
1000
|
+
threshold?: number;
|
|
1001
|
+
intensity?: number;
|
|
1002
|
+
};
|
|
1003
|
+
/** Cinematic color-grade sugar for `effects: [{ effect: 'color_grade', ... }]` —
|
|
1004
|
+
* the "land AI media" wedge: one grade unifies mismatched clips into a single
|
|
1005
|
+
* look. All five fields are optional and default to the neutral identity
|
|
1006
|
+
* (`exposure` 0, `contrast` 1, `saturation` 1, `temperature` 0, `tint` 0), so
|
|
1007
|
+
* `{}` is a no-op. Honored by Vello AND the CPU reference. */
|
|
1008
|
+
grade?: {
|
|
1009
|
+
/** Linear exposure gain (`2^exposure`); 0 = identity. */
|
|
1010
|
+
exposure?: number;
|
|
1011
|
+
/** Contrast around a 0.5 pivot; 1 = identity. */
|
|
1012
|
+
contrast?: number;
|
|
1013
|
+
/** Saturation; 1 = identity, 0 = grayscale, >1 = punchier. */
|
|
1014
|
+
saturation?: number;
|
|
1015
|
+
/** Warm/cool shift (R up / B down for positive); 0 = neutral. */
|
|
1016
|
+
temperature?: number;
|
|
1017
|
+
/** Green/magenta shift on G (positive = green); 0 = neutral. */
|
|
1018
|
+
tint?: number;
|
|
1019
|
+
};
|
|
1020
|
+
/** Gooey / liquid / metaball-morph sugar for `effects: [{ effect: 'goo', ... }]`:
|
|
1021
|
+
* the subtree is blurred with `sigma`, then its alpha is sharpened around
|
|
1022
|
+
* `threshold` (the 0..1 cutoff, default 0.5) so overlapping shapes fuse into
|
|
1023
|
+
* solid forms joined by smooth necks (the "drops of liquid coalescing" look).
|
|
1024
|
+
* A bare number is the `sigma`. Honored by Vello AND the CPU reference. */
|
|
1025
|
+
goo?: number | {
|
|
1026
|
+
sigma: number;
|
|
1027
|
+
threshold?: number;
|
|
1028
|
+
};
|
|
1029
|
+
/** Film-grain sugar for `effects: [{ effect: 'grain', ... }]`: luminance-banded,
|
|
1030
|
+
* animated monochrome noise added late over the subtree — the compositing "glue"
|
|
1031
|
+
* that makes mismatched sources read as one photographed image, and the dither
|
|
1032
|
+
* that hides 8-bit banding on dark gradients. A bare number is the `intensity`
|
|
1033
|
+
* (~0.04–0.1 is filmic); the object form adds `size` (grain scale in px, default
|
|
1034
|
+
* 1) and `seed` (animation offset — pass the current frame for *living* grain,
|
|
1035
|
+
* default 0 = static). Honored by Vello AND the CPU reference. */
|
|
1036
|
+
grain?: number | {
|
|
1037
|
+
intensity: number;
|
|
1038
|
+
size?: number;
|
|
1039
|
+
seed?: number;
|
|
1040
|
+
};
|
|
1041
|
+
/** Frosted-glass sugar for `effects: [{ effect: 'backdrop_blur', ... }]`: samples
|
|
1042
|
+
* the already-composited BACKDROP *behind* this node (not its own subtree),
|
|
1043
|
+
* blurs it by `sigma` (output px), and draws it as the node's backing — then the
|
|
1044
|
+
* node's own content (e.g. a translucent panel `fill`) composites on top. A bare
|
|
1045
|
+
* number is just the `sigma`; the object form adds a `tint` (its alpha = tint
|
|
1046
|
+
* strength), a `brightness` and a `saturation` (CSS-style, `1` = identity).
|
|
1047
|
+
* Honored by Vello AND the CPU reference. */
|
|
1048
|
+
backdropBlur?: number | {
|
|
1049
|
+
sigma: number;
|
|
1050
|
+
tint?: ColorInput;
|
|
1051
|
+
brightness?: number;
|
|
1052
|
+
saturation?: number;
|
|
1053
|
+
};
|
|
1054
|
+
/** Light-wrap sugar for `effects: [{ effect: 'light_wrap', ... }]`: bleeds the
|
|
1055
|
+
* blurred BACKDROP behind this node onto its own feathered EDGES — the #1
|
|
1056
|
+
* "shot in, not pasted on" compositing tell for a cut-out plate. A bare number
|
|
1057
|
+
* is the `sigma` (the backdrop blur / rim width); the object form adds a
|
|
1058
|
+
* `strength` (0 = off, ~1 = a natural spill). EXPORT/NATIVE only — the live
|
|
1059
|
+
* preview draws the node un-wrapped. */
|
|
1060
|
+
lightWrap?: number | {
|
|
1061
|
+
sigma: number;
|
|
1062
|
+
strength?: number;
|
|
1063
|
+
};
|
|
1064
|
+
children?: ReactNode;
|
|
1065
|
+
}, Element>;
|
|
1066
|
+
interface CenterProps extends Omit<NodeProps, 'children'> {
|
|
1067
|
+
/** Top of the centering row (px). Default 0. */
|
|
1068
|
+
y?: number;
|
|
1069
|
+
/** Height of the row the content is centered within (px). Omit to size to content. */
|
|
1070
|
+
height?: number;
|
|
1071
|
+
children?: ReactNode;
|
|
1072
|
+
}
|
|
1073
|
+
/** Horizontally CENTER children across the composition width at vertical position `y` —
|
|
1074
|
+
* sugar for a full-width `<Flex justify="center">`. The reliable way to center text:
|
|
1075
|
+
* the layout pass measures the real glyph width natively, so you never hand-compute an
|
|
1076
|
+
* `x` (which mis-centers the moment the text, font, or size changes). */
|
|
1077
|
+
declare function Center(props: CenterProps): react.FunctionComponentElement<FlexProps>;
|
|
1078
|
+
type AbsoluteFillProps = Omit<FlexProps, 'width' | 'height'>;
|
|
1079
|
+
/** A full-canvas flex container (like Remotion's `<AbsoluteFill>`): fills the
|
|
1080
|
+
* composition and lays children out (column by default) — ideal for centering
|
|
1081
|
+
* or stacking. Combine with `justify`/`align` to center content. */
|
|
1082
|
+
declare function AbsoluteFill(props: AbsoluteFillProps): react.DOMElement<{
|
|
1083
|
+
layout: Layout;
|
|
1084
|
+
/** Stable id, required to target the node from an animation timeline. */
|
|
1085
|
+
id?: number;
|
|
1086
|
+
/** Translation in pixels. */
|
|
1087
|
+
x?: number;
|
|
1088
|
+
y?: number;
|
|
1089
|
+
/** Scale factor (1 = identity). */
|
|
1090
|
+
scaleX?: number;
|
|
1091
|
+
scaleY?: number;
|
|
1092
|
+
/** Clockwise rotation in degrees, about the transform origin (default (0,0)).
|
|
1093
|
+
* Renders on the GPU (Vello) backend; the CPU reference rasterizer ignores it. */
|
|
1094
|
+
rotation?: number;
|
|
1095
|
+
/** Pivot for scale + rotation in local px (CSS transform-origin). Default (0,0).
|
|
1096
|
+
* For "about the center", pass half the node's width/height. */
|
|
1097
|
+
originX?: number;
|
|
1098
|
+
originY?: number;
|
|
1099
|
+
/** Opacity, 0..1. */
|
|
1100
|
+
opacity?: number;
|
|
1101
|
+
/** DEPTH (z) of this layer for depth-of-field, in the same arbitrary units as
|
|
1102
|
+
* `<Composition dof={{ focus }}>`. Layers at the focus depth stay sharp; the
|
|
1103
|
+
* farther a layer's `depth` is from `focus`, the more it defocuses (a blur the
|
|
1104
|
+
* reconciler computes from the camera aperture). Animate the comp's `focus` for a
|
|
1105
|
+
* rack-focus pull. No effect unless the comp sets `dof`. */
|
|
1106
|
+
depth?: number;
|
|
1107
|
+
/** 3D LAYER position `[x, y, z]` in world pixels — meaningful only inside a
|
|
1108
|
+
* `<Scene3D>`. `z = 0` is the framing plane (matches the 2D placement); larger
|
|
1109
|
+
* `z` is farther into the screen (smaller), negative `z` nearer the camera (After
|
|
1110
|
+
* Effects convention). Animate for fly-throughs / parallax / exploded views. */
|
|
1111
|
+
position3d?: [number, number, number];
|
|
1112
|
+
/** 3D LAYER rotation `[x, y, z]` in degrees (Z·Y·X): X pitch (tilt toward/away),
|
|
1113
|
+
* Y yaw (swing), Z roll (in-plane spin). Inside `<Scene3D>` only. GPU-only — the
|
|
1114
|
+
* CPU reference degrades to a flat depth-sorted composite (no out-of-plane tilt). */
|
|
1115
|
+
rotation3d?: [number, number, number];
|
|
1116
|
+
/** Pivot within this layer's content plane (px) that `position3d`/`rotation3d`
|
|
1117
|
+
* act about. Default: the layer's center. */
|
|
1118
|
+
anchor3d?: [number, number];
|
|
1119
|
+
/** EXTRUDE this layer's 2D outline into a lit 3D SOLID (the "3D logo / title"):
|
|
1120
|
+
* inside a `<Scene3D>`, a shape or text layer becomes a mesh with `depth`
|
|
1121
|
+
* thickness + side walls, shaded by a directional light so it catches the light
|
|
1122
|
+
* as it rotates. GPU only — the CPU reference + live preview draw the flat outline. */
|
|
1123
|
+
extrude?: number | {
|
|
1124
|
+
depth: number;
|
|
1125
|
+
};
|
|
1126
|
+
/** Blend this node's subtree against the backdrop (CSS mix-blend-mode).
|
|
1127
|
+
* GPU/Vello-rendered (e.g. `'screen'`, `'multiply'`, `'overlay'`). */
|
|
1128
|
+
blendMode?: BlendMode;
|
|
1129
|
+
/** Clip this node and its subtree to a region (local space). */
|
|
1130
|
+
clip?: ClipInput;
|
|
1131
|
+
/** Matte (track matte / mask): a stencil SUBTREE, passed as a React element,
|
|
1132
|
+
* through which this node's content is revealed. The matte's alpha — or its
|
|
1133
|
+
* luminance, per `matteMode` — multiplies the content's alpha, so the content
|
|
1134
|
+
* (this node's children) shows only where the matte covers. The
|
|
1135
|
+
* strictly-more-powerful sibling of `clip`: the matte is a fully rendered,
|
|
1136
|
+
* animatable subtree (giant text, a gradient, a shape) — the signature
|
|
1137
|
+
* "media-through-type" move (a photo seen only through animated type). */
|
|
1138
|
+
matte?: ReactElement;
|
|
1139
|
+
/** Which channel of the {@link NodeProps.matte} subtree drives the reveal (CSS
|
|
1140
|
+
* `mask-mode`). `'alpha'` (default): content alpha ×= matte alpha. `'luminance'`:
|
|
1141
|
+
* content alpha ×= luma(matte) × matte alpha (white reveals, black hides). */
|
|
1142
|
+
matteMode?: MatteMode;
|
|
1143
|
+
/** Ordered, low-level screen-space effects on this node + subtree (render-to-texture). */
|
|
1144
|
+
effects?: Effect[];
|
|
1145
|
+
/** Gaussian blur std-dev in output px; sugar for `effects: [{ effect: 'blur', sigma }]`.
|
|
1146
|
+
* Honored by Vello AND the CPU reference once Phase 1 lands. */
|
|
1147
|
+
blur?: number;
|
|
1148
|
+
/** Directional (motion) blur sugar for `effects: [{ effect: 'directional_blur', … }]`:
|
|
1149
|
+
* a 1D blur of std-dev `sigma` (px) along `angle` (radians, default 0 = horizontal) —
|
|
1150
|
+
* the cinematic "in-motion" smear. Honored by Vello AND the CPU reference. */
|
|
1151
|
+
directionalBlur?: {
|
|
1152
|
+
sigma: number;
|
|
1153
|
+
angle?: number;
|
|
1154
|
+
};
|
|
1155
|
+
/** Chromatic-aberration sugar: R/B split by `amount` px radially from centre. */
|
|
1156
|
+
chromaticAberration?: number;
|
|
1157
|
+
/** Vignette sugar — radial edge darkening. `amount` 0..1; `softness` 0..1 (default 0.5). */
|
|
1158
|
+
vignette?: number | {
|
|
1159
|
+
amount: number;
|
|
1160
|
+
softness?: number;
|
|
1161
|
+
};
|
|
1162
|
+
/** Posterize sugar: quantize each channel to `levels` (≥2) discrete steps. */
|
|
1163
|
+
posterize?: number;
|
|
1164
|
+
/** Duotone sugar: map luminance to a gradient from `shadow` to `highlight`. */
|
|
1165
|
+
duotone?: {
|
|
1166
|
+
shadow: ColorInput;
|
|
1167
|
+
highlight: ColorInput;
|
|
1168
|
+
};
|
|
1169
|
+
/** Chroma-key sugar: knock out `color`; `threshold` (default 0.4) + `smoothness`
|
|
1170
|
+
* (default 0.1) shape the soft matte edge. */
|
|
1171
|
+
chromaKey?: {
|
|
1172
|
+
color: ColorInput;
|
|
1173
|
+
threshold?: number;
|
|
1174
|
+
smoothness?: number;
|
|
1175
|
+
};
|
|
1176
|
+
/** Glow / bloom sugar for `effects: [{ effect: 'bloom', ... }]`: bright regions
|
|
1177
|
+
* (luminance above `threshold`, default 0.7; scaled by `intensity`, default 1)
|
|
1178
|
+
* blur with `sigma` and composite additively over the sharp subtree. Honored by
|
|
1179
|
+
* Vello AND the CPU reference. */
|
|
1180
|
+
bloom?: number | {
|
|
1181
|
+
sigma: number;
|
|
1182
|
+
threshold?: number;
|
|
1183
|
+
intensity?: number;
|
|
1184
|
+
};
|
|
1185
|
+
/** Cinematic color-grade sugar for `effects: [{ effect: 'color_grade', ... }]` —
|
|
1186
|
+
* the "land AI media" wedge: one grade unifies mismatched clips into a single
|
|
1187
|
+
* look. All five fields are optional and default to the neutral identity
|
|
1188
|
+
* (`exposure` 0, `contrast` 1, `saturation` 1, `temperature` 0, `tint` 0), so
|
|
1189
|
+
* `{}` is a no-op. Honored by Vello AND the CPU reference. */
|
|
1190
|
+
grade?: {
|
|
1191
|
+
/** Linear exposure gain (`2^exposure`); 0 = identity. */
|
|
1192
|
+
exposure?: number;
|
|
1193
|
+
/** Contrast around a 0.5 pivot; 1 = identity. */
|
|
1194
|
+
contrast?: number;
|
|
1195
|
+
/** Saturation; 1 = identity, 0 = grayscale, >1 = punchier. */
|
|
1196
|
+
saturation?: number;
|
|
1197
|
+
/** Warm/cool shift (R up / B down for positive); 0 = neutral. */
|
|
1198
|
+
temperature?: number;
|
|
1199
|
+
/** Green/magenta shift on G (positive = green); 0 = neutral. */
|
|
1200
|
+
tint?: number;
|
|
1201
|
+
};
|
|
1202
|
+
/** Gooey / liquid / metaball-morph sugar for `effects: [{ effect: 'goo', ... }]`:
|
|
1203
|
+
* the subtree is blurred with `sigma`, then its alpha is sharpened around
|
|
1204
|
+
* `threshold` (the 0..1 cutoff, default 0.5) so overlapping shapes fuse into
|
|
1205
|
+
* solid forms joined by smooth necks (the "drops of liquid coalescing" look).
|
|
1206
|
+
* A bare number is the `sigma`. Honored by Vello AND the CPU reference. */
|
|
1207
|
+
goo?: number | {
|
|
1208
|
+
sigma: number;
|
|
1209
|
+
threshold?: number;
|
|
1210
|
+
};
|
|
1211
|
+
/** Film-grain sugar for `effects: [{ effect: 'grain', ... }]`: luminance-banded,
|
|
1212
|
+
* animated monochrome noise added late over the subtree — the compositing "glue"
|
|
1213
|
+
* that makes mismatched sources read as one photographed image, and the dither
|
|
1214
|
+
* that hides 8-bit banding on dark gradients. A bare number is the `intensity`
|
|
1215
|
+
* (~0.04–0.1 is filmic); the object form adds `size` (grain scale in px, default
|
|
1216
|
+
* 1) and `seed` (animation offset — pass the current frame for *living* grain,
|
|
1217
|
+
* default 0 = static). Honored by Vello AND the CPU reference. */
|
|
1218
|
+
grain?: number | {
|
|
1219
|
+
intensity: number;
|
|
1220
|
+
size?: number;
|
|
1221
|
+
seed?: number;
|
|
1222
|
+
};
|
|
1223
|
+
/** Frosted-glass sugar for `effects: [{ effect: 'backdrop_blur', ... }]`: samples
|
|
1224
|
+
* the already-composited BACKDROP *behind* this node (not its own subtree),
|
|
1225
|
+
* blurs it by `sigma` (output px), and draws it as the node's backing — then the
|
|
1226
|
+
* node's own content (e.g. a translucent panel `fill`) composites on top. A bare
|
|
1227
|
+
* number is just the `sigma`; the object form adds a `tint` (its alpha = tint
|
|
1228
|
+
* strength), a `brightness` and a `saturation` (CSS-style, `1` = identity).
|
|
1229
|
+
* Honored by Vello AND the CPU reference. */
|
|
1230
|
+
backdropBlur?: number | {
|
|
1231
|
+
sigma: number;
|
|
1232
|
+
tint?: ColorInput;
|
|
1233
|
+
brightness?: number;
|
|
1234
|
+
saturation?: number;
|
|
1235
|
+
};
|
|
1236
|
+
/** Light-wrap sugar for `effects: [{ effect: 'light_wrap', ... }]`: bleeds the
|
|
1237
|
+
* blurred BACKDROP behind this node onto its own feathered EDGES — the #1
|
|
1238
|
+
* "shot in, not pasted on" compositing tell for a cut-out plate. A bare number
|
|
1239
|
+
* is the `sigma` (the backdrop blur / rim width); the object form adds a
|
|
1240
|
+
* `strength` (0 = off, ~1 = a natural spill). EXPORT/NATIVE only — the live
|
|
1241
|
+
* preview draws the node un-wrapped. */
|
|
1242
|
+
lightWrap?: number | {
|
|
1243
|
+
sigma: number;
|
|
1244
|
+
strength?: number;
|
|
1245
|
+
};
|
|
1246
|
+
children?: ReactNode;
|
|
1247
|
+
}, Element>;
|
|
1248
|
+
interface CameraProps {
|
|
1249
|
+
/** The world — children laid out in absolute WORLD-pixel coordinates. */
|
|
1250
|
+
children?: ReactNode;
|
|
1251
|
+
/** World x (px) to center in the viewport. Default: viewport center (no pan). */
|
|
1252
|
+
focusX?: number;
|
|
1253
|
+
/** World y (px) to center in the viewport. Default: viewport center (no pan). */
|
|
1254
|
+
focusY?: number;
|
|
1255
|
+
/** Zoom about the focus point. 1 = neutral, >1 = pushed in. */
|
|
1256
|
+
zoom?: number;
|
|
1257
|
+
/** Camera roll in degrees (2D rotation about the focus point). GPU-only. */
|
|
1258
|
+
rotate?: number;
|
|
1259
|
+
/** Viewport size; defaults to the composition canvas. */
|
|
1260
|
+
viewportWidth?: number;
|
|
1261
|
+
viewportHeight?: number;
|
|
1262
|
+
}
|
|
1263
|
+
/**
|
|
1264
|
+
* A 2D camera: frames an oversized "world" (its children, laid out in world-pixel
|
|
1265
|
+
* coordinates) by centering a world point in the viewport at a given zoom + roll —
|
|
1266
|
+
* pans across a grid larger than the canvas, push-in fly-overs, focus moves.
|
|
1267
|
+
*
|
|
1268
|
+
* Pure translate/scale/rotate — a STACK OF {@link Group}s, no new scene node:
|
|
1269
|
+
* `translate(vw/2,vh/2) ∘ [scale·rotate about origin] ∘ translate(-focus)`, so the
|
|
1270
|
+
* world point `focus` lands at the viewport center, scaled by `zoom`. (`rotate`
|
|
1271
|
+
* renders on the GPU/Vello backend only, like {@link NodeProps.rotation}.) Animate
|
|
1272
|
+
* focus/zoom per frame ({@link useCurrentFrame} + interpolate) for a moving camera.
|
|
1273
|
+
*/
|
|
1274
|
+
declare function Camera(props: CameraProps): react.FunctionComponentElement<NodeProps>;
|
|
1275
|
+
interface Scene3DProps extends Omit<NodeProps, 'children'> {
|
|
1276
|
+
/** The perspective camera for this 3D world. Omit fields to derive a default that
|
|
1277
|
+
* frames the `z = 0` plane to fill the comp (so layers at `z = 0` match their 2D
|
|
1278
|
+
* placement). Animate `position`/`target` per frame for camera moves. */
|
|
1279
|
+
camera?: Camera3D;
|
|
1280
|
+
/** The 3D LAYERS — direct children, each placed by its `position3d` / `rotation3d`
|
|
1281
|
+
* / `anchor3d`. Layers without a `position3d` sit at `z = 0` (their 2D spot). */
|
|
1282
|
+
children?: ReactNode;
|
|
1283
|
+
}
|
|
1284
|
+
/**
|
|
1285
|
+
* A 3D SCENE: its direct children become 3D LAYERS in one shared 3D world, viewed
|
|
1286
|
+
* through a perspective `camera`. Each layer is a flat plane (its rendered 2D
|
|
1287
|
+
* content) placed by `position3d` (world x/y/z) and tilted by `rotation3d`, then
|
|
1288
|
+
* depth-sorted and composited as a single layer. The mograph core of "3D" —
|
|
1289
|
+
* camera fly-throughs, card walls, parallax, exploded UI, billboard text.
|
|
1290
|
+
*
|
|
1291
|
+
* GPU (Vello) runs true perspective; the CPU reference degrades to a 2.5D
|
|
1292
|
+
* depth-sorted composite (per-layer distance scale, no out-of-plane tilt). A layer
|
|
1293
|
+
* at `z = 0` with no rotation renders pixel-identical to its 2D placement, so
|
|
1294
|
+
* wrapping content in `<Scene3D>` changes nothing until you move layers in z.
|
|
1295
|
+
*/
|
|
1296
|
+
declare function Scene3D(props: Scene3DProps): ReactElement<{
|
|
1297
|
+
camera3d: Camera3D;
|
|
1298
|
+
blur?: number
|
|
1299
|
+
/** Directional (motion) blur sugar for `effects: [{ effect: 'directional_blur', … }]`:
|
|
1300
|
+
* a 1D blur of std-dev `sigma` (px) along `angle` (radians, default 0 = horizontal) —
|
|
1301
|
+
* the cinematic "in-motion" smear. Honored by Vello AND the CPU reference. */
|
|
1302
|
+
| undefined;
|
|
1303
|
+
vignette?: number | {
|
|
1304
|
+
amount: number;
|
|
1305
|
+
softness?: number;
|
|
1306
|
+
}
|
|
1307
|
+
/** Posterize sugar: quantize each channel to `levels` (≥2) discrete steps. */
|
|
1308
|
+
| undefined;
|
|
1309
|
+
posterize?: number
|
|
1310
|
+
/** Duotone sugar: map luminance to a gradient from `shadow` to `highlight`. */
|
|
1311
|
+
| undefined;
|
|
1312
|
+
duotone?: {
|
|
1313
|
+
shadow: ColorInput;
|
|
1314
|
+
highlight: ColorInput;
|
|
1315
|
+
}
|
|
1316
|
+
/** Chroma-key sugar: knock out `color`; `threshold` (default 0.4) + `smoothness`
|
|
1317
|
+
* (default 0.1) shape the soft matte edge. */
|
|
1318
|
+
| undefined;
|
|
1319
|
+
bloom?: number | {
|
|
1320
|
+
sigma: number;
|
|
1321
|
+
threshold?: number;
|
|
1322
|
+
intensity?: number;
|
|
1323
|
+
}
|
|
1324
|
+
/** Cinematic color-grade sugar for `effects: [{ effect: 'color_grade', ... }]` —
|
|
1325
|
+
* the "land AI media" wedge: one grade unifies mismatched clips into a single
|
|
1326
|
+
* look. All five fields are optional and default to the neutral identity
|
|
1327
|
+
* (`exposure` 0, `contrast` 1, `saturation` 1, `temperature` 0, `tint` 0), so
|
|
1328
|
+
* `{}` is a no-op. Honored by Vello AND the CPU reference. */
|
|
1329
|
+
| undefined;
|
|
1330
|
+
goo?: number | {
|
|
1331
|
+
sigma: number;
|
|
1332
|
+
threshold?: number;
|
|
1333
|
+
}
|
|
1334
|
+
/** Film-grain sugar for `effects: [{ effect: 'grain', ... }]`: luminance-banded,
|
|
1335
|
+
* animated monochrome noise added late over the subtree — the compositing "glue"
|
|
1336
|
+
* that makes mismatched sources read as one photographed image, and the dither
|
|
1337
|
+
* that hides 8-bit banding on dark gradients. A bare number is the `intensity`
|
|
1338
|
+
* (~0.04–0.1 is filmic); the object form adds `size` (grain scale in px, default
|
|
1339
|
+
* 1) and `seed` (animation offset — pass the current frame for *living* grain,
|
|
1340
|
+
* default 0 = static). Honored by Vello AND the CPU reference. */
|
|
1341
|
+
| undefined;
|
|
1342
|
+
grain?: number | {
|
|
1343
|
+
intensity: number;
|
|
1344
|
+
size?: number;
|
|
1345
|
+
seed?: number;
|
|
1346
|
+
}
|
|
1347
|
+
/** Frosted-glass sugar for `effects: [{ effect: 'backdrop_blur', ... }]`: samples
|
|
1348
|
+
* the already-composited BACKDROP *behind* this node (not its own subtree),
|
|
1349
|
+
* blurs it by `sigma` (output px), and draws it as the node's backing — then the
|
|
1350
|
+
* node's own content (e.g. a translucent panel `fill`) composites on top. A bare
|
|
1351
|
+
* number is just the `sigma`; the object form adds a `tint` (its alpha = tint
|
|
1352
|
+
* strength), a `brightness` and a `saturation` (CSS-style, `1` = identity).
|
|
1353
|
+
* Honored by Vello AND the CPU reference. */
|
|
1354
|
+
| undefined;
|
|
1355
|
+
id?: number
|
|
1356
|
+
/** Translation in pixels. */
|
|
1357
|
+
| undefined;
|
|
1358
|
+
x?: number | undefined;
|
|
1359
|
+
y?: number
|
|
1360
|
+
/** Scale factor (1 = identity). */
|
|
1361
|
+
| undefined;
|
|
1362
|
+
scaleX?: number | undefined;
|
|
1363
|
+
scaleY?: number
|
|
1364
|
+
/** Clockwise rotation in degrees, about the transform origin (default (0,0)).
|
|
1365
|
+
* Renders on the GPU (Vello) backend; the CPU reference rasterizer ignores it. */
|
|
1366
|
+
| undefined;
|
|
1367
|
+
rotation?: number
|
|
1368
|
+
/** Pivot for scale + rotation in local px (CSS transform-origin). Default (0,0).
|
|
1369
|
+
* For "about the center", pass half the node's width/height. */
|
|
1370
|
+
| undefined;
|
|
1371
|
+
originX?: number | undefined;
|
|
1372
|
+
originY?: number
|
|
1373
|
+
/** Opacity, 0..1. */
|
|
1374
|
+
| undefined;
|
|
1375
|
+
opacity?: number
|
|
1376
|
+
/** DEPTH (z) of this layer for depth-of-field, in the same arbitrary units as
|
|
1377
|
+
* `<Composition dof={{ focus }}>`. Layers at the focus depth stay sharp; the
|
|
1378
|
+
* farther a layer's `depth` is from `focus`, the more it defocuses (a blur the
|
|
1379
|
+
* reconciler computes from the camera aperture). Animate the comp's `focus` for a
|
|
1380
|
+
* rack-focus pull. No effect unless the comp sets `dof`. */
|
|
1381
|
+
| undefined;
|
|
1382
|
+
depth?: number
|
|
1383
|
+
/** 3D LAYER position `[x, y, z]` in world pixels — meaningful only inside a
|
|
1384
|
+
* `<Scene3D>`. `z = 0` is the framing plane (matches the 2D placement); larger
|
|
1385
|
+
* `z` is farther into the screen (smaller), negative `z` nearer the camera (After
|
|
1386
|
+
* Effects convention). Animate for fly-throughs / parallax / exploded views. */
|
|
1387
|
+
| undefined;
|
|
1388
|
+
position3d?: [number, number, number]
|
|
1389
|
+
/** 3D LAYER rotation `[x, y, z]` in degrees (Z·Y·X): X pitch (tilt toward/away),
|
|
1390
|
+
* Y yaw (swing), Z roll (in-plane spin). Inside `<Scene3D>` only. GPU-only — the
|
|
1391
|
+
* CPU reference degrades to a flat depth-sorted composite (no out-of-plane tilt). */
|
|
1392
|
+
| undefined;
|
|
1393
|
+
rotation3d?: [number, number, number]
|
|
1394
|
+
/** Pivot within this layer's content plane (px) that `position3d`/`rotation3d`
|
|
1395
|
+
* act about. Default: the layer's center. */
|
|
1396
|
+
| undefined;
|
|
1397
|
+
anchor3d?: [number, number]
|
|
1398
|
+
/** EXTRUDE this layer's 2D outline into a lit 3D SOLID (the "3D logo / title"):
|
|
1399
|
+
* inside a `<Scene3D>`, a shape or text layer becomes a mesh with `depth`
|
|
1400
|
+
* thickness + side walls, shaded by a directional light so it catches the light
|
|
1401
|
+
* as it rotates. GPU only — the CPU reference + live preview draw the flat outline. */
|
|
1402
|
+
| undefined;
|
|
1403
|
+
extrude?: number | {
|
|
1404
|
+
depth: number;
|
|
1405
|
+
}
|
|
1406
|
+
/** Blend this node's subtree against the backdrop (CSS mix-blend-mode).
|
|
1407
|
+
* GPU/Vello-rendered (e.g. `'screen'`, `'multiply'`, `'overlay'`). */
|
|
1408
|
+
| undefined;
|
|
1409
|
+
blendMode?: BlendMode
|
|
1410
|
+
/** Clip this node and its subtree to a region (local space). */
|
|
1411
|
+
| undefined;
|
|
1412
|
+
clip?: ClipInput
|
|
1413
|
+
/** Matte (track matte / mask): a stencil SUBTREE, passed as a React element,
|
|
1414
|
+
* through which this node's content is revealed. The matte's alpha — or its
|
|
1415
|
+
* luminance, per `matteMode` — multiplies the content's alpha, so the content
|
|
1416
|
+
* (this node's children) shows only where the matte covers. The
|
|
1417
|
+
* strictly-more-powerful sibling of `clip`: the matte is a fully rendered,
|
|
1418
|
+
* animatable subtree (giant text, a gradient, a shape) — the signature
|
|
1419
|
+
* "media-through-type" move (a photo seen only through animated type). */
|
|
1420
|
+
| undefined;
|
|
1421
|
+
matte?: ReactElement
|
|
1422
|
+
/** Which channel of the {@link NodeProps.matte} subtree drives the reveal (CSS
|
|
1423
|
+
* `mask-mode`). `'alpha'` (default): content alpha ×= matte alpha. `'luminance'`:
|
|
1424
|
+
* content alpha ×= luma(matte) × matte alpha (white reveals, black hides). */
|
|
1425
|
+
| undefined;
|
|
1426
|
+
matteMode?: MatteMode
|
|
1427
|
+
/** Ordered, low-level screen-space effects on this node + subtree (render-to-texture). */
|
|
1428
|
+
| undefined;
|
|
1429
|
+
effects?: Effect[]
|
|
1430
|
+
/** Gaussian blur std-dev in output px; sugar for `effects: [{ effect: 'blur', sigma }]`.
|
|
1431
|
+
* Honored by Vello AND the CPU reference once Phase 1 lands. */
|
|
1432
|
+
| undefined;
|
|
1433
|
+
directionalBlur?: {
|
|
1434
|
+
sigma: number;
|
|
1435
|
+
angle?: number;
|
|
1436
|
+
}
|
|
1437
|
+
/** Chromatic-aberration sugar: R/B split by `amount` px radially from centre. */
|
|
1438
|
+
| undefined;
|
|
1439
|
+
chromaticAberration?: number
|
|
1440
|
+
/** Vignette sugar — radial edge darkening. `amount` 0..1; `softness` 0..1 (default 0.5). */
|
|
1441
|
+
| undefined;
|
|
1442
|
+
chromaKey?: {
|
|
1443
|
+
color: ColorInput;
|
|
1444
|
+
threshold?: number;
|
|
1445
|
+
smoothness?: number;
|
|
1446
|
+
}
|
|
1447
|
+
/** Glow / bloom sugar for `effects: [{ effect: 'bloom', ... }]`: bright regions
|
|
1448
|
+
* (luminance above `threshold`, default 0.7; scaled by `intensity`, default 1)
|
|
1449
|
+
* blur with `sigma` and composite additively over the sharp subtree. Honored by
|
|
1450
|
+
* Vello AND the CPU reference. */
|
|
1451
|
+
| undefined;
|
|
1452
|
+
grade?: {
|
|
1453
|
+
/** Linear exposure gain (`2^exposure`); 0 = identity. */
|
|
1454
|
+
exposure?: number;
|
|
1455
|
+
/** Contrast around a 0.5 pivot; 1 = identity. */
|
|
1456
|
+
contrast?: number;
|
|
1457
|
+
/** Saturation; 1 = identity, 0 = grayscale, >1 = punchier. */
|
|
1458
|
+
saturation?: number;
|
|
1459
|
+
/** Warm/cool shift (R up / B down for positive); 0 = neutral. */
|
|
1460
|
+
temperature?: number;
|
|
1461
|
+
/** Green/magenta shift on G (positive = green); 0 = neutral. */
|
|
1462
|
+
tint?: number;
|
|
1463
|
+
}
|
|
1464
|
+
/** Gooey / liquid / metaball-morph sugar for `effects: [{ effect: 'goo', ... }]`:
|
|
1465
|
+
* the subtree is blurred with `sigma`, then its alpha is sharpened around
|
|
1466
|
+
* `threshold` (the 0..1 cutoff, default 0.5) so overlapping shapes fuse into
|
|
1467
|
+
* solid forms joined by smooth necks (the "drops of liquid coalescing" look).
|
|
1468
|
+
* A bare number is the `sigma`. Honored by Vello AND the CPU reference. */
|
|
1469
|
+
| undefined;
|
|
1470
|
+
backdropBlur?: number | {
|
|
1471
|
+
sigma: number;
|
|
1472
|
+
tint?: ColorInput;
|
|
1473
|
+
brightness?: number;
|
|
1474
|
+
saturation?: number;
|
|
1475
|
+
}
|
|
1476
|
+
/** Light-wrap sugar for `effects: [{ effect: 'light_wrap', ... }]`: bleeds the
|
|
1477
|
+
* blurred BACKDROP behind this node onto its own feathered EDGES — the #1
|
|
1478
|
+
* "shot in, not pasted on" compositing tell for a cut-out plate. A bare number
|
|
1479
|
+
* is the `sigma` (the backdrop blur / rim width); the object form adds a
|
|
1480
|
+
* `strength` (0 = off, ~1 = a natural spill). EXPORT/NATIVE only — the live
|
|
1481
|
+
* preview draws the node un-wrapped. */
|
|
1482
|
+
| undefined;
|
|
1483
|
+
lightWrap?: number | {
|
|
1484
|
+
sigma: number;
|
|
1485
|
+
strength?: number;
|
|
1486
|
+
} | undefined;
|
|
1487
|
+
}, string | react.JSXElementConstructor<any>>;
|
|
1488
|
+
interface RectProps extends NodeProps, PaintProps {
|
|
1489
|
+
width: number;
|
|
1490
|
+
height: number;
|
|
1491
|
+
cornerRadius?: number;
|
|
1492
|
+
}
|
|
1493
|
+
declare function Rect(props: RectProps): react.DOMElement<RectProps, Element>;
|
|
1494
|
+
interface EllipseProps extends NodeProps, PaintProps {
|
|
1495
|
+
width: number;
|
|
1496
|
+
height: number;
|
|
1497
|
+
}
|
|
1498
|
+
declare function Ellipse(props: EllipseProps): react.DOMElement<EllipseProps, Element>;
|
|
1499
|
+
interface PathProps extends NodeProps, PaintProps {
|
|
1500
|
+
/** SVG path data (e.g. `"M0 0 L100 0 Z"`), in the node's local space. */
|
|
1501
|
+
d: string;
|
|
1502
|
+
}
|
|
1503
|
+
/** An arbitrary vector outline from SVG path data. Renders on the GPU (Vello)
|
|
1504
|
+
* backend; the CPU reference rasterizer skips paths. */
|
|
1505
|
+
declare function Path(props: PathProps): react.DOMElement<PathProps, Element>;
|
|
1506
|
+
/** One styled run for rich `<Text>` — overrides the node's style. */
|
|
1507
|
+
interface TextRunInput {
|
|
1508
|
+
text: string;
|
|
1509
|
+
color?: ColorInput;
|
|
1510
|
+
fontSize?: number;
|
|
1511
|
+
/** Font family (must be loaded; bundled: "Open Sans", "IBM Plex Sans"). */
|
|
1512
|
+
fontFamily?: string;
|
|
1513
|
+
/** CSS weight 1..1000 (700 = bold). */
|
|
1514
|
+
fontWeight?: number;
|
|
1515
|
+
italic?: boolean;
|
|
1516
|
+
}
|
|
1517
|
+
interface TextProps extends NodeProps {
|
|
1518
|
+
fontSize?: number;
|
|
1519
|
+
color?: ColorInput;
|
|
1520
|
+
/** Font family (must be loaded; bundled: "Open Sans", "IBM Plex Sans"). */
|
|
1521
|
+
fontFamily?: string;
|
|
1522
|
+
/** CSS weight 1..1000 (700 = bold). */
|
|
1523
|
+
fontWeight?: number;
|
|
1524
|
+
italic?: boolean;
|
|
1525
|
+
/** Extra px between glyphs (CSS `letter-spacing` / tracking). `0` = natural;
|
|
1526
|
+
* negative tightens. Applied on the GPU/preview (Vello) text path. */
|
|
1527
|
+
letterSpacing?: number;
|
|
1528
|
+
/** Rich multi-style runs. When set, these replace the text children — each run
|
|
1529
|
+
* may override color/size/family/weight/style. Renders per-run on the GPU
|
|
1530
|
+
* (Vello); the CPU backend draws their concatenated text in the node style. */
|
|
1531
|
+
runs?: TextRunInput[];
|
|
1532
|
+
children?: ReactNode;
|
|
1533
|
+
}
|
|
1534
|
+
declare function Text(props: TextProps): react.DOMElement<TextProps, Element>;
|
|
1535
|
+
interface ImageProps extends NodeProps {
|
|
1536
|
+
src: string;
|
|
1537
|
+
/** Target box width in px. With `height`, the decoded image is fitted into this
|
|
1538
|
+
* box per `fit` — the renderer measures the image, so the component doesn't
|
|
1539
|
+
* need its intrinsic size. Omit both for the image's intrinsic pixel size. */
|
|
1540
|
+
width?: number;
|
|
1541
|
+
height?: number;
|
|
1542
|
+
/** How to fit the image into the `width`×`height` box (default `'cover'`). */
|
|
1543
|
+
fit?: ImageFit;
|
|
1544
|
+
/** Gaussian blur radius (sigma, in source pixels) applied to the decoded image
|
|
1545
|
+
* by the engine's image pass. `0`/omitted leaves it sharp; animating it gives
|
|
1546
|
+
* a soft→sharp "focus pull" entrance. Identical on every backend. */
|
|
1547
|
+
blur?: number;
|
|
1548
|
+
}
|
|
1549
|
+
declare function Image(props: ImageProps): react.DOMElement<ImageProps, Element>;
|
|
1550
|
+
interface VideoProps extends NodeProps {
|
|
1551
|
+
/** Path, URL, or `data:` URI of the video. The frame at the current time is
|
|
1552
|
+
* decoded by the player (browser: an off-screen `<video>`/WebCodecs) or by
|
|
1553
|
+
* `onda export` (native ffmpeg) — the author layer never decodes. */
|
|
1554
|
+
src: string;
|
|
1555
|
+
/** Seconds into the SOURCE shown at this clip's frame 0 (trim the head).
|
|
1556
|
+
* Default `0`. */
|
|
1557
|
+
startFrom?: number;
|
|
1558
|
+
/** Source seconds advanced per composition second (1 = realtime, 2 = 2× fast,
|
|
1559
|
+
* 0.5 = slow-mo). Default `1`. */
|
|
1560
|
+
playbackRate?: number;
|
|
1561
|
+
/** Seconds into the SOURCE to stop at (trim the tail). Past it the clip holds
|
|
1562
|
+
* its last frame, unless `loop` is set. Omit to play to the source's end. */
|
|
1563
|
+
endAt?: number;
|
|
1564
|
+
/** Loop the trimmed span `[startFrom, endAt)` (requires `endAt`). The source
|
|
1565
|
+
* time wraps so the clip repeats for as long as the `<Sequence>` shows it. */
|
|
1566
|
+
loop?: boolean;
|
|
1567
|
+
/** Target box width in px. With `height`, the frame is fitted into this box
|
|
1568
|
+
* per `fit`. Omit both for the video's intrinsic pixel size. */
|
|
1569
|
+
width?: number;
|
|
1570
|
+
height?: number;
|
|
1571
|
+
/** How to fit the frame into the `width`×`height` box (default `'cover'`). */
|
|
1572
|
+
fit?: ImageFit;
|
|
1573
|
+
/**
|
|
1574
|
+
* Preview-only behaviour when the browser can't composite this source — i.e. a
|
|
1575
|
+
* cross-origin video without CORS headers. **Never affects `onda export`**,
|
|
1576
|
+
* which always composites via ffmpeg.
|
|
1577
|
+
* - `'skip'` (default): leave it blank in preview + log a one-time hint.
|
|
1578
|
+
* - `'element'`: overlay a plain `<video>` so it still *plays* in preview
|
|
1579
|
+
* (display-only — no engine effects, and it sits above the canvas). Useful
|
|
1580
|
+
* for prototyping with a third-party URL you can't add CORS to. For your own
|
|
1581
|
+
* assets, serving them same-origin or with CORS is better (full compositing).
|
|
1582
|
+
*/
|
|
1583
|
+
previewFallback?: 'skip' | 'element';
|
|
1584
|
+
}
|
|
1585
|
+
/** A video clip. At composition frame *f* it shows the source frame at
|
|
1586
|
+
* `startFrom + (f / fps) * playbackRate` seconds; the player/engine decodes that
|
|
1587
|
+
* exact frame (browser: `<video>`/WebCodecs; native export: ffmpeg) and the
|
|
1588
|
+
* renderer draws it like an image. Place/scale it like any node; combine with a
|
|
1589
|
+
* `<Sequence>` to position it on the timeline. */
|
|
1590
|
+
declare function Video({ startFrom, playbackRate, endAt, loop, ...rest }: VideoProps): react.DOMElement<{
|
|
1591
|
+
time: number;
|
|
1592
|
+
/** Path, URL, or `data:` URI of the video. The frame at the current time is
|
|
1593
|
+
* decoded by the player (browser: an off-screen `<video>`/WebCodecs) or by
|
|
1594
|
+
* `onda export` (native ffmpeg) — the author layer never decodes. */
|
|
1595
|
+
src: string;
|
|
1596
|
+
/** Target box width in px. With `height`, the frame is fitted into this box
|
|
1597
|
+
* per `fit`. Omit both for the video's intrinsic pixel size. */
|
|
1598
|
+
width?: number;
|
|
1599
|
+
height?: number;
|
|
1600
|
+
/** How to fit the frame into the `width`×`height` box (default `'cover'`). */
|
|
1601
|
+
fit?: ImageFit;
|
|
1602
|
+
/**
|
|
1603
|
+
* Preview-only behaviour when the browser can't composite this source — i.e. a
|
|
1604
|
+
* cross-origin video without CORS headers. **Never affects `onda export`**,
|
|
1605
|
+
* which always composites via ffmpeg.
|
|
1606
|
+
* - `'skip'` (default): leave it blank in preview + log a one-time hint.
|
|
1607
|
+
* - `'element'`: overlay a plain `<video>` so it still *plays* in preview
|
|
1608
|
+
* (display-only — no engine effects, and it sits above the canvas). Useful
|
|
1609
|
+
* for prototyping with a third-party URL you can't add CORS to. For your own
|
|
1610
|
+
* assets, serving them same-origin or with CORS is better (full compositing).
|
|
1611
|
+
*/
|
|
1612
|
+
previewFallback?: "skip" | "element";
|
|
1613
|
+
/** Stable id, required to target the node from an animation timeline. */
|
|
1614
|
+
id?: number;
|
|
1615
|
+
/** Translation in pixels. */
|
|
1616
|
+
x?: number;
|
|
1617
|
+
y?: number;
|
|
1618
|
+
/** Scale factor (1 = identity). */
|
|
1619
|
+
scaleX?: number;
|
|
1620
|
+
scaleY?: number;
|
|
1621
|
+
/** Clockwise rotation in degrees, about the transform origin (default (0,0)).
|
|
1622
|
+
* Renders on the GPU (Vello) backend; the CPU reference rasterizer ignores it. */
|
|
1623
|
+
rotation?: number;
|
|
1624
|
+
/** Pivot for scale + rotation in local px (CSS transform-origin). Default (0,0).
|
|
1625
|
+
* For "about the center", pass half the node's width/height. */
|
|
1626
|
+
originX?: number;
|
|
1627
|
+
originY?: number;
|
|
1628
|
+
/** Opacity, 0..1. */
|
|
1629
|
+
opacity?: number;
|
|
1630
|
+
/** DEPTH (z) of this layer for depth-of-field, in the same arbitrary units as
|
|
1631
|
+
* `<Composition dof={{ focus }}>`. Layers at the focus depth stay sharp; the
|
|
1632
|
+
* farther a layer's `depth` is from `focus`, the more it defocuses (a blur the
|
|
1633
|
+
* reconciler computes from the camera aperture). Animate the comp's `focus` for a
|
|
1634
|
+
* rack-focus pull. No effect unless the comp sets `dof`. */
|
|
1635
|
+
depth?: number;
|
|
1636
|
+
/** 3D LAYER position `[x, y, z]` in world pixels — meaningful only inside a
|
|
1637
|
+
* `<Scene3D>`. `z = 0` is the framing plane (matches the 2D placement); larger
|
|
1638
|
+
* `z` is farther into the screen (smaller), negative `z` nearer the camera (After
|
|
1639
|
+
* Effects convention). Animate for fly-throughs / parallax / exploded views. */
|
|
1640
|
+
position3d?: [number, number, number];
|
|
1641
|
+
/** 3D LAYER rotation `[x, y, z]` in degrees (Z·Y·X): X pitch (tilt toward/away),
|
|
1642
|
+
* Y yaw (swing), Z roll (in-plane spin). Inside `<Scene3D>` only. GPU-only — the
|
|
1643
|
+
* CPU reference degrades to a flat depth-sorted composite (no out-of-plane tilt). */
|
|
1644
|
+
rotation3d?: [number, number, number];
|
|
1645
|
+
/** Pivot within this layer's content plane (px) that `position3d`/`rotation3d`
|
|
1646
|
+
* act about. Default: the layer's center. */
|
|
1647
|
+
anchor3d?: [number, number];
|
|
1648
|
+
/** EXTRUDE this layer's 2D outline into a lit 3D SOLID (the "3D logo / title"):
|
|
1649
|
+
* inside a `<Scene3D>`, a shape or text layer becomes a mesh with `depth`
|
|
1650
|
+
* thickness + side walls, shaded by a directional light so it catches the light
|
|
1651
|
+
* as it rotates. GPU only — the CPU reference + live preview draw the flat outline. */
|
|
1652
|
+
extrude?: number | {
|
|
1653
|
+
depth: number;
|
|
1654
|
+
};
|
|
1655
|
+
/** Blend this node's subtree against the backdrop (CSS mix-blend-mode).
|
|
1656
|
+
* GPU/Vello-rendered (e.g. `'screen'`, `'multiply'`, `'overlay'`). */
|
|
1657
|
+
blendMode?: BlendMode;
|
|
1658
|
+
/** Clip this node and its subtree to a region (local space). */
|
|
1659
|
+
clip?: ClipInput;
|
|
1660
|
+
/** Matte (track matte / mask): a stencil SUBTREE, passed as a React element,
|
|
1661
|
+
* through which this node's content is revealed. The matte's alpha — or its
|
|
1662
|
+
* luminance, per `matteMode` — multiplies the content's alpha, so the content
|
|
1663
|
+
* (this node's children) shows only where the matte covers. The
|
|
1664
|
+
* strictly-more-powerful sibling of `clip`: the matte is a fully rendered,
|
|
1665
|
+
* animatable subtree (giant text, a gradient, a shape) — the signature
|
|
1666
|
+
* "media-through-type" move (a photo seen only through animated type). */
|
|
1667
|
+
matte?: ReactElement;
|
|
1668
|
+
/** Which channel of the {@link NodeProps.matte} subtree drives the reveal (CSS
|
|
1669
|
+
* `mask-mode`). `'alpha'` (default): content alpha ×= matte alpha. `'luminance'`:
|
|
1670
|
+
* content alpha ×= luma(matte) × matte alpha (white reveals, black hides). */
|
|
1671
|
+
matteMode?: MatteMode;
|
|
1672
|
+
/** Ordered, low-level screen-space effects on this node + subtree (render-to-texture). */
|
|
1673
|
+
effects?: Effect[];
|
|
1674
|
+
/** Gaussian blur std-dev in output px; sugar for `effects: [{ effect: 'blur', sigma }]`.
|
|
1675
|
+
* Honored by Vello AND the CPU reference once Phase 1 lands. */
|
|
1676
|
+
blur?: number;
|
|
1677
|
+
/** Directional (motion) blur sugar for `effects: [{ effect: 'directional_blur', … }]`:
|
|
1678
|
+
* a 1D blur of std-dev `sigma` (px) along `angle` (radians, default 0 = horizontal) —
|
|
1679
|
+
* the cinematic "in-motion" smear. Honored by Vello AND the CPU reference. */
|
|
1680
|
+
directionalBlur?: {
|
|
1681
|
+
sigma: number;
|
|
1682
|
+
angle?: number;
|
|
1683
|
+
};
|
|
1684
|
+
/** Chromatic-aberration sugar: R/B split by `amount` px radially from centre. */
|
|
1685
|
+
chromaticAberration?: number;
|
|
1686
|
+
/** Vignette sugar — radial edge darkening. `amount` 0..1; `softness` 0..1 (default 0.5). */
|
|
1687
|
+
vignette?: number | {
|
|
1688
|
+
amount: number;
|
|
1689
|
+
softness?: number;
|
|
1690
|
+
};
|
|
1691
|
+
/** Posterize sugar: quantize each channel to `levels` (≥2) discrete steps. */
|
|
1692
|
+
posterize?: number;
|
|
1693
|
+
/** Duotone sugar: map luminance to a gradient from `shadow` to `highlight`. */
|
|
1694
|
+
duotone?: {
|
|
1695
|
+
shadow: ColorInput;
|
|
1696
|
+
highlight: ColorInput;
|
|
1697
|
+
};
|
|
1698
|
+
/** Chroma-key sugar: knock out `color`; `threshold` (default 0.4) + `smoothness`
|
|
1699
|
+
* (default 0.1) shape the soft matte edge. */
|
|
1700
|
+
chromaKey?: {
|
|
1701
|
+
color: ColorInput;
|
|
1702
|
+
threshold?: number;
|
|
1703
|
+
smoothness?: number;
|
|
1704
|
+
};
|
|
1705
|
+
/** Glow / bloom sugar for `effects: [{ effect: 'bloom', ... }]`: bright regions
|
|
1706
|
+
* (luminance above `threshold`, default 0.7; scaled by `intensity`, default 1)
|
|
1707
|
+
* blur with `sigma` and composite additively over the sharp subtree. Honored by
|
|
1708
|
+
* Vello AND the CPU reference. */
|
|
1709
|
+
bloom?: number | {
|
|
1710
|
+
sigma: number;
|
|
1711
|
+
threshold?: number;
|
|
1712
|
+
intensity?: number;
|
|
1713
|
+
};
|
|
1714
|
+
/** Cinematic color-grade sugar for `effects: [{ effect: 'color_grade', ... }]` —
|
|
1715
|
+
* the "land AI media" wedge: one grade unifies mismatched clips into a single
|
|
1716
|
+
* look. All five fields are optional and default to the neutral identity
|
|
1717
|
+
* (`exposure` 0, `contrast` 1, `saturation` 1, `temperature` 0, `tint` 0), so
|
|
1718
|
+
* `{}` is a no-op. Honored by Vello AND the CPU reference. */
|
|
1719
|
+
grade?: {
|
|
1720
|
+
/** Linear exposure gain (`2^exposure`); 0 = identity. */
|
|
1721
|
+
exposure?: number;
|
|
1722
|
+
/** Contrast around a 0.5 pivot; 1 = identity. */
|
|
1723
|
+
contrast?: number;
|
|
1724
|
+
/** Saturation; 1 = identity, 0 = grayscale, >1 = punchier. */
|
|
1725
|
+
saturation?: number;
|
|
1726
|
+
/** Warm/cool shift (R up / B down for positive); 0 = neutral. */
|
|
1727
|
+
temperature?: number;
|
|
1728
|
+
/** Green/magenta shift on G (positive = green); 0 = neutral. */
|
|
1729
|
+
tint?: number;
|
|
1730
|
+
};
|
|
1731
|
+
/** Gooey / liquid / metaball-morph sugar for `effects: [{ effect: 'goo', ... }]`:
|
|
1732
|
+
* the subtree is blurred with `sigma`, then its alpha is sharpened around
|
|
1733
|
+
* `threshold` (the 0..1 cutoff, default 0.5) so overlapping shapes fuse into
|
|
1734
|
+
* solid forms joined by smooth necks (the "drops of liquid coalescing" look).
|
|
1735
|
+
* A bare number is the `sigma`. Honored by Vello AND the CPU reference. */
|
|
1736
|
+
goo?: number | {
|
|
1737
|
+
sigma: number;
|
|
1738
|
+
threshold?: number;
|
|
1739
|
+
};
|
|
1740
|
+
/** Film-grain sugar for `effects: [{ effect: 'grain', ... }]`: luminance-banded,
|
|
1741
|
+
* animated monochrome noise added late over the subtree — the compositing "glue"
|
|
1742
|
+
* that makes mismatched sources read as one photographed image, and the dither
|
|
1743
|
+
* that hides 8-bit banding on dark gradients. A bare number is the `intensity`
|
|
1744
|
+
* (~0.04–0.1 is filmic); the object form adds `size` (grain scale in px, default
|
|
1745
|
+
* 1) and `seed` (animation offset — pass the current frame for *living* grain,
|
|
1746
|
+
* default 0 = static). Honored by Vello AND the CPU reference. */
|
|
1747
|
+
grain?: number | {
|
|
1748
|
+
intensity: number;
|
|
1749
|
+
size?: number;
|
|
1750
|
+
seed?: number;
|
|
1751
|
+
};
|
|
1752
|
+
/** Frosted-glass sugar for `effects: [{ effect: 'backdrop_blur', ... }]`: samples
|
|
1753
|
+
* the already-composited BACKDROP *behind* this node (not its own subtree),
|
|
1754
|
+
* blurs it by `sigma` (output px), and draws it as the node's backing — then the
|
|
1755
|
+
* node's own content (e.g. a translucent panel `fill`) composites on top. A bare
|
|
1756
|
+
* number is just the `sigma`; the object form adds a `tint` (its alpha = tint
|
|
1757
|
+
* strength), a `brightness` and a `saturation` (CSS-style, `1` = identity).
|
|
1758
|
+
* Honored by Vello AND the CPU reference. */
|
|
1759
|
+
backdropBlur?: number | {
|
|
1760
|
+
sigma: number;
|
|
1761
|
+
tint?: ColorInput;
|
|
1762
|
+
brightness?: number;
|
|
1763
|
+
saturation?: number;
|
|
1764
|
+
};
|
|
1765
|
+
/** Light-wrap sugar for `effects: [{ effect: 'light_wrap', ... }]`: bleeds the
|
|
1766
|
+
* blurred BACKDROP behind this node onto its own feathered EDGES — the #1
|
|
1767
|
+
* "shot in, not pasted on" compositing tell for a cut-out plate. A bare number
|
|
1768
|
+
* is the `sigma` (the backdrop blur / rim width); the object form adds a
|
|
1769
|
+
* `strength` (0 = off, ~1 = a natural spill). EXPORT/NATIVE only — the live
|
|
1770
|
+
* preview draws the node un-wrapped. */
|
|
1771
|
+
lightWrap?: number | {
|
|
1772
|
+
sigma: number;
|
|
1773
|
+
strength?: number;
|
|
1774
|
+
};
|
|
1775
|
+
children?: ReactNode;
|
|
1776
|
+
}, Element>;
|
|
1777
|
+
interface AudioProps {
|
|
1778
|
+
/** Path, URL, or `data:` URI of the audio. */
|
|
1779
|
+
src: string;
|
|
1780
|
+
/** Composition time (seconds) at which the clip begins playing. Default 0. */
|
|
1781
|
+
start?: number;
|
|
1782
|
+
/** Seconds into the source to begin from (trim the head). Default 0. */
|
|
1783
|
+
startAt?: number;
|
|
1784
|
+
/** Linear gain, 0..1. Default 1. */
|
|
1785
|
+
volume?: number;
|
|
1786
|
+
}
|
|
1787
|
+
/** A non-visual audio clip on the timeline. It draws nothing — the player plays
|
|
1788
|
+
* it during preview (and export muxes it). Place it anywhere in the tree; `start`
|
|
1789
|
+
* sets when it begins (seconds), `startAt` trims into the source, `volume`
|
|
1790
|
+
* scales its gain. The higher-level `<AudioClip>` (`@onda-engine/components`) wraps this
|
|
1791
|
+
* with a fade envelope. */
|
|
1792
|
+
declare function Audio(props: AudioProps): ReactElement<AudioProps, string | react.JSXElementConstructor<any>>;
|
|
1793
|
+
interface SvgProps extends NodeProps {
|
|
1794
|
+
/** A file path/URL to the SVG (resolved at render time by `onda render`). */
|
|
1795
|
+
src?: string;
|
|
1796
|
+
/** Inline SVG markup (self-contained; preferred when present). */
|
|
1797
|
+
markup?: string;
|
|
1798
|
+
}
|
|
1799
|
+
/** An SVG document, expanded into vector nodes by the engine (`onda-svg`).
|
|
1800
|
+
* Use `x`/`y`/`scaleX`/`scaleY` to place and size it. Renders on the GPU
|
|
1801
|
+
* (Vello) backend. */
|
|
1802
|
+
declare function Svg(props: SvgProps): react.DOMElement<SvgProps, Element>;
|
|
1803
|
+
|
|
1804
|
+
/** Resolution and timing of the composition being rendered. */
|
|
1805
|
+
interface VideoConfig {
|
|
1806
|
+
width: number;
|
|
1807
|
+
height: number;
|
|
1808
|
+
fps: number;
|
|
1809
|
+
durationInFrames: number;
|
|
1810
|
+
}
|
|
1811
|
+
/** The frame currently being rendered (0-based). */
|
|
1812
|
+
declare function useCurrentFrame(): number;
|
|
1813
|
+
/** The composition's resolution and timing. */
|
|
1814
|
+
declare function useVideoConfig(): VideoConfig;
|
|
1815
|
+
|
|
1816
|
+
interface SpringConfig {
|
|
1817
|
+
mass?: number;
|
|
1818
|
+
stiffness?: number;
|
|
1819
|
+
damping?: number;
|
|
1820
|
+
}
|
|
1821
|
+
interface SpringOptions {
|
|
1822
|
+
/** Current frame (e.g. from `useCurrentFrame()`). */
|
|
1823
|
+
frame: number;
|
|
1824
|
+
/** Composition frame rate. */
|
|
1825
|
+
fps: number;
|
|
1826
|
+
/** Output at rest start (default 0). */
|
|
1827
|
+
from?: number;
|
|
1828
|
+
/** Output at settle (default 1). */
|
|
1829
|
+
to?: number;
|
|
1830
|
+
config?: SpringConfig;
|
|
1831
|
+
/** Re-time the spring so it settles in this many frames (like Remotion's
|
|
1832
|
+
* `durationInFrames`). Without it, the settle is governed purely by the
|
|
1833
|
+
* spring physics — and for an overdamped config (e.g. the Onda house spring)
|
|
1834
|
+
* that can be far slower than you want. */
|
|
1835
|
+
durationInFrames?: number;
|
|
1836
|
+
/** When `durationInFrames` is set, the spring counts as "settled" once it
|
|
1837
|
+
* stays within this distance of `to` with near-zero velocity. Default 0.005. */
|
|
1838
|
+
durationRestThreshold?: number;
|
|
1839
|
+
}
|
|
1840
|
+
/** Spring value at `frame`. Settles toward `to`; underdamped configs overshoot.
|
|
1841
|
+
* With `durationInFrames`, the whole settle is time-remapped to land in that
|
|
1842
|
+
* many frames. */
|
|
1843
|
+
declare function spring({ frame, fps, from, to, config, durationInFrames, durationRestThreshold, }: SpringOptions): number;
|
|
1844
|
+
|
|
1845
|
+
interface SequenceProps {
|
|
1846
|
+
/** Frame at which this sequence starts (children's frame 0). Default 0. */
|
|
1847
|
+
from?: number;
|
|
1848
|
+
/** How many frames it lasts; unbounded if omitted. */
|
|
1849
|
+
durationInFrames?: number;
|
|
1850
|
+
children?: ReactNode;
|
|
1851
|
+
}
|
|
1852
|
+
/** Shift children in time: inside, the frame is `outerFrame - from`, and the
|
|
1853
|
+
* children render only while `0 <= localFrame < durationInFrames`. When a
|
|
1854
|
+
* `durationInFrames` is given, children's `useVideoConfig().durationInFrames`
|
|
1855
|
+
* reflects the SEQUENCE's length (Remotion semantics) — so a component can ask
|
|
1856
|
+
* "how long is my clip?" and fit its entrance to it. */
|
|
1857
|
+
declare function Sequence({ from, durationInFrames, children, }: SequenceProps): ReactElement | null;
|
|
1858
|
+
interface LoopProps {
|
|
1859
|
+
/** Length of one loop iteration in frames. */
|
|
1860
|
+
durationInFrames: number;
|
|
1861
|
+
children?: ReactNode;
|
|
1862
|
+
}
|
|
1863
|
+
/** Repeat children forever: children see `frame % durationInFrames`. */
|
|
1864
|
+
declare function Loop({ durationInFrames, children }: LoopProps): ReactElement | null;
|
|
1865
|
+
interface SeriesSequenceProps {
|
|
1866
|
+
durationInFrames: number;
|
|
1867
|
+
children?: ReactNode;
|
|
1868
|
+
}
|
|
1869
|
+
declare function SeriesSequence(_props: SeriesSequenceProps): ReactElement | null;
|
|
1870
|
+
interface SeriesProps {
|
|
1871
|
+
children?: ReactNode;
|
|
1872
|
+
}
|
|
1873
|
+
/** Play `<Series.Sequence>` children back-to-back: each starts where the
|
|
1874
|
+
* previous ended (cumulative offsets from their `durationInFrames`). */
|
|
1875
|
+
declare function SeriesRoot({ children }: SeriesProps): ReactElement;
|
|
1876
|
+
/** `<Series>` with `<Series.Sequence durationInFrames={…}>` children. */
|
|
1877
|
+
declare const Series: typeof SeriesRoot & {
|
|
1878
|
+
Sequence: typeof SeriesSequence;
|
|
1879
|
+
};
|
|
1880
|
+
|
|
1881
|
+
/** Derive a deterministic alternate seed from `(seed, variant)` — the cheap
|
|
1882
|
+
* "give me take #N" knob. `variant` 0/undefined returns `seed` UNCHANGED
|
|
1883
|
+
* (identity — existing compositions keep their exact pixels); any other
|
|
1884
|
+
* integer yields a well-mixed, stable new numeric seed. Pure. */
|
|
1885
|
+
declare function variantSeed(seed: number, variant?: number): number;
|
|
1886
|
+
declare function variantSeed(seed: number | string, variant?: number): number | string;
|
|
1887
|
+
/** A deterministic value in `[0, 1)` for `seed` (mulberry32, one step). */
|
|
1888
|
+
declare function random(seed: number | string): number;
|
|
1889
|
+
/** Smooth 2D value noise in `[-1, 1]` — coherent (nearby inputs give nearby
|
|
1890
|
+
* outputs), deterministic per `seed`. Scale `x`/`y` to set the frequency. */
|
|
1891
|
+
declare function noise2D(seed: number | string, x: number, y: number): number;
|
|
1892
|
+
/** Smooth 3D value noise in `[-1, 1]` (e.g. animate `z` over frames for drift). */
|
|
1893
|
+
declare function noise3D(seed: number | string, x: number, y: number, z: number): number;
|
|
1894
|
+
|
|
1895
|
+
interface ParticlesProps {
|
|
1896
|
+
/** Number of particles. */
|
|
1897
|
+
count?: number;
|
|
1898
|
+
/** Seed for every per-particle random — the same seed always renders the same field. */
|
|
1899
|
+
seed?: number | string;
|
|
1900
|
+
/** Emitter origin (px). */
|
|
1901
|
+
x?: number;
|
|
1902
|
+
y?: number;
|
|
1903
|
+
/** Particles spawn at a random point within this radius of the origin (0 = a point). */
|
|
1904
|
+
spawnRadius?: number;
|
|
1905
|
+
/** Base launch speed (px per frame). */
|
|
1906
|
+
speed?: number;
|
|
1907
|
+
/** Random speed reduction, 0..1 (each particle gets `speed × (1 − variance×rand)`). */
|
|
1908
|
+
speedVariance?: number;
|
|
1909
|
+
/** Launch direction in degrees: 0 = right, −90 = up, 90 = down, 180 = left. */
|
|
1910
|
+
angle?: number;
|
|
1911
|
+
/** Spread cone around `angle`, in degrees (360 = omnidirectional burst). */
|
|
1912
|
+
spread?: number;
|
|
1913
|
+
/** Constant downward acceleration (px per frame²). */
|
|
1914
|
+
gravity?: number;
|
|
1915
|
+
/** Particle lifetime in frames. */
|
|
1916
|
+
lifetime?: number;
|
|
1917
|
+
/** Stagger the emission across this many frames (0 = a single burst). */
|
|
1918
|
+
emitOver?: number;
|
|
1919
|
+
/** Re-emit each particle when it dies → a continuous stream (set `emitOver`≈`lifetime`). */
|
|
1920
|
+
loop?: boolean;
|
|
1921
|
+
/** Frames before emission begins. */
|
|
1922
|
+
delay?: number;
|
|
1923
|
+
/** Particle shape. */
|
|
1924
|
+
shape?: 'circle' | 'square';
|
|
1925
|
+
/** Diameter (px) at birth → death (lerped over the lifetime). A number = constant. */
|
|
1926
|
+
size?: number | [number, number];
|
|
1927
|
+
/** Opacity at birth → death. */
|
|
1928
|
+
opacity?: [number, number];
|
|
1929
|
+
/** Palette each particle picks one colour from. */
|
|
1930
|
+
colors?: string[];
|
|
1931
|
+
/** Rotation in degrees over the lifetime (visible on `square`). */
|
|
1932
|
+
spin?: number;
|
|
1933
|
+
}
|
|
1934
|
+
/** A deterministic particle emitter — bursts, fountains, confetti, sparks, dust,
|
|
1935
|
+
* snow. See {@link ParticlesProps}. */
|
|
1936
|
+
declare function Particles({ count, seed, x, y, spawnRadius, speed, speedVariance, angle, spread, gravity, lifetime, emitOver, loop, delay, shape, size, opacity, colors, spin, }: ParticlesProps): ReactElement;
|
|
1937
|
+
|
|
1938
|
+
/** Maps a frame within a transition to progress `0..1` (may overshoot 1 for
|
|
1939
|
+
* springs). `durationInFrames` is how long the transition (overlap) lasts. */
|
|
1940
|
+
interface TransitionTiming {
|
|
1941
|
+
durationInFrames: number;
|
|
1942
|
+
getProgress(frame: number, fps: number): number;
|
|
1943
|
+
}
|
|
1944
|
+
/** A linear transition over `durationInFrames`. */
|
|
1945
|
+
declare function linearTiming({ durationInFrames }: {
|
|
1946
|
+
durationInFrames: number;
|
|
1947
|
+
}): TransitionTiming;
|
|
1948
|
+
/** A spring-driven transition (natural ease, optional overshoot). */
|
|
1949
|
+
declare function springTiming({ durationInFrames, config, }?: {
|
|
1950
|
+
durationInFrames?: number;
|
|
1951
|
+
config?: SpringConfig;
|
|
1952
|
+
}): TransitionTiming;
|
|
1953
|
+
/** Which edge a slide/wipe moves from. */
|
|
1954
|
+
type SlideDirection = 'from-left' | 'from-right' | 'from-top' | 'from-bottom';
|
|
1955
|
+
interface PresentationState {
|
|
1956
|
+
/** Transition progress `0..1` (0 = fully out, 1 = fully in). */
|
|
1957
|
+
progress: number;
|
|
1958
|
+
/** True for the incoming scene, false for the outgoing one. */
|
|
1959
|
+
entering: boolean;
|
|
1960
|
+
width: number;
|
|
1961
|
+
height: number;
|
|
1962
|
+
}
|
|
1963
|
+
/** Wraps a scene to present it at a point in a transition. Identity at the
|
|
1964
|
+
* resting state (entering progress 1 / exiting progress 0). */
|
|
1965
|
+
type TransitionPresentation = (children: ReactNode, state: PresentationState) => ReactElement;
|
|
1966
|
+
/** Cross-fade via opacity. */
|
|
1967
|
+
declare function fade(): TransitionPresentation;
|
|
1968
|
+
/** Slide the scenes across; `direction` is where the incoming scene comes from. */
|
|
1969
|
+
declare function slide({ direction, }?: {
|
|
1970
|
+
direction?: SlideDirection;
|
|
1971
|
+
}): TransitionPresentation;
|
|
1972
|
+
/** Wipe the incoming scene over the outgoing one with a growing clip mask. */
|
|
1973
|
+
declare function wipe({ direction, }?: {
|
|
1974
|
+
direction?: SlideDirection;
|
|
1975
|
+
}): TransitionPresentation;
|
|
1976
|
+
/** A hard cut — the overlap timing with no visual effect. The incoming scene
|
|
1977
|
+
* (drawn on top) simply replaces the outgoing one. */
|
|
1978
|
+
declare function none(): TransitionPresentation;
|
|
1979
|
+
/** A 2D card flip: the outgoing scene collapses horizontally to the centre line
|
|
1980
|
+
* by the midpoint, then the incoming scene expands out of it. */
|
|
1981
|
+
declare function flip(): TransitionPresentation;
|
|
1982
|
+
/** Iris: a circular reveal of the incoming scene expanding from the centre. The
|
|
1983
|
+
* outgoing scene stays full beneath it (the incoming draws on top). */
|
|
1984
|
+
declare function iris(): TransitionPresentation;
|
|
1985
|
+
/** Clock wipe: an angular sweep revealing the incoming scene clockwise from 12
|
|
1986
|
+
* o'clock. Outgoing stays full beneath (the incoming draws on top). The wedge is
|
|
1987
|
+
* a polygon fan (M/L/Z only — no arc command) so it clips on any path renderer. */
|
|
1988
|
+
declare function clockWipe(): TransitionPresentation;
|
|
1989
|
+
type PushDirection = 'left' | 'right' | 'up' | 'down';
|
|
1990
|
+
/** Both scenes translate together in `direction`, like a camera pan. */
|
|
1991
|
+
declare function push({ direction, }?: {
|
|
1992
|
+
direction?: PushDirection;
|
|
1993
|
+
}): TransitionPresentation;
|
|
1994
|
+
/** Scale-and-fade punch. `direction` 'in' pushes toward the viewer, 'out' pulls back. */
|
|
1995
|
+
declare function zoom({ direction, scaleAmount, }?: {
|
|
1996
|
+
direction?: 'in' | 'out';
|
|
1997
|
+
scaleAmount?: number;
|
|
1998
|
+
}): TransitionPresentation;
|
|
1999
|
+
/** Push with parallax depth — a scale layered on the translate (a camera dolly). */
|
|
2000
|
+
declare function depthPush({ direction, scaleAmount, }?: {
|
|
2001
|
+
direction?: PushDirection;
|
|
2002
|
+
scaleAmount?: number;
|
|
2003
|
+
}): TransitionPresentation;
|
|
2004
|
+
/** Outgoing fades to `color`, incoming fades up from it (dip-to-black/white). */
|
|
2005
|
+
declare function dipToColor({ color }?: {
|
|
2006
|
+
color?: string;
|
|
2007
|
+
}): TransitionPresentation;
|
|
2008
|
+
/** Blur cross: each scene blurs toward the midpoint and sharpens at rest, with an
|
|
2009
|
+
* opacity cross. (Multi-tap approximation — see {@link blurStack}.) */
|
|
2010
|
+
declare function blur({ maxBlur }?: {
|
|
2011
|
+
maxBlur?: number;
|
|
2012
|
+
}): TransitionPresentation;
|
|
2013
|
+
/** Zoom-blur / "smooth zoom" — the punch-in (or -out) with a motion-blur smear
|
|
2014
|
+
* heaviest mid-transition, snapping sharp at rest, with an opacity cross. The
|
|
2015
|
+
* most-used viral/social transition. `direction` 'in' rushes toward the viewer,
|
|
2016
|
+
* 'out' pulls back. */
|
|
2017
|
+
declare function zoomBlur({ direction, scaleAmount, maxBlur, }?: {
|
|
2018
|
+
direction?: 'in' | 'out';
|
|
2019
|
+
scaleAmount?: number;
|
|
2020
|
+
maxBlur?: number;
|
|
2021
|
+
}): TransitionPresentation;
|
|
2022
|
+
/** Whip-pan — a fast directional swish with a motion-blur smear ALONG the pan
|
|
2023
|
+
* axis (the high-energy "camera whip" cut, best paired with a whoosh SFX).
|
|
2024
|
+
* `direction` is where the camera swings toward (left/right/up/down). */
|
|
2025
|
+
declare function whipPan({ direction, maxBlur, }?: {
|
|
2026
|
+
direction?: PushDirection;
|
|
2027
|
+
maxBlur?: number;
|
|
2028
|
+
}): TransitionPresentation;
|
|
2029
|
+
/** Film-burn / light-leak — the scenes crossfade while a warm leak blooms over the
|
|
2030
|
+
* cut, screen-blended and peaking at the midpoint (the cinematic-warmth flare).
|
|
2031
|
+
* The leak draws once (on the incoming layer); a dark gradient screen-blends to
|
|
2032
|
+
* ~nothing, so only the warm centre flares. */
|
|
2033
|
+
declare function filmBurn({ color }?: {
|
|
2034
|
+
color?: string;
|
|
2035
|
+
}): TransitionPresentation;
|
|
2036
|
+
/** Luma-wipe — reveal the incoming scene through a soft LUMINANCE ramp that sweeps
|
|
2037
|
+
* across (a gradient matte; white reveals, black hides). The organic, edge-feathered
|
|
2038
|
+
* reveal Premiere/Resolve ship as a workhorse. */
|
|
2039
|
+
declare function lumaWipe(): TransitionPresentation;
|
|
2040
|
+
/** Chromatic split: the scene tears into horizontally offset ghosts that spread
|
|
2041
|
+
* at the midpoint and converge at rest (an RGB-fringe feel — the engine has no
|
|
2042
|
+
* per-channel tint, so the copies are uncoloured). */
|
|
2043
|
+
declare function chromaticAberration({ maxShift, }?: {
|
|
2044
|
+
maxShift?: number;
|
|
2045
|
+
}): TransitionPresentation;
|
|
2046
|
+
/** Device pullback: the outgoing scene shrinks back (and lifts) as if pulled into
|
|
2047
|
+
* the distance, uncovering the incoming scene that settles forward into place. */
|
|
2048
|
+
declare function devicePullback(): TransitionPresentation;
|
|
2049
|
+
/** Expand morph: the incoming scene bursts open from the centre while the
|
|
2050
|
+
* outgoing one balloons out and dissolves — a quick morph-expand. */
|
|
2051
|
+
declare function expandMorph(): TransitionPresentation;
|
|
2052
|
+
/** Morph: a soft scale-and-fade blend — the scenes ease through each other with a
|
|
2053
|
+
* gentle breathing scale. */
|
|
2054
|
+
declare function morph(): TransitionPresentation;
|
|
2055
|
+
/** Glass wipe: the incoming scene reveals behind a sweeping edge and blurs sharp
|
|
2056
|
+
* as the "frosted panel" passes (blur is the {@link blurStack} approximation). */
|
|
2057
|
+
declare function glassWipe({ direction, }?: {
|
|
2058
|
+
direction?: SlideDirection;
|
|
2059
|
+
}): TransitionPresentation;
|
|
2060
|
+
/** Grid pixelate: the incoming scene fills in as a grid of blocks, each popping
|
|
2061
|
+
* on in a deterministic scatter (a blocky reveal — true pixelation needs an
|
|
2062
|
+
* engine sampling pass). */
|
|
2063
|
+
declare function gridPixelate({ cols, rows, }?: {
|
|
2064
|
+
cols?: number;
|
|
2065
|
+
rows?: number;
|
|
2066
|
+
}): TransitionPresentation;
|
|
2067
|
+
/** Type mask: the incoming scene reveals through a row of vertical bars that
|
|
2068
|
+
* widen into place — a typographic blinds reveal. */
|
|
2069
|
+
declare function typeMask({ bars }?: {
|
|
2070
|
+
bars?: number;
|
|
2071
|
+
}): TransitionPresentation;
|
|
2072
|
+
/** Alias of {@link fade} — Studio's "cross-fade" slug. */
|
|
2073
|
+
declare const crossFade: typeof fade;
|
|
2074
|
+
interface TransitionSeriesSequenceProps {
|
|
2075
|
+
durationInFrames: number;
|
|
2076
|
+
children?: ReactNode;
|
|
2077
|
+
}
|
|
2078
|
+
interface TransitionSeriesTransitionProps {
|
|
2079
|
+
presentation: TransitionPresentation;
|
|
2080
|
+
timing: TransitionTiming;
|
|
2081
|
+
}
|
|
2082
|
+
declare function TransitionSequence(_props: TransitionSeriesSequenceProps): ReactElement | null;
|
|
2083
|
+
declare function TransitionTransition(_props: TransitionSeriesTransitionProps): ReactElement | null;
|
|
2084
|
+
declare function TransitionSeriesRoot({ children }: {
|
|
2085
|
+
children?: ReactNode;
|
|
2086
|
+
}): ReactElement;
|
|
2087
|
+
/** Play sequences back-to-back with overlapping transitions between them. */
|
|
2088
|
+
declare const TransitionSeries: typeof TransitionSeriesRoot & {
|
|
2089
|
+
Sequence: typeof TransitionSequence;
|
|
2090
|
+
Transition: typeof TransitionTransition;
|
|
2091
|
+
};
|
|
2092
|
+
|
|
2093
|
+
/** Render `element` (root must be `<Composition>`) at `frame` to a static
|
|
2094
|
+
* {@link Scene}. Components read the frame via {@link useCurrentFrame}. */
|
|
2095
|
+
declare function renderFrame(element: ReactElement, frame: number): Scene;
|
|
2096
|
+
/** Render the composition once, at frame 0. */
|
|
2097
|
+
declare function renderToScene(element: ReactElement): Scene;
|
|
2098
|
+
/** The MOTION BLUR config declared on `<Composition motionBlur={…}>`, normalised, or
|
|
2099
|
+
* `undefined` when off. `true` → a 180° shutter at 16 samples; `samples < 2` is off.
|
|
2100
|
+
* Exported so the export orchestration can pass the matching `--motion-blur K`. */
|
|
2101
|
+
declare function motionBlurConfig(element: ReactElement): {
|
|
2102
|
+
shutter: number;
|
|
2103
|
+
samples: number;
|
|
2104
|
+
} | undefined;
|
|
2105
|
+
/** Render every frame `0..durationInFrames` to static scenes. With
|
|
2106
|
+
* `<Composition motionBlur>`, each frame expands to `samples` sub-frame scenes for
|
|
2107
|
+
* the CLI to average (so the array length is `durationInFrames × samples`). */
|
|
2108
|
+
declare function renderFrames(element: ReactElement): Scene[];
|
|
2109
|
+
/** Render a sub-range `[startFrame, endFrame)` to static scenes.
|
|
2110
|
+
* The returned array starts at index 0; the scenes carry the original frame
|
|
2111
|
+
* numbers so `useCurrentFrame()` reads the correct composition time. Motion blur
|
|
2112
|
+
* expands each frame to `samples` sub-frames, exactly like {@link renderFrames}. */
|
|
2113
|
+
declare function renderFramesRange(element: ReactElement, startFrame: number, endFrame: number): Scene[];
|
|
2114
|
+
/** Render frame 0 to a JSON string (for `onda render`). */
|
|
2115
|
+
declare function renderToSceneJSON(element: ReactElement, space?: number): string;
|
|
2116
|
+
/** Render all frames to a JSON array of scenes (for `onda export-frames`). */
|
|
2117
|
+
declare function renderFramesJSON(element: ReactElement, space?: number): string;
|
|
2118
|
+
/** Render a sub-range `[startFrame, endFrame)` to a JSON array (for `onda export-frames`).
|
|
2119
|
+
* Produces a short clip covering only those frames — useful for fast scene-level iteration. */
|
|
2120
|
+
declare function renderFrameRangeJSON(element: ReactElement, startFrame: number, endFrame: number, space?: number): string;
|
|
2121
|
+
|
|
2122
|
+
/** Retain font bytes so the render harness can pass them to the renderer. Deduped
|
|
2123
|
+
* by content signature — declaring the same font twice is harmless. Synchronous
|
|
2124
|
+
* and independent of any async engine load, so the bytes are registered the
|
|
2125
|
+
* instant `loadFont` is called, even before the wasm measurement engine warms. */
|
|
2126
|
+
declare function registerFont(data: Uint8Array): void;
|
|
2127
|
+
/** A snapshot of the fonts declared so far — for the render harness to write out
|
|
2128
|
+
* and pass to the CLI. Callers receive a copy and must not mutate the registry. */
|
|
2129
|
+
declare function registeredFonts(): readonly Uint8Array[];
|
|
2130
|
+
/** Clear the registry — for tests, or a long-running process between renders of
|
|
2131
|
+
* different compositions (so one comp's fonts don't leak into the next). */
|
|
2132
|
+
declare function clearRegisteredFonts(): void;
|
|
2133
|
+
|
|
2134
|
+
type Warmer = () => Promise<void>;
|
|
2135
|
+
/** Register an async warmer to run before a render. Idempotent per function. */
|
|
2136
|
+
declare function registerEngineWarmer(warm: Warmer): void;
|
|
2137
|
+
/** Run all registered warmers (best-effort — a warmer that throws is ignored, so
|
|
2138
|
+
* the render still proceeds with whatever fallback the component uses). */
|
|
2139
|
+
declare function runEngineWarmers(): Promise<void>;
|
|
2140
|
+
|
|
2141
|
+
export { AbsoluteFill, type AbsoluteFillProps, Audio, type AudioProps, Camera, type Camera3D, type CameraProps, Center, type CenterProps, type ClipInput, type Color, type ColorInput, Composition, type Composition$1 as CompositionData, type CompositionProps, Easing, type EasingFn, type Effect, Ellipse, type EllipseProps, type Extrude, Flex, type FlexProps, type Gradient, type GradientInput, type GradientStop, type GradientStopInput, Group, type GroupProps, Image, type ImageProps, Image as Img, type InterpolateOptions, type Layout, Loop, type LoopProps, Merge, type MergeProps, type MorphOptions, type NodeKind, type NodeProps, type PaintProps, Particles, type ParticlesProps, Path, type PathProps, type Point, Precomp, type PrecompProps, type PresentationState, type PushDirection, Rect, type RectProps, Repeater, type RepeaterProps, type Scene, Scene3D, type Scene3DProps, type SceneNode, type SceneTextRun, Sequence, type SequenceProps, Series, type SeriesSequenceProps, type ShapeGeometry, type Size, type SlideDirection, type SpringConfig, type SpringOptions, type Stroke, Svg, type SvgProps, Text, type TextProps, type TextRunInput, type Transform, type Transform3D, type TransitionPresentation, TransitionSeries, type TransitionSeriesSequenceProps, type TransitionSeriesTransitionProps, type TransitionTiming, type Vec2, Video, type VideoConfig, type VideoProps, blur, chromaticAberration, clearRegisteredFonts, clipEllipse, clipPath, clipRect, clockWipe, crossFade, cubicBezier, depthPush, devicePullback, dipToColor, expandMorph, fade, fbmGradient, filmBurn, flip, glassWipe, gridPixelate, interpolate, interpolateColors, iris, linearGradient, linearTiming, lumaWipe, morph, morphPath, morphPathSequence, motionBlurConfig, noise2D, noise3D, none, parseClip, parseColor, parseGradient, push, radialGradient, random, registerEngineWarmer, registerFont, registeredFonts, renderFrame, renderFrameRangeJSON, renderFrames, renderFramesJSON, renderFramesRange, renderToScene, renderToSceneJSON, runEngineWarmers, slide, spring, springTiming, typeMask, useCurrentFrame, useVideoConfig, variantSeed, whipPan, wipe, zoom, zoomBlur };
|