@clipkit/protocol 1.0.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 +201 -0
- package/README.md +156 -0
- package/dist/defaults.d.ts +16 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +122 -0
- package/dist/defaults.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +1326 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +154 -0
- package/dist/types.js.map +1 -0
- package/dist/validate.d.ts +25 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +41 -0
- package/dist/validate.js.map +1 -0
- package/dist/zod.d.ts +71291 -0
- package/dist/zod.d.ts.map +1 -0
- package/dist/zod.js +727 -0
- package/dist/zod.js.map +1 -0
- package/package.json +36 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,1326 @@
|
|
|
1
|
+
export declare const OUTPUT_FORMATS: readonly ["mp4", "gif"];
|
|
2
|
+
export type OutputFormat = (typeof OUTPUT_FORMATS)[number];
|
|
3
|
+
export declare const ELEMENT_TYPES: readonly ["video", "image", "text", "shape", "audio", "group", "caption", "particles"];
|
|
4
|
+
export type ElementType = (typeof ELEMENT_TYPES)[number];
|
|
5
|
+
export declare const UNITS: readonly ["px", "%", "vw", "vh", "vmin", "vmax"];
|
|
6
|
+
export type Unit = (typeof UNITS)[number];
|
|
7
|
+
export declare const EASING_FUNCTIONS: readonly ["linear", "ease", "ease-in", "ease-out", "ease-in-out", "ease-in-cubic", "ease-out-cubic", "ease-in-out-cubic", "ease-in-quad", "ease-out-quad", "ease-in-out-quad", "ease-in-quart", "ease-out-quart", "ease-in-out-quart", "ease-in-quint", "ease-out-quint", "ease-in-out-quint", "ease-in-sine", "ease-out-sine", "ease-in-out-sine", "ease-in-expo", "ease-out-expo", "ease-in-out-expo", "ease-in-circ", "ease-out-circ", "ease-in-out-circ", "ease-in-back", "ease-out-back", "ease-in-out-back", "spring", "elastic-in", "elastic-out", "elastic-in-out", "bounce-in", "bounce-out", "bounce-in-out"];
|
|
8
|
+
export type EasingFunction = (typeof EASING_FUNCTIONS)[number];
|
|
9
|
+
/**
|
|
10
|
+
* An easing value: a named curve from EASING_FUNCTIONS, or a parametric
|
|
11
|
+
* form —
|
|
12
|
+
* `cubic-bezier(x1, y1, x2, y2)` — CSS timing-function semantics
|
|
13
|
+
* (x1/x2 clamped to [0, 1]; y1/y2 unbounded for overshoot).
|
|
14
|
+
* `steps(n)` — n equidistant steps, jump-at-end (CSS `steps(n, end)`).
|
|
15
|
+
*/
|
|
16
|
+
export type Easing = EasingFunction | `cubic-bezier(${string})` | `steps(${string})`;
|
|
17
|
+
export declare const ANIMATION_TYPES: readonly ["fade-in", "fade-out", "slide-left-in", "slide-right-in", "slide-up-in", "slide-down-in", "slide-left-out", "slide-right-out", "slide-up-out", "slide-down-out", "scale-in", "scale-out", "rotate-in", "rotate-out", "bounce-in", "bounce-out", "spin", "shake", "wiggle", "squash", "pan", "shift", "drift", "breathe", "orbit", "text-appear", "text-slide", "text-fly", "text-typewriter", "text-wave", "text-flip"];
|
|
18
|
+
export type AnimationType = (typeof ANIMATION_TYPES)[number];
|
|
19
|
+
export declare const CAPTION_STYLES: readonly ["tiktok_bounce", "fade_reveal", "kinetic_typewriter", "word_pop"];
|
|
20
|
+
export type CaptionStyle = (typeof CAPTION_STYLES)[number];
|
|
21
|
+
/**
|
|
22
|
+
* Tier-A expression (CKP/1.0, §Expressions). A numeric property may be
|
|
23
|
+
* `{ expr: "..." }` — a PURE function of the element's local time `t` and its
|
|
24
|
+
* own index/params (`i`, `n`, `dur`, `value`). No element references, no runtime
|
|
25
|
+
* inputs: deterministic across renderers, and bakeable to keyframes. The scope is
|
|
26
|
+
* closed (a fixed set of math/motion functions); anything else is a parse error
|
|
27
|
+
* and the property falls back to its base value. See PROTOCOL.md §Expressions.
|
|
28
|
+
*/
|
|
29
|
+
export interface Expr {
|
|
30
|
+
expr: string;
|
|
31
|
+
}
|
|
32
|
+
export interface Keyframe {
|
|
33
|
+
time: number | string;
|
|
34
|
+
value: number | string | [number, number] | [number, number, number];
|
|
35
|
+
easing?: Easing;
|
|
36
|
+
/**
|
|
37
|
+
* Spatial bezier handles for `property: "position"` paths (§6.7),
|
|
38
|
+
* RELATIVE to this keyframe's value: `out_tangent` shapes the curve
|
|
39
|
+
* leaving this keyframe, `in_tangent` the curve arriving at it.
|
|
40
|
+
* Omitted handles default to the straight-line third-points, so a
|
|
41
|
+
* path without handles is polyline motion. On a 3D path a
|
|
42
|
+
* 2-component handle's z defaults to the straight-line third-point
|
|
43
|
+
* in z; 3-component handles on a 2D path are invalid. Ignored on
|
|
44
|
+
* scalar keyframes.
|
|
45
|
+
*/
|
|
46
|
+
in_tangent?: [number, number] | [number, number, number];
|
|
47
|
+
out_tangent?: [number, number] | [number, number, number];
|
|
48
|
+
}
|
|
49
|
+
export interface Animation {
|
|
50
|
+
type: AnimationType;
|
|
51
|
+
duration?: number;
|
|
52
|
+
easing?: Easing;
|
|
53
|
+
/**
|
|
54
|
+
* Unit granularity for text-* animations: animate per letter or per
|
|
55
|
+
* word. Defaults per type (see ANIMATION_TYPES). Ignored on
|
|
56
|
+
* non-text animations.
|
|
57
|
+
*/
|
|
58
|
+
split?: 'letter' | 'word';
|
|
59
|
+
/**
|
|
60
|
+
* Seconds between successive units' start times (text-* animations).
|
|
61
|
+
* Defaults: 0.09 for word splits, 0.035 for letter splits.
|
|
62
|
+
*/
|
|
63
|
+
stagger?: number;
|
|
64
|
+
time?: 'start' | 'end' | number;
|
|
65
|
+
/** Oscillation frequency in Hz (shake, wiggle). Defaults: shake 8, wiggle 2. */
|
|
66
|
+
frequency?: number;
|
|
67
|
+
/** Total rotation in degrees (spin), wobble amplitude in degrees (wiggle), or starting flip angle in degrees (text-flip, default 90). */
|
|
68
|
+
rotation?: number;
|
|
69
|
+
/** Rotation axis for text-flip: 'x' (flip up, default), 'y' (swing in), 'z' (in-plane spin). CKP/1.0. */
|
|
70
|
+
axis?: 'x' | 'y' | 'z';
|
|
71
|
+
/** Travel distance in pixels (pan, shift) or shake amplitude in pixels. Defaults: pan/shift 200, shake 24. */
|
|
72
|
+
distance?: number;
|
|
73
|
+
/** Motion direction (pan, shift). Default 'right'. */
|
|
74
|
+
direction?: 'left' | 'right' | 'up' | 'down';
|
|
75
|
+
/** Squash depth in [0, 1] (squash) or scale amplitude (breathe, default 0.05). */
|
|
76
|
+
scale?: number;
|
|
77
|
+
/** Lattice seed for `drift`'s normative noise (integer ≥ 0). Default 0. */
|
|
78
|
+
seed?: number;
|
|
79
|
+
}
|
|
80
|
+
export interface KeyframeAnimation {
|
|
81
|
+
property: string;
|
|
82
|
+
keyframes: Keyframe[];
|
|
83
|
+
easing?: Easing;
|
|
84
|
+
/**
|
|
85
|
+
* Repeat the keyframe pattern for the element's whole life (§6.3):
|
|
86
|
+
* `true` wraps local time modulo the last keyframe's time;
|
|
87
|
+
* `'ping-pong'` reflects it (forward, backward, forward, …).
|
|
88
|
+
*/
|
|
89
|
+
loop?: boolean | 'ping-pong';
|
|
90
|
+
/**
|
|
91
|
+
* For `property: "position"` paths (§6.7): rotate the element to the
|
|
92
|
+
* path's travel direction (tangent), added to its own rotation.
|
|
93
|
+
* Strictly in-plane: on 3D paths the tangent's xy projection is
|
|
94
|
+
* used and dz is ignored — auto_orient never derives x_rotation or
|
|
95
|
+
* y_rotation. Default false.
|
|
96
|
+
*/
|
|
97
|
+
auto_orient?: boolean;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Mosaic: the element's pixels quantize to square cells; every pixel in
|
|
101
|
+
* a cell takes the color sampled at the cell's center.
|
|
102
|
+
*/
|
|
103
|
+
export interface PixelateEffect {
|
|
104
|
+
type: 'pixelate';
|
|
105
|
+
/** Cell size in canvas pixels. Default 8, minimum 1. Animatable. */
|
|
106
|
+
cell_size?: number | Keyframe[] | Expr;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Ordered dithering: each color channel quantizes to `levels` values,
|
|
110
|
+
* thresholded by the normative 4×4 Bayer matrix, producing the classic
|
|
111
|
+
* retro crosshatch. levels: 2 = 1-bit per channel.
|
|
112
|
+
*/
|
|
113
|
+
export interface DitherEffect {
|
|
114
|
+
type: 'dither';
|
|
115
|
+
/** Quantization levels per channel. Default 4, minimum 2. Animatable. */
|
|
116
|
+
levels?: number | Keyframe[] | Expr;
|
|
117
|
+
/**
|
|
118
|
+
* Size of each Bayer dither cell in LOGICAL pixels. Default 2. Larger
|
|
119
|
+
* = chunkier, more visible retro dots; 1 = ultra-fine. Resolution-
|
|
120
|
+
* independent (the dot size is stable across preview DPI / export, and
|
|
121
|
+
* survives the editor's fit-to-stage downscale). Animatable.
|
|
122
|
+
*/
|
|
123
|
+
pixel_size?: number | Keyframe[] | Expr;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Print-style halftone: a rotated grid of dots, each dot's radius
|
|
127
|
+
* proportional to the underlying luminance, colored with the cell's
|
|
128
|
+
* sampled color. Coverage outside dots is transparent.
|
|
129
|
+
*/
|
|
130
|
+
export interface HalftoneEffect {
|
|
131
|
+
type: 'halftone';
|
|
132
|
+
/** Dot-grid cell size in canvas pixels. Default 8. Animatable. */
|
|
133
|
+
cell_size?: number | Keyframe[] | Expr;
|
|
134
|
+
/** Grid rotation in degrees. Default 45. Animatable. */
|
|
135
|
+
angle?: number | Keyframe[] | Expr;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* ASCII-art: cells map to glyphs from a fixed 10-step density ramp,
|
|
139
|
+
* tinted with the cell's sampled color. Glyph shapes come from the
|
|
140
|
+
* protocol's embedded 8×8 bitmap font (normative — identical pixels on
|
|
141
|
+
* every platform, no system-font dependence).
|
|
142
|
+
*/
|
|
143
|
+
export interface AsciiEffect {
|
|
144
|
+
type: 'ascii';
|
|
145
|
+
/** Cell size in canvas pixels. Default 12, minimum 4. Animatable. */
|
|
146
|
+
cell_size?: number | Keyframe[] | Expr;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Liquid glass: the element becomes a refractive, frosted pane over
|
|
150
|
+
* its BACKDROP — the pixels already drawn beneath it in draw order.
|
|
151
|
+
*
|
|
152
|
+
* THE EXCEPTION (§4.7): every other effect reads only the element's
|
|
153
|
+
* own rendered pixels; glass additionally reads the backdrop. It gets
|
|
154
|
+
* this carve-out because the effect is widely known and in high
|
|
155
|
+
* demand, and there is no proper decomposition — refraction needs the
|
|
156
|
+
* pixels behind the pane. No other effect type reads the backdrop.
|
|
157
|
+
*
|
|
158
|
+
* The element's own rendered shape is the lens: its alpha masks the
|
|
159
|
+
* pane (text and path shapes work too) and the refraction normal comes
|
|
160
|
+
* from the alpha field's gradient. The element's fill COLOR is unused
|
|
161
|
+
* under glass — tint with the `tint` param instead.
|
|
162
|
+
*/
|
|
163
|
+
export interface GlassEffect {
|
|
164
|
+
type: 'glass';
|
|
165
|
+
/** Backdrop Gaussian blur σ in px (frosting). Default 0 (clear glass). Animatable. */
|
|
166
|
+
blur_radius?: number | Keyframe[] | Expr;
|
|
167
|
+
/**
|
|
168
|
+
* Refraction strength — approximate rim displacement in canvas px
|
|
169
|
+
* (0 = flat frosted panel). The magnitude is used: displacement is
|
|
170
|
+
* always toward the pane's interior, so glass magnifies what's
|
|
171
|
+
* under it and never pulls in content from outside its footprint.
|
|
172
|
+
* Default 21. Animatable.
|
|
173
|
+
*/
|
|
174
|
+
refraction?: number | Keyframe[] | Expr;
|
|
175
|
+
/** How far the lens curl reaches inward, in px. Default 40. Animatable. */
|
|
176
|
+
edge_width?: number | Keyframe[] | Expr;
|
|
177
|
+
/**
|
|
178
|
+
* Intensity of the glass lighting rig — Blinn-Phong speculars,
|
|
179
|
+
* Fresnel edge whitening, and the thin top-lit stroke — 0..1.
|
|
180
|
+
* Default 0.35. Animatable.
|
|
181
|
+
*/
|
|
182
|
+
edge_highlight?: number | Keyframe[] | Expr;
|
|
183
|
+
/**
|
|
184
|
+
* Drop-shadow strength 0..1, drawn ONLY outside the pane's footprint
|
|
185
|
+
* (real glass never frosts its own shadow — prefer this over a
|
|
186
|
+
* shadow sibling beneath the lens). Default 0.3. Animatable.
|
|
187
|
+
*/
|
|
188
|
+
shadow?: number | Keyframe[] | Expr;
|
|
189
|
+
/**
|
|
190
|
+
* Chromatic dispersion: R/G/B refract at strengths
|
|
191
|
+
* refraction × (1−d, 1, 1+d), producing the subtle rainbow fringe
|
|
192
|
+
* of real glass at the lens edges. Default 0.05 (0 = off). Try 0.2.
|
|
193
|
+
* Animatable.
|
|
194
|
+
*/
|
|
195
|
+
dispersion?: number | Keyframe[] | Expr;
|
|
196
|
+
/**
|
|
197
|
+
* Saturation boost applied to the frosted backdrop (Rec. 709, same
|
|
198
|
+
* math as the `saturation` filter) so content behind the glass stays
|
|
199
|
+
* vibrant instead of going muddy. 1 = unchanged (default).
|
|
200
|
+
* Animatable.
|
|
201
|
+
*/
|
|
202
|
+
backdrop_saturation?: number | Keyframe[] | Expr;
|
|
203
|
+
/** Tint drawn over the glass (use alpha for strength, e.g. "#FFFFFF22"). */
|
|
204
|
+
tint?: string;
|
|
205
|
+
/**
|
|
206
|
+
* Lens cross-section: 'pill' (biconvex — light refracts at entry and
|
|
207
|
+
* exit, the default card/button look) or 'dome' (flat bottom,
|
|
208
|
+
* curved top — with edge_width = the shape's radius this is a
|
|
209
|
+
* half-sphere magnifier).
|
|
210
|
+
*/
|
|
211
|
+
mode?: 'pill' | 'dome';
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Outer glow: the element's silhouette, blurred and tinted, composited
|
|
215
|
+
* BENEATH the element. The classic AE layer style.
|
|
216
|
+
*/
|
|
217
|
+
export interface GlowEffect {
|
|
218
|
+
type: 'glow';
|
|
219
|
+
/** Glow reach — Gaussian σ of the silhouette blur, px. Default 20. Animatable. */
|
|
220
|
+
radius?: number | Keyframe[] | Expr;
|
|
221
|
+
/** Glow strength multiplier. Default 1. Animatable. */
|
|
222
|
+
intensity?: number | Keyframe[] | Expr;
|
|
223
|
+
/** Glow color. Default "#FFFFFF". */
|
|
224
|
+
color?: string;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Drop shadow on ANY element (shapes have a native `shadow`; this one
|
|
228
|
+
* works on text, images, shapes, groups — the blurred silhouette, offset
|
|
229
|
+
* and tinted, composited beneath the element).
|
|
230
|
+
*/
|
|
231
|
+
export interface DropShadowEffect {
|
|
232
|
+
type: 'drop_shadow';
|
|
233
|
+
/** Shadow offset in px. Defaults (0, 12). Animatable. */
|
|
234
|
+
offset_x?: number | Keyframe[] | Expr;
|
|
235
|
+
offset_y?: number | Keyframe[] | Expr;
|
|
236
|
+
/** Shadow softness — Gaussian σ in px. Default 18. Animatable. */
|
|
237
|
+
blur?: number | Keyframe[] | Expr;
|
|
238
|
+
/** Shadow color. Default "#000000". */
|
|
239
|
+
color?: string;
|
|
240
|
+
/** Shadow opacity 0..1. Default 0.6. Animatable. */
|
|
241
|
+
opacity?: number | Keyframe[] | Expr;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Outline stroke around the element's alpha silhouette (outside the
|
|
245
|
+
* edge), on any element type.
|
|
246
|
+
*/
|
|
247
|
+
export interface StrokeEffect {
|
|
248
|
+
type: 'stroke';
|
|
249
|
+
/** Stroke width in px. Default 4. Animatable. */
|
|
250
|
+
width?: number | Keyframe[] | Expr;
|
|
251
|
+
/** Stroke color. Default "#FFFFFF". */
|
|
252
|
+
color?: string;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Chroma key: pixels whose chroma (BT.709 CbCr) is close to `color`
|
|
256
|
+
* become transparent — green-screen / blue-screen removal. The alpha
|
|
257
|
+
* ramp is linear from `tolerance` to `tolerance + softness` in CbCr
|
|
258
|
+
* distance. Spill suppression caps the key color's dominant channel at
|
|
259
|
+
* the max of the other two, scaled by `spill`.
|
|
260
|
+
*/
|
|
261
|
+
export interface ChromaKeyEffect {
|
|
262
|
+
type: 'chroma_key';
|
|
263
|
+
/** The screen color to remove. Default "#00FF00". */
|
|
264
|
+
color?: string;
|
|
265
|
+
/** CbCr distance fully removed. Default 0.18. Animatable. */
|
|
266
|
+
tolerance?: number | Keyframe[] | Expr;
|
|
267
|
+
/** Ramp width above tolerance (0 = hard edge). Default 0.1. Animatable. */
|
|
268
|
+
softness?: number | Keyframe[] | Expr;
|
|
269
|
+
/** Spill suppression strength 0..1. Default 0.5. Animatable. */
|
|
270
|
+
spill?: number | Keyframe[] | Expr;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Luma key: pixels darker than `threshold` (BT.709 luma of the
|
|
274
|
+
* straight-alpha color) become transparent; `invert` keys out bright
|
|
275
|
+
* pixels instead. The classic way to lift white-on-black mattes,
|
|
276
|
+
* flares, and smoke elements.
|
|
277
|
+
*/
|
|
278
|
+
export interface LumaKeyEffect {
|
|
279
|
+
type: 'luma_key';
|
|
280
|
+
/** Luma below this is fully removed (0..1). Default 0.5. Animatable. */
|
|
281
|
+
threshold?: number | Keyframe[] | Expr;
|
|
282
|
+
/** Ramp width above threshold (0 = hard edge). Default 0.1. Animatable. */
|
|
283
|
+
softness?: number | Keyframe[] | Expr;
|
|
284
|
+
/** Key out BRIGHT pixels instead of dark. Default false. */
|
|
285
|
+
invert?: boolean;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Levels: the classic five-param grade, per channel on the
|
|
289
|
+
* straight-alpha color: `x = clamp((c − in_black) / (in_white −
|
|
290
|
+
* in_black)); y = x^(1/gamma); out = out_black + y × (out_white −
|
|
291
|
+
* out_black)`. gamma > 1 brightens mids (Photoshop semantics).
|
|
292
|
+
*/
|
|
293
|
+
export interface LevelsEffect {
|
|
294
|
+
type: 'levels';
|
|
295
|
+
/** Input black point 0..1. Default 0. Animatable. */
|
|
296
|
+
in_black?: number | Keyframe[] | Expr;
|
|
297
|
+
/** Input white point 0..1. Default 1. Animatable. */
|
|
298
|
+
in_white?: number | Keyframe[] | Expr;
|
|
299
|
+
/** Mid-tone gamma (> 0; > 1 brightens). Default 1. Animatable. */
|
|
300
|
+
gamma?: number | Keyframe[] | Expr;
|
|
301
|
+
/** Output black point 0..1. Default 0. Animatable. */
|
|
302
|
+
out_black?: number | Keyframe[] | Expr;
|
|
303
|
+
/** Output white point 0..1. Default 1. Animatable. */
|
|
304
|
+
out_white?: number | Keyframe[] | Expr;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Color lookup table: a .cube file (3D LUT) applied to the element's
|
|
308
|
+
* straight-alpha color with trilinear interpolation over the lattice.
|
|
309
|
+
* The asset loads like any other (http(s), relative, or data: URI).
|
|
310
|
+
* Unloadable or malformed LUTs skip the pass with a warning.
|
|
311
|
+
*/
|
|
312
|
+
export interface LutEffect {
|
|
313
|
+
type: 'lut';
|
|
314
|
+
/** URL of the .cube file (LUT_3D_SIZE, 0..1 domain). */
|
|
315
|
+
source: string;
|
|
316
|
+
/** Blend between original (0) and graded (1) color. Default 1. Animatable. */
|
|
317
|
+
intensity?: number | Keyframe[] | Expr;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Fractal noise: fills the element's alpha footprint with seeded,
|
|
321
|
+
* animatable value-noise fBM (grayscale; chain `levels` / `lut` /
|
|
322
|
+
* `hue_rotate` to color it). The noise function is NORMATIVE (§4.7) —
|
|
323
|
+
* an integer PCG hash over the lattice — so the same seed produces the
|
|
324
|
+
* same pixels on every runtime. Animate `evolution` to make the noise
|
|
325
|
+
* churn in place; animate `offset_x`/`offset_y` to scroll it.
|
|
326
|
+
*/
|
|
327
|
+
export interface FractalNoiseEffect {
|
|
328
|
+
type: 'fractal_noise';
|
|
329
|
+
/** Feature size in canvas px (one noise lattice cell). Default 100. Animatable. */
|
|
330
|
+
scale?: number | Keyframe[] | Expr;
|
|
331
|
+
/** Third noise axis — animate for in-place churn. Default 0. Animatable. */
|
|
332
|
+
evolution?: number | Keyframe[] | Expr;
|
|
333
|
+
/** Scroll offsets in canvas px. Default 0. Animatable. */
|
|
334
|
+
offset_x?: number | Keyframe[] | Expr;
|
|
335
|
+
offset_y?: number | Keyframe[] | Expr;
|
|
336
|
+
/** fBM octaves, integer 1–8. Default 4. */
|
|
337
|
+
octaves?: number;
|
|
338
|
+
/** Lattice seed, integer ≥ 0. Default 0. */
|
|
339
|
+
seed?: number;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Turbulent displace: warps the element's own pixels by a seeded noise
|
|
343
|
+
* vector field — wavy text, heat shimmer, organic wobble. Same
|
|
344
|
+
* normative noise as `fractal_noise`. Animate `evolution` for motion.
|
|
345
|
+
*/
|
|
346
|
+
export interface TurbulentDisplaceEffect {
|
|
347
|
+
type: 'turbulent_displace';
|
|
348
|
+
/** Max displacement in canvas px. Default 16. Animatable. */
|
|
349
|
+
amount?: number | Keyframe[] | Expr;
|
|
350
|
+
/** Feature size of the displacement field in canvas px. Default 120. Animatable. */
|
|
351
|
+
scale?: number | Keyframe[] | Expr;
|
|
352
|
+
/** Third noise axis — animate for churn. Default 0. Animatable. */
|
|
353
|
+
evolution?: number | Keyframe[] | Expr;
|
|
354
|
+
/** fBM octaves, integer 1–8. Default 2. */
|
|
355
|
+
octaves?: number;
|
|
356
|
+
/** Lattice seed, integer ≥ 0. Default 0. */
|
|
357
|
+
seed?: number;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* A stylize pass over the element's rendered pixels. Effects run in
|
|
361
|
+
* array order, after the filter fields (§4.6 → §4.7). Params accept
|
|
362
|
+
* keyframes evaluated against element-local time.
|
|
363
|
+
*/
|
|
364
|
+
export type Effect = PixelateEffect | DitherEffect | HalftoneEffect | AsciiEffect | GlassEffect | GlowEffect | DropShadowEffect | StrokeEffect | ChromaKeyEffect | LumaKeyEffect | LevelsEffect | LutEffect | FractalNoiseEffect | TurbulentDisplaceEffect;
|
|
365
|
+
export interface BaseElement {
|
|
366
|
+
id?: string;
|
|
367
|
+
name?: string;
|
|
368
|
+
type: ElementType;
|
|
369
|
+
/**
|
|
370
|
+
* Paint order within the element's container, like an After Effects
|
|
371
|
+
* layer: each element owns a UNIQUE `layer` integer in 1..1000 and
|
|
372
|
+
* LOWER numbers draw in front (layer 1 is on top). Required. `z`
|
|
373
|
+
* (depth) takes precedence; `layer` orders elements within equal
|
|
374
|
+
* depth. Unique per container (top-level `elements`, each group's
|
|
375
|
+
* `elements`, each group mask's `elements`).
|
|
376
|
+
*/
|
|
377
|
+
layer: number;
|
|
378
|
+
time?: number | string;
|
|
379
|
+
duration?: number | string | 'auto' | 'end';
|
|
380
|
+
/** When false, the element is not rendered at all. Default true. */
|
|
381
|
+
visible?: boolean;
|
|
382
|
+
x?: number | string | Keyframe[] | Expr;
|
|
383
|
+
y?: number | string | Keyframe[] | Expr;
|
|
384
|
+
x_anchor?: number | string;
|
|
385
|
+
y_anchor?: number | string;
|
|
386
|
+
width?: number | string | Keyframe[] | Expr;
|
|
387
|
+
height?: number | string | Keyframe[] | Expr;
|
|
388
|
+
/**
|
|
389
|
+
* Width / height ratio. When exactly one of width/height is set, the
|
|
390
|
+
* other derives from this ratio (e.g. width 800 + aspect_ratio 16/9 →
|
|
391
|
+
* height 450). Ignored when both or neither dimension is set.
|
|
392
|
+
*/
|
|
393
|
+
aspect_ratio?: number;
|
|
394
|
+
/**
|
|
395
|
+
* Rotation in the element's plane, degrees clockwise. Exact alias for
|
|
396
|
+
* `z_rotation` (CKP/1.0): authoring BOTH on one element is a
|
|
397
|
+
* validation error. Animatable.
|
|
398
|
+
*/
|
|
399
|
+
rotation?: number | Keyframe[] | Expr;
|
|
400
|
+
/**
|
|
401
|
+
* 3D rotation (CKP/1.0, §4.4): degrees around the element's local z
|
|
402
|
+
* axis. Same slot as `rotation` — use one or the other.
|
|
403
|
+
*/
|
|
404
|
+
z_rotation?: number | Keyframe[] | Expr;
|
|
405
|
+
/**
|
|
406
|
+
* 3D rotation (CKP/1.0, §4.4): degrees around the element's local
|
|
407
|
+
* x axis (positive tips the top edge away from the viewer). Without a
|
|
408
|
+
* Source camera the projection has no perspective (affine
|
|
409
|
+
* foreshortening only). Animatable.
|
|
410
|
+
*/
|
|
411
|
+
x_rotation?: number | Keyframe[] | Expr;
|
|
412
|
+
/**
|
|
413
|
+
* 3D rotation (CKP/1.0, §4.4): degrees around the element's local
|
|
414
|
+
* y axis (positive turns the right edge away from the viewer).
|
|
415
|
+
* Animatable.
|
|
416
|
+
*/
|
|
417
|
+
y_rotation?: number | Keyframe[] | Expr;
|
|
418
|
+
/**
|
|
419
|
+
* Position offset along the z axis in pixels (CKP/1.0, §4.4);
|
|
420
|
+
* positive moves TOWARD the viewer. Visible only under a Source
|
|
421
|
+
* camera (it feeds the perspective divide); does NOT affect paint
|
|
422
|
+
* order. Animatable.
|
|
423
|
+
*/
|
|
424
|
+
z?: number | Keyframe[] | Expr;
|
|
425
|
+
scale?: number | Keyframe[] | Expr;
|
|
426
|
+
/**
|
|
427
|
+
* Per-axis scale factors, multiplied with the uniform `scale`. A number
|
|
428
|
+
* is a factor (1 = unscaled); a string percentage ("50%") is parsed as
|
|
429
|
+
* factor/100. Animatable via keyframe_animations.
|
|
430
|
+
*/
|
|
431
|
+
x_scale?: number | string | Keyframe[] | Expr;
|
|
432
|
+
y_scale?: number | string | Keyframe[] | Expr;
|
|
433
|
+
/**
|
|
434
|
+
* Shear in DEGREES, following CSS `skewX(...)` / `skewY(...)`
|
|
435
|
+
* semantics: positive x_skew moves the bottom edge right; positive
|
|
436
|
+
* y_skew moves the right edge down. Animatable.
|
|
437
|
+
*/
|
|
438
|
+
x_skew?: number | Keyframe[] | Expr;
|
|
439
|
+
y_skew?: number | Keyframe[] | Expr;
|
|
440
|
+
/** Opacity 0..1 (CSS convention). Default 1 (opaque). Animatable. */
|
|
441
|
+
opacity?: number | Keyframe[] | Expr;
|
|
442
|
+
/**
|
|
443
|
+
* How this element's pixels combine with what's already on the
|
|
444
|
+
* canvas beneath it (element-local, like opacity). Follows the W3C
|
|
445
|
+
* Compositing & Blending separable-blend definitions:
|
|
446
|
+
* 'normal' source-over (default)
|
|
447
|
+
* 'multiply' darkens — white is neutral
|
|
448
|
+
* 'screen' lightens — black is neutral
|
|
449
|
+
* 'add' additive glow — black is neutral
|
|
450
|
+
* 'overlay' multiply where backdrop is dark, screen where light
|
|
451
|
+
* 'hard-light' overlay with source and backdrop swapped
|
|
452
|
+
* 'soft-light' a gentler overlay (soft burn/dodge)
|
|
453
|
+
* 'overlay'/'hard-light'/'soft-light' are piecewise on the backdrop/
|
|
454
|
+
* source and can't be done with fixed-function GPU blending — the
|
|
455
|
+
* runtime isolates the element to a layer and composites it against a
|
|
456
|
+
* snapshot of the backdrop.
|
|
457
|
+
*/
|
|
458
|
+
blend_mode?: 'normal' | 'multiply' | 'screen' | 'add' | 'overlay' | 'hard-light' | 'soft-light';
|
|
459
|
+
/**
|
|
460
|
+
* Gaussian blur of this element's rendered pixels; the value is the
|
|
461
|
+
* standard deviation (σ) in canvas pixels, CSS `filter: blur()`
|
|
462
|
+
* semantics. 0 = off. Element-local: the blur may bleed past the
|
|
463
|
+
* element's box but never touches other elements. Animatable.
|
|
464
|
+
*/
|
|
465
|
+
blur_radius?: number | Keyframe[] | Expr;
|
|
466
|
+
/**
|
|
467
|
+
* Brightness multiplier (CSS `filter: brightness()`): 1 = unchanged,
|
|
468
|
+
* 0 = black, >1 brightens. Element-local, animatable.
|
|
469
|
+
*/
|
|
470
|
+
brightness?: number | Keyframe[] | Expr;
|
|
471
|
+
/**
|
|
472
|
+
* Contrast multiplier around mid-gray (CSS `filter: contrast()`):
|
|
473
|
+
* 1 = unchanged, 0 = solid gray, >1 increases. Element-local,
|
|
474
|
+
* animatable.
|
|
475
|
+
*/
|
|
476
|
+
contrast?: number | Keyframe[] | Expr;
|
|
477
|
+
/**
|
|
478
|
+
* Saturation multiplier (CSS `filter: saturate()`): 1 = unchanged,
|
|
479
|
+
* 0 = grayscale, >1 oversaturates. Element-local, animatable.
|
|
480
|
+
*/
|
|
481
|
+
saturation?: number | Keyframe[] | Expr;
|
|
482
|
+
/**
|
|
483
|
+
* Hue rotation in degrees (CSS `filter: hue-rotate()` — the SVG
|
|
484
|
+
* feColorMatrix hueRotate matrix, normative in §4.6): 0 = unchanged.
|
|
485
|
+
* Element-local, animatable.
|
|
486
|
+
*/
|
|
487
|
+
hue_rotate?: number | Keyframe[] | Expr;
|
|
488
|
+
/**
|
|
489
|
+
* Stylize effects, applied IN ARRAY ORDER after the filter fields
|
|
490
|
+
* (blur → brightness → contrast → saturation → hue_rotate →
|
|
491
|
+
* effects[0..n]).
|
|
492
|
+
* Element-local: each effect re-renders only this element's pixels;
|
|
493
|
+
* other elements are never read or altered. Effect params accept
|
|
494
|
+
* keyframes (element-local time) and are NOT addressable via
|
|
495
|
+
* keyframe_animations.
|
|
496
|
+
*/
|
|
497
|
+
effects?: Effect[];
|
|
498
|
+
/**
|
|
499
|
+
* PBR surface material (CKP/1.0, §4.8). Opt-in: with no `material` the
|
|
500
|
+
* element renders unlit exactly as before. When present (and the Source
|
|
501
|
+
* declares `lights`), the element's own pixels act as albedo and the
|
|
502
|
+
* runtime shades them — diffuse + view-dependent specular + environment
|
|
503
|
+
* reflection — so highlights/reflections sweep as the camera moves.
|
|
504
|
+
*/
|
|
505
|
+
material?: Material;
|
|
506
|
+
animations?: Animation[];
|
|
507
|
+
keyframe_animations?: KeyframeAnimation[];
|
|
508
|
+
[key: string]: unknown;
|
|
509
|
+
}
|
|
510
|
+
export interface VideoElement extends BaseElement {
|
|
511
|
+
type: 'video';
|
|
512
|
+
source: string;
|
|
513
|
+
volume?: number | Keyframe[] | Expr;
|
|
514
|
+
playback_rate?: number | Keyframe[] | Expr;
|
|
515
|
+
trim_start?: number;
|
|
516
|
+
trim_duration?: number;
|
|
517
|
+
loop?: boolean;
|
|
518
|
+
/**
|
|
519
|
+
* Time remapping (§5.3.2): keyframes mapping element-local time
|
|
520
|
+
* (seconds) → MEDIA time (seconds). Speed ramps are steep segments,
|
|
521
|
+
* freeze frames are flat ones, reverse plays from decreasing values.
|
|
522
|
+
* When present it REPLACES the trim_start / trim_duration /
|
|
523
|
+
* playback_rate / loop mapping entirely. The embedded audio follows
|
|
524
|
+
* the warp varispeed-style (§5.3.2): pitch shifts with speed,
|
|
525
|
+
* freezes are silent, reverse plays the sound backwards.
|
|
526
|
+
*/
|
|
527
|
+
time_remap?: Keyframe[];
|
|
528
|
+
/** Embedded-audio gain ramps 0→volume over the first N timeline seconds. */
|
|
529
|
+
audio_fade_in?: number;
|
|
530
|
+
/** Embedded-audio gain ramps volume→0 over the last N timeline seconds. */
|
|
531
|
+
audio_fade_out?: number;
|
|
532
|
+
/**
|
|
533
|
+
* How the media fills the element box (CSS object-fit semantics):
|
|
534
|
+
* 'cover' scales to fill and crops overflow (default), 'contain'
|
|
535
|
+
* letterboxes, 'fill' stretches, 'none' renders at natural size
|
|
536
|
+
* cropped to the box.
|
|
537
|
+
*/
|
|
538
|
+
fit?: 'cover' | 'contain' | 'fill' | 'none';
|
|
539
|
+
/**
|
|
540
|
+
* Source crop — a normalized sub-rectangle of the media (0..1, origin
|
|
541
|
+
* top-left) selected BEFORE `fit` maps it into the element box. The
|
|
542
|
+
* element box is unchanged; crop only chooses which part of the source
|
|
543
|
+
* fills it. Default `0,0,1,1` (whole source) — omit for no crop. Each
|
|
544
|
+
* component is keyframeable (animate them for a Ken Burns pan/zoom).
|
|
545
|
+
*/
|
|
546
|
+
crop_x?: number;
|
|
547
|
+
crop_y?: number;
|
|
548
|
+
crop_width?: number;
|
|
549
|
+
crop_height?: number;
|
|
550
|
+
}
|
|
551
|
+
export interface ImageElement extends BaseElement {
|
|
552
|
+
type: 'image';
|
|
553
|
+
source: string;
|
|
554
|
+
fit?: 'cover' | 'contain' | 'fill' | 'none';
|
|
555
|
+
/**
|
|
556
|
+
* Rounded-corner radius in pixels. Pixels outside the rounded rect
|
|
557
|
+
* are masked out by the renderer (with anti-aliased edges). Clamped
|
|
558
|
+
* by the runtime to half the smaller dimension, so passing a huge
|
|
559
|
+
* value produces a pill / circle. Matches CSS `border-radius`.
|
|
560
|
+
*/
|
|
561
|
+
border_radius?: number;
|
|
562
|
+
/**
|
|
563
|
+
* Source crop — a normalized sub-rectangle of the media (0..1, origin
|
|
564
|
+
* top-left) selected BEFORE `fit` maps it into the element box. The
|
|
565
|
+
* element box is unchanged; crop only chooses which part of the source
|
|
566
|
+
* fills it. Default `0,0,1,1` (whole source) — omit for no crop. Each
|
|
567
|
+
* component is keyframeable (animate them for a Ken Burns pan/zoom).
|
|
568
|
+
*/
|
|
569
|
+
crop_x?: number;
|
|
570
|
+
crop_y?: number;
|
|
571
|
+
crop_width?: number;
|
|
572
|
+
crop_height?: number;
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* A styled run within a text element. When `spans` is set on a TextElement
|
|
576
|
+
* the runtime renders each run inline left-to-right, applying any per-span
|
|
577
|
+
* style overrides on top of the element's defaults. A span with text
|
|
578
|
+
* `'\n'` acts as a hard line break.
|
|
579
|
+
*
|
|
580
|
+
* Clipkit extension to the baseline TextElement; allows
|
|
581
|
+
* mid-string emphasis (bold within a sentence, colored highlight on one
|
|
582
|
+
* word, etc.) without authoring N positioned siblings.
|
|
583
|
+
*/
|
|
584
|
+
/**
|
|
585
|
+
* Stylized background for a TextSpan — a "highlight band" effect.
|
|
586
|
+
*
|
|
587
|
+
* The fields refine how the background rect is positioned and shaped:
|
|
588
|
+
* - `height_ratio` < 1 makes the band shorter than the line box
|
|
589
|
+
* (e.g. 0.5 for a marker-style underline highlight).
|
|
590
|
+
* - `inset_y_ratio` shifts the band vertically within the line box.
|
|
591
|
+
* - `padding_x` extends the band horizontally past the text glyphs.
|
|
592
|
+
* - `skew_x` shears the band horizontally (parallelogram edges).
|
|
593
|
+
* - `border_radius` rounds the band corners.
|
|
594
|
+
*
|
|
595
|
+
* All optional — minimal usage `{ color }` is equivalent to a flat
|
|
596
|
+
* full-line-box rectangle (same as the older `background_color`).
|
|
597
|
+
*/
|
|
598
|
+
export interface TextSpanBackground {
|
|
599
|
+
/** CSS color (hex / rgb / rgba). */
|
|
600
|
+
color: string;
|
|
601
|
+
/**
|
|
602
|
+
* Band height as a fraction of the line-box height. 1.0 = full line
|
|
603
|
+
* (default), 0.5 = half-line marker, etc.
|
|
604
|
+
*/
|
|
605
|
+
height_ratio?: number;
|
|
606
|
+
/**
|
|
607
|
+
* Top edge of the band as a fraction of the line-box height, measured
|
|
608
|
+
* from the line-box top. 0 = flush top, 1 - height_ratio = flush
|
|
609
|
+
* bottom. Default 0.
|
|
610
|
+
*/
|
|
611
|
+
inset_y_ratio?: number;
|
|
612
|
+
/**
|
|
613
|
+
* Horizontal padding in PIXELS extending past the text glyph bounds
|
|
614
|
+
* on each side. Useful for the "Swipe" effect where the band sticks
|
|
615
|
+
* out a few pixels past the letters.
|
|
616
|
+
*/
|
|
617
|
+
padding_x?: number;
|
|
618
|
+
/**
|
|
619
|
+
* Horizontal skew in DEGREES (CSS `skewX(...)`). Positive shears the
|
|
620
|
+
* top to the right; negative to the left.
|
|
621
|
+
*/
|
|
622
|
+
skew_x?: number;
|
|
623
|
+
/** Corner radius in pixels. */
|
|
624
|
+
border_radius?: number;
|
|
625
|
+
/** 0..1 opacity. Multiplies with the element's opacity. */
|
|
626
|
+
opacity?: number;
|
|
627
|
+
}
|
|
628
|
+
export interface TextSpan {
|
|
629
|
+
text: string;
|
|
630
|
+
font_weight?: number | string;
|
|
631
|
+
font_style?: 'normal' | 'italic';
|
|
632
|
+
font_family?: string;
|
|
633
|
+
font_size?: number | string;
|
|
634
|
+
fill_color?: string;
|
|
635
|
+
/**
|
|
636
|
+
* Tracking in pixels, added after every character (Chrome's
|
|
637
|
+
* letter-spacing model). Inherits the element's letter_spacing when
|
|
638
|
+
* unset.
|
|
639
|
+
*/
|
|
640
|
+
letter_spacing?: number;
|
|
641
|
+
/**
|
|
642
|
+
* Solid color background spanning the full line box. Shortcut for
|
|
643
|
+
* `background: { color }`. Ignored when `background` is set.
|
|
644
|
+
*/
|
|
645
|
+
background_color?: string;
|
|
646
|
+
/** Stylized background — overrides `background_color` when present. */
|
|
647
|
+
background?: TextSpanBackground;
|
|
648
|
+
/**
|
|
649
|
+
* When true, the runtime's word-wrap treats this span's text as an
|
|
650
|
+
* atomic unit: it never breaks mid-span. Matches CSS
|
|
651
|
+
* `white-space: nowrap` / `display: inline-block` semantics. Used
|
|
652
|
+
* for highlighted phrases that must stay together (the Swipe band
|
|
653
|
+
* "before you leave" reads wrong if it wraps after "before").
|
|
654
|
+
*/
|
|
655
|
+
nowrap?: boolean;
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* Per-glyph text shadow (CSS `text-shadow` semantics). Each glyph casts
|
|
659
|
+
* its OWN shadow, so it tracks per-letter animation (flip/stagger/3D) and
|
|
660
|
+
* overlapping glyphs — unlike the silhouette `drop_shadow` effect, which
|
|
661
|
+
* shadows the flattened text as one shape. Use an ARRAY for stacked
|
|
662
|
+
* shadows (painted back-to-front; the last entry sits nearest the glyphs).
|
|
663
|
+
*/
|
|
664
|
+
export interface TextShadow {
|
|
665
|
+
/** Shadow color (§3.4: hex / rgb() / hsl() / named). */
|
|
666
|
+
color: string;
|
|
667
|
+
/** Offset in px, in the text's local frame (rotates with it). Default 0. */
|
|
668
|
+
offset_x?: number;
|
|
669
|
+
offset_y?: number;
|
|
670
|
+
/** Gaussian softness in px (0 = crisp). Default 0. */
|
|
671
|
+
blur?: number;
|
|
672
|
+
/** Shadow opacity 0..1, multiplies the color's alpha. Default 1. */
|
|
673
|
+
opacity?: number;
|
|
674
|
+
}
|
|
675
|
+
export interface TextElement extends BaseElement {
|
|
676
|
+
type: 'text';
|
|
677
|
+
/** Static text content. Optional when `spans` is provided. */
|
|
678
|
+
text?: string;
|
|
679
|
+
/**
|
|
680
|
+
* Inline-styled runs. When present, takes precedence over `text`. Each
|
|
681
|
+
* span inherits the element's font_family / font_size / fill_color /
|
|
682
|
+
* etc. unless it overrides them.
|
|
683
|
+
*/
|
|
684
|
+
spans?: TextSpan[];
|
|
685
|
+
font_family?: string;
|
|
686
|
+
font_size?: number | string;
|
|
687
|
+
/**
|
|
688
|
+
* Lower bound for `font_size: "auto"` fitting. Number = px; unit
|
|
689
|
+
* strings (vmin etc.) resolve against the canvas. Default 8.
|
|
690
|
+
*/
|
|
691
|
+
font_size_minimum?: number | string;
|
|
692
|
+
/** Upper bound for `font_size: "auto"`. Default 400. */
|
|
693
|
+
font_size_maximum?: number | string;
|
|
694
|
+
font_weight?: number | string;
|
|
695
|
+
font_style?: 'normal' | 'italic';
|
|
696
|
+
fill_color?: string;
|
|
697
|
+
stroke_color?: string;
|
|
698
|
+
stroke_width?: number;
|
|
699
|
+
/**
|
|
700
|
+
* Case transform applied before layout: 'uppercase', 'lowercase',
|
|
701
|
+
* 'capitalize' (word-initial caps). Default 'none'.
|
|
702
|
+
*/
|
|
703
|
+
text_transform?: 'none' | 'uppercase' | 'lowercase' | 'capitalize';
|
|
704
|
+
/**
|
|
705
|
+
* When false, text never soft-wraps — only explicit "\n" breaks
|
|
706
|
+
* lines. Default true (plain text wraps to element.width when set;
|
|
707
|
+
* spans keep their author/importer breaks).
|
|
708
|
+
*/
|
|
709
|
+
text_wrap?: boolean;
|
|
710
|
+
text_align?: 'left' | 'center' | 'right';
|
|
711
|
+
vertical_align?: 'top' | 'middle' | 'bottom';
|
|
712
|
+
/**
|
|
713
|
+
* Content insets in pixels: the text box shrinks by 2×padding on the
|
|
714
|
+
* axis and content shifts inward. Numbers or unit strings.
|
|
715
|
+
*/
|
|
716
|
+
x_padding?: number | string;
|
|
717
|
+
y_padding?: number | string;
|
|
718
|
+
/**
|
|
719
|
+
* Percentage-based content alignment, overriding text_align /
|
|
720
|
+
* vertical_align when present: "0%" = left/top, "50%" = center,
|
|
721
|
+
* "100%" = right/bottom. Numbers are fractions (0.5 = center).
|
|
722
|
+
*/
|
|
723
|
+
x_alignment?: number | string;
|
|
724
|
+
y_alignment?: number | string;
|
|
725
|
+
line_height?: number;
|
|
726
|
+
letter_spacing?: number;
|
|
727
|
+
/**
|
|
728
|
+
* Solid background behind the text — drawn as ONE band PER LINE, each
|
|
729
|
+
* shrink-wrapped to that line's glyphs (not the element box), so
|
|
730
|
+
* centered / ragged multi-line text gets per-line pills. Tracks
|
|
731
|
+
* wrapping and `font_size: "auto"`. For a per-run highlight band use a
|
|
732
|
+
* span `background`; for a drop shadow use a `drop_shadow` effect.
|
|
733
|
+
*/
|
|
734
|
+
background_color?: string;
|
|
735
|
+
/** Corner radius (px) for `background_color`. Default 0. */
|
|
736
|
+
background_border_radius?: number;
|
|
737
|
+
/**
|
|
738
|
+
* Padding (px) added around the shrink-wrapped `background_color` on all
|
|
739
|
+
* sides, OR `[x, y]` for separate horizontal / vertical padding. Default
|
|
740
|
+
* 0 (bg hugs the glyphs). A pill usually wants ~16–28 horizontal.
|
|
741
|
+
*/
|
|
742
|
+
background_padding?: number | [number, number];
|
|
743
|
+
/**
|
|
744
|
+
* Per-glyph drop shadow (CSS `text-shadow`), or an array for stacked
|
|
745
|
+
* shadows. Distinct from the silhouette `drop_shadow` effect — see
|
|
746
|
+
* TextShadow. Animatable params are not supported (static per shadow).
|
|
747
|
+
*/
|
|
748
|
+
text_shadow?: TextShadow | TextShadow[];
|
|
749
|
+
/**
|
|
750
|
+
* Reveal mask. When present, text is rendered to an offscreen canvas
|
|
751
|
+
* and masked before display. linear-wipe sweeps a soft diagonal edge
|
|
752
|
+
* across the text driven by `progress` (0 = hidden, 1 = revealed).
|
|
753
|
+
*/
|
|
754
|
+
mask?: TextMask;
|
|
755
|
+
}
|
|
756
|
+
export interface TextMask {
|
|
757
|
+
type: 'linear-wipe';
|
|
758
|
+
/**
|
|
759
|
+
* Wipe direction in degrees. 0 = left→right, -45 = bottom-left→top-right
|
|
760
|
+
* (a common text-fade default). Default -45.
|
|
761
|
+
*/
|
|
762
|
+
angle?: number;
|
|
763
|
+
/**
|
|
764
|
+
* Reveal progress, 0..1. Animatable via keyframes. 0 = fully hidden,
|
|
765
|
+
* 1 = fully revealed.
|
|
766
|
+
*/
|
|
767
|
+
progress?: number | Keyframe[] | Expr;
|
|
768
|
+
/**
|
|
769
|
+
* Soft-edge width as a fraction of the bounding box diagonal, 0..1.
|
|
770
|
+
* Larger = softer wipe edge. Default 0.3.
|
|
771
|
+
*/
|
|
772
|
+
softness?: number;
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* Drop shadow drawn behind the shape. Follows CSS `box-shadow`
|
|
776
|
+
* semantics for the outer (non-inset) case:
|
|
777
|
+
* - `color` is the base color of the shadow (CSS color string).
|
|
778
|
+
* - `offset_x` / `offset_y` translate the shadow relative to the
|
|
779
|
+
* shape in PIXELS.
|
|
780
|
+
* - `blur` is the falloff distance in pixels: at offset 0 the
|
|
781
|
+
* shadow has full alpha; alpha fades linearly to 0 over `blur`
|
|
782
|
+
* pixels past the shape's edge.
|
|
783
|
+
*
|
|
784
|
+
* Inset shadows and `spread` are not (yet) supported.
|
|
785
|
+
*/
|
|
786
|
+
export interface BoxShadow {
|
|
787
|
+
color: string;
|
|
788
|
+
offset_x?: number;
|
|
789
|
+
offset_y?: number;
|
|
790
|
+
blur?: number;
|
|
791
|
+
}
|
|
792
|
+
/**
|
|
793
|
+
* A `shape` draws geometry to the frame in one of two representations,
|
|
794
|
+
* chosen by whether `paths` is present:
|
|
795
|
+
*
|
|
796
|
+
* • PRIMITIVE — `shape: 'rectangle' | 'ellipse'` (+ `border_radius`): a GPU
|
|
797
|
+
* SDF quad. Resolution-independent and cheap; corners come from a shader.
|
|
798
|
+
* • PATH — `paths`: arbitrary vector geometry rasterized via the path engine,
|
|
799
|
+
* with keyframeable `d` morphing, per-sub-path fill/stroke, and stroke
|
|
800
|
+
* trim/draw-on. Resolution is bound by `view_box`.
|
|
801
|
+
*
|
|
802
|
+
* One element, two pixel-generation strategies — the renderer dispatches on
|
|
803
|
+
* `paths`. (Absorbs the former `svg` element; CKP/1.0.)
|
|
804
|
+
*/
|
|
805
|
+
export interface ShapeElement extends BaseElement {
|
|
806
|
+
type: 'shape';
|
|
807
|
+
/** Primitive kind. Default 'rectangle'. */
|
|
808
|
+
shape?: 'rectangle' | 'ellipse';
|
|
809
|
+
fill_color?: string;
|
|
810
|
+
/** Gradient fill. When present, overrides fill_color. Up to 4 stops. */
|
|
811
|
+
gradient?: LinearGradient | RadialGradient;
|
|
812
|
+
stroke_color?: string;
|
|
813
|
+
stroke_width?: number;
|
|
814
|
+
border_radius?: number;
|
|
815
|
+
/** Drop shadow rendered before the shape itself. */
|
|
816
|
+
shadow?: BoxShadow;
|
|
817
|
+
/** Vector geometry: one or more sub-paths, painted back-to-front. When
|
|
818
|
+
* present, the primitive fields above are ignored. */
|
|
819
|
+
paths?: PathDef[];
|
|
820
|
+
/** [x, y, width, height] viewBox for `paths`. Default [0, 0, 100, 100]. */
|
|
821
|
+
view_box?: [number, number, number, number];
|
|
822
|
+
/** Linear gradients addressable from `paths` via `fill: "url(#id)"`. */
|
|
823
|
+
gradients?: PathGradient[];
|
|
824
|
+
}
|
|
825
|
+
export interface GradientStop {
|
|
826
|
+
/** Position along the gradient in [0, 1]. */
|
|
827
|
+
offset: number;
|
|
828
|
+
/** Hex color. */
|
|
829
|
+
color: string;
|
|
830
|
+
}
|
|
831
|
+
export interface LinearGradient {
|
|
832
|
+
type: 'linear';
|
|
833
|
+
/**
|
|
834
|
+
* Direction in degrees, following the CSS `linear-gradient()`
|
|
835
|
+
* convention: 0° = to top, measured clockwise — 90° = to right,
|
|
836
|
+
* 180° = to bottom, 270° = to left. Default 180 (to bottom).
|
|
837
|
+
*/
|
|
838
|
+
angle?: number;
|
|
839
|
+
/** Color stops. Up to 4 are honored by the v1 runtime. */
|
|
840
|
+
stops: GradientStop[];
|
|
841
|
+
}
|
|
842
|
+
export interface RadialGradient {
|
|
843
|
+
type: 'radial';
|
|
844
|
+
/** Center X as a fraction of the shape's box. Default 0.5 (center). */
|
|
845
|
+
cx?: number;
|
|
846
|
+
/** Center Y as a fraction. Default 0.5. */
|
|
847
|
+
cy?: number;
|
|
848
|
+
/** Outer radius as a fraction of the shape's box. Default 0.5. */
|
|
849
|
+
radius?: number;
|
|
850
|
+
stops: GradientStop[];
|
|
851
|
+
}
|
|
852
|
+
export interface AudioElement extends BaseElement {
|
|
853
|
+
type: 'audio';
|
|
854
|
+
source: string;
|
|
855
|
+
volume?: number | Keyframe[] | Expr;
|
|
856
|
+
trim_start?: number;
|
|
857
|
+
trim_duration?: number;
|
|
858
|
+
loop?: boolean;
|
|
859
|
+
/** Gain ramps 0→volume over the first N timeline seconds. */
|
|
860
|
+
audio_fade_in?: number;
|
|
861
|
+
/** Gain ramps volume→0 over the last N timeline seconds. */
|
|
862
|
+
audio_fade_out?: number;
|
|
863
|
+
}
|
|
864
|
+
/**
|
|
865
|
+
* Group element — a positioned container whose children inherit its
|
|
866
|
+
* transform, opacity, and time window. The fundamental nesting primitive.
|
|
867
|
+
*
|
|
868
|
+
* Semantic rules:
|
|
869
|
+
* - Children's `x`/`y` are coordinates in the group's LOCAL space. The
|
|
870
|
+
* group's anchor sets the local origin.
|
|
871
|
+
* - The group's `rotation`, `scale`, and `opacity` stack with each
|
|
872
|
+
* descendant. (Transforms multiply, opacities multiply.)
|
|
873
|
+
* - A child's `time` is relative to the group's `time`. A child whose
|
|
874
|
+
* time + duration falls outside the group's window is clipped.
|
|
875
|
+
* - Layers on children are LOCAL paint order within the group; siblings
|
|
876
|
+
* of the group (or its ancestor) use their own layers for global
|
|
877
|
+
* paint order. Layer 1 is on top (drawn last).
|
|
878
|
+
*/
|
|
879
|
+
/**
|
|
880
|
+
* A mask owned by the group it masks — the masked thing declares its
|
|
881
|
+
* own mask (like CSS mask-image), rather than a sibling element
|
|
882
|
+
* reaching across the timeline. Mask elements render into their own
|
|
883
|
+
* layer in the group's local coordinate space (same as children) and
|
|
884
|
+
* may animate like any elements.
|
|
885
|
+
*
|
|
886
|
+
* Modes: 'alpha' shows content where the mask is opaque;
|
|
887
|
+
* 'alpha-inverted' where it is transparent; 'luma' scales content by
|
|
888
|
+
* the mask's luminance (white = visible, black = hidden);
|
|
889
|
+
* 'luma-inverted' the reverse.
|
|
890
|
+
*/
|
|
891
|
+
export interface GroupMask {
|
|
892
|
+
mode: 'alpha' | 'alpha-inverted' | 'luma' | 'luma-inverted';
|
|
893
|
+
elements: Element[];
|
|
894
|
+
}
|
|
895
|
+
export interface GroupElement extends BaseElement {
|
|
896
|
+
type: 'group';
|
|
897
|
+
elements: Element[];
|
|
898
|
+
/**
|
|
899
|
+
* Time remapping for the SUBTREE (§5.8.4): keyframes mapping the
|
|
900
|
+
* group's local time (seconds) → warped local time the children run
|
|
901
|
+
* on. Speed-ramp, freeze, or reverse a whole composed scene: every
|
|
902
|
+
* child `time`, animation, and nested video reads the warped clock.
|
|
903
|
+
* The group's OWN transform/opacity animations stay on real time.
|
|
904
|
+
* Audio inside a remapped subtree plays varispeed (§5.3.2).
|
|
905
|
+
*/
|
|
906
|
+
time_remap?: Keyframe[];
|
|
907
|
+
/**
|
|
908
|
+
* When true, children render into an offscreen layer the size of the
|
|
909
|
+
* group's box and anything outside it is clipped (CSS
|
|
910
|
+
* `overflow: hidden`). Requires explicit `width` and `height`.
|
|
911
|
+
* The group's own opacity/rotation/scale apply to the clipped layer
|
|
912
|
+
* as a whole.
|
|
913
|
+
*/
|
|
914
|
+
clip?: boolean;
|
|
915
|
+
/**
|
|
916
|
+
* Corner radius in pixels for a clipped group: rounds the clip box so
|
|
917
|
+
* children are masked to a rounded rectangle (a rounded card clipping
|
|
918
|
+
* its content). Only meaningful with `clip: true` (or `mask`); ignored
|
|
919
|
+
* on an unclipped group. Clamped to half the smaller box dimension.
|
|
920
|
+
*/
|
|
921
|
+
border_radius?: number;
|
|
922
|
+
/**
|
|
923
|
+
* Mask the group's content through a second layer (see GroupMask).
|
|
924
|
+
* Requires explicit `width` and `height`. Implies clipping to the
|
|
925
|
+
* group's box (both layers are box-sized).
|
|
926
|
+
*/
|
|
927
|
+
mask?: GroupMask;
|
|
928
|
+
}
|
|
929
|
+
export interface CaptionWord {
|
|
930
|
+
text: string;
|
|
931
|
+
/** Seconds, relative to the caption element's `time`. */
|
|
932
|
+
start: number;
|
|
933
|
+
/** Seconds, relative to the caption element's `time`. */
|
|
934
|
+
end: number;
|
|
935
|
+
}
|
|
936
|
+
export interface CaptionElement extends BaseElement {
|
|
937
|
+
type: 'caption';
|
|
938
|
+
words: CaptionWord[];
|
|
939
|
+
style?: CaptionStyle;
|
|
940
|
+
/**
|
|
941
|
+
* Windowing — how much of the transcript shows at once. A whole-video caption
|
|
942
|
+
* would otherwise render as one unreadable block; instead the words are split
|
|
943
|
+
* into CHUNKS and only the chunk active at the current time is shown.
|
|
944
|
+
*
|
|
945
|
+
* number — max LETTERS per chunk (a chunk grows word-by-word until adding
|
|
946
|
+
* the next word would exceed this many characters).
|
|
947
|
+
* "auto" — chunk automatically by words (a few words per chunk, also
|
|
948
|
+
* breaking on pauses) — the sensible default for speech.
|
|
949
|
+
* absent — no windowing; the whole transcript shows at once.
|
|
950
|
+
*/
|
|
951
|
+
max_length?: number | 'auto';
|
|
952
|
+
font_family?: string;
|
|
953
|
+
font_size?: number | string;
|
|
954
|
+
font_weight?: number | string;
|
|
955
|
+
font_style?: 'normal' | 'italic';
|
|
956
|
+
fill_color?: string;
|
|
957
|
+
stroke_color?: string;
|
|
958
|
+
stroke_width?: number;
|
|
959
|
+
text_align?: 'left' | 'center' | 'right';
|
|
960
|
+
line_height?: number;
|
|
961
|
+
letter_spacing?: number;
|
|
962
|
+
/**
|
|
963
|
+
* Solid background drawn behind the caption phrase, SHRINK-WRAPPED to
|
|
964
|
+
* the laid-out glyph bounds (not the element box). For a per-word
|
|
965
|
+
* background use `highlight_background_color`; for a drop shadow use a
|
|
966
|
+
* `drop_shadow` effect.
|
|
967
|
+
*/
|
|
968
|
+
background_color?: string;
|
|
969
|
+
/** Corner radius (px) for `background_color`. Default 0. */
|
|
970
|
+
background_border_radius?: number;
|
|
971
|
+
/**
|
|
972
|
+
* Padding (px) around the shrink-wrapped `background_color`, or `[x, y]`
|
|
973
|
+
* for separate horizontal / vertical padding. Default 0. A caption pill
|
|
974
|
+
* usually wants ~20–32 horizontal.
|
|
975
|
+
*/
|
|
976
|
+
background_padding?: number | [number, number];
|
|
977
|
+
/** Per-glyph drop shadow (CSS `text-shadow`), or an array. See TextShadow. */
|
|
978
|
+
text_shadow?: TextShadow | TextShadow[];
|
|
979
|
+
/** Color applied to the currently-active word. Defaults to fill_color. */
|
|
980
|
+
highlight_color?: string;
|
|
981
|
+
/** Background color applied to the currently-active word. */
|
|
982
|
+
highlight_background_color?: string;
|
|
983
|
+
}
|
|
984
|
+
export interface ParticlesElement extends BaseElement {
|
|
985
|
+
type: 'particles';
|
|
986
|
+
/** Particles per second (continuous mode). Default 60. */
|
|
987
|
+
rate?: number;
|
|
988
|
+
/** Lifetime per particle, in seconds. Default 1.5. */
|
|
989
|
+
lifetime?: number;
|
|
990
|
+
/** Initial speed in px/s (mean — actual = velocity × (1 ± 0.3·random)). Default 300. */
|
|
991
|
+
velocity?: number;
|
|
992
|
+
/** Spread cone in degrees. 0 = directional, 360 = omnidirectional. Default 360. */
|
|
993
|
+
spread?: number;
|
|
994
|
+
/** Emission direction in degrees. 0° = right, 90° = down, -90° = up. Default -90. */
|
|
995
|
+
direction?: number;
|
|
996
|
+
/** Gravity in px/s². Positive y = downward. Default 600. */
|
|
997
|
+
gravity?: number;
|
|
998
|
+
/** Particle color. Pass an array of hex strings for per-particle randomization. Default '#ffffff'. */
|
|
999
|
+
color?: string | string[];
|
|
1000
|
+
/** Particle size in pixels. Default 12. */
|
|
1001
|
+
size?: number;
|
|
1002
|
+
/** Random size variation in [0, 1]. 0 = uniform, 1 = anywhere in [0, size]. Default 0.4. */
|
|
1003
|
+
size_variation?: number;
|
|
1004
|
+
/** Particle shape. Default 'square'. */
|
|
1005
|
+
particle_shape?: 'square' | 'circle';
|
|
1006
|
+
/** Initial rotation speed in deg/s (sign randomized per particle). Default 360. */
|
|
1007
|
+
rotation_speed?: number;
|
|
1008
|
+
/** If true, emit `burst_count` particles instantly at element start. Default false. */
|
|
1009
|
+
burst?: boolean;
|
|
1010
|
+
/** Number of particles in burst (only used when burst=true). Default 80. */
|
|
1011
|
+
burst_count?: number;
|
|
1012
|
+
/** Fraction of lifetime [0..1] at which particles start fading out. Default 0.7. */
|
|
1013
|
+
fade_at?: number;
|
|
1014
|
+
/**
|
|
1015
|
+
* Depth velocity in px/s along the emitter plane's normal (+z toward
|
|
1016
|
+
* the viewer, §4.4), CKP/1.0. Per particle: vz = z_velocity +
|
|
1017
|
+
* (random − 0.5) × z_spread; depth = vz × age. Like the `z` field,
|
|
1018
|
+
* invisible without perspective in the chain; paint order is
|
|
1019
|
+
* unchanged (z never sorts, §4.4.3). Default 0.
|
|
1020
|
+
*/
|
|
1021
|
+
z_velocity?: number;
|
|
1022
|
+
/** Width of the uniform random vz range in px/s (see z_velocity). Default 0. */
|
|
1023
|
+
z_spread?: number;
|
|
1024
|
+
/**
|
|
1025
|
+
* Convergence mode. When set (non-empty), the particle simulation switches
|
|
1026
|
+
* off ballistic emission — instead each particle interpolates from a
|
|
1027
|
+
* random scattered start position toward one of these target points
|
|
1028
|
+
* (assigned round-robin by index) over its lifetime, producing the
|
|
1029
|
+
* "particles assemble into a logo" effect.
|
|
1030
|
+
*
|
|
1031
|
+
* Points are in canvas pixel coordinates. Typical use: pre-sample
|
|
1032
|
+
* positions along an SVG path with `SVGPathElement.getPointAtLength()`
|
|
1033
|
+
* and pair with `burst: true, burst_count: target_points.length`.
|
|
1034
|
+
*/
|
|
1035
|
+
target_points?: [number, number][];
|
|
1036
|
+
/** Easing applied to the convergence position. Default 'ease-out-quart'. */
|
|
1037
|
+
convergence_easing?: EasingFunction;
|
|
1038
|
+
/**
|
|
1039
|
+
* Radius of the random scatter region around the emitter point where
|
|
1040
|
+
* particles start. Default = max(canvas_width, canvas_height).
|
|
1041
|
+
*/
|
|
1042
|
+
scatter_radius?: number;
|
|
1043
|
+
}
|
|
1044
|
+
export interface PathGradient {
|
|
1045
|
+
/** Gradient id; reference with fill: "url(#id)" or stroke: "url(#id)". */
|
|
1046
|
+
id: string;
|
|
1047
|
+
type: 'linear';
|
|
1048
|
+
/** Endpoints in viewBox coordinates. */
|
|
1049
|
+
x1: number;
|
|
1050
|
+
y1: number;
|
|
1051
|
+
x2: number;
|
|
1052
|
+
y2: number;
|
|
1053
|
+
stops: GradientStop[];
|
|
1054
|
+
}
|
|
1055
|
+
export interface PathDef {
|
|
1056
|
+
/**
|
|
1057
|
+
* SVG path data ("M x y L x y ..."), or keyframes of d-strings for
|
|
1058
|
+
* PATH MORPHING (§5.6.2): when two keyframe values share an
|
|
1059
|
+
* identical command sequence (same letters, same argument counts,
|
|
1060
|
+
* no arc commands), their numeric arguments interpolate with the
|
|
1061
|
+
* destination keyframe's easing; incompatible pairs SNAP at the
|
|
1062
|
+
* destination keyframe's time.
|
|
1063
|
+
*/
|
|
1064
|
+
d: string | Keyframe[];
|
|
1065
|
+
/** Hex color, or "url(#gradient-id)" to reference a linear gradient. */
|
|
1066
|
+
fill?: string;
|
|
1067
|
+
/** Hex color, or "url(#gradient-id)" to reference a linear gradient. */
|
|
1068
|
+
stroke?: string;
|
|
1069
|
+
/** Stroke width in viewBox units. */
|
|
1070
|
+
stroke_width?: number;
|
|
1071
|
+
/**
|
|
1072
|
+
* Fraction of the stroke to draw, 0..1. Sugar for a trim window of
|
|
1073
|
+
* [0, progress] — equivalent to `trim_end` with `trim_start: 0`.
|
|
1074
|
+
* Ignored when any trim_* field is present. Animatable.
|
|
1075
|
+
*/
|
|
1076
|
+
stroke_progress?: number | Keyframe[] | Expr;
|
|
1077
|
+
/**
|
|
1078
|
+
* Trim window (§5.6.1): only the stroke between `trim_start` and
|
|
1079
|
+
* `trim_end` (fractions of the path's total length, 0..1) is drawn.
|
|
1080
|
+
* `trim_offset` rotates the window around the path (wrapping — 1 is
|
|
1081
|
+
* a full lap), which animated makes the classic traveling-dash
|
|
1082
|
+
* "snake". All three animatable. Defaults 0 / 1 / 0.
|
|
1083
|
+
*/
|
|
1084
|
+
trim_start?: number | Keyframe[] | Expr;
|
|
1085
|
+
trim_end?: number | Keyframe[] | Expr;
|
|
1086
|
+
trim_offset?: number | Keyframe[] | Expr;
|
|
1087
|
+
/**
|
|
1088
|
+
* Path data ("M x y L x y ...") that clips this path's drawing. Only
|
|
1089
|
+
* pixels inside the clip path are visible. Equivalent to SVG mask with
|
|
1090
|
+
* a solid black fill.
|
|
1091
|
+
*/
|
|
1092
|
+
clip_path?: string;
|
|
1093
|
+
/** Linecap style. Default "butt". */
|
|
1094
|
+
stroke_linecap?: 'butt' | 'round' | 'square';
|
|
1095
|
+
/** Linejoin style. Default "miter". */
|
|
1096
|
+
stroke_linejoin?: 'miter' | 'round' | 'bevel';
|
|
1097
|
+
/** Per-path opacity, applied to both fill and stroke. 0..1, default 1. */
|
|
1098
|
+
opacity?: number;
|
|
1099
|
+
}
|
|
1100
|
+
export type Element = VideoElement | ImageElement | TextElement | ShapeElement | AudioElement | GroupElement | CaptionElement | ParticlesElement;
|
|
1101
|
+
/**
|
|
1102
|
+
* The current Clipkit Protocol version. Bumped on backward-incompatible
|
|
1103
|
+
* changes to the Source schema. See PROTOCOL.md for the version policy.
|
|
1104
|
+
*/
|
|
1105
|
+
export declare const CLIPKIT_PROTOCOL_VERSION = "1.0";
|
|
1106
|
+
export interface FontFace {
|
|
1107
|
+
/** CSS font-family the runtime should register the face as. */
|
|
1108
|
+
family: string;
|
|
1109
|
+
/** CSS font-weight (e.g. 400, 700, "bold"). Defaults to "normal". */
|
|
1110
|
+
weight?: number | string;
|
|
1111
|
+
/** CSS font-style. Defaults to "normal". */
|
|
1112
|
+
style?: 'normal' | 'italic';
|
|
1113
|
+
/**
|
|
1114
|
+
* URL the runtime fetches to load the font. Can be absolute (http(s):),
|
|
1115
|
+
* relative (resolved against the document hosting the Source), or a
|
|
1116
|
+
* data: URI carrying the font bytes inline.
|
|
1117
|
+
*/
|
|
1118
|
+
src: string;
|
|
1119
|
+
/**
|
|
1120
|
+
* CSS unicode-range of the face (e.g. "U+0000-00FF, U+0131"). Needed
|
|
1121
|
+
* for subsetted webfonts, which ship one file per script under an
|
|
1122
|
+
* identical family/weight/style — without the range, every subset
|
|
1123
|
+
* competes for every codepoint and the winning file may not contain
|
|
1124
|
+
* the glyphs being rendered.
|
|
1125
|
+
*/
|
|
1126
|
+
unicode_range?: string;
|
|
1127
|
+
}
|
|
1128
|
+
/**
|
|
1129
|
+
* Source-level motion blur — exact sub-frame supersampling. The renderer
|
|
1130
|
+
* renders `samples` evenly spaced sub-frame times across a shutter window
|
|
1131
|
+
* centered on each output frame time and averages them (arithmetic mean
|
|
1132
|
+
* per 8-bit channel, single rounding). Deterministic: same Source → same
|
|
1133
|
+
* pixels.
|
|
1134
|
+
*
|
|
1135
|
+
* Sample times for the output frame at time t with frame rate f:
|
|
1136
|
+
* t_k = clamp(t + ((k + 0.5) / samples − 0.5) × shutter / f, 0, duration)
|
|
1137
|
+
*
|
|
1138
|
+
* Applies at export/render time. Interactive previews MAY render the
|
|
1139
|
+
* unblurred scene (single sample) for speed.
|
|
1140
|
+
*/
|
|
1141
|
+
export interface MotionBlur {
|
|
1142
|
+
/** Sub-frame samples per output frame. Integer 1–32; default 8. 1 disables blur. */
|
|
1143
|
+
samples?: number;
|
|
1144
|
+
/** Fraction of the frame interval the shutter is open, (0..1]. Default 0.5 (a 180° shutter). */
|
|
1145
|
+
shutter?: number;
|
|
1146
|
+
}
|
|
1147
|
+
/**
|
|
1148
|
+
* Source-level scene camera (CKP/1.0, §4.4). One camera for the whole
|
|
1149
|
+
* composition: a perspective lens (`perspective` + origin, CSS-perspective
|
|
1150
|
+
* semantics — smaller distance = stronger foreshortening) plus an optional
|
|
1151
|
+
* rigid pose (`x`/`y`/`z` position and `x_rotation`/`y_rotation`/
|
|
1152
|
+
* `z_rotation` Euler orientation) that moves the viewpoint through the
|
|
1153
|
+
* scene. The runtime applies `camera = P · V` at the root (§4.4.2). With
|
|
1154
|
+
* the pose at its defaults `V = I` and the camera reduces to the lens
|
|
1155
|
+
* bit-for-bit. Absent camera = identity = exact 2D rendering. All fields
|
|
1156
|
+
* animatable via Keyframe[].
|
|
1157
|
+
*
|
|
1158
|
+
* Elements' `x_rotation` / `y_rotation` render without a camera too
|
|
1159
|
+
* (affine foreshortening, no perspective); `z` offsets are only visible
|
|
1160
|
+
* under a camera.
|
|
1161
|
+
*/
|
|
1162
|
+
export interface Camera {
|
|
1163
|
+
/** Focal distance in px (CSS `perspective()`). Must be > 0. Animatable. */
|
|
1164
|
+
perspective: number | Keyframe[] | Expr;
|
|
1165
|
+
/** Projection origin; number (px) or length string. Default "50%" of width. */
|
|
1166
|
+
origin_x?: number | string;
|
|
1167
|
+
/** Projection origin; number (px) or length string. Default "50%" of height. */
|
|
1168
|
+
origin_y?: number | string;
|
|
1169
|
+
/** Eye position offset from the default eye, px, about the origin. +x right. Default 0. Animatable. */
|
|
1170
|
+
x?: number | Keyframe[] | Expr;
|
|
1171
|
+
/** Eye position offset, px. +y down. Default 0. Animatable. */
|
|
1172
|
+
y?: number | Keyframe[] | Expr;
|
|
1173
|
+
/** Eye position along the view axis, px. +z = eye toward the scene (dolly in). Default 0. Animatable. */
|
|
1174
|
+
z?: number | Keyframe[] | Expr;
|
|
1175
|
+
/** Eye pitch in degrees (Euler, applied Rz·Ry·Rx). Default 0. Animatable. */
|
|
1176
|
+
x_rotation?: number | Keyframe[] | Expr;
|
|
1177
|
+
/** Eye yaw in degrees. Default 0. Animatable. */
|
|
1178
|
+
y_rotation?: number | Keyframe[] | Expr;
|
|
1179
|
+
/** Eye roll in degrees. Default 0. Animatable. */
|
|
1180
|
+
z_rotation?: number | Keyframe[] | Expr;
|
|
1181
|
+
/**
|
|
1182
|
+
* Compositing order under this camera (§4.4.3). `'depth'` (default)
|
|
1183
|
+
* paints flat cards back-to-front by camera distance (2.5D occlusion).
|
|
1184
|
+
* `'paint'` forces fixed `layer` order even under the camera.
|
|
1185
|
+
*/
|
|
1186
|
+
sort?: 'depth' | 'paint';
|
|
1187
|
+
}
|
|
1188
|
+
/**
|
|
1189
|
+
* PBR material on an element (CKP/1.0, §4.8). The element's own rendered
|
|
1190
|
+
* pixels are the albedo; these fields control how it responds to the
|
|
1191
|
+
* scene `lights` and `environment`. All animatable. Absent ⇒ unlit.
|
|
1192
|
+
*/
|
|
1193
|
+
export interface Material {
|
|
1194
|
+
/** Surface roughness 0 (mirror/tight highlight) .. 1 (matte/broad). Default 0.5. */
|
|
1195
|
+
roughness?: number | Keyframe[] | Expr;
|
|
1196
|
+
/** Metalness 0 (dielectric, F0≈0.04) .. 1 (metal — albedo tints reflections). Default 0. */
|
|
1197
|
+
metalness?: number | Keyframe[] | Expr;
|
|
1198
|
+
/** Environment-reflection strength (art dial over the physical term). Default 1. */
|
|
1199
|
+
reflectivity?: number | Keyframe[] | Expr;
|
|
1200
|
+
/** Self-illumination 0..(>1): mixes the element toward its own unlit pixels. Default 0. */
|
|
1201
|
+
emissive?: number | Keyframe[] | Expr;
|
|
1202
|
+
/**
|
|
1203
|
+
* Tangent-space normal map URL (CKP/1.0 Phase 2, §4.8). RGB encodes a
|
|
1204
|
+
* per-texel surface normal (the usual 0.5-centered convention; flat =
|
|
1205
|
+
* #8080ff). Perturbs the face normal across the surface for bumps /
|
|
1206
|
+
* brushed detail, sampled in the element's UV space. Absent ⇒ flat
|
|
1207
|
+
* face normal.
|
|
1208
|
+
*/
|
|
1209
|
+
normal_map?: string;
|
|
1210
|
+
/**
|
|
1211
|
+
* Strength of `normal_map` perturbation. 0 = flat (ignore the map),
|
|
1212
|
+
* 1 = as authored, >1 exaggerates. Default 1. Animatable.
|
|
1213
|
+
*/
|
|
1214
|
+
normal_scale?: number | Keyframe[] | Expr;
|
|
1215
|
+
}
|
|
1216
|
+
/**
|
|
1217
|
+
* A scene light (CKP/1.0, §4.8). One of:
|
|
1218
|
+
* - ambient: uniform fill.
|
|
1219
|
+
* - directional: a parallel light whose direction is given by `azimuth`
|
|
1220
|
+
* (around the view axis, degrees) and `elevation` (above the screen
|
|
1221
|
+
* plane toward the viewer, degrees).
|
|
1222
|
+
*/
|
|
1223
|
+
export type Light = {
|
|
1224
|
+
type: 'ambient';
|
|
1225
|
+
color?: string;
|
|
1226
|
+
intensity?: number | Keyframe[] | Expr;
|
|
1227
|
+
} | {
|
|
1228
|
+
type: 'directional';
|
|
1229
|
+
/** Direction azimuth in degrees (0 = +x, CCW). Default 0. Animatable. */
|
|
1230
|
+
azimuth?: number | Keyframe[] | Expr;
|
|
1231
|
+
/** Direction elevation in degrees above the screen plane. Default 45. Animatable. */
|
|
1232
|
+
elevation?: number | Keyframe[] | Expr;
|
|
1233
|
+
color?: string;
|
|
1234
|
+
intensity?: number | Keyframe[] | Expr;
|
|
1235
|
+
};
|
|
1236
|
+
/**
|
|
1237
|
+
* The scene environment surfaces reflect (CKP/1.0, §4.8). Either a
|
|
1238
|
+
* gradient "sky" or an equirectangular image, sampled along the
|
|
1239
|
+
* reflection vector. Roughness blurs the reflection toward the
|
|
1240
|
+
* environment's average color (so both types share one IBL path).
|
|
1241
|
+
*/
|
|
1242
|
+
export type Environment = {
|
|
1243
|
+
type: 'gradient';
|
|
1244
|
+
/** Gradient stops; offset 0 = looking down, 1 = looking up. */
|
|
1245
|
+
stops: GradientStop[];
|
|
1246
|
+
} | {
|
|
1247
|
+
/**
|
|
1248
|
+
* Equirectangular (2:1 lat-long) environment image URL. Reflective
|
|
1249
|
+
* surfaces mirror it along the reflection vector — real photographic
|
|
1250
|
+
* reflections (Phase 3 IBL). Sharp at roughness 0, blurring toward
|
|
1251
|
+
* the image's average color as roughness rises.
|
|
1252
|
+
*/
|
|
1253
|
+
type: 'image';
|
|
1254
|
+
src: string;
|
|
1255
|
+
};
|
|
1256
|
+
export interface Source {
|
|
1257
|
+
/**
|
|
1258
|
+
* The Clipkit Protocol version this Source conforms to. SHOULD be
|
|
1259
|
+
* present on documents produced by tooling. Absence is interpreted as
|
|
1260
|
+
* "1.0" for backward compatibility. Runtimes MUST attempt to render
|
|
1261
|
+
* documents declaring a higher patch / minor version and SHOULD warn
|
|
1262
|
+
* about a higher major version. See PROTOCOL.md §11. The 3D transform
|
|
1263
|
+
* fields and `camera` require "1.1".
|
|
1264
|
+
*/
|
|
1265
|
+
clipkit_version?: string;
|
|
1266
|
+
output_format?: OutputFormat;
|
|
1267
|
+
width?: number;
|
|
1268
|
+
height?: number;
|
|
1269
|
+
duration?: number | 'auto';
|
|
1270
|
+
frame_rate?: number;
|
|
1271
|
+
background_color?: string;
|
|
1272
|
+
/**
|
|
1273
|
+
* Font faces the runtime must register before rendering. Each entry is
|
|
1274
|
+
* loaded via the FontFace API; the resulting face becomes available
|
|
1275
|
+
* under `family` at the given `weight`/`style`. Without this block,
|
|
1276
|
+
* the runtime depends on the host document to have registered the
|
|
1277
|
+
* fonts itself.
|
|
1278
|
+
*/
|
|
1279
|
+
fonts?: FontFace[];
|
|
1280
|
+
/**
|
|
1281
|
+
* Exact sub-frame supersampled motion blur, applied to the whole frame
|
|
1282
|
+
* at export/render time. See the MotionBlur type for the normative
|
|
1283
|
+
* sampling math. Previews may show the unblurred scene.
|
|
1284
|
+
*/
|
|
1285
|
+
motion_blur?: MotionBlur;
|
|
1286
|
+
/**
|
|
1287
|
+
* Scene perspective camera (CKP/1.0, §4.4). Absent = exact 2D
|
|
1288
|
+
* (identity projection, zero cost).
|
|
1289
|
+
*/
|
|
1290
|
+
camera?: Camera;
|
|
1291
|
+
/**
|
|
1292
|
+
* Scene lights (CKP/1.0, §4.8). Absent ⇒ unlit (today's render). Only
|
|
1293
|
+
* elements that carry a `material` are shaded by these.
|
|
1294
|
+
*/
|
|
1295
|
+
lights?: Light[];
|
|
1296
|
+
/**
|
|
1297
|
+
* The environment reflective materials sample (CKP/1.0, §4.8). A
|
|
1298
|
+
* gradient "sky" in Phase 1.
|
|
1299
|
+
*/
|
|
1300
|
+
environment?: Environment;
|
|
1301
|
+
/**
|
|
1302
|
+
* Scene bloom (CKP/1.0 Phase 2, §4.8) — a whole-frame post-process:
|
|
1303
|
+
* pixels brighter than `threshold` bleed light into their surroundings
|
|
1304
|
+
* (bright specular highlights, emissive surfaces, bright media). Opt-in;
|
|
1305
|
+
* absent ⇒ no bloom (byte-identical). The amount each region blooms is
|
|
1306
|
+
* driven by its own brightness — these are the global "lens" knobs.
|
|
1307
|
+
*/
|
|
1308
|
+
bloom?: Bloom;
|
|
1309
|
+
elements: Element[];
|
|
1310
|
+
}
|
|
1311
|
+
/** Scene bloom parameters (§4.8). All animatable. */
|
|
1312
|
+
export interface Bloom {
|
|
1313
|
+
/** Luma above which a pixel blooms, 0..1. Default 0.75. */
|
|
1314
|
+
threshold?: number | Keyframe[] | Expr;
|
|
1315
|
+
/** Soft knee width above the threshold, 0..1. Default 0.1. */
|
|
1316
|
+
knee?: number | Keyframe[] | Expr;
|
|
1317
|
+
/** Bloom add strength. Default 1. */
|
|
1318
|
+
intensity?: number | Keyframe[] | Expr;
|
|
1319
|
+
/** Blur spread (Gaussian σ) in canvas px. Default 24. */
|
|
1320
|
+
radius?: number | Keyframe[] | Expr;
|
|
1321
|
+
}
|
|
1322
|
+
export interface ParsedValue {
|
|
1323
|
+
value: number;
|
|
1324
|
+
unit: Unit;
|
|
1325
|
+
}
|
|
1326
|
+
//# sourceMappingURL=types.d.ts.map
|