@pixerate/flair 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/LICENSE +21 -0
- package/README.md +254 -2
- package/dist/catalog/index.d.ts +74 -0
- package/dist/catalog/index.js +47 -0
- package/dist/catalog/index.js.map +1 -0
- package/dist/chunk-36DTNSHU.js +160 -0
- package/dist/chunk-36DTNSHU.js.map +1 -0
- package/dist/chunk-3FAUZOGL.js +331 -0
- package/dist/chunk-3FAUZOGL.js.map +1 -0
- package/dist/chunk-CFCLT2XL.js +1 -0
- package/dist/chunk-CFCLT2XL.js.map +1 -0
- package/dist/chunk-EHDJ3CPJ.js +327 -0
- package/dist/chunk-EHDJ3CPJ.js.map +1 -0
- package/dist/chunk-G5FNZDTA.js +536 -0
- package/dist/chunk-G5FNZDTA.js.map +1 -0
- package/dist/chunk-HKXOHRCD.js +763 -0
- package/dist/chunk-HKXOHRCD.js.map +1 -0
- package/dist/chunk-J55UBNAT.js +164 -0
- package/dist/chunk-J55UBNAT.js.map +1 -0
- package/dist/chunk-JWZCPMFG.js +2074 -0
- package/dist/chunk-JWZCPMFG.js.map +1 -0
- package/dist/chunk-MWVTQFV5.js +1894 -0
- package/dist/chunk-MWVTQFV5.js.map +1 -0
- package/dist/chunk-UQQNZSYL.js +594 -0
- package/dist/chunk-UQQNZSYL.js.map +1 -0
- package/dist/chunk-WMZQCUFJ.js +73 -0
- package/dist/chunk-WMZQCUFJ.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +331 -0
- package/dist/cli.js.map +1 -0
- package/dist/clock-BhdXWH-n.d.ts +47 -0
- package/dist/controls-DdXMbovi.d.ts +97 -0
- package/dist/editor/index.d.ts +413 -0
- package/dist/editor/index.js +1009 -0
- package/dist/editor/index.js.map +1 -0
- package/dist/export-FEBPEEO7.js +22 -0
- package/dist/export-FEBPEEO7.js.map +1 -0
- package/dist/index.d.ts +1431 -0
- package/dist/index.js +1263 -0
- package/dist/index.js.map +1 -0
- package/dist/motion-D0TVv2CF.d.ts +148 -0
- package/dist/node.d.ts +24 -0
- package/dist/node.js +10 -0
- package/dist/node.js.map +1 -0
- package/dist/recorder-WJTWMEQN.js +10 -0
- package/dist/recorder-WJTWMEQN.js.map +1 -0
- package/dist/renderer-Oyynz-fs.d.ts +293 -0
- package/dist/types-CkKkavvB.d.ts +71 -0
- package/dist/vector/index.d.ts +83 -0
- package/dist/vector/index.js +39 -0
- package/dist/vector/index.js.map +1 -0
- package/package.json +93 -3
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { T as TextureSettings, a as ControlDef, C as ControlValue } from './controls-DdXMbovi.js';
|
|
2
|
+
|
|
3
|
+
/** Why an image control's URL could not be shown. */
|
|
4
|
+
declare class ImageLoadError extends Error {
|
|
5
|
+
readonly url: string;
|
|
6
|
+
constructor(url: string, cause?: unknown);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The long edge, in pixels, SVG images are rasterised at. WebGL2 guarantees
|
|
10
|
+
* textures this large on every device.
|
|
11
|
+
*/
|
|
12
|
+
declare const SVG_EDGE = 2048;
|
|
13
|
+
/** Whether `url` is an SVG: a `data:image/svg+xml` URL, or a path ending in `.svg`. */
|
|
14
|
+
declare function isSvgUrl(url: string): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* An SVG's markup with `width` and `height` set so its long edge is `edge`
|
|
17
|
+
* pixels, keeping its aspect ratio. An image decodes an SVG at its own size
|
|
18
|
+
* (often icon-sized, or 300 × 150 when it has none), so it would make a
|
|
19
|
+
* small, blurry texture; at this size it is rasterised crisply. A `viewBox`
|
|
20
|
+
* is added where missing, so the drawing scales with the new size rather
|
|
21
|
+
* than staying in the corner. Throws for markup that is not an SVG.
|
|
22
|
+
*/
|
|
23
|
+
declare function sizeSvg(markup: string, edge: number): string;
|
|
24
|
+
/**
|
|
25
|
+
* Loads and decodes an image for WebGL. Images from other origins are
|
|
26
|
+
* requested with CORS (`crossOrigin = "anonymous"`): WebGL refuses pixels a
|
|
27
|
+
* page is not allowed to read. SVGs (see {@link isSvgUrl}) are fetched, also
|
|
28
|
+
* with CORS, and sized to {@link SVG_EDGE} pixels on their long edge before
|
|
29
|
+
* they are decoded, so they stay sharp however small they were drawn.
|
|
30
|
+
*/
|
|
31
|
+
declare function loadImage(url: string): Promise<HTMLImageElement>;
|
|
32
|
+
/**
|
|
33
|
+
* Loads and decodes images ahead of time, for every WebGL context on the
|
|
34
|
+
* page: a texture cache that meets one of them afterwards (in a
|
|
35
|
+
* `ShaderRenderer`, `ShaderFrames` or thumbnail) uploads it at once, so even
|
|
36
|
+
* its first frame shows the image. Otherwise an image arrives a moment after
|
|
37
|
+
* the first frame, which is black where it goes. Use it before drawing frames
|
|
38
|
+
* that cannot wait, such as a video player asking a new `ShaderFrames` for
|
|
39
|
+
* frame _n_.
|
|
40
|
+
*
|
|
41
|
+
* Each URL loads once, however often it is preloaded. Rejects with the first
|
|
42
|
+
* {@link ImageLoadError}; the other images still load. Preloaded images stay
|
|
43
|
+
* in memory until {@link releaseImages}.
|
|
44
|
+
*/
|
|
45
|
+
declare function preloadImages(urls: Iterable<string>): Promise<void>;
|
|
46
|
+
/** Forgets preloaded images (all of them without `urls`). Textures already made from them stay. */
|
|
47
|
+
declare function releaseImages(urls?: Iterable<string>): void;
|
|
48
|
+
/** Something that hands `drawFrame` a texture for an image URL. */
|
|
49
|
+
interface TextureSource {
|
|
50
|
+
/** The texture for `url`: the image once loaded, a 1 × 1 opaque black placeholder until then. */
|
|
51
|
+
texture(url: string): WebGLTexture | null;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The textures of one WebGL context, by image URL. A URL starts loading the
|
|
55
|
+
* first time it is asked for; until it arrives the placeholder is drawn, and
|
|
56
|
+
* `onLoad` hears when it does (or fails) so the owner can redraw. An image
|
|
57
|
+
* already decoded by {@link preloadImages} is uploaded at once instead. Images are
|
|
58
|
+
* uploaded upright (`fragCoord / iResolution` samples them the right way up)
|
|
59
|
+
* with mipmaps.
|
|
60
|
+
*/
|
|
61
|
+
declare class TextureCache implements TextureSource {
|
|
62
|
+
private readonly gl;
|
|
63
|
+
private readonly entries;
|
|
64
|
+
private readonly onLoad;
|
|
65
|
+
private readonly load;
|
|
66
|
+
private placeholder;
|
|
67
|
+
private disposed;
|
|
68
|
+
constructor(gl: WebGL2RenderingContext, onLoad?: (url: string, error: ImageLoadError | null) => void, load?: (url: string) => Promise<TexImageSource>);
|
|
69
|
+
texture(url: string): WebGLTexture | null;
|
|
70
|
+
/** Starts loading `url` if it is new. */
|
|
71
|
+
request(url: string): void;
|
|
72
|
+
private entry;
|
|
73
|
+
/** The error for `url`, if it failed to load. */
|
|
74
|
+
error(url: string): ImageLoadError | null;
|
|
75
|
+
/**
|
|
76
|
+
* Settles once every one of `urls` has loaded or failed (starting any that
|
|
77
|
+
* are new). Rejects with the first {@link ImageLoadError}.
|
|
78
|
+
*/
|
|
79
|
+
ready(urls: Iterable<string>): Promise<void>;
|
|
80
|
+
/** Deletes the textures of every URL not in `urls`; a later request loads them again. */
|
|
81
|
+
retain(urls: Iterable<string>): void;
|
|
82
|
+
/** Deletes every texture; loads still in flight are dropped. */
|
|
83
|
+
dispose(): void;
|
|
84
|
+
private blank;
|
|
85
|
+
private upload;
|
|
86
|
+
}
|
|
87
|
+
/** Sets the bound `TEXTURE_2D`'s filter and wrap. */
|
|
88
|
+
declare function applyTextureSettings(gl: WebGL2RenderingContext, settings: TextureSettings): void;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Shaders are written Shadertoy-style: the source defines
|
|
92
|
+
* `void mainImage(out vec4 fragColor, in vec2 fragCoord)` and may use the
|
|
93
|
+
* built-in uniforms below. It is compiled as GLSL ES 3.00 (WebGL2) inside a
|
|
94
|
+
* small wrapper; `#line 1` keeps compiler line numbers matching the source.
|
|
95
|
+
*/
|
|
96
|
+
declare const BUILTIN_UNIFORMS: readonly [{
|
|
97
|
+
readonly name: "iResolution";
|
|
98
|
+
readonly type: "vec3";
|
|
99
|
+
readonly doc: "viewport size in pixels (z = 1)";
|
|
100
|
+
}, {
|
|
101
|
+
readonly name: "iTime";
|
|
102
|
+
readonly type: "float";
|
|
103
|
+
readonly doc: "seconds since the shader started";
|
|
104
|
+
}, {
|
|
105
|
+
readonly name: "iTimeDelta";
|
|
106
|
+
readonly type: "float";
|
|
107
|
+
readonly doc: "seconds since the previous frame";
|
|
108
|
+
}, {
|
|
109
|
+
readonly name: "iFrame";
|
|
110
|
+
readonly type: "int";
|
|
111
|
+
readonly doc: "frame number";
|
|
112
|
+
}, {
|
|
113
|
+
readonly name: "iMouse";
|
|
114
|
+
readonly type: "vec4";
|
|
115
|
+
readonly doc: "xy = pointer while pressed (pixels), zw = press position (negative once released)";
|
|
116
|
+
}];
|
|
117
|
+
/** A full-screen triangle from `gl_VertexID` alone: no buffers or attributes. */
|
|
118
|
+
declare const VERTEX_SOURCE = "#version 300 es\nvoid main() {\n vec2 p = vec2(float((gl_VertexID << 1) & 2), float(gl_VertexID & 2));\n gl_Position = vec4(p * 2.0 - 1.0, 0.0, 1.0);\n}\n";
|
|
119
|
+
/** One compiler message, mapped back to the user's source. */
|
|
120
|
+
interface CompileError {
|
|
121
|
+
/** 1-based line in the user's source (0 when the driver gave none, or it is outside the source). */
|
|
122
|
+
line: number;
|
|
123
|
+
message: string;
|
|
124
|
+
}
|
|
125
|
+
/** A linked program and the uniform locations `drawFrame` sets. */
|
|
126
|
+
interface CompiledShader {
|
|
127
|
+
program: WebGLProgram;
|
|
128
|
+
builtins: Record<string, WebGLUniformLocation | null>;
|
|
129
|
+
uniforms: Map<string, WebGLUniformLocation | null>;
|
|
130
|
+
}
|
|
131
|
+
type CompileResult = {
|
|
132
|
+
ok: true;
|
|
133
|
+
shader: CompiledShader;
|
|
134
|
+
} | {
|
|
135
|
+
ok: false;
|
|
136
|
+
errors: CompileError[];
|
|
137
|
+
};
|
|
138
|
+
/** Thrown by the APIs that cannot carry on without a program (`ShaderFrames`, `recordGif`). */
|
|
139
|
+
declare class ShaderCompileError extends Error {
|
|
140
|
+
readonly errors: CompileError[];
|
|
141
|
+
constructor(errors: CompileError[]);
|
|
142
|
+
}
|
|
143
|
+
/** "The shader does not compile (line 3): 'x' : undeclared identifier", from the first error. */
|
|
144
|
+
declare function formatCompileError(errors: CompileError[]): string;
|
|
145
|
+
/** The complete GLSL ES 3.00 fragment shader for a `mainImage` source. */
|
|
146
|
+
declare function wrapSource(source: string): string;
|
|
147
|
+
/** Turns a driver log ("ERROR: 0:12: 'foo' : undeclared identifier") into line-numbered errors. */
|
|
148
|
+
declare function parseCompileLog(log: string, lineCount: number): CompileError[];
|
|
149
|
+
/** Forgets cached GL objects. Call it after a context loss, before compiling on the restored context. */
|
|
150
|
+
declare function resetGlCaches(): void;
|
|
151
|
+
/**
|
|
152
|
+
* Compiles and links a `mainImage` source. Errors come back with lines in
|
|
153
|
+
* the user's source, never thrown. `controls` (from `parseControls`) says
|
|
154
|
+
* which uniform locations to look up.
|
|
155
|
+
*/
|
|
156
|
+
declare function compileShader(gl: WebGL2RenderingContext, source: string, controls: ControlDef[]): CompileResult;
|
|
157
|
+
/** What one frame shows: its size in pixels, its time and the pointer. */
|
|
158
|
+
interface FrameState {
|
|
159
|
+
width: number;
|
|
160
|
+
height: number;
|
|
161
|
+
/** `iTime`, in seconds. */
|
|
162
|
+
time: number;
|
|
163
|
+
/** `iTimeDelta`, in seconds. */
|
|
164
|
+
delta: number;
|
|
165
|
+
/** `iFrame`. */
|
|
166
|
+
frame: number;
|
|
167
|
+
/** `iMouse`, Shadertoy semantics. */
|
|
168
|
+
mouse: [number, number, number, number];
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Draws one frame of a compiled shader into the bound framebuffer, from (0, 0).
|
|
172
|
+
* Image controls are bound to texture units 0, 1, … in source order, with
|
|
173
|
+
* textures from `textures` (a {@link TextureCache} for the same context);
|
|
174
|
+
* without it they sample nothing.
|
|
175
|
+
*/
|
|
176
|
+
declare function drawFrame(gl: WebGL2RenderingContext, shader: CompiledShader, controls: ControlDef[], values: Record<string, ControlValue> | undefined, state: FrameState, textures?: TextureSource): void;
|
|
177
|
+
/**
|
|
178
|
+
* A WebGL2 context set up for full-screen fragment shaders: opaque, no depth,
|
|
179
|
+
* stencil or antialiasing. `preserveDrawingBuffer` keeps the last frame
|
|
180
|
+
* readable after the task that drew it (for captures). Null without WebGL2.
|
|
181
|
+
*/
|
|
182
|
+
declare function createContext(canvas: HTMLCanvasElement | OffscreenCanvas, preserveDrawingBuffer?: boolean): WebGL2RenderingContext | null;
|
|
183
|
+
|
|
184
|
+
/** Whether the latest source compiled, and if not, why. */
|
|
185
|
+
interface CompileStatus {
|
|
186
|
+
ok: boolean;
|
|
187
|
+
errors: CompileError[];
|
|
188
|
+
}
|
|
189
|
+
/** What `onStats` reports: on play, pause, seek and restart, and twice a second while running. */
|
|
190
|
+
interface RendererStats {
|
|
191
|
+
/** `iTime`, in seconds. */
|
|
192
|
+
time: number;
|
|
193
|
+
/** Frames drawn per second over the last half second (0 while paused). */
|
|
194
|
+
fps: number;
|
|
195
|
+
playing: boolean;
|
|
196
|
+
/** The drawing buffer's size in device pixels. */
|
|
197
|
+
width: number;
|
|
198
|
+
height: number;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Runs one shader on a canvas: the editor's live preview. A source that does
|
|
202
|
+
* not compile leaves the last working program on screen, so a typo never
|
|
203
|
+
* blanks the preview; the errors are reported instead.
|
|
204
|
+
*
|
|
205
|
+
* The renderer owns its canvas (added to `host`, removed on dispose): a
|
|
206
|
+
* canvas keeps its WebGL context for life, so reusing one after disposing
|
|
207
|
+
* (a remount, hot reload) would get the released, lost context back.
|
|
208
|
+
*/
|
|
209
|
+
declare class ShaderRenderer {
|
|
210
|
+
readonly canvas: HTMLCanvasElement;
|
|
211
|
+
private gl;
|
|
212
|
+
private shader;
|
|
213
|
+
private textures;
|
|
214
|
+
private controls;
|
|
215
|
+
private values;
|
|
216
|
+
private source;
|
|
217
|
+
private raf;
|
|
218
|
+
private lastNow;
|
|
219
|
+
private frame;
|
|
220
|
+
private fpsFrames;
|
|
221
|
+
private fpsSince;
|
|
222
|
+
private resizeObserver;
|
|
223
|
+
private mouse;
|
|
224
|
+
private disposed;
|
|
225
|
+
/** The latest source's status. */
|
|
226
|
+
status: CompileStatus;
|
|
227
|
+
/** `iTime`, in seconds. Use `seek` to change it. */
|
|
228
|
+
time: number;
|
|
229
|
+
/** Playback speed: 1 is real time. */
|
|
230
|
+
speed: number;
|
|
231
|
+
/** Device pixels per CSS pixel; lower renders faster. Use `setPixelRatio` to change it. */
|
|
232
|
+
pixelRatio: number;
|
|
233
|
+
playing: boolean;
|
|
234
|
+
fps: number;
|
|
235
|
+
onStats?: (stats: RendererStats) => void;
|
|
236
|
+
/** Called with `true` when the GL context is lost and `false` once it is restored and recompiled. */
|
|
237
|
+
onContextLost?: (lost: boolean) => void;
|
|
238
|
+
/** Called when an image control's URL cannot be loaded; the control shows black. */
|
|
239
|
+
onImageError?: (error: ImageLoadError) => void;
|
|
240
|
+
/** Creates a canvas in `host` (with `className`) and starts the animation loop. Size the canvas with CSS. */
|
|
241
|
+
constructor(host: HTMLElement, className?: string);
|
|
242
|
+
/** False when the browser has no WebGL2. */
|
|
243
|
+
get supported(): boolean;
|
|
244
|
+
/** Compiles a new source; returns its status. Keeps the previous program when it fails. */
|
|
245
|
+
setSource(source: string): CompileStatus;
|
|
246
|
+
/**
|
|
247
|
+
* Sets control values (see `controlValue`); a paused preview redraws.
|
|
248
|
+
* Images load in the background and show once they arrive: await
|
|
249
|
+
* `ready()` before a `capture` that needs them.
|
|
250
|
+
*/
|
|
251
|
+
setValues(values: Record<string, ControlValue> | undefined): void;
|
|
252
|
+
/**
|
|
253
|
+
* Settles once the images the current controls show have loaded. Rejects
|
|
254
|
+
* with an {@link ImageLoadError} when one cannot be (it shows black).
|
|
255
|
+
*/
|
|
256
|
+
ready(): Promise<void>;
|
|
257
|
+
play(): void;
|
|
258
|
+
pause(): void;
|
|
259
|
+
/** Back to `iTime` 0 and frame 0. */
|
|
260
|
+
restart(): void;
|
|
261
|
+
/** Jumps to `time` seconds (not below 0) and draws it. */
|
|
262
|
+
seek(time: number): void;
|
|
263
|
+
setPixelRatio(ratio: number): void;
|
|
264
|
+
/**
|
|
265
|
+
* Captures the current frame (optionally at another time) as a data URL
|
|
266
|
+
* (JPEG unless `type` says PNG), at most `maxEdge` pixels on the long side
|
|
267
|
+
* (default 1024). Playback time is left as it was. Null when nothing has
|
|
268
|
+
* compiled yet.
|
|
269
|
+
*/
|
|
270
|
+
capture(options?: {
|
|
271
|
+
time?: number;
|
|
272
|
+
maxEdge?: number;
|
|
273
|
+
type?: "image/jpeg" | "image/png";
|
|
274
|
+
}): string | null;
|
|
275
|
+
/** Stops the loop, releases the context and removes the canvas. The renderer cannot be used again. */
|
|
276
|
+
dispose(): void;
|
|
277
|
+
private resize;
|
|
278
|
+
private render;
|
|
279
|
+
private textureCache;
|
|
280
|
+
/** Starts loading the images now shown, and frees the ones no longer shown. */
|
|
281
|
+
private syncTextures;
|
|
282
|
+
private tick;
|
|
283
|
+
private emit;
|
|
284
|
+
/** Pointer position in shader pixels (origin bottom-left, like gl_FragCoord). */
|
|
285
|
+
private toPixels;
|
|
286
|
+
private onPointerDown;
|
|
287
|
+
private onPointerMove;
|
|
288
|
+
private onPointerUp;
|
|
289
|
+
private onLost;
|
|
290
|
+
private onRestored;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export { BUILTIN_UNIFORMS as B, type CompileError as C, type FrameState as F, ImageLoadError as I, type RendererStats as R, SVG_EDGE as S, TextureCache as T, VERTEX_SOURCE as V, type CompileStatus as a, type CompileResult as b, type CompiledShader as c, ShaderCompileError as d, ShaderRenderer as e, type TextureSource as f, applyTextureSettings as g, compileShader as h, createContext as i, drawFrame as j, formatCompileError as k, isSvgUrl as l, loadImage as m, preloadImages as n, resetGlCaches as o, parseCompileLog as p, releaseImages as r, sizeSvg as s, wrapSource as w };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { C as ControlValue, a as ControlDef } from './controls-DdXMbovi.js';
|
|
2
|
+
import { S as SvgMotion } from './motion-D0TVv2CF.js';
|
|
3
|
+
|
|
4
|
+
/** What an effect is for, used to group the catalog. */
|
|
5
|
+
type EffectCategory = "gradient" | "organic" | "pattern" | "light" | "space" | "retro" | "image" | "transition" | "loader" | "data" | "icon";
|
|
6
|
+
/** Every category, in the order the catalog lists them. */
|
|
7
|
+
declare const EFFECT_CATEGORIES: readonly EffectCategory[];
|
|
8
|
+
/** Named control values: a look an effect can be switched to. */
|
|
9
|
+
interface EffectPreset {
|
|
10
|
+
name: string;
|
|
11
|
+
values: Record<string, ControlValue>;
|
|
12
|
+
}
|
|
13
|
+
interface EffectBase {
|
|
14
|
+
/** Stable id, kebab-case: `aurora`, `image-glitch`. */
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
/** One sentence: what it looks like. */
|
|
18
|
+
description: string;
|
|
19
|
+
category: EffectCategory;
|
|
20
|
+
tags: readonly string[];
|
|
21
|
+
presets?: readonly EffectPreset[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A WebGL2 fragment shader (Shadertoy-style `mainImage`). Its controls are the
|
|
25
|
+
* `// @control` uniforms in `source`; run it with `ShaderRenderer`,
|
|
26
|
+
* `ShaderFrames`, `ThumbnailPool`, `recordGif` or `standaloneHtml`.
|
|
27
|
+
*/
|
|
28
|
+
interface ShaderEffect extends EffectBase {
|
|
29
|
+
kind: "shader";
|
|
30
|
+
source: string;
|
|
31
|
+
/** Seconds after which it repeats exactly, when it loops seamlessly. */
|
|
32
|
+
loop?: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A control of a vector effect. The same shape as a shader's controls (see
|
|
36
|
+
* `ControlDef`) less what only sources have; `vec3` colours are written into
|
|
37
|
+
* the picture as `#rrggbb`.
|
|
38
|
+
*/
|
|
39
|
+
type VectorControl = Pick<ControlDef, "name" | "type" | "default"> & Partial<Pick<ControlDef, "label" | "color" | "min" | "max" | "step">>;
|
|
40
|
+
/**
|
|
41
|
+
* An animated SVG picture (see `SvgMotion`). `{{name}}` in the motion is
|
|
42
|
+
* replaced by the control's value (see {@link renderVectorEffect}); run the
|
|
43
|
+
* result with `SvgPlayer`.
|
|
44
|
+
*/
|
|
45
|
+
interface VectorEffect extends EffectBase {
|
|
46
|
+
kind: "vector";
|
|
47
|
+
motion: SvgMotion;
|
|
48
|
+
controls: readonly VectorControl[];
|
|
49
|
+
/**
|
|
50
|
+
* More placeholders worked out from the control values (a bar's height
|
|
51
|
+
* from its value, say), filled in after the controls.
|
|
52
|
+
*/
|
|
53
|
+
derived?: (values: Record<string, ControlValue>) => Record<string, string | number>;
|
|
54
|
+
/** Ms to rest on the last frame before it loops (default 600). */
|
|
55
|
+
hold?: number;
|
|
56
|
+
}
|
|
57
|
+
type EffectDefinition = ShaderEffect | VectorEffect;
|
|
58
|
+
/** A vector control as a full `ControlDef`, so editors treat both kinds of effect alike. */
|
|
59
|
+
declare function vectorControlDef(control: VectorControl, line?: number): ControlDef;
|
|
60
|
+
/**
|
|
61
|
+
* A vector effect's motion with its controls filled in: `"{{name}}"` (a
|
|
62
|
+
* whole JSON string) becomes the value itself, so numbers stay numbers, and
|
|
63
|
+
* `{{name}}` inside a string becomes its text. Missing values use defaults.
|
|
64
|
+
*/
|
|
65
|
+
declare function renderVectorEffect(effect: Pick<VectorEffect, "motion" | "controls" | "derived">, values?: Record<string, ControlValue>): SvgMotion;
|
|
66
|
+
/** A colour control for vector effects. */
|
|
67
|
+
declare function colorControl(name: string, hex: string, label?: string): VectorControl;
|
|
68
|
+
/** A number control for vector effects. */
|
|
69
|
+
declare function numberControl(name: string, value: number, min: number, max: number, label?: string, step?: number): VectorControl;
|
|
70
|
+
|
|
71
|
+
export { type EffectDefinition as E, type ShaderEffect as S, type VectorControl as V, type EffectCategory as a, EFFECT_CATEGORIES as b, type EffectPreset as c, type VectorEffect as d, colorControl as e, numberControl as n, renderVectorEffect as r, vectorControlDef as v };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { S as SvgMotion } from '../motion-D0TVv2CF.js';
|
|
2
|
+
export { D as DataKey, E as EASES, a as EaseName, b as STEP_MS, c as SVG_PICTURE, d as SvgAnimation, e as SvgBox, f as SvgElementFrame, g as defaultDataKey, l as lerpAttr, h as lerpData, s as stepData, i as stepProgress, j as stepStart, k as svgFrame, m as svgMotionIssues, n as svgOpeningTag } from '../motion-D0TVv2CF.js';
|
|
3
|
+
import { C as Clock } from '../clock-BhdXWH-n.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Drawing animated SVG pictures (see `SvgMotion`) in the DOM: a sanitising
|
|
7
|
+
* parser, a view that applies frames, and a player that runs on a `Clock`.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The `<svg>` in `markup`, parsed and made safe to show: no scripts, event
|
|
12
|
+
* handlers, `<foreignObject>` or links outside itself. Undefined when it is
|
|
13
|
+
* not an SVG.
|
|
14
|
+
*/
|
|
15
|
+
declare function parseSvg(markup: string): SVGSVGElement | undefined;
|
|
16
|
+
interface SvgViewOptions {
|
|
17
|
+
/** Called with the id of the innermost element with an id that is clicked. */
|
|
18
|
+
onPick?: (id: string) => void;
|
|
19
|
+
}
|
|
20
|
+
/** An {@link SvgMotion} drawn into an element; call `draw` with a time to show it then. */
|
|
21
|
+
interface SvgView {
|
|
22
|
+
/** A `div` filled by the picture; put it anywhere. */
|
|
23
|
+
readonly element: HTMLDivElement;
|
|
24
|
+
/** Shows the picture at `timeMs`, with steps starting at `steps` (ms). */
|
|
25
|
+
draw(timeMs: number, steps?: readonly number[]): void;
|
|
26
|
+
/** An image of the picture as drawn now. */
|
|
27
|
+
capture(pixels: {
|
|
28
|
+
width: number;
|
|
29
|
+
height: number;
|
|
30
|
+
}): Promise<HTMLCanvasElement | undefined>;
|
|
31
|
+
}
|
|
32
|
+
/** Shows an {@link SvgMotion} as a live view; with `onPick`, clicks report the id of the element clicked. */
|
|
33
|
+
declare function svgView(motion: SvgMotion, options?: SvgViewOptions): SvgView;
|
|
34
|
+
/** How long an {@link SvgMotion} runs: its last change's end, in ms (at least 1). */
|
|
35
|
+
declare function svgDuration(motion: SvgMotion, steps?: readonly number[]): number;
|
|
36
|
+
interface SvgPlayerOptions extends SvgViewOptions {
|
|
37
|
+
/** Time source (default: animation frames). Pass a `ManualClock` to step frames yourself. */
|
|
38
|
+
clock?: Clock;
|
|
39
|
+
/** Start playing at once (default `true`). */
|
|
40
|
+
autoplay?: boolean;
|
|
41
|
+
/** Start again at the end (default `true`). */
|
|
42
|
+
loop?: boolean;
|
|
43
|
+
/** Loop length in ms (default: the picture's own, see {@link svgDuration}, plus `hold`). */
|
|
44
|
+
duration?: number;
|
|
45
|
+
/** Ms to rest on the last frame before looping (default 600). */
|
|
46
|
+
hold?: number;
|
|
47
|
+
/** Playback speed (default 1). */
|
|
48
|
+
speed?: number;
|
|
49
|
+
/** Step start times in ms, for pictures that change on steps (default none). */
|
|
50
|
+
steps?: readonly number[];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Plays an {@link SvgMotion} inside `container`: loops by default, and can be
|
|
54
|
+
* paused, sought and sped up. Dispose it to stop and remove the picture.
|
|
55
|
+
*/
|
|
56
|
+
declare class SvgPlayer {
|
|
57
|
+
private readonly container;
|
|
58
|
+
readonly view: SvgView;
|
|
59
|
+
private readonly clock;
|
|
60
|
+
private readonly steps;
|
|
61
|
+
private readonly loop;
|
|
62
|
+
private readonly length;
|
|
63
|
+
private speed;
|
|
64
|
+
private time;
|
|
65
|
+
private last;
|
|
66
|
+
private playing;
|
|
67
|
+
private disposed;
|
|
68
|
+
constructor(container: HTMLElement, motion: SvgMotion, options?: SvgPlayerOptions);
|
|
69
|
+
/** The loop length in ms. */
|
|
70
|
+
get duration(): number;
|
|
71
|
+
/** The time shown, in ms. */
|
|
72
|
+
get currentTime(): number;
|
|
73
|
+
get isPlaying(): boolean;
|
|
74
|
+
play(): void;
|
|
75
|
+
pause(): void;
|
|
76
|
+
/** Shows the picture at `ms` (wrapped into the loop when looping). */
|
|
77
|
+
seek(ms: number): void;
|
|
78
|
+
setSpeed(speed: number): void;
|
|
79
|
+
dispose(): void;
|
|
80
|
+
private run;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export { SvgMotion, SvgPlayer, type SvgPlayerOptions, type SvgView, type SvgViewOptions, parseSvg, svgDuration, svgView };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import "../chunk-CFCLT2XL.js";
|
|
2
|
+
import {
|
|
3
|
+
EASES,
|
|
4
|
+
STEP_MS,
|
|
5
|
+
SVG_PICTURE,
|
|
6
|
+
SvgPlayer,
|
|
7
|
+
defaultDataKey,
|
|
8
|
+
lerpAttr,
|
|
9
|
+
lerpData,
|
|
10
|
+
parseSvg,
|
|
11
|
+
stepData,
|
|
12
|
+
stepProgress,
|
|
13
|
+
stepStart,
|
|
14
|
+
svgDuration,
|
|
15
|
+
svgFrame,
|
|
16
|
+
svgMotionIssues,
|
|
17
|
+
svgOpeningTag,
|
|
18
|
+
svgView
|
|
19
|
+
} from "../chunk-G5FNZDTA.js";
|
|
20
|
+
import "../chunk-WMZQCUFJ.js";
|
|
21
|
+
export {
|
|
22
|
+
EASES,
|
|
23
|
+
STEP_MS,
|
|
24
|
+
SVG_PICTURE,
|
|
25
|
+
SvgPlayer,
|
|
26
|
+
defaultDataKey,
|
|
27
|
+
lerpAttr,
|
|
28
|
+
lerpData,
|
|
29
|
+
parseSvg,
|
|
30
|
+
stepData,
|
|
31
|
+
stepProgress,
|
|
32
|
+
stepStart,
|
|
33
|
+
svgDuration,
|
|
34
|
+
svgFrame,
|
|
35
|
+
svgMotionIssues,
|
|
36
|
+
svgOpeningTag,
|
|
37
|
+
svgView
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,96 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixerate/flair",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Web visual effects and motion graphics: WebGL2 shader effects, animated vector effects, a catalog of ready-made effects, and a UI-agnostic, agent-ready effect editor.",
|
|
5
|
+
"author": "Pixerate",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/Pixerate/flair.git"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://pixerate.github.io/flair/",
|
|
12
|
+
"bugs": "https://github.com/Pixerate/flair/issues",
|
|
13
|
+
"type": "module",
|
|
14
|
+
"sideEffects": false,
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md",
|
|
18
|
+
"LICENSE",
|
|
19
|
+
"CHANGELOG.md"
|
|
20
|
+
],
|
|
21
|
+
"main": "./dist/index.js",
|
|
22
|
+
"module": "./dist/index.js",
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"import": "./dist/index.js"
|
|
28
|
+
},
|
|
29
|
+
"./catalog": {
|
|
30
|
+
"types": "./dist/catalog/index.d.ts",
|
|
31
|
+
"import": "./dist/catalog/index.js"
|
|
32
|
+
},
|
|
33
|
+
"./editor": {
|
|
34
|
+
"types": "./dist/editor/index.d.ts",
|
|
35
|
+
"import": "./dist/editor/index.js"
|
|
36
|
+
},
|
|
37
|
+
"./vector": {
|
|
38
|
+
"types": "./dist/vector/index.d.ts",
|
|
39
|
+
"import": "./dist/vector/index.js"
|
|
40
|
+
},
|
|
41
|
+
"./node": {
|
|
42
|
+
"types": "./dist/node.d.ts",
|
|
43
|
+
"import": "./dist/node.js"
|
|
44
|
+
},
|
|
45
|
+
"./package.json": "./package.json"
|
|
46
|
+
},
|
|
47
|
+
"bin": {
|
|
48
|
+
"flair": "dist/cli.js"
|
|
49
|
+
},
|
|
50
|
+
"keywords": [
|
|
51
|
+
"webgl2",
|
|
52
|
+
"shaders",
|
|
53
|
+
"shadertoy",
|
|
54
|
+
"motion-graphics",
|
|
55
|
+
"animation",
|
|
56
|
+
"svg",
|
|
57
|
+
"effects",
|
|
58
|
+
"generative",
|
|
59
|
+
"editor",
|
|
60
|
+
"ai-agents"
|
|
61
|
+
],
|
|
62
|
+
"dependencies": {
|
|
63
|
+
"commander": "^12.0.0",
|
|
64
|
+
"gifenc": "^1.0.3"
|
|
65
|
+
},
|
|
66
|
+
"peerDependencies": {
|
|
67
|
+
"@pixerate/editor": ">=0.27.0 <1"
|
|
68
|
+
},
|
|
69
|
+
"peerDependenciesMeta": {
|
|
70
|
+
"@pixerate/editor": {
|
|
71
|
+
"optional": true
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
"devDependencies": {
|
|
75
|
+
"@changesets/cli": "^2.27.12",
|
|
76
|
+
"@pixerate/editor": "^0.27.0",
|
|
77
|
+
"@types/node": "^24.19.2",
|
|
78
|
+
"jsdom": "^30.1.3",
|
|
79
|
+
"tsup": "^8.5",
|
|
80
|
+
"typescript": "^5.9",
|
|
81
|
+
"vitest": "^4.1.11"
|
|
82
|
+
},
|
|
83
|
+
"engines": {
|
|
84
|
+
"node": ">=20"
|
|
85
|
+
},
|
|
86
|
+
"scripts": {
|
|
87
|
+
"build": "tsup",
|
|
88
|
+
"dev": "pnpm --filter demo dev",
|
|
89
|
+
"test": "vitest run",
|
|
90
|
+
"test:watch": "vitest",
|
|
91
|
+
"typecheck": "tsc --noEmit && pnpm --filter demo typecheck",
|
|
92
|
+
"changeset": "changeset",
|
|
93
|
+
"version-packages": "changeset version",
|
|
94
|
+
"release": "changeset publish"
|
|
95
|
+
}
|
|
6
96
|
}
|