kuinetic 0.1.3 → 0.2.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/README.md +93 -10
- package/dist/esm/advanced/index.mjs +4727 -0
- package/dist/esm/chunk-AEQGC2KM.mjs +189 -0
- package/dist/esm/chunk-MQSNMYRP.mjs +9332 -0
- package/dist/esm/chunk-RVTYN6NZ.mjs +3446 -0
- package/dist/esm/chunk-U43BX5O2.mjs +2984 -0
- package/dist/esm/core/index.mjs +16 -9
- package/dist/esm/effects/index.mjs +19 -4
- package/dist/esm/index.mjs +17 -10
- package/dist/kuinetic.advanced.js +5070 -0
- package/dist/kuinetic.advanced.min.js +749 -0
- package/dist/kuinetic.all.js +15218 -5595
- package/dist/kuinetic.all.min.js +2 -0
- package/dist/kuinetic.css +2900 -360
- package/dist/kuinetic.js +15217 -5593
- package/dist/kuinetic.min.css +1 -0
- package/dist/kuinetic.min.js +7 -0
- package/dist/types/3d/angles.d.ts +30 -0
- package/dist/types/3d/flattening.d.ts +49 -0
- package/dist/types/3d/index.d.ts +36 -0
- package/dist/types/3d/model-3d.d.ts +115 -0
- package/dist/types/3d/register.d.ts +26 -0
- package/dist/types/3d/webgl.d.ts +24 -0
- package/dist/types/advanced/audio.d.ts +322 -0
- package/dist/types/advanced/base.d.ts +233 -0
- package/dist/types/advanced/camera-3d.d.ts +236 -0
- package/dist/types/advanced/fluid-cursor.d.ts +149 -0
- package/dist/types/advanced/gl-utils.d.ts +52 -0
- package/dist/types/advanced/glsl.d.ts +60 -0
- package/dist/types/advanced/index.d.ts +23 -0
- package/dist/types/advanced/particles.d.ts +108 -0
- package/dist/types/advanced/scenes.d.ts +207 -0
- package/dist/types/advanced/shaders.d.ts +972 -0
- package/dist/types/browser/boot.d.ts +72 -0
- package/dist/types/core/activation.d.ts +227 -2
- package/dist/types/core/animator.d.ts +446 -11
- package/dist/types/core/attrs.d.ts +9 -0
- package/dist/types/core/breakpoints.d.ts +260 -0
- package/dist/types/core/bundles.d.ts +71 -0
- package/dist/types/core/callback.d.ts +64 -0
- package/dist/types/core/capabilities.d.ts +47 -0
- package/dist/types/core/channels.d.ts +120 -2
- package/dist/types/core/cloak-selectors.d.ts +47 -0
- package/dist/types/core/compile.d.ts +207 -2
- package/dist/types/core/control.d.ts +218 -0
- package/dist/types/core/declarations.d.ts +128 -0
- package/dist/types/core/derived/aggregate.d.ts +43 -0
- package/dist/types/core/derived/book.d.ts +30 -0
- package/dist/types/core/derived/diagnostics.d.ts +51 -0
- package/dist/types/core/derived/group-gate.d.ts +62 -0
- package/dist/types/core/derived/install.d.ts +110 -0
- package/dist/types/core/derived/late-matches.d.ts +19 -0
- package/dist/types/core/derived/types.d.ts +108 -0
- package/dist/types/core/easing.d.ts +57 -0
- package/dist/types/core/element-config.d.ts +47 -6
- package/dist/types/core/element-size.d.ts +23 -0
- package/dist/types/core/event-sources.d.ts +39 -0
- package/dist/types/core/flip.d.ts +34 -1
- package/dist/types/core/gesture.d.ts +12 -0
- package/dist/types/core/host-facts.d.ts +155 -0
- package/dist/types/core/index.d.ts +7 -3
- package/dist/types/core/owned-styles.d.ts +129 -2
- package/dist/types/core/params.d.ts +48 -0
- package/dist/types/core/parse.d.ts +28 -1
- package/dist/types/core/register-into.d.ts +29 -0
- package/dist/types/core/registry.d.ts +10 -3
- package/dist/types/core/repeat.d.ts +91 -0
- package/dist/types/core/sequence.d.ts +126 -0
- package/dist/types/core/stagger-config.d.ts +199 -0
- package/dist/types/core/stagger-keys.d.ts +63 -0
- package/dist/types/core/stagger.d.ts +187 -6
- package/dist/types/core/style-plan.d.ts +21 -16
- package/dist/types/core/target.d.ts +128 -0
- package/dist/types/core/threshold-reachability.d.ts +45 -0
- package/dist/types/core/time-scale.d.ts +9 -0
- package/dist/types/core/toggle-actions.d.ts +141 -0
- package/dist/types/core/travel.d.ts +59 -0
- package/dist/types/core/types.d.ts +705 -13
- package/dist/types/core/unquoted-selectors.d.ts +53 -0
- package/dist/types/effects/carousel/drag.d.ts +80 -0
- package/dist/types/effects/carousel/index.d.ts +149 -0
- package/dist/types/effects/catalog/background-media.d.ts +152 -0
- package/dist/types/effects/catalog/discrete.d.ts +13 -0
- package/dist/types/effects/catalog/interaction-proximity.d.ts +24 -0
- package/dist/types/effects/catalog/interaction-reveal.d.ts +248 -0
- package/dist/types/effects/catalog/interaction-shared.d.ts +42 -0
- package/dist/types/effects/catalog/interaction-states.d.ts +68 -0
- package/dist/types/effects/catalog/materials.d.ts +67 -0
- package/dist/types/effects/catalog/media-shared.d.ts +3 -2
- package/dist/types/effects/catalog/numbers-shared.d.ts +8 -5
- package/dist/types/effects/catalog/shared.d.ts +2 -2
- package/dist/types/effects/catalog/text-shared.d.ts +92 -10
- package/dist/types/effects/catalog/transforms.d.ts +13 -0
- package/dist/types/effects/catalog/view-transitions.d.ts +13 -0
- package/dist/types/effects/forms/primitives.d.ts +15 -4
- package/dist/types/effects/gestures/index.d.ts +53 -0
- package/dist/types/effects/index.d.ts +5 -0
- package/dist/types/effects/layout/presets.d.ts +35 -0
- package/dist/types/effects/motion-path/index.d.ts +35 -0
- package/dist/types/effects/scroll-mechanics/params.d.ts +23 -0
- package/dist/types/effects/scroll-mechanics/presets.d.ts +51 -0
- package/dist/types/effects/scroll-mechanics/section-index.d.ts +47 -0
- package/dist/types/effects/shared.d.ts +162 -2
- package/dist/types/effects/step-index.d.ts +121 -0
- package/dist/types/effects/step-marking.d.ts +41 -33
- package/dist/types/effects/svg/icon-parts.d.ts +23 -0
- package/dist/types/effects/three-d/flip-parts.d.ts +46 -0
- package/dist/types/effects/tween/index.d.ts +57 -0
- package/dist/types/effects/tween/properties.d.ts +107 -0
- package/dist/types/effects/tween/waypoints.d.ts +106 -0
- package/dist/types/showcase/compare.d.ts +4 -0
- package/dist/types/showcase/device-frame.d.ts +3 -0
- package/dist/types/showcase/hotspots.d.ts +3 -0
- package/dist/types/showcase/index.d.ts +30 -0
- package/dist/types/showcase/lightbox.d.ts +3 -0
- package/dist/types/showcase/media-source.d.ts +13 -0
- package/dist/types/showcase/modal-shell.d.ts +22 -0
- package/dist/types/showcase/scroll-story.d.ts +4 -0
- package/dist/types/showcase/shared.d.ts +47 -0
- package/dist/types/showcase/slideshow.d.ts +3 -0
- package/dist/types/showcase/slow-mo.d.ts +5 -0
- package/package.json +14 -7
- package/dist/esm/chunk-5DON3UFQ.mjs +0 -4380
- package/dist/esm/chunk-JT4PZL3A.mjs +0 -773
- package/dist/esm/chunk-QUVFODSQ.mjs +0 -1278
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared primitives and runtime utilities for kUInetic Advanced Modules.
|
|
3
|
+
*/
|
|
4
|
+
import type { EffectInstance, PrepareContext, Preset, Primitive } from '../core/types.js';
|
|
5
|
+
import type { StyleLedger } from '../core/owned-styles.js';
|
|
6
|
+
import type { Registry } from '../core/registry.js';
|
|
7
|
+
import type { Animator } from '../core/animator.js';
|
|
8
|
+
export interface WindowLike {
|
|
9
|
+
innerWidth?: number;
|
|
10
|
+
innerHeight?: number;
|
|
11
|
+
devicePixelRatio?: number;
|
|
12
|
+
performance?: {
|
|
13
|
+
now?: () => number;
|
|
14
|
+
};
|
|
15
|
+
addEventListener?: (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions) => void;
|
|
16
|
+
removeEventListener?: (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions) => void;
|
|
17
|
+
requestAnimationFrame?: (fn: FrameRequestCallback) => number;
|
|
18
|
+
cancelAnimationFrame?: (id: number) => void;
|
|
19
|
+
getComputedStyle?: (el: Element) => CSSStyleDeclaration;
|
|
20
|
+
}
|
|
21
|
+
export interface DocumentLike {
|
|
22
|
+
body?: {
|
|
23
|
+
appendChild?: (node: unknown) => unknown;
|
|
24
|
+
} | null;
|
|
25
|
+
createElement?: (tagName: string) => unknown;
|
|
26
|
+
}
|
|
27
|
+
export type AnyWindow = Window | WindowLike | null;
|
|
28
|
+
export type AnyDocument = Document | DocumentLike | null;
|
|
29
|
+
export type RafFunction = (fn: FrameRequestCallback) => number | null;
|
|
30
|
+
export type CafFunction = (id: number | null) => void | null;
|
|
31
|
+
/**
|
|
32
|
+
* A wall-clock delay, and its cancel — the env's answer to "later, once".
|
|
33
|
+
*
|
|
34
|
+
* Separate from {@link RafFunction} because the two answer different questions: `raf` schedules the
|
|
35
|
+
* *next frame*, which is what a loop wants, while this schedules a fixed duration, which is what a
|
|
36
|
+
* grace period wants. A grace period counted in frames is a grace period that never elapses in a
|
|
37
|
+
* background tab — the one place where holding the resource costs the most.
|
|
38
|
+
*
|
|
39
|
+
* It is injectable for the same reason `raf` is: it is a timing decision the host can own, and a
|
|
40
|
+
* suite that cannot drive it either waits out the real duration or leaves the timer pending. Do
|
|
41
|
+
* *not* reach for `window.setTimeout` instead — {@link WindowLike} does not declare it, and the
|
|
42
|
+
* partial window doubles these suites inject would silently never fire.
|
|
43
|
+
*
|
|
44
|
+
* Named to match `defaultGestureDeps` in `core/gesture.ts`, which is the same pattern in core.
|
|
45
|
+
*/
|
|
46
|
+
export type SetTimerFunction = (fn: () => void, ms: number) => number | null;
|
|
47
|
+
export type ClearTimerFunction = (id: number | null) => void;
|
|
48
|
+
export interface AdvancedEnv {
|
|
49
|
+
window?: AnyWindow;
|
|
50
|
+
document?: AnyDocument;
|
|
51
|
+
createCanvas?: () => HTMLCanvasElement | null;
|
|
52
|
+
raf?: RafFunction;
|
|
53
|
+
caf?: CafFunction;
|
|
54
|
+
setTimer?: SetTimerFunction;
|
|
55
|
+
clearTimer?: ClearTimerFunction;
|
|
56
|
+
}
|
|
57
|
+
export interface ResolvedEnv {
|
|
58
|
+
window: AnyWindow;
|
|
59
|
+
document: AnyDocument;
|
|
60
|
+
createCanvas: () => HTMLCanvasElement | null;
|
|
61
|
+
raf: RafFunction;
|
|
62
|
+
caf: CafFunction;
|
|
63
|
+
setTimer: SetTimerFunction;
|
|
64
|
+
clearTimer: ClearTimerFunction;
|
|
65
|
+
}
|
|
66
|
+
export interface EffectInstanceOptions {
|
|
67
|
+
continuous?: boolean;
|
|
68
|
+
activate?: () => void;
|
|
69
|
+
cancel?: () => void;
|
|
70
|
+
finish?: () => void;
|
|
71
|
+
destroy?: () => void;
|
|
72
|
+
}
|
|
73
|
+
export declare function clamp(val: number, min: number, max: number): number;
|
|
74
|
+
/**
|
|
75
|
+
* Anything that can hand back one element's inline-style ledger.
|
|
76
|
+
*
|
|
77
|
+
* Deliberately narrower than `LedgerSet`: core's set (`createLedgerSet`) and this directory's
|
|
78
|
+
* shared registry (`createAdvancedLedgers`) both satisfy it, so `styleOf` is one guard for both
|
|
79
|
+
* and a module can be moved from one to the other without touching a single write site.
|
|
80
|
+
*/
|
|
81
|
+
export interface ElementLedgers {
|
|
82
|
+
style(el: Element): StyleLedger;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* This element's owned-write ledger, or `null` when the object cannot carry one.
|
|
86
|
+
*
|
|
87
|
+
* Every module here manages the author's inline styles through `core/owned-styles.ts` rather than
|
|
88
|
+
* a snapshot of its own, and the reason is timing: `style(el)` builds that element's ledger the
|
|
89
|
+
* first time it is *asked for*, and the ledger records a property's prior value the first time
|
|
90
|
+
* that property is *written*. Asking at the write site is therefore the same thing as "capture
|
|
91
|
+
* immediately before the first write", which is the invariant five rounds of review kept finding
|
|
92
|
+
* broken — a snapshot taken at construction or preparation, restored much later over an author
|
|
93
|
+
* value that had changed in between.
|
|
94
|
+
*
|
|
95
|
+
* The guard exists because `createStyleLedger` reads `hasAttribute('style')` the moment it is
|
|
96
|
+
* built, and these controllers are constructed directly rather than by the animator: `prepare`
|
|
97
|
+
* hands them whatever element the author wrote the attribute on, and the suites hand them `null`,
|
|
98
|
+
* `{}`, and `{ getAttribute: () => null }` to exercise the degenerate paths. One check here beats
|
|
99
|
+
* the same two clauses repeated at every write site.
|
|
100
|
+
*
|
|
101
|
+
* @param ledgers - The controller's ledger source, opened over its host element.
|
|
102
|
+
* @param el - The element about to be written to.
|
|
103
|
+
* @returns Its memoised ledger, or `null` when there is nothing to write to.
|
|
104
|
+
* @complexity O(1).
|
|
105
|
+
*/
|
|
106
|
+
export declare function styleOf(ledgers: ElementLedgers, el: Element | null | undefined): StyleLedger | null;
|
|
107
|
+
/**
|
|
108
|
+
* A controller's claim on the shared per-element ledgers.
|
|
109
|
+
*
|
|
110
|
+
* `style` is not guarded — go through {@link styleOf}, which is the one place the "can this object
|
|
111
|
+
* carry a ledger at all" question is answered.
|
|
112
|
+
*/
|
|
113
|
+
export interface AdvancedLedgers {
|
|
114
|
+
/** This element's shared ledger, created on first ask by anyone. */
|
|
115
|
+
style(el: Element): StyleLedger;
|
|
116
|
+
/**
|
|
117
|
+
* Give up this controller's claim on every element it wrote to, restoring each one that no other
|
|
118
|
+
* controller still holds.
|
|
119
|
+
*
|
|
120
|
+
* Every element is attempted. One that throws on the way out does not cost the ones after it; the
|
|
121
|
+
* failures are re-thrown together as an `AggregateError` once the sweep is complete.
|
|
122
|
+
*/
|
|
123
|
+
restore(): void;
|
|
124
|
+
/** Elements this controller has asked for. Diagnostics and leak assertions. */
|
|
125
|
+
elements(): Element[];
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Open one controller's claim on the shared, ref-counted per-element ledgers.
|
|
129
|
+
*
|
|
130
|
+
* The registry itself lives in `core/owned-styles.ts` ({@link createStyleClaim}), and that is not
|
|
131
|
+
* an implementation detail — it is the fix. This tier used to keep a `WeakMap` of its own, holding
|
|
132
|
+
* one animator's private ledger on behalf of everybody, with a per-entry `foreign` flag deciding
|
|
133
|
+
* whether the entry was ever restored. Both halves were decided *once*, by whichever controller
|
|
134
|
+
* arrived first: a second controller's own `hostLedger` was silently ignored, and anything the
|
|
135
|
+
* first controller flagged foreign was never restored by this path at all, so a property written
|
|
136
|
+
* by a controller that outlived the animator outlived every restore that would have unwound it.
|
|
137
|
+
*
|
|
138
|
+
* Ref-counting removes the flag rather than fixing it. Core's `LedgerSet` is now an owner in the
|
|
139
|
+
* same registry, so "the animator will restore this one" is no longer a special case a boolean has
|
|
140
|
+
* to remember — it is simply another claim, and the element is unwound by whichever owner lets go
|
|
141
|
+
* last, controller or animator.
|
|
142
|
+
*
|
|
143
|
+
* There is also no `hostLedger` parameter any more, and its absence is the point. It existed
|
|
144
|
+
* because this tier ships as its own bundle with its own copy of `owned-styles.ts`, so the
|
|
145
|
+
* animator's ledger for the host had to be *handed over* to be shared. That made sharing opt-in at
|
|
146
|
+
* the call site and left two ways to open a capture. The registry now lives on the element itself,
|
|
147
|
+
* under a `Symbol.for` key both bundles compute identically, so a controller and the animator find
|
|
148
|
+
* the same entry by asking — and the only way to open a capture is to ask.
|
|
149
|
+
*
|
|
150
|
+
* What this tier still needs the registry *for* is what it always did. These controllers write to
|
|
151
|
+
* elements they merely **found** — a `camera-layer` under a `camera-scene`, a `scene-step` under a
|
|
152
|
+
* `scene` — and one found element can belong to two controllers. {@link ownedDescendants} removed
|
|
153
|
+
* the *same-kind* half of that overlap; the cross-kind half is a supported authoring shape (an
|
|
154
|
+
* element authored `camera-layer z:-100, scene-step from:0 to:1` genuinely has a camera and a scene
|
|
155
|
+
* writing to it), and a controller constructed directly rather than through `prepare` never went
|
|
156
|
+
* through the scan at all. Both still need one capture between them.
|
|
157
|
+
*
|
|
158
|
+
* @param host - The authored element this controller was prepared on. Released last, for the
|
|
159
|
+
* reason `createLedgerSet` documents: the host carries `data-kui-state`, which is the cloak
|
|
160
|
+
* layer's release key, so it must not become visible before the subtree under it is back to the
|
|
161
|
+
* author's markup.
|
|
162
|
+
* @complexity O(1) per lookup; O(n) space and O(n) time to restore, in elements written to.
|
|
163
|
+
*/
|
|
164
|
+
export declare function createAdvancedLedgers(host: Element): AdvancedLedgers;
|
|
165
|
+
/**
|
|
166
|
+
* The descendants carrying `descendantEffect` that `host` actually owns.
|
|
167
|
+
*
|
|
168
|
+
* > A host claims a descendant only when no nearer host **of the same kind** sits between them.
|
|
169
|
+
*
|
|
170
|
+
* `prepareScene` and `prepareCameraScene` used the raw `[data-kui*="…"]` query, which is
|
|
171
|
+
* descendant-wide and does not stop at a nested host — so an **outer** host over-reached into an
|
|
172
|
+
* inner one and both controllers wrote the inner host's children every frame, with different
|
|
173
|
+
* progress values. Listener and rAF order decided which write survived, which is to say nothing
|
|
174
|
+
* decided it. {@link createAdvancedLedgers} made that survivable on *teardown* by sharing one
|
|
175
|
+
* capture per element; it never arbitrated the writes themselves, because `ledger.set()` writes
|
|
176
|
+
* straight through. This is the other half.
|
|
177
|
+
*
|
|
178
|
+
* "Of the same kind" is load-bearing and is not a tidy-up of the rule. An element authored
|
|
179
|
+
* `camera-layer z:-100, scene-step from:0 to:1` under a `camera-scene` under a `scene` genuinely
|
|
180
|
+
* has two owners afterwards — a scene and a camera, writing different properties for different
|
|
181
|
+
* reasons — and `ownership.test.ts`'s 'an element that is both a scene step and a camera layer'
|
|
182
|
+
* is the standing proof that it still does.
|
|
183
|
+
*
|
|
184
|
+
* The `*=` query is a native prefilter and nothing else, so both halves of the rule are predicates
|
|
185
|
+
* run over what it returned: the candidate must itself *declare* `descendantEffect`, and no nearer
|
|
186
|
+
* host of `hostEffect`'s kind may stand between it and `host`. The first half is not redundant with
|
|
187
|
+
* the query. `[data-kui*="camera-layer"]` matches any attribute *containing* that text, which
|
|
188
|
+
* includes a parameter value — `<img data-kui='fade-up target:".camera-layer"'>` merely names the
|
|
189
|
+
* class it animates, and the scan used to claim it and write `preserve-3d` and a `translate3d` over
|
|
190
|
+
* the author's own effect. {@link declaresEffect} is the same name test the parent walk already
|
|
191
|
+
* uses, applied to the element the walk is about.
|
|
192
|
+
*
|
|
193
|
+
* The cost stays O(matched descendants × depth), not a walk of the subtree.
|
|
194
|
+
*
|
|
195
|
+
* @param host - The authored element the controller was prepared on.
|
|
196
|
+
* @param hostEffect - The host's own primitive name, e.g. `scene`. A nearer element declaring it
|
|
197
|
+
* is what blocks the claim.
|
|
198
|
+
* @param descendantEffect - The primitive name to collect, e.g. `scene-step`.
|
|
199
|
+
* @returns The owned descendants, in document order. Empty when `host` cannot be queried.
|
|
200
|
+
*/
|
|
201
|
+
export declare function ownedDescendants<T extends Element>(host: Element, hostEffect: string, descendantEffect: string): T[];
|
|
202
|
+
export declare function lerp(start: number, end: number, progress: number): number;
|
|
203
|
+
export declare function defaultRaf(win: Window | WindowLike | null | undefined, fn: FrameRequestCallback): number | null;
|
|
204
|
+
export declare function defaultCaf(win: Window | WindowLike | null | undefined, id: number | null | undefined): null;
|
|
205
|
+
/**
|
|
206
|
+
* `globalThis` rather than the resolved window: the window here is routinely a `WindowLike` double
|
|
207
|
+
* with four properties on it, and `setTimeout` is not one of them. Falling back to the real global
|
|
208
|
+
* keeps the default working in every host that has one and leaves injection as the way to control
|
|
209
|
+
* it, instead of making the default depend on how complete the caller's window happens to be.
|
|
210
|
+
*
|
|
211
|
+
* The `as unknown as number` is the usual Node-vs-DOM split — Node's `setTimeout` answers a
|
|
212
|
+
* `Timeout` object, the DOM's a number — and only the round trip back through `clearTimer` cares.
|
|
213
|
+
*/
|
|
214
|
+
export declare function defaultSetTimer(fn: () => void, ms: number): number | null;
|
|
215
|
+
export declare function defaultClearTimer(id: number | null | undefined): void;
|
|
216
|
+
interface ContextWithEnv {
|
|
217
|
+
win?: AnyWindow;
|
|
218
|
+
doc?: AnyDocument;
|
|
219
|
+
reducedMotion?: boolean | {
|
|
220
|
+
enabled?: boolean;
|
|
221
|
+
};
|
|
222
|
+
createCanvas?: () => HTMLCanvasElement | null;
|
|
223
|
+
raf?: RafFunction;
|
|
224
|
+
caf?: CafFunction;
|
|
225
|
+
setTimer?: SetTimerFunction;
|
|
226
|
+
clearTimer?: ClearTimerFunction;
|
|
227
|
+
}
|
|
228
|
+
export declare function resolveEnv(ctx?: ContextWithEnv | PrepareContext | null, env?: AdvancedEnv): ResolvedEnv;
|
|
229
|
+
export declare function isReducedMotion(ctx?: ContextWithEnv | PrepareContext | null): boolean;
|
|
230
|
+
export declare function createEffectInstance(opts?: EffectInstanceOptions): EffectInstance;
|
|
231
|
+
export declare function createInertInstance(destroy?: () => void): EffectInstance;
|
|
232
|
+
export declare function registerInto(target: unknown, primitives: Primitive | Primitive[] | unknown, presets: Preset | Preset[] | unknown, name?: string): Registry | Animator;
|
|
233
|
+
export {};
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* kUInetic 3D Virtual Camera & Depth Projection Module
|
|
3
|
+
*/
|
|
4
|
+
import type { EffectInstance, EffectParams, PrepareContext, Preset, Primitive } from '../core/types.js';
|
|
5
|
+
import type { Registry } from '../core/registry.js';
|
|
6
|
+
import type { Animator } from '../core/animator.js';
|
|
7
|
+
import { type AdvancedEnv, type WindowLike, type RafFunction, type CafFunction, clamp } from './base.js';
|
|
8
|
+
import { type AudioBand } from './audio.js';
|
|
9
|
+
export { clamp };
|
|
10
|
+
export type CameraParamAccessor = EffectParams | {
|
|
11
|
+
num?: (name: string, fallback?: number) => number;
|
|
12
|
+
text?: (name: string, fallback?: string) => string;
|
|
13
|
+
};
|
|
14
|
+
export interface CameraLayer {
|
|
15
|
+
element: HTMLElement;
|
|
16
|
+
depthZ: number;
|
|
17
|
+
}
|
|
18
|
+
export interface CameraOptions {
|
|
19
|
+
depth?: number;
|
|
20
|
+
mouseTilt?: boolean;
|
|
21
|
+
/** Which `audio-source` band pushes the camera forward, or absent/null for none. */
|
|
22
|
+
audio?: AudioBand | null;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Parse depth value from CSS string.
|
|
26
|
+
*/
|
|
27
|
+
export declare function parseDepth(str?: string | null): number;
|
|
28
|
+
/**
|
|
29
|
+
* Pure 3D transform calculation for a single layer.
|
|
30
|
+
*/
|
|
31
|
+
export declare function computeLayerTransform(depthZ: number, cameraZ: number, tiltX?: number, tiltY?: number): string;
|
|
32
|
+
export declare class CameraController {
|
|
33
|
+
container: HTMLElement;
|
|
34
|
+
options: CameraOptions;
|
|
35
|
+
env: AdvancedEnv;
|
|
36
|
+
window: Window | WindowLike | null;
|
|
37
|
+
raf: RafFunction;
|
|
38
|
+
caf: CafFunction;
|
|
39
|
+
layers: CameraLayer[];
|
|
40
|
+
cameraZ: number;
|
|
41
|
+
mouse: {
|
|
42
|
+
x: number;
|
|
43
|
+
y: number;
|
|
44
|
+
targetX: number;
|
|
45
|
+
targetY: number;
|
|
46
|
+
};
|
|
47
|
+
rafId: number | null;
|
|
48
|
+
scrollRafId: number | null;
|
|
49
|
+
audioRafId: number | null;
|
|
50
|
+
/** Last value read for the selected band, 0..1. Stays 0 for a scene with no `audio:`. */
|
|
51
|
+
audioLevel: number;
|
|
52
|
+
isListening: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Container and every depth layer, each ledger opened at that element's first write and shared
|
|
55
|
+
* with every other controller writing to the same element — see `createAdvancedLedgers`.
|
|
56
|
+
*
|
|
57
|
+
* This used to say "an inner scene claims the outer scene's layers", which is backwards: an
|
|
58
|
+
* inner `querySelectorAll` only ever sees its own descendants, so it is the **outer** scene that
|
|
59
|
+
* over-reaches into the inner one. `prepareCameraScene` now scopes the scan with
|
|
60
|
+
* {@link ownedDescendants}, so an outer camera stops at a nested `camera-scene` and the two no
|
|
61
|
+
* longer write one layer's `transform` on alternate frames.
|
|
62
|
+
*
|
|
63
|
+
* Sharing still matters after that fix, and not only for the controllers built directly by the
|
|
64
|
+
* suites: a `camera-layer` that is *also* a `scene-step` has two owners by design, because they
|
|
65
|
+
* are different kinds of host. The ledger is what keeps that case honest.
|
|
66
|
+
*/
|
|
67
|
+
private ledgers;
|
|
68
|
+
constructor(container: HTMLElement, options?: CameraOptions, env?: AdvancedEnv);
|
|
69
|
+
addLayer(element: HTMLElement, depthZ: number): void;
|
|
70
|
+
applyLayer3D(): void;
|
|
71
|
+
bindEvents(): void;
|
|
72
|
+
/**
|
|
73
|
+
* The 3D space itself: the container's perspective and every layer's `preserve-3d`.
|
|
74
|
+
*
|
|
75
|
+
* Separated from {@link start} because the reduced-motion path needs exactly this and none of
|
|
76
|
+
* the listeners or loops below it — see {@link renderStatic}.
|
|
77
|
+
*/
|
|
78
|
+
private applyStage;
|
|
79
|
+
/**
|
|
80
|
+
* The scene composed once, with the camera parked where its travel begins.
|
|
81
|
+
*
|
|
82
|
+
* What a visitor who asked for reduced motion gets instead of nothing, following the decision
|
|
83
|
+
* `shaders.ts` records: a static frame where one genuinely exists. Here it does, and it is most
|
|
84
|
+
* of the effect — `depth` and each layer's `z:` *are* the composition, and the scroll only moves
|
|
85
|
+
* a camera through an arrangement the author already described. One `render()` at `cameraZ = 0`
|
|
86
|
+
* puts every layer at its authored depth through the container's perspective, so the scene keeps
|
|
87
|
+
* its real scale hierarchy and simply does not travel. Without it the layers are written nothing
|
|
88
|
+
* at all and the whole scene collapses flat — the same bug `start()`'s own `render()` call fixed
|
|
89
|
+
* for the live path.
|
|
90
|
+
*
|
|
91
|
+
* Deliberately *not* the scene's end state, which is where the animator leaves a CSS effect under
|
|
92
|
+
* this policy (`openGate`, `core/animator.ts`). "The end" here is `cameraZ = depth`, i.e. the
|
|
93
|
+
* camera pushed all the way through: a layer then sits at `z = depthZ + depth / 2`, which against
|
|
94
|
+
* a `perspective` of `depth` is a 2x blow-up at `z:0` and 10x at `z:400px` of a 1000px scene, with
|
|
95
|
+
* nearer layers passing the viewer entirely. An end state nobody can see is not a still frame.
|
|
96
|
+
*
|
|
97
|
+
* Runs during `prepare`, because it has to — under reduced motion `openGate` marks the element
|
|
98
|
+
* finished and never activates any instance. See `prepareReducedMotion` in `shaders.ts`.
|
|
99
|
+
*/
|
|
100
|
+
renderStatic(): void;
|
|
101
|
+
start(): void;
|
|
102
|
+
stop(): void;
|
|
103
|
+
updateScroll(): void;
|
|
104
|
+
/** The selected band's current value, or 0 for a scene that asked for none. */
|
|
105
|
+
readAudio(): void;
|
|
106
|
+
/**
|
|
107
|
+
* The one frame loop an audio-driven scene runs, doing every read before every write.
|
|
108
|
+
*
|
|
109
|
+
* An audio band changes on its own, without a scroll or a pointer move to hang a frame on, so
|
|
110
|
+
* this scene needs a loop of its own — and then it needs to be the *only* loop, which is why
|
|
111
|
+
* `onScroll` and `startLoop` both stand down while it is running. Three callbacks each reading
|
|
112
|
+
* geometry (`getBoundingClientRect`) or style (`readAudioBand`'s computed fallback) and then
|
|
113
|
+
* writing transforms would force a layout or style recalculation per callback per frame; one
|
|
114
|
+
* pass that reads scroll position, reads the band, steps the pointer spring and only then
|
|
115
|
+
* renders forces at most one.
|
|
116
|
+
*/
|
|
117
|
+
startAudioLoop(): void;
|
|
118
|
+
onScroll(): void;
|
|
119
|
+
onMouseMove(e: MouseEvent | {
|
|
120
|
+
clientX: number;
|
|
121
|
+
clientY: number;
|
|
122
|
+
}): void;
|
|
123
|
+
stepMouse(): boolean;
|
|
124
|
+
startLoop(): void;
|
|
125
|
+
/**
|
|
126
|
+
* Tilt the whole stage toward the pointer.
|
|
127
|
+
*
|
|
128
|
+
* The author's own transform is read here, at the first frame that overwrites it, rather than
|
|
129
|
+
* when the effect activated. Between those two moments sits at least one frame in which the
|
|
130
|
+
* page's own code can write a transform, and a capture taken at activation would both overwrite
|
|
131
|
+
* that write and hand the older value back on destroy as if it had never happened.
|
|
132
|
+
*
|
|
133
|
+
* `claim()` is what makes that true without a private snapshot field: it remembers `transform`'s
|
|
134
|
+
* current value the first time this runs and is a no-op on every call after, so `peek()` always
|
|
135
|
+
* answers with whatever was there just before this method's first write — the ledger already
|
|
136
|
+
* tracks that for `restore()`; `peek()` is just asking it without writing.
|
|
137
|
+
*/
|
|
138
|
+
private renderStageTilt;
|
|
139
|
+
/**
|
|
140
|
+
* Hand `transform` back when the tilt settles at exactly zero.
|
|
141
|
+
*
|
|
142
|
+
* `peek()` reports only what `restore()` would put back, which is the **inline** capture and
|
|
143
|
+
* nothing else — by design (`owned-styles.ts`, and `test/owned-styles.test.ts` asserts it). So
|
|
144
|
+
* `peek() || 'rotateX(0deg) rotateY(0deg)'` was right only for an author who had written the
|
|
145
|
+
* transform inline. For the ordinary case — `.hero { transform: translateY(-20px) }` in a
|
|
146
|
+
* stylesheet — `peek()` answers `''` and the fallback wrote a *fabricated* identity inline,
|
|
147
|
+
* which outranks the class and switches the author's own transform off the moment the effect
|
|
148
|
+
* activates. `start()` renders immediately with the pointer at the synthetic centre, so that is
|
|
149
|
+
* activation, not some edge case.
|
|
150
|
+
*
|
|
151
|
+
* Removing the declaration instead is what actually lands on "the author's own transform": their
|
|
152
|
+
* inline value if they had one, their stylesheet's if they did not, and nothing at all if
|
|
153
|
+
* neither. The `removeProperty` is not a ledger bypass — `claim()` above has already recorded
|
|
154
|
+
* the property, `peek()` answering `''` *is* the ledger saying it found no inline declaration
|
|
155
|
+
* here, and removal is precisely what its own `restore()` does for that capture.
|
|
156
|
+
*
|
|
157
|
+
* Not fixed here: an inline `transform: scale(1.2) !important` comes back through `peek()`
|
|
158
|
+
* without its priority, so while the effect is live at rest a competing `!important` rule the
|
|
159
|
+
* author had deliberately beaten wins again. `restore()` puts the priority back, so it ends at
|
|
160
|
+
* the right value. Closing that needs a per-property give-back on `StyleLedger` (core).
|
|
161
|
+
*
|
|
162
|
+
* @complexity O(1).
|
|
163
|
+
*/
|
|
164
|
+
private restStageTransform;
|
|
165
|
+
render(): void;
|
|
166
|
+
/**
|
|
167
|
+
* `try`/`finally` because the restore must not be hostage to the listener teardown.
|
|
168
|
+
*
|
|
169
|
+
* The animator swallows a throwing instance teardown (`runQuietly(() => instance.destroy())`),
|
|
170
|
+
* and every element this controller reached on its own — the layers — is in no ledger core will
|
|
171
|
+
* ever restore. A `removeEventListener` the page has replaced, or a window torn down under a
|
|
172
|
+
* detached document, would otherwise leave `transform` on each layer permanently.
|
|
173
|
+
*/
|
|
174
|
+
destroy(): void;
|
|
175
|
+
}
|
|
176
|
+
export declare function prepareCameraScene(el: Element, params: EffectParams, ctx?: PrepareContext | null): EffectInstance;
|
|
177
|
+
export declare const CAMERA_PARAMETERS: {
|
|
178
|
+
depth: {
|
|
179
|
+
type: "number";
|
|
180
|
+
default: string;
|
|
181
|
+
minimum: number;
|
|
182
|
+
maximum: number;
|
|
183
|
+
cssProperty: string;
|
|
184
|
+
};
|
|
185
|
+
'mouse-tilt': {
|
|
186
|
+
type: "keyword";
|
|
187
|
+
default: string;
|
|
188
|
+
keywords: string[];
|
|
189
|
+
cssProperty: string;
|
|
190
|
+
};
|
|
191
|
+
/**
|
|
192
|
+
* Which `audio-source` band pushes the camera forward, if any.
|
|
193
|
+
*
|
|
194
|
+
* Same name, same words and the same `off` default as the `shaders` primitive's: one spelling
|
|
195
|
+
* for "follow this band" across this directory rather than a second word per consumer. Opt-in
|
|
196
|
+
* for the reason that one is — the value is written by another primitive, and a scene that read
|
|
197
|
+
* it unasked would start pulsing the moment an unrelated `audio-source` appeared above it.
|
|
198
|
+
*
|
|
199
|
+
* Turning it on also changes *how* the scene renders: see `startAudioLoop`, which becomes the
|
|
200
|
+
* scene's only frame loop.
|
|
201
|
+
*/
|
|
202
|
+
audio: {
|
|
203
|
+
type: "keyword";
|
|
204
|
+
default: string;
|
|
205
|
+
keywords: string[];
|
|
206
|
+
cssProperty: string;
|
|
207
|
+
};
|
|
208
|
+
};
|
|
209
|
+
/**
|
|
210
|
+
* `camera-layer`'s own parameters. `z` is read straight off the raw `data-kui` attribute by
|
|
211
|
+
* `prepareCameraScene`'s own regex (see its `layerEls` loop above), not through this primitive's
|
|
212
|
+
* `prepare` — declaring it here is only what lets the compiler accept `z:-400` on a layer element
|
|
213
|
+
* instead of warning "unknown parameter" once "unknown effect" (below) is fixed.
|
|
214
|
+
*/
|
|
215
|
+
export declare const CAMERA_LAYER_PARAMETERS: {
|
|
216
|
+
z: {
|
|
217
|
+
type: "number";
|
|
218
|
+
default: string;
|
|
219
|
+
minimum: number;
|
|
220
|
+
maximum: number;
|
|
221
|
+
cssProperty: string;
|
|
222
|
+
};
|
|
223
|
+
};
|
|
224
|
+
/**
|
|
225
|
+
* `camera-layer` never runs on its own: `prepareCameraScene`'s `[data-kui*="camera-layer"]` scan
|
|
226
|
+
* reads each layer's `z:` directly off its attribute, and the parent `CameraController` is what
|
|
227
|
+
* writes `transform`/`transform-style` to it every frame (`applyLayer3D`, `render`). Without a
|
|
228
|
+
* registered primitive for the name, every `camera-layer` element compiled as an unrecognised
|
|
229
|
+
* effect — the scene still positioned it correctly, but the console warned "unknown effect
|
|
230
|
+
* camera-layer" once per layer. This primitive exists only so the name resolves; it deliberately
|
|
231
|
+
* does nothing of its own.
|
|
232
|
+
*/
|
|
233
|
+
export declare function prepareCameraLayer(): EffectInstance;
|
|
234
|
+
export declare const CAMERA_PRIMITIVES: Primitive[];
|
|
235
|
+
export declare const CAMERA_PRESETS: Preset[];
|
|
236
|
+
export declare function registerCamera(target: unknown): Registry | Animator;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* kUInetic Fluid Cursor - Interactive Liquid Cursor Trails
|
|
3
|
+
*/
|
|
4
|
+
import type { EffectInstance, EffectParams, PrepareContext, Preset, Primitive } from '../core/types.js';
|
|
5
|
+
import type { Registry } from '../core/registry.js';
|
|
6
|
+
import type { Animator } from '../core/animator.js';
|
|
7
|
+
import { type AdvancedEnv, type WindowLike, type DocumentLike, type RafFunction, type CafFunction, clamp } from './base.js';
|
|
8
|
+
export { clamp };
|
|
9
|
+
export type FluidParamAccessor = EffectParams | {
|
|
10
|
+
num?: (name: string, fallback?: number) => number;
|
|
11
|
+
text?: (name: string, fallback?: string) => string;
|
|
12
|
+
};
|
|
13
|
+
export interface FluidDrop {
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
vx: number;
|
|
17
|
+
vy: number;
|
|
18
|
+
size: number;
|
|
19
|
+
alpha: number;
|
|
20
|
+
color: string;
|
|
21
|
+
viscosity?: number;
|
|
22
|
+
}
|
|
23
|
+
export interface FluidTrailOptions {
|
|
24
|
+
size?: number;
|
|
25
|
+
viscosity?: number;
|
|
26
|
+
color?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface FluidClient {
|
|
29
|
+
options: FluidTrailOptions;
|
|
30
|
+
el?: Element;
|
|
31
|
+
}
|
|
32
|
+
export declare function stepFluidDrop(drop: FluidDrop, friction: number): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Size the canvas backing store *and* its CSS box from the same numbers.
|
|
35
|
+
*
|
|
36
|
+
* The CSS box used to be a fixed `100vw`/`100vh` in {@link FluidTrail.setupCanvas}, which reads
|
|
37
|
+
* from the visual/layout viewport rather than `window.innerWidth`/`innerHeight`. On iOS Safari with
|
|
38
|
+
* the address bar visible those two disagree, so the browser scales the backing store to fit the
|
|
39
|
+
* CSS box and a drop spawned at `clientY` renders off from the pointer — the same defect
|
|
40
|
+
* `syncCanvasDimensions` (`shaders.ts`) fixes for the shader tier, by the same move: pin the CSS box
|
|
41
|
+
* to the exact `innerWidth`/`innerHeight` the backing store is derived from, every time either is
|
|
42
|
+
* synced (see {@link syncCanvasStyleBox}).
|
|
43
|
+
*/
|
|
44
|
+
export declare function syncCanvasSize(canvas: HTMLCanvasElement | null, win: Window | WindowLike | null): number;
|
|
45
|
+
export declare class FluidTrail {
|
|
46
|
+
options: FluidTrailOptions;
|
|
47
|
+
env: AdvancedEnv;
|
|
48
|
+
window: Window | WindowLike | null;
|
|
49
|
+
document: Document | DocumentLike | null;
|
|
50
|
+
createCanvas: () => HTMLCanvasElement | null;
|
|
51
|
+
raf: RafFunction;
|
|
52
|
+
caf: CafFunction;
|
|
53
|
+
drops: FluidDrop[];
|
|
54
|
+
canvas: HTMLCanvasElement | null;
|
|
55
|
+
ctx: CanvasRenderingContext2D | null;
|
|
56
|
+
rafId: number | null;
|
|
57
|
+
isListening: boolean;
|
|
58
|
+
lastMouse: {
|
|
59
|
+
x: number;
|
|
60
|
+
y: number;
|
|
61
|
+
};
|
|
62
|
+
hasLastMouse: boolean;
|
|
63
|
+
wasOutside: boolean;
|
|
64
|
+
refCount: number;
|
|
65
|
+
clients: Map<number, FluidClient>;
|
|
66
|
+
activeClients: Map<number, FluidClient>;
|
|
67
|
+
private nextClientId;
|
|
68
|
+
onResize?: () => void;
|
|
69
|
+
onPointerMove?: (e: PointerEvent | {
|
|
70
|
+
clientX: number;
|
|
71
|
+
clientY: number;
|
|
72
|
+
}) => void;
|
|
73
|
+
mapKey: object;
|
|
74
|
+
constructor(options?: FluidTrailOptions, env?: AdvancedEnv);
|
|
75
|
+
acquire(): boolean;
|
|
76
|
+
release(): void;
|
|
77
|
+
registerClient(options: FluidTrailOptions, el?: Element): number;
|
|
78
|
+
activateClient(id: number): boolean;
|
|
79
|
+
deactivateClient(id: number): void;
|
|
80
|
+
/**
|
|
81
|
+
* Wipe the overlay when the last client stands down.
|
|
82
|
+
*
|
|
83
|
+
* `draw()` clears the canvas at the *start* of a frame, so stopping the loop leaves whatever was
|
|
84
|
+
* in flight painted. The overlay is `position: fixed` at `z-index: 9998` across the whole
|
|
85
|
+
* viewport, so a `fluid-trail` on `on:pointerenter`/`pointerleave` — or an author's
|
|
86
|
+
* `control.cancel()` mid-move — left a frozen blob of drops over the entire page until something
|
|
87
|
+
* reactivated it or the element was destroyed.
|
|
88
|
+
*
|
|
89
|
+
* The canvas itself stays mounted on purpose: registration happens at prepare, so the last
|
|
90
|
+
* *unregister* owns the teardown and no client can have the canvas pulled from under it.
|
|
91
|
+
*
|
|
92
|
+
* @complexity O(1).
|
|
93
|
+
*/
|
|
94
|
+
private clearOverlay;
|
|
95
|
+
unregisterClient(id: number): void;
|
|
96
|
+
setupCanvas(): boolean;
|
|
97
|
+
attachListeners(): void;
|
|
98
|
+
detachListeners(): void;
|
|
99
|
+
init(): boolean;
|
|
100
|
+
private findClientByTarget;
|
|
101
|
+
private findClientByCoords;
|
|
102
|
+
resolveClientOwner(e: {
|
|
103
|
+
clientX: number;
|
|
104
|
+
clientY: number;
|
|
105
|
+
target?: EventTarget | null;
|
|
106
|
+
}): FluidClient | null;
|
|
107
|
+
getOptionsAt(x: number, y: number): FluidTrailOptions | null;
|
|
108
|
+
spawnDrop(x: number, y: number, vx: number, vy: number, customOpts?: FluidTrailOptions): void;
|
|
109
|
+
startLoop(): void;
|
|
110
|
+
stopLoop(): void;
|
|
111
|
+
update(): void;
|
|
112
|
+
draw(): void;
|
|
113
|
+
destroy(): void;
|
|
114
|
+
}
|
|
115
|
+
export declare function getSharedFluidTrail(env?: AdvancedEnv): FluidTrail;
|
|
116
|
+
/**
|
|
117
|
+
* Install (or clear) the trail for one document.
|
|
118
|
+
*
|
|
119
|
+
* Same asymmetry `setSharedShaderRenderer` closes, for the same reason: `destroy()` deletes only
|
|
120
|
+
* `this.mapKey`, so an instance stored under a different document's key outlives its own teardown
|
|
121
|
+
* and is handed to every later lookup for that document with its canvas already removed. The
|
|
122
|
+
* instance's own key wins; a mismatched caller key is cleared rather than left dangling.
|
|
123
|
+
*/
|
|
124
|
+
export declare function setSharedFluidTrail(instance: FluidTrail | null, env?: AdvancedEnv): void;
|
|
125
|
+
export declare function prepareFluidCursor(el: Element, params: EffectParams, ctx?: PrepareContext | null): EffectInstance;
|
|
126
|
+
export declare const FLUID_PARAMETERS: {
|
|
127
|
+
size: {
|
|
128
|
+
type: "number";
|
|
129
|
+
default: string;
|
|
130
|
+
minimum: number;
|
|
131
|
+
maximum: number;
|
|
132
|
+
cssProperty: string;
|
|
133
|
+
};
|
|
134
|
+
viscosity: {
|
|
135
|
+
type: "number";
|
|
136
|
+
default: string;
|
|
137
|
+
minimum: number;
|
|
138
|
+
maximum: number;
|
|
139
|
+
cssProperty: string;
|
|
140
|
+
};
|
|
141
|
+
color: {
|
|
142
|
+
type: "color";
|
|
143
|
+
default: string;
|
|
144
|
+
cssProperty: string;
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
export declare const FLUID_PRIMITIVES: Primitive[];
|
|
148
|
+
export declare const FLUID_PRESETS: Preset[];
|
|
149
|
+
export declare function registerFluidCursor(target: unknown): Registry | Animator;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Low-level WebGL helper utilities for kUInetic Shaders
|
|
3
|
+
*/
|
|
4
|
+
export interface ProgramLocations {
|
|
5
|
+
program?: WebGLProgram;
|
|
6
|
+
a_position?: number;
|
|
7
|
+
u_image?: WebGLUniformLocation | null;
|
|
8
|
+
u_image_to?: WebGLUniformLocation | null;
|
|
9
|
+
u_uvOrigin?: WebGLUniformLocation | null;
|
|
10
|
+
u_uvScale?: WebGLUniformLocation | null;
|
|
11
|
+
u_maskBox?: WebGLUniformLocation | null;
|
|
12
|
+
u_maskRx?: WebGLUniformLocation | null;
|
|
13
|
+
u_maskRy?: WebGLUniformLocation | null;
|
|
14
|
+
u_maskAlpha?: WebGLUniformLocation | null;
|
|
15
|
+
u_time?: WebGLUniformLocation | null;
|
|
16
|
+
u_strength?: WebGLUniformLocation | null;
|
|
17
|
+
u_frequency?: WebGLUniformLocation | null;
|
|
18
|
+
u_chromatic?: WebGLUniformLocation | null;
|
|
19
|
+
u_iridescence?: WebGLUniformLocation | null;
|
|
20
|
+
u_mouse?: WebGLUniformLocation | null;
|
|
21
|
+
u_tint?: WebGLUniformLocation | null;
|
|
22
|
+
u_color1?: WebGLUniformLocation | null;
|
|
23
|
+
u_color2?: WebGLUniformLocation | null;
|
|
24
|
+
u_duotone?: WebGLUniformLocation | null;
|
|
25
|
+
u_blend?: WebGLUniformLocation | null;
|
|
26
|
+
u_progress?: WebGLUniformLocation | null;
|
|
27
|
+
u_seed?: WebGLUniformLocation | null;
|
|
28
|
+
u_scale?: WebGLUniformLocation | null;
|
|
29
|
+
u_warp?: WebGLUniformLocation | null;
|
|
30
|
+
u_grain?: WebGLUniformLocation | null;
|
|
31
|
+
u_hue?: WebGLUniformLocation | null;
|
|
32
|
+
u_detail?: WebGLUniformLocation | null;
|
|
33
|
+
u_bands?: WebGLUniformLocation | null;
|
|
34
|
+
u_colorCount?: WebGLUniformLocation | null;
|
|
35
|
+
/** Element 0 of `vec4 u_colors[5]`; one `uniform4fv` of 20 floats fills the whole array. */
|
|
36
|
+
u_colors?: WebGLUniformLocation | null;
|
|
37
|
+
/** Which stencil the generative program cuts its field with. See `glyphMask()` in `glsl.ts`. */
|
|
38
|
+
u_maskMode?: WebGLUniformLocation | null;
|
|
39
|
+
/** `hover:` as bits — 1 stir, 2 light, 3 both. See `kuiHoverFalloff()` in `glsl.ts`. */
|
|
40
|
+
u_hover?: WebGLUniformLocation | null;
|
|
41
|
+
/** The colour the generative field is composited over, straight (non-premultiplied) RGBA. */
|
|
42
|
+
u_backdrop?: WebGLUniformLocation | null;
|
|
43
|
+
/** The field's orientation in **radians**; also the axis `motion: drift` travels along. */
|
|
44
|
+
u_angle?: WebGLUniformLocation | null;
|
|
45
|
+
/** `motion:` — 0 evolve, 1 drift, 2 swirl. */
|
|
46
|
+
u_motion?: WebGLUniformLocation | null;
|
|
47
|
+
}
|
|
48
|
+
export declare function compileShader(gl: WebGLRenderingContext | WebGL2RenderingContext, type: number, source: string): WebGLShader | null;
|
|
49
|
+
export declare function createProgram(gl: WebGLRenderingContext | WebGL2RenderingContext, vsSource: string, fsSource: string): WebGLProgram | null;
|
|
50
|
+
export declare function extractLocations(gl: WebGLRenderingContext | WebGL2RenderingContext, program: WebGLProgram | null): ProgramLocations | null;
|
|
51
|
+
export declare function disposeGLResources(gl: WebGLRenderingContext | WebGL2RenderingContext | null, quadBuffer: WebGLBuffer | null, programs: Record<string, ProgramLocations | WebGLProgram | null | undefined>): void;
|
|
52
|
+
export declare function createGLTexture(gl: WebGLRenderingContext | WebGL2RenderingContext, source: TexImageSource): WebGLTexture | null;
|