@pixerate/flair 0.24.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/README.md +1 -0
- package/dist/catalog/index.js +2 -2
- package/dist/{chunk-WAMA45G3.js → chunk-5USSDEQL.js} +77 -21
- package/dist/chunk-5USSDEQL.js.map +1 -0
- package/dist/{chunk-GTIAOYOK.js → chunk-74ZLCZOG.js} +13 -10
- package/dist/chunk-74ZLCZOG.js.map +1 -0
- package/dist/{chunk-NGKNI3QX.js → chunk-CK6EV37I.js} +19 -495
- package/dist/chunk-CK6EV37I.js.map +1 -0
- package/dist/chunk-DBTLCXKY.js +332 -0
- package/dist/chunk-DBTLCXKY.js.map +1 -0
- package/dist/chunk-G2B5L234.js +414 -0
- package/dist/chunk-G2B5L234.js.map +1 -0
- package/dist/{chunk-VP6IEWIK.js → chunk-H6L67KHI.js} +1 -1
- package/dist/chunk-H6VDFBIO.js +498 -0
- package/dist/chunk-H6VDFBIO.js.map +1 -0
- package/dist/{chunk-OQ4EWZ3B.js → chunk-HVXWNGTW.js} +83 -6
- package/dist/{chunk-OQ4EWZ3B.js.map → chunk-HVXWNGTW.js.map} +1 -1
- package/dist/chunk-JL6TI6II.js +724 -0
- package/dist/chunk-JL6TI6II.js.map +1 -0
- package/dist/{chunk-OHW7UG6D.js → chunk-ORAFCHX3.js} +26 -2
- package/dist/{chunk-OHW7UG6D.js.map → chunk-ORAFCHX3.js.map} +1 -1
- package/dist/{chunk-ARKC7LDW.js → chunk-RDU63CDO.js} +2 -331
- package/dist/chunk-RDU63CDO.js.map +1 -0
- package/dist/{chunk-LVPIIWPP.js → chunk-STKEKXCK.js} +18 -8
- package/dist/chunk-STKEKXCK.js.map +1 -0
- package/dist/chunk-UCZ43ARE.js +902 -0
- package/dist/chunk-UCZ43ARE.js.map +1 -0
- package/dist/chunk-YBGRXVAE.js +407 -0
- package/dist/chunk-YBGRXVAE.js.map +1 -0
- package/dist/cli.js +74 -11
- package/dist/cli.js.map +1 -1
- package/dist/editor/index.d.ts +1 -1
- package/dist/editor/index.js +14 -12
- package/dist/editor/index.js.map +1 -1
- package/dist/effect-GGH3OSOT.js +47 -0
- package/dist/embed/index.d.ts +215 -0
- package/dist/embed/index.js +21 -0
- package/dist/{export-DH2HMACO.js → export-QVW474KM.js} +3 -3
- package/dist/export-QVW474KM.js.map +1 -0
- package/dist/frames-VEcqa40g.d.ts +161 -0
- package/dist/index.d.ts +47 -164
- package/dist/index.js +102 -80
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +167 -7
- package/dist/node.js +25 -3
- package/dist/react/index.d.ts +33 -2
- package/dist/react/index.js +54 -9
- package/dist/react/index.js.map +1 -1
- package/dist/recorder-CDPPTJMG.js +31 -0
- package/dist/recorder-CDPPTJMG.js.map +1 -0
- package/dist/{renderer-C2P1qGzP.d.ts → renderer-teaa98RE.d.ts} +1 -1
- package/dist/svelte/index.d.ts +33 -4
- package/dist/svelte/index.js +51 -9
- package/dist/svelte/index.js.map +1 -1
- package/dist/vector/index.d.ts +52 -1
- package/dist/vector/index.js +8 -4
- package/package.json +1 -1
- package/dist/chunk-ARKC7LDW.js.map +0 -1
- package/dist/chunk-GTIAOYOK.js.map +0 -1
- package/dist/chunk-LVPIIWPP.js.map +0 -1
- package/dist/chunk-NGKNI3QX.js.map +0 -1
- package/dist/chunk-UP6QQVRS.js +0 -331
- package/dist/chunk-UP6QQVRS.js.map +0 -1
- package/dist/chunk-WAMA45G3.js.map +0 -1
- package/dist/recorder-HKFFHQES.js +0 -10
- /package/dist/{chunk-VP6IEWIK.js.map → chunk-H6L67KHI.js.map} +0 -0
- /package/dist/{export-DH2HMACO.js.map → effect-GGH3OSOT.js.map} +0 -0
- /package/dist/{recorder-HKFFHQES.js.map → embed/index.js.map} +0 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { C as ControlValue } from '../controls-Ec6P0Vpy.js';
|
|
2
|
+
import { b as SvgPlayer } from '../svg-BhRboN9q.js';
|
|
3
|
+
import { E as EffectDefinition } from '../types-DUOMxZaq.js';
|
|
4
|
+
import { L as LiveSource, S as ShaderRenderer } from '../renderer-teaa98RE.js';
|
|
5
|
+
import { R as RenderOptions } from '../frames-VEcqa40g.js';
|
|
6
|
+
|
|
7
|
+
/** What {@link recordEffect} makes: a video (`mp4`, `webm`), an animated `gif`, or `png` frames in a ZIP. */
|
|
8
|
+
type RecordFormat = "mp4" | "webm" | "gif" | "png";
|
|
9
|
+
/** The pointer for one frame of a shader: `iPointer`, `iMouse`, and clicks and trail so far (times in seconds). */
|
|
10
|
+
type RecordPointer = Pick<RenderOptions, "pointer" | "mouse" | "clicks" | "trail">;
|
|
11
|
+
interface RecordOptions {
|
|
12
|
+
/** What to apply the effect to (see {@link EffectSubject}); several fill several controls in order. */
|
|
13
|
+
subject?: EffectSubject | readonly EffectSubject[];
|
|
14
|
+
/** A preset by name, then these values, over the effect's defaults. */
|
|
15
|
+
preset?: string;
|
|
16
|
+
values?: Record<string, ControlValue>;
|
|
17
|
+
/**
|
|
18
|
+
* The file to make (default `mp4` where the browser encodes H.264, else
|
|
19
|
+
* `webm`; `webm` when `alpha` is on).
|
|
20
|
+
*/
|
|
21
|
+
format?: RecordFormat;
|
|
22
|
+
/** Pixels (default 1280 × 720). Videos round them up to even numbers, as their encoders need. */
|
|
23
|
+
width?: number;
|
|
24
|
+
height?: number;
|
|
25
|
+
/** Frames per second (default 30). GIF delays are whole hundredths of a second, so 10, 20, 25 and 50 play back exactly there. */
|
|
26
|
+
fps?: number;
|
|
27
|
+
/**
|
|
28
|
+
* Seconds to record (default: a shader's `loop`, or a vector effect's
|
|
29
|
+
* picture plus its `hold`, else 4).
|
|
30
|
+
*/
|
|
31
|
+
duration?: number;
|
|
32
|
+
/** The time of the first frame, in seconds (default 0). */
|
|
33
|
+
start?: number;
|
|
34
|
+
/** Bits per second for `mp4` and `webm` (default `width × height × fps × 0.15`). */
|
|
35
|
+
bitrate?: number;
|
|
36
|
+
/**
|
|
37
|
+
* Keep transparency (default: the effect's `transparent`): `webm` (VP9
|
|
38
|
+
* or VP8 with an alpha channel, which Chrome, Edge and Firefox play),
|
|
39
|
+
* `png`, and `gif` (one see-through colour). `mp4` cannot, so it lays the
|
|
40
|
+
* picture over `background` unless `alpha: true` was asked for. Without
|
|
41
|
+
* it, transparent pixels are laid over `background`.
|
|
42
|
+
*/
|
|
43
|
+
alpha?: boolean;
|
|
44
|
+
/** A CSS colour under the picture when `alpha` is off (default black for shaders, white for vector effects). */
|
|
45
|
+
background?: string;
|
|
46
|
+
/**
|
|
47
|
+
* The pointer, for shaders that answer it: the same every frame, or a
|
|
48
|
+
* function of the frame's time in seconds. Without it, interactive
|
|
49
|
+
* effects play their idle demos, as on a page nobody has touched.
|
|
50
|
+
*
|
|
51
|
+
* ```ts
|
|
52
|
+
* pointer: { clicks: [{ x: 640, y: 360, time: 0.5 }] }
|
|
53
|
+
* pointer: (t) => ({ pointer: [640 + 200 * Math.sin(t), 360, 1, 0] })
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
pointer?: RecordPointer | ((time: number) => RecordPointer);
|
|
57
|
+
/** A vector effect's step start times in ms, for pictures that change on steps (default none). */
|
|
58
|
+
steps?: readonly number[];
|
|
59
|
+
/**
|
|
60
|
+
* Called before each frame is drawn, with its time in seconds: draw a
|
|
61
|
+
* canvas subject for that time here. (A `<video>` subject is paused and
|
|
62
|
+
* sought to each frame's time for you.)
|
|
63
|
+
*/
|
|
64
|
+
beforeFrame?: (time: number, index: number) => void | Promise<void>;
|
|
65
|
+
/** Called after each frame with the share done, 0–1. */
|
|
66
|
+
onProgress?: (fraction: number) => void;
|
|
67
|
+
/** Aborting rejects with an `AbortError` `DOMException`. */
|
|
68
|
+
signal?: AbortSignal;
|
|
69
|
+
}
|
|
70
|
+
/** What a recording will be, worked out from the options before any frame is drawn (see {@link recordingPlan}). */
|
|
71
|
+
interface RecordingPlan {
|
|
72
|
+
effect: EffectDefinition;
|
|
73
|
+
format: RecordFormat;
|
|
74
|
+
width: number;
|
|
75
|
+
height: number;
|
|
76
|
+
fps: number;
|
|
77
|
+
duration: number;
|
|
78
|
+
start: number;
|
|
79
|
+
frames: number;
|
|
80
|
+
alpha: boolean;
|
|
81
|
+
/** For `mp4` and `webm`: the encoder's settings. */
|
|
82
|
+
encoder?: VideoEncoderConfig;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* What {@link recordEffect} would make of these options, without drawing a
|
|
86
|
+
* frame: the format (after falling back where the browser cannot encode
|
|
87
|
+
* one), size, length, frame count, whether it keeps transparency, and the
|
|
88
|
+
* encoder settings. Rejects with a sentence when the effect is unknown, an
|
|
89
|
+
* option is out of range, or the browser cannot make the format asked for.
|
|
90
|
+
*/
|
|
91
|
+
declare function recordingPlan(effect: EffectDefinition | string, options?: RecordOptions): Promise<RecordingPlan>;
|
|
92
|
+
/**
|
|
93
|
+
* Records a catalog effect (by id or definition), applied to `subject`, to a
|
|
94
|
+
* file in the browser: an `mp4` or `webm` video (WebCodecs, muxed here with
|
|
95
|
+
* no dependencies), an animated `gif`, or `png` frames.
|
|
96
|
+
*
|
|
97
|
+
* Frames are drawn off screen at exact times (`start + i / fps`), so the
|
|
98
|
+
* result is smooth whatever the page's frame rate, and the same on every
|
|
99
|
+
* machine. Shaders render with `ShaderFrames` (a `<video>` subject is paused
|
|
100
|
+
* and sought to each frame, and put back after); vector effects are drawn
|
|
101
|
+
* with `svgView` and rasterised. Shaders that answer the pointer play their
|
|
102
|
+
* idle demos unless `pointer` scripts it.
|
|
103
|
+
*
|
|
104
|
+
* `png` resolves to a ZIP of numbered frames (`frame-0001.png`, …), so every
|
|
105
|
+
* format is one `Blob` to save or upload.
|
|
106
|
+
*
|
|
107
|
+
* Rejects with a sentence when the effect is unknown, takes no such
|
|
108
|
+
* subject, or the browser cannot make the format (naming the formats that
|
|
109
|
+
* would work); with a `ShaderCompileError` or `ImageLoadError` as
|
|
110
|
+
* `ShaderFrames` does; and with an `AbortError` when `signal` aborts.
|
|
111
|
+
*
|
|
112
|
+
* ```ts
|
|
113
|
+
* const mp4 = await recordEffect("image-duotone", { subject: { image: "/team.jpg" }, preset: "Spotify" });
|
|
114
|
+
* const gif = await recordEffect("typewriter", { subject: { text: "Hello" }, format: "gif", width: 640, height: 360, fps: 25 });
|
|
115
|
+
* const webm = await recordEffect("click-ripple", { format: "webm", alpha: true, pointer: { clicks: [{ x: 640, y: 360, time: 0.2 }] } });
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
declare function recordEffect(effect: EffectDefinition | string, options?: RecordOptions): Promise<Blob>;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Catalog effects on a page in one call: pick an effect, give it what it
|
|
122
|
+
* takes (a picture, a video, an SVG, words or a path) and get it running.
|
|
123
|
+
*
|
|
124
|
+
* - Pairing: `subjectValues` turns a subject into the control values (and
|
|
125
|
+
* live sources) an effect needs, using `effectInputs`.
|
|
126
|
+
* - Embedding: `mountEffect` runs a shader effect (`ShaderRenderer`) or a
|
|
127
|
+
* vector effect (`SvgPlayer`) in an element, with its subject.
|
|
128
|
+
*
|
|
129
|
+
* @packageDocumentation
|
|
130
|
+
*/
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* What an effect is applied to:
|
|
134
|
+
* - `{ image }`: a picture's URL (or `data:` URL).
|
|
135
|
+
* - `{ video }`: a playing `<video>` (or a canvas), shown live.
|
|
136
|
+
* - `{ svg }`: an SVG, as markup (`"<svg …>"`) or a URL; drawn as a picture, keeping its transparency.
|
|
137
|
+
* - `{ text }`: words, for a vector effect's text, or drawn with `textImage` for a shader's text or mask.
|
|
138
|
+
* - `{ path }`: SVG path data (`d`), for a shape control.
|
|
139
|
+
*/
|
|
140
|
+
type EffectSubject = {
|
|
141
|
+
image: string;
|
|
142
|
+
} | {
|
|
143
|
+
video: LiveSource;
|
|
144
|
+
} | {
|
|
145
|
+
svg: string;
|
|
146
|
+
} | {
|
|
147
|
+
text: string;
|
|
148
|
+
font?: string;
|
|
149
|
+
weight?: number | string;
|
|
150
|
+
} | {
|
|
151
|
+
path: string;
|
|
152
|
+
};
|
|
153
|
+
/** What a subject becomes for an effect: control values, and live sources by image control. */
|
|
154
|
+
interface SubjectValues {
|
|
155
|
+
values: Record<string, ControlValue>;
|
|
156
|
+
live: Record<string, LiveSource>;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* The control values (and live sources) that put `subject` in `effect`,
|
|
160
|
+
* into the control named `slot` or the first that suits it: a picture or
|
|
161
|
+
* SVG into an image control, a video into a picture control as a live
|
|
162
|
+
* source, words into a vector effect's text or (drawn by `textImage`) a
|
|
163
|
+
* shader's text or mask control, path data into a shape control. Several
|
|
164
|
+
* subjects fill several controls in order (a transition's from and to).
|
|
165
|
+
* Throws a sentence when the effect takes no such thing.
|
|
166
|
+
*/
|
|
167
|
+
declare function subjectValues(effect: EffectDefinition, subject: EffectSubject | readonly EffectSubject[], slot?: string): SubjectValues;
|
|
168
|
+
interface MountOptions {
|
|
169
|
+
/** What to apply the effect to (see {@link EffectSubject}); several fill several controls in order. */
|
|
170
|
+
subject?: EffectSubject | readonly EffectSubject[];
|
|
171
|
+
/** A preset by name, then these values, over the effect's defaults. */
|
|
172
|
+
preset?: string;
|
|
173
|
+
values?: Record<string, ControlValue>;
|
|
174
|
+
/** Start playing at once (default true). */
|
|
175
|
+
autoplay?: boolean;
|
|
176
|
+
/** Class for the canvas (shaders) or the player's element (vector effects). */
|
|
177
|
+
className?: string;
|
|
178
|
+
/** Pause while scrolled out of view (default true). */
|
|
179
|
+
pauseWhenHidden?: boolean;
|
|
180
|
+
}
|
|
181
|
+
/** A running effect, from {@link mountEffect}. */
|
|
182
|
+
interface MountedEffect {
|
|
183
|
+
readonly effect: EffectDefinition;
|
|
184
|
+
/** What it draws into: the shader's canvas, or the vector player's element. */
|
|
185
|
+
readonly element: HTMLElement;
|
|
186
|
+
/** The shader renderer, for a shader effect. */
|
|
187
|
+
readonly renderer?: ShaderRenderer;
|
|
188
|
+
/** The vector player, for a vector effect (replaced when values change). */
|
|
189
|
+
readonly player?: SvgPlayer;
|
|
190
|
+
/** Applies it to something else. */
|
|
191
|
+
setSubject(subject: EffectSubject | readonly EffectSubject[]): void;
|
|
192
|
+
/** Changes control values (merged over the current ones). */
|
|
193
|
+
setValues(values: Record<string, ControlValue>): void;
|
|
194
|
+
play(): void;
|
|
195
|
+
pause(): void;
|
|
196
|
+
/** Stops it and removes what it drew. */
|
|
197
|
+
dispose(): void;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Runs a catalog effect (by id or definition) in `host`, applied to
|
|
201
|
+
* `subject`: a shader on a canvas (transparent for overlays, so it lays over
|
|
202
|
+
* the page), or a vector effect in an SVG player that answers its trigger
|
|
203
|
+
* (hover, press, click). Throws a sentence when the effect is unknown or
|
|
204
|
+
* takes no such subject.
|
|
205
|
+
*
|
|
206
|
+
* ```ts
|
|
207
|
+
* mountEffect(el, "image-duotone", { subject: { image: "/team.jpg" }, preset: "Spotify" });
|
|
208
|
+
* mountEffect(el, "crt", { subject: { video: videoElement } });
|
|
209
|
+
* mountEffect(el, "typewriter", { subject: { text: "Hello there" } });
|
|
210
|
+
* mountEffect(el, "neon-outline", { subject: { svg: logoMarkup } });
|
|
211
|
+
* ```
|
|
212
|
+
*/
|
|
213
|
+
declare function mountEffect(host: HTMLElement, effect: EffectDefinition | string, options?: MountOptions): MountedEffect;
|
|
214
|
+
|
|
215
|
+
export { type EffectSubject, type MountOptions, type MountedEffect, type RecordFormat, type RecordOptions, type RecordPointer, type RecordingPlan, type SubjectValues, mountEffect, recordEffect, recordingPlan, subjectValues };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
mountEffect,
|
|
3
|
+
recordEffect,
|
|
4
|
+
recordingPlan,
|
|
5
|
+
subjectValues
|
|
6
|
+
} from "../chunk-UCZ43ARE.js";
|
|
7
|
+
import "../chunk-H6VDFBIO.js";
|
|
8
|
+
import "../chunk-RDU63CDO.js";
|
|
9
|
+
import "../chunk-HVXWNGTW.js";
|
|
10
|
+
import "../chunk-EHDJ3CPJ.js";
|
|
11
|
+
import "../chunk-VYOMXE6I.js";
|
|
12
|
+
import "../chunk-PFGGPIMT.js";
|
|
13
|
+
import "../chunk-WMZQCUFJ.js";
|
|
14
|
+
import "../chunk-ORAFCHX3.js";
|
|
15
|
+
export {
|
|
16
|
+
mountEffect,
|
|
17
|
+
recordEffect,
|
|
18
|
+
recordingPlan,
|
|
19
|
+
subjectValues
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
exportMotn,
|
|
8
8
|
framesToTimecode,
|
|
9
9
|
timecodeToFrames
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-74ZLCZOG.js";
|
|
11
|
+
import "./chunk-5USSDEQL.js";
|
|
12
12
|
import "./chunk-WMZQCUFJ.js";
|
|
13
13
|
export {
|
|
14
14
|
calculateShotTimings,
|
|
@@ -20,4 +20,4 @@ export {
|
|
|
20
20
|
framesToTimecode,
|
|
21
21
|
timecodeToFrames
|
|
22
22
|
};
|
|
23
|
-
//# sourceMappingURL=export-
|
|
23
|
+
//# sourceMappingURL=export-QVW474KM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { a as ControlDef, C as ControlValue } from './controls-Ec6P0Vpy.js';
|
|
2
|
+
import { L as LiveSource } from './renderer-teaa98RE.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The pointer as shaders see it, beyond Shadertoy's `iMouse`: where it is
|
|
6
|
+
* while it is over the canvas, how hovered the canvas is (eased in and out),
|
|
7
|
+
* how long it has been pressed, the last few clicks, and where it has just
|
|
8
|
+
* been (its trail), so effects can answer hovers, presses, taps and moves.
|
|
9
|
+
* Times are in `iTime` seconds, so a recording can script them (see
|
|
10
|
+
* `ShaderFrames`' `pointer`, `clicks` and `trail`).
|
|
11
|
+
*/
|
|
12
|
+
/** How many clicks `iClicks` holds; older ones drop off. */
|
|
13
|
+
declare const MAX_CLICKS = 8;
|
|
14
|
+
/** How many of the pointer's recent positions `iTrail` holds; older ones drop off. */
|
|
15
|
+
declare const MAX_TRAIL = 32;
|
|
16
|
+
/**
|
|
17
|
+
* The least time between two positions in the trail, in seconds: moves in
|
|
18
|
+
* between update the newest. With {@link MAX_TRAIL}, about a second of path.
|
|
19
|
+
*/
|
|
20
|
+
declare const TRAIL_SECONDS: number;
|
|
21
|
+
/** How long hovering eases in or out, in seconds. */
|
|
22
|
+
declare const HOVER_SECONDS = 0.25;
|
|
23
|
+
/** A click, or a point of the trail: where (pixels from the bottom left, like `iMouse`) and when (`iTime` seconds). */
|
|
24
|
+
interface ShaderClick {
|
|
25
|
+
x: number;
|
|
26
|
+
y: number;
|
|
27
|
+
time: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* `iClicks` from a list of clicks, newest first: `vec4(x, y, time, 1)` for
|
|
31
|
+
* each click at or before `time`, zeros for the rest.
|
|
32
|
+
*/
|
|
33
|
+
declare function clicksUniform(clicks: readonly ShaderClick[], time: number): Float32Array;
|
|
34
|
+
/**
|
|
35
|
+
* `iTrail` from the pointer's positions, oldest first in the list: the
|
|
36
|
+
* newest {@link MAX_TRAIL} at or before `time`, newest first, as
|
|
37
|
+
* `vec4(x, y, time, 1)`, zeros for the rest.
|
|
38
|
+
*/
|
|
39
|
+
declare function trailUniform(trail: readonly ShaderClick[], time: number): Float32Array;
|
|
40
|
+
/**
|
|
41
|
+
* Follows one canvas's pointer for `iPointer` and `iClicks`: feed it pointer
|
|
42
|
+
* events with the `iTime` they happen at, and read the uniforms for a frame.
|
|
43
|
+
*/
|
|
44
|
+
declare class PointerTracker {
|
|
45
|
+
private x;
|
|
46
|
+
private y;
|
|
47
|
+
private over;
|
|
48
|
+
private hoverFrom;
|
|
49
|
+
private changedAt;
|
|
50
|
+
private pressedAt;
|
|
51
|
+
private releasedAt;
|
|
52
|
+
private clicks;
|
|
53
|
+
private trail;
|
|
54
|
+
/**
|
|
55
|
+
* The pointer moved to (x, y), in pixels from the bottom left. With a
|
|
56
|
+
* `time`, the move joins the trail: a new point at most every
|
|
57
|
+
* {@link TRAIL_SECONDS}, the newest point following the pointer between.
|
|
58
|
+
*/
|
|
59
|
+
move(x: number, y: number, time?: number): void;
|
|
60
|
+
/** The pointer came over the canvas (`true`) or left it. */
|
|
61
|
+
hover(over: boolean, time: number): void;
|
|
62
|
+
/** A press at (x, y): counts as a click. */
|
|
63
|
+
down(x: number, y: number, time: number): void;
|
|
64
|
+
up(time: number): void;
|
|
65
|
+
/** Forgets clicks, presses and the trail (when time jumps back, say). */
|
|
66
|
+
clear(): void;
|
|
67
|
+
/** How hovered the canvas is at `time`, 0–1, eased. */
|
|
68
|
+
hovered(time: number): number;
|
|
69
|
+
/**
|
|
70
|
+
* `iPointer` at `time`: x, y, how hovered (0–1), and the press: seconds
|
|
71
|
+
* held while pressed, minus the seconds since it was let go after, 0
|
|
72
|
+
* before the first press.
|
|
73
|
+
*/
|
|
74
|
+
pointer(time: number): [number, number, number, number];
|
|
75
|
+
/** `iClicks` at `time` (see {@link clicksUniform}). */
|
|
76
|
+
clicksAt(time: number): Float32Array;
|
|
77
|
+
/** `iTrail` at `time` (see {@link trailUniform}). */
|
|
78
|
+
trailAt(time: number): Float32Array;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
interface ShaderFramesOptions {
|
|
82
|
+
source: string;
|
|
83
|
+
values?: Record<string, ControlValue>;
|
|
84
|
+
width: number;
|
|
85
|
+
height: number;
|
|
86
|
+
/** Draw on this canvas instead of a new, detached one. It is resized to `width` × `height`. */
|
|
87
|
+
canvas?: HTMLCanvasElement;
|
|
88
|
+
/** Keep the shader's alpha (`fragColor.a`) in the frames, for transparent recordings (default false: opaque). */
|
|
89
|
+
alpha?: boolean;
|
|
90
|
+
}
|
|
91
|
+
interface RenderOptions {
|
|
92
|
+
/** `iFrame` (default: the number of frames rendered so far). */
|
|
93
|
+
frame?: number;
|
|
94
|
+
/** `iTimeDelta` in seconds (default: the time since the previous `render`, else 0). */
|
|
95
|
+
delta?: number;
|
|
96
|
+
/** `iMouse` (default: all zero, as on a page nobody has touched). */
|
|
97
|
+
mouse?: [number, number, number, number];
|
|
98
|
+
/** `iPointer`: x, y, how hovered (0–1), the press (seconds held, or minus seconds since release; default all zero). */
|
|
99
|
+
pointer?: [number, number, number, number];
|
|
100
|
+
/** Clicks so far, for `iClicks` (the latest `MAX_CLICKS` at or before the frame's time count). */
|
|
101
|
+
clicks?: readonly ShaderClick[];
|
|
102
|
+
/** Where the pointer has been, oldest first, for `iTrail` (the latest `MAX_TRAIL` at or before the frame's time count). */
|
|
103
|
+
trail?: readonly ShaderClick[];
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Renders a shader at exact times you choose, off screen. There is no
|
|
107
|
+
* animation loop and no clock: frame `n` of a recording at `fps` is
|
|
108
|
+
* `render(start + n / fps)`, so the output is the same on any machine. It
|
|
109
|
+
* suits recorders, video pipelines and anything else stepped by its own
|
|
110
|
+
* clock. The constructor throws a {@link ShaderCompileError} when the source
|
|
111
|
+
* does not compile.
|
|
112
|
+
*
|
|
113
|
+
* Image controls load in the background: `await frames.ready()` before the
|
|
114
|
+
* first `render`, or the frames show black where the images go.
|
|
115
|
+
*
|
|
116
|
+
* A video in an image control (see `setLiveSource`) is drawn at whatever
|
|
117
|
+
* frame it is on. To step it with the shader, seek it first: `await
|
|
118
|
+
* seekVideo(video, t); frames.render(t)`.
|
|
119
|
+
*/
|
|
120
|
+
declare class ShaderFrames {
|
|
121
|
+
readonly canvas: HTMLCanvasElement;
|
|
122
|
+
readonly width: number;
|
|
123
|
+
readonly height: number;
|
|
124
|
+
readonly controls: ControlDef[];
|
|
125
|
+
private gl;
|
|
126
|
+
private shader;
|
|
127
|
+
private textures;
|
|
128
|
+
private values;
|
|
129
|
+
private rendered;
|
|
130
|
+
private lastTime;
|
|
131
|
+
private pixels;
|
|
132
|
+
constructor(options: ShaderFramesOptions);
|
|
133
|
+
/** Changes control values for the frames that follow. */
|
|
134
|
+
setValues(values: Record<string, ControlValue> | undefined): void;
|
|
135
|
+
/**
|
|
136
|
+
* Draws a `<video>` (or a canvas) in the image control `name` instead of
|
|
137
|
+
* its URL, at the frame it is on when `render` runs; `null` goes back to
|
|
138
|
+
* the URL. See `ShaderRenderer.setLiveSource`.
|
|
139
|
+
*/
|
|
140
|
+
setLiveSource(name: string, source: LiveSource | null): void;
|
|
141
|
+
/**
|
|
142
|
+
* Settles once every image the controls show has loaded, and every live
|
|
143
|
+
* video has a frame. Rejects with an {@link ImageLoadError} when one
|
|
144
|
+
* cannot be.
|
|
145
|
+
*/
|
|
146
|
+
ready(): Promise<void>;
|
|
147
|
+
/** Draws the frame at `time` seconds onto `canvas`. */
|
|
148
|
+
render(time: number, options?: RenderOptions): void;
|
|
149
|
+
/**
|
|
150
|
+
* The last rendered frame as RGBA bytes, rows top down (as in `ImageData`;
|
|
151
|
+
* WebGL itself reads bottom up). Pass `out` to reuse a buffer of
|
|
152
|
+
* `width * height * 4` bytes.
|
|
153
|
+
*/
|
|
154
|
+
readPixels(out?: Uint8Array | Uint8ClampedArray): Uint8Array | Uint8ClampedArray;
|
|
155
|
+
/** Releases the GL context now rather than at garbage collection (browsers cap live contexts). */
|
|
156
|
+
dispose(): void;
|
|
157
|
+
private syncTextures;
|
|
158
|
+
private context;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export { HOVER_SECONDS as H, MAX_CLICKS as M, PointerTracker as P, type RenderOptions as R, type ShaderClick as S, TRAIL_SECONDS as T, MAX_TRAIL as a, ShaderFrames as b, type ShaderFramesOptions as c, clicksUniform as d, trailUniform as t };
|