kuinetic 0.1.4 → 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 +15147 -6039
- package/dist/kuinetic.all.min.js +2 -0
- package/dist/kuinetic.css +2801 -318
- package/dist/kuinetic.js +15147 -6038
- 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 +699 -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/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 +1 -1
- package/dist/types/effects/catalog/text-shared.d.ts +86 -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 +124 -4
- 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-7WMNPIOZ.mjs +0 -4883
- package/dist/esm/chunk-JT4PZL3A.mjs +0 -773
- package/dist/esm/chunk-TJDDIQRG.mjs +0 -1290
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An authored `<angle>` as a number of degrees.
|
|
3
|
+
*
|
|
4
|
+
* Copied from `degreesOf` in `src/effects/carousel/index.ts:523` rather than imported: that file is
|
|
5
|
+
* part of the default catalog, and a value import from it would pull the catalog into this tier's
|
|
6
|
+
* bundle to save nine lines. See `src/3d/register.ts` for the same argument at length.
|
|
7
|
+
*
|
|
8
|
+
* It has to exist at all because `core/js-params.ts`'s `toNumber` (js-params.ts:165) returns its
|
|
9
|
+
* *fallback* for any unit other than `''` and `%` — `params.num('spin')` on a validated `"360deg"`
|
|
10
|
+
* reads back as `0`. `core/params.ts` accepts every CSS angle unit and normalises only the bare and
|
|
11
|
+
* `d`-suffixed spellings to `deg`, so a value reaching here can legitimately be `0.05turn` or
|
|
12
|
+
* `1.2rad`, and `Number('0.05turn')` is `NaN`.
|
|
13
|
+
*
|
|
14
|
+
* Falls back rather than throwing on an unrecognised unit, for the reason every reader in this
|
|
15
|
+
* library does: the value has already been validated, so an unfamiliar spelling here means this
|
|
16
|
+
* function is behind `params.ts`, and a model that does not spin is a better answer than one that
|
|
17
|
+
* throws during `prepare`.
|
|
18
|
+
*
|
|
19
|
+
* @param value - A validated CSS angle.
|
|
20
|
+
* @param fallbackDeg - Used when the value is not an angle this function converts.
|
|
21
|
+
* @returns Degrees.
|
|
22
|
+
* @complexity O(n) time in value length; O(1) space.
|
|
23
|
+
*/
|
|
24
|
+
export declare function degreesOf(value: string, fallbackDeg: number): number;
|
|
25
|
+
/**
|
|
26
|
+
* Clamp to an inclusive range.
|
|
27
|
+
*
|
|
28
|
+
* @complexity O(1).
|
|
29
|
+
*/
|
|
30
|
+
export declare function clamp(val: number, min: number, max: number): number;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dev-mode diagnostic: which ancestor is clipping the scene.
|
|
3
|
+
*
|
|
4
|
+
* Adapted from `warnFlatteningAncestor` in `src/effects/carousel/index.ts:129-175` — copied rather
|
|
5
|
+
* than imported, for the bundle reason `src/3d/register.ts` sets out.
|
|
6
|
+
*
|
|
7
|
+
* **Why this tier needs one at all.** A canvas is a canvas: an ancestor cannot flatten what it
|
|
8
|
+
* renders the way it flattens a CSS `preserve-3d` subtree. But the *host* is an ordinary element,
|
|
9
|
+
* and an ancestor that clips it clips the render with it. The symptom — "the 3D scene is cut in
|
|
10
|
+
* half, or gone" — points squarely at this effect while the cause is three levels up, and that gap
|
|
11
|
+
* is the whole value of naming the element. So: yes, its own copy.
|
|
12
|
+
*
|
|
13
|
+
* **But a narrower table than the carousel's.** The original tests five properties, because all
|
|
14
|
+
* five defeat `transform-style: preserve-3d`. Only two of them clip a canvas. `opacity` below 1, a
|
|
15
|
+
* `filter` and a `backdrop-filter` are ordinary compositing on an ordinary element here — a dimmed
|
|
16
|
+
* or blurred 3D hero is a design, not a bug, and warning about it would be a false positive on a
|
|
17
|
+
* deliberate choice. Firing on things that are fine is how a diagnostic teaches people to ignore
|
|
18
|
+
* it, which is the same reason the original stops at `<body>`.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* The slice of `PrepareContext` this needs. A real one satisfies it structurally.
|
|
22
|
+
*
|
|
23
|
+
* Declared narrow rather than importing `PrepareContext` so a test can drive the walk with a fake
|
|
24
|
+
* `getComputedStyle` and no realm, which is the only way to reach the guilty-ancestor branches
|
|
25
|
+
* under jsdom.
|
|
26
|
+
*/
|
|
27
|
+
export interface FlatteningContext {
|
|
28
|
+
win: {
|
|
29
|
+
getComputedStyle?: (el: Element) => CSSStyleDeclaration | null;
|
|
30
|
+
};
|
|
31
|
+
warn(message: string): void;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Walk the ancestors and warn about the first one that clips the scene.
|
|
35
|
+
*
|
|
36
|
+
* A diagnostic, not a fix: there is nothing this library can safely do about an ancestor it does
|
|
37
|
+
* not own — removing an `overflow: hidden` a page relies on to clip something else would trade a
|
|
38
|
+
* cropped model for a broken layout. Naming the element is the whole value.
|
|
39
|
+
*
|
|
40
|
+
* Stops at the first offender rather than listing all of them: the first one already clips
|
|
41
|
+
* everything below it, so the rest are consequences of a page the author has yet to change. Stops
|
|
42
|
+
* at `<body>` because a page-level `overflow-x: hidden` on `<html>`/`<body>` — which is on a large
|
|
43
|
+
* fraction of all sites — would otherwise fire on every model ever authored.
|
|
44
|
+
*
|
|
45
|
+
* @param el - The model host.
|
|
46
|
+
* @param ctx - Effect context, for the window (`getComputedStyle`) and the warning sink.
|
|
47
|
+
* @complexity O(d) time in tree depth, once per instance; O(1) space.
|
|
48
|
+
*/
|
|
49
|
+
export declare function warnClippingAncestor(el: Element, ctx: FlatteningContext): void;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* kUInetic 3D — real geometry, opt-in.
|
|
3
|
+
*
|
|
4
|
+
* Tier 2. A `<div data-kui="model-3d src:…">` becomes a glTF model on a canvas the library inserts
|
|
5
|
+
* and owns, with the div's own children painting over it. One div, all settings: there is no child
|
|
6
|
+
* element per mesh, per light or per camera, because those would be DOM as bookkeeping rather than
|
|
7
|
+
* content. See `docs/3d-tier-grammar.md`.
|
|
8
|
+
*
|
|
9
|
+
* Reached only by subpath, exactly like `kuinetic/advanced`: the default entry never imports this,
|
|
10
|
+
* so a page that does not ask for 3D does not pay a byte for it. It also does not depend on
|
|
11
|
+
* `kuinetic/advanced` — the two are siblings, and either ships without the other.
|
|
12
|
+
*
|
|
13
|
+
* **The renderer is not here yet.** This tier currently mounts the canvas, claims the host's
|
|
14
|
+
* properties, resolves the `target:`/`poster:` fallback and tears all of it back down. It imports
|
|
15
|
+
* no three.js and requests no GL context.
|
|
16
|
+
*/
|
|
17
|
+
import type { Registry } from '../core/registry.js';
|
|
18
|
+
import type { Animator } from '../core/animator.js';
|
|
19
|
+
export { registerModel3D, prepareModel3D, resolveModelOptions, MODEL_3D_PARAMETERS, MODEL_3D_PRIMITIVE, MODEL_3D_PRIMITIVES, MODEL_3D_PRESETS, type ModelOptions, type ModelAxis, type LightRig, } from './model-3d.js';
|
|
20
|
+
export { registerInto } from './register.js';
|
|
21
|
+
export { degreesOf, clamp } from './angles.js';
|
|
22
|
+
export { detectWebGL } from './webgl.js';
|
|
23
|
+
export { warnClippingAncestor, type FlatteningContext } from './flattening.js';
|
|
24
|
+
/**
|
|
25
|
+
* Register every 3D module into a kUInetic `Registry` or `Animator`.
|
|
26
|
+
*
|
|
27
|
+
* Named `register3D`, not `registerThreeD`: `registerThreeD` is already taken by
|
|
28
|
+
* `src/effects/three-d/` — the CSS-transform catalog that ships `card-flip-x`, `cube-rotate` and
|
|
29
|
+
* `fold-panel` in the default entry. The two are unrelated and confusingly close in name; this one
|
|
30
|
+
* is the WebGL tier.
|
|
31
|
+
*
|
|
32
|
+
* @param target - A `Registry`, an `Animator`, or anything carrying either shape.
|
|
33
|
+
* @returns The registry that was written to, so callers can chain.
|
|
34
|
+
* @complexity O(n) in primitives plus presets.
|
|
35
|
+
*/
|
|
36
|
+
export declare function register3D(target: unknown): Registry | Animator;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `model-3d` — one div, one glTF model, one canvas.
|
|
3
|
+
*
|
|
4
|
+
* The grammar is `docs/3d-tier-grammar.md`; this file is the half of it that does not draw.
|
|
5
|
+
* It owns the canvas, the host's two claimed properties, the `target:`/`poster:` fallback and the
|
|
6
|
+
* teardown. It imports no renderer, requests no GL context and paints nothing. Everything here is
|
|
7
|
+
* exercisable in jsdom, which is deliberate: a skeleton that stubbed `prepare()` into an inert
|
|
8
|
+
* no-op would make `channels` a lie — declaring properties it never writes — and would prove only
|
|
9
|
+
* that a name registers.
|
|
10
|
+
*
|
|
11
|
+
* ```html
|
|
12
|
+
* <div data-kui="model-3d src:/models/robot.glb spin:360deg light:studio target:img">
|
|
13
|
+
* <h2>Meet the robot</h2>
|
|
14
|
+
* <img src="/img/robot.jpg" alt="A red toy robot" />
|
|
15
|
+
* </div>
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
import type { EffectInstance, EffectParams, ParameterSchema, PrepareContext, Preset, Primitive } from '../core/types.js';
|
|
19
|
+
import type { Registry } from '../core/registry.js';
|
|
20
|
+
import type { Animator } from '../core/animator.js';
|
|
21
|
+
declare const AXES: readonly ["x", "y", "z"];
|
|
22
|
+
declare const LIGHT_RIGS: readonly ["studio", "key", "rim", "flat"];
|
|
23
|
+
export type ModelAxis = (typeof AXES)[number];
|
|
24
|
+
export type LightRig = (typeof LIGHT_RIGS)[number];
|
|
25
|
+
/**
|
|
26
|
+
* Everything `prepare()` decided, in the form the controller consumes.
|
|
27
|
+
*
|
|
28
|
+
* Split from the controller so the reading of the attribute and the writing to the DOM are two
|
|
29
|
+
* testable halves: a suite can assert what `src:`/`spin:`/`target:` resolved to without a document,
|
|
30
|
+
* and assert what got mounted without re-deriving the parameters.
|
|
31
|
+
*/
|
|
32
|
+
export interface ModelOptions {
|
|
33
|
+
/** The glTF/GLB URL. Empty means there is nothing to render, whatever else was authored. */
|
|
34
|
+
src: string;
|
|
35
|
+
/** Total turn across the element's scroll pass, in degrees. Not a rate. */
|
|
36
|
+
spinDeg: number;
|
|
37
|
+
axis: ModelAxis;
|
|
38
|
+
/** Camera elevation in degrees, clamped to ±{@link MAX_TILT_DEG}. Positive is above. */
|
|
39
|
+
tiltDeg: number;
|
|
40
|
+
light: LightRig;
|
|
41
|
+
/**
|
|
42
|
+
* The element `target:` named, already inside the host. Shown when nothing renders, hidden when
|
|
43
|
+
* something does. The library never creates this one.
|
|
44
|
+
*/
|
|
45
|
+
fallbackEl: Element | null;
|
|
46
|
+
/** A still-image URL. Used only when `target:` named nothing — see the grammar doc's §4. */
|
|
47
|
+
posterUrl: string;
|
|
48
|
+
/** Whether to mount a canvas at all. False under reduced motion, no WebGL, or no `src:`. */
|
|
49
|
+
render: boolean;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Turn the validated attribute into the decisions the controller acts on.
|
|
53
|
+
*
|
|
54
|
+
* `render` is the whole point of the function: three unrelated reasons collapse into one boolean,
|
|
55
|
+
* so the controller has one branch instead of three and every caller agrees on what "nothing is
|
|
56
|
+
* going to draw" means. Nothing renders without a `src:`, nothing renders under reduced motion
|
|
57
|
+
* (the grammar's §4 — a spin's end is a camera position, not a design, so the fallback is a still
|
|
58
|
+
* image and never the end state), and nothing renders without WebGL 2.
|
|
59
|
+
*
|
|
60
|
+
* @complexity O(n) in matches for the `target:` query; O(1) otherwise.
|
|
61
|
+
*/
|
|
62
|
+
export declare function resolveModelOptions(el: Element, params: EffectParams, ctx: PrepareContext): ModelOptions;
|
|
63
|
+
/**
|
|
64
|
+
* Wire up one `model-3d` host.
|
|
65
|
+
*
|
|
66
|
+
* `ctx` is required, unlike `camera-3d.ts`'s `prepareCameraScene`, which takes it optional to be
|
|
67
|
+
* defensive about direct construction. `Primitive.prepare`'s own signature already says the
|
|
68
|
+
* animator passes a real one, and every `ctx?.` arm underneath an optional parameter is a branch
|
|
69
|
+
* that only a test can reach — under this repo's 100% branch threshold that is a branch written to
|
|
70
|
+
* be covered rather than to be right. A suite constructs a context object instead.
|
|
71
|
+
*
|
|
72
|
+
* @param el - The authored host.
|
|
73
|
+
* @param params - Validated parameters; a primitive never sees a raw author string.
|
|
74
|
+
* @param ctx - The prepare context, for the document, the host's ledger, and the warning sink.
|
|
75
|
+
* @returns A lifecycle handle. Nothing has started — the animator decides when.
|
|
76
|
+
* @complexity O(d) in tree depth for the clipping diagnostic; O(1) otherwise.
|
|
77
|
+
*/
|
|
78
|
+
export declare function prepareModel3D(el: Element, params: EffectParams, ctx: PrepareContext): EffectInstance;
|
|
79
|
+
/**
|
|
80
|
+
* `model-3d`'s parameters.
|
|
81
|
+
*
|
|
82
|
+
* Every custom property is namespaced `--kui-model-*`, and that is not tidiness. A custom property
|
|
83
|
+
* published on a host inherits into its entire subtree, and three of these names are already taken:
|
|
84
|
+
* `--kui-tilt` is read by `src/css/carousel.css:77`, so a model containing a carousel would tilt
|
|
85
|
+
* the ring; `--kui-axis` is read by `src/css/text.css:360` as a `font-variation-settings` tag, so
|
|
86
|
+
* `axis:y` would hand every variable-font descendant `font-variation-settings: y 100`; and
|
|
87
|
+
* `--kui-poster` belongs to `effects/catalog/media.ts:325`. `--kui-progress` was lost this way once
|
|
88
|
+
* already. `target:` keeps the shared `--kui-target` spelling on purpose — it is one convention
|
|
89
|
+
* across the library (`advanced/audio.ts:828`, `scroll-mechanics/primitives.ts:727`) and, being
|
|
90
|
+
* `text`, it is dropped before the stylesheet and can collide with nothing.
|
|
91
|
+
*/
|
|
92
|
+
export declare const MODEL_3D_PARAMETERS: ParameterSchema;
|
|
93
|
+
/**
|
|
94
|
+
* The primitive.
|
|
95
|
+
*
|
|
96
|
+
* `channels` names both properties this writes to the host — see {@link HOST_STYLE} for why there
|
|
97
|
+
* are two. It deliberately does *not* name `display`, which goes to a `target:`-named descendant
|
|
98
|
+
* and never to the host: `findConflicts` (`core/channels.ts:223`) groups claims per compiled host
|
|
99
|
+
* element, so declaring it would make `model-3d` falsely conflict with any host-level effect that
|
|
100
|
+
* claims `display`, over a write that never lands on the host.
|
|
101
|
+
*
|
|
102
|
+
* `reducedMotion: 'disable'` is what makes the animator refuse to activate this instance, and the
|
|
103
|
+
* still image is therefore mounted in `prepare` precisely because nothing else runs — the same
|
|
104
|
+
* arrangement `camera-scene` and `shaders` use.
|
|
105
|
+
*/
|
|
106
|
+
export declare const MODEL_3D_PRIMITIVE: Primitive;
|
|
107
|
+
export declare const MODEL_3D_PRIMITIVES: Primitive[];
|
|
108
|
+
export declare const MODEL_3D_PRESETS: Preset[];
|
|
109
|
+
/**
|
|
110
|
+
* Register `model-3d` onto a `Registry`, an `Animator`, or anything carrying either shape.
|
|
111
|
+
*
|
|
112
|
+
* @complexity O(1).
|
|
113
|
+
*/
|
|
114
|
+
export declare function registerModel3D(target: unknown): Registry | Animator;
|
|
115
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How this tier is handed a registry.
|
|
3
|
+
*
|
|
4
|
+
* A near-copy of `registerInto`/`asRegistry`/`hasRegistrarShape` from `src/advanced/base.ts:519-568`
|
|
5
|
+
* — deliberately copied rather than imported. `kuinetic/3d` ships as its own `<script>` bundle and
|
|
6
|
+
* its own subpath, and importing a sibling tier's helper would mean you cannot ship 3D without also
|
|
7
|
+
* shipping advanced. The originals stay the reference implementation; if the shape gate's rule ever
|
|
8
|
+
* changes, both move, and `test/3d-register-gate.test.ts` mirrors
|
|
9
|
+
* `src/advanced/__tests__/register-gate.test.ts` case for case so a drift shows up as a failure
|
|
10
|
+
* rather than as a browser bug.
|
|
11
|
+
*/
|
|
12
|
+
import type { Preset, Primitive } from '../core/types.js';
|
|
13
|
+
import type { Registry } from '../core/registry.js';
|
|
14
|
+
import type { Animator } from '../core/animator.js';
|
|
15
|
+
/**
|
|
16
|
+
* Register one module's primitives and presets onto a `Registry`, an `Animator`, or anything
|
|
17
|
+
* carrying either shape.
|
|
18
|
+
*
|
|
19
|
+
* @param target - The registry, the animator, or a host exposing one as `.registry`.
|
|
20
|
+
* @param primitives - One primitive or a list of them.
|
|
21
|
+
* @param presets - One preset or a list of them.
|
|
22
|
+
* @param name - Spelled into the thrown message, so it names the function the consumer called.
|
|
23
|
+
* @returns `target`, so callers can chain.
|
|
24
|
+
* @complexity O(n) in primitives plus presets.
|
|
25
|
+
*/
|
|
26
|
+
export declare function registerInto(target: unknown, primitives: Primitive | Primitive[], presets: Preset | Preset[], name?: string): Registry | Animator;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Does this environment have WebGL 2 at all?
|
|
3
|
+
*
|
|
4
|
+
* **This deliberately does not request a context.** `getContext('webgl2')` is the only answer that
|
|
5
|
+
* is true in every sense, and it is also an allocation: on a machine at its context limit it evicts
|
|
6
|
+
* a live one, and in a browser with a blocklisted GPU it can take tens of milliseconds. A presence
|
|
7
|
+
* check is cheap, synchronous, and wrong only in the direction that is safe — an environment that
|
|
8
|
+
* has the constructor but refuses a context falls through to the renderer's own failure path, which
|
|
9
|
+
* shows the same still image this one does.
|
|
10
|
+
*
|
|
11
|
+
* It is also the only probe that works before there is a renderer to fail. The skeleton has to
|
|
12
|
+
* decide canvas-or-fallback in `prepare()`, and it has no GL code to ask.
|
|
13
|
+
*
|
|
14
|
+
* Not a field on `core/capabilities.ts`'s `Capabilities`, and not added to it: that record is the
|
|
15
|
+
* *core* feature-detection surface, every entry of which gates something core renders. A tier that
|
|
16
|
+
* is opt-in by subpath should not widen core's public type to hold a flag core never reads.
|
|
17
|
+
*
|
|
18
|
+
* @param win - The window to interrogate. Injected rather than read off the global so a test can
|
|
19
|
+
* drive both answers; jsdom defines no `WebGL2RenderingContext`, so the real one is always
|
|
20
|
+
* `false` there and the mounted-canvas path would otherwise be unreachable.
|
|
21
|
+
* @returns Whether WebGL 2 is present.
|
|
22
|
+
* @complexity O(1).
|
|
23
|
+
*/
|
|
24
|
+
export declare function detectWebGL(win: object | null | undefined): boolean;
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* kUInetic Audio - Web Audio Reactive Source Module
|
|
3
|
+
*
|
|
4
|
+
* Exposes audio frequency bands (bass, mid, treble, overall level)
|
|
5
|
+
* as CSS custom properties on scoped elements:
|
|
6
|
+
* - --kui-audio-bass (0..1)
|
|
7
|
+
* - --kui-audio-mid (0..1)
|
|
8
|
+
* - --kui-audio-treble (0..1)
|
|
9
|
+
* - --kui-audio-level (0..1)
|
|
10
|
+
* - --kui-audio (alias to level)
|
|
11
|
+
*
|
|
12
|
+
* Supports page audio/video elements by default, with opt-in mic streaming.
|
|
13
|
+
*/
|
|
14
|
+
import type { EffectInstance, EffectParams, PrepareContext, Preset, Primitive } from '../core/types.js';
|
|
15
|
+
import type { Registry } from '../core/registry.js';
|
|
16
|
+
import type { Animator } from '../core/animator.js';
|
|
17
|
+
import { type AdvancedEnv, type AnyWindow, type AnyDocument, type RafFunction, type CafFunction } from './base.js';
|
|
18
|
+
/** The host custom properties this module owns. Also the primitive's declared channels. */
|
|
19
|
+
export declare const AUDIO_CHANNELS: readonly ["--kui-audio-bass", "--kui-audio-mid", "--kui-audio-treble", "--kui-audio-level", "--kui-audio"];
|
|
20
|
+
export interface AudioBands {
|
|
21
|
+
bass: number;
|
|
22
|
+
mid: number;
|
|
23
|
+
treble: number;
|
|
24
|
+
level: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The bands a *consumer* can subscribe to, and the custom property each one reads.
|
|
28
|
+
*
|
|
29
|
+
* The same names {@link AUDIO_CHANNELS} declares, minus the `--kui-audio` alias — an alias is a
|
|
30
|
+
* second spelling of `level`, not a fifth band, and offering both as separate choices would make
|
|
31
|
+
* two authored values mean exactly the same thing. `__tests__/audio.test.ts` asserts every
|
|
32
|
+
* property here is one this module actually writes, so the two cannot drift apart.
|
|
33
|
+
*/
|
|
34
|
+
export declare const AUDIO_BAND_PROPERTIES: {
|
|
35
|
+
readonly bass: "--kui-audio-bass";
|
|
36
|
+
readonly mid: "--kui-audio-mid";
|
|
37
|
+
readonly treble: "--kui-audio-treble";
|
|
38
|
+
readonly level: "--kui-audio-level";
|
|
39
|
+
};
|
|
40
|
+
export type AudioBand = keyof typeof AUDIO_BAND_PROPERTIES;
|
|
41
|
+
/** Band names, for a consumer's `keywords` list. */
|
|
42
|
+
export declare const AUDIO_BANDS: readonly AudioBand[];
|
|
43
|
+
/**
|
|
44
|
+
* The band an authored keyword names, or `null` for "no band" — including `off` and any word that
|
|
45
|
+
* is not a band at all.
|
|
46
|
+
*
|
|
47
|
+
* `Object.hasOwn`, not `AUDIO_BANDS.includes`, for the same reason `readParams` uses it: a plain
|
|
48
|
+
* property read answers for `__proto__`/`constructor` too, and would report those as bands whose
|
|
49
|
+
* property is a function.
|
|
50
|
+
*/
|
|
51
|
+
export declare function parseAudioBand(raw: string | null | undefined): AudioBand | null;
|
|
52
|
+
/**
|
|
53
|
+
* One band's current value for this element, as a consumer sees it.
|
|
54
|
+
*
|
|
55
|
+
* Inline first, then computed — the same two-step `shaders.ts`'s `readElementProgress` uses, and
|
|
56
|
+
* for the same reason: `--kui-audio-*` are ordinary unregistered custom properties (nothing in
|
|
57
|
+
* this codebase declares them with `@property`), so they inherit, and an `audio-source` on an
|
|
58
|
+
* *ancestor* is already visible through `getComputedStyle` without this module doing anything
|
|
59
|
+
* special. The inline read is the fast path for the common case — the driver on the element
|
|
60
|
+
* itself, where its own per-frame write lands.
|
|
61
|
+
*
|
|
62
|
+
* `0` when nothing has declared a value, which is also what a silent driver writes: a consumer
|
|
63
|
+
* that reads 0 behaves as if there were no audio, rather than having to distinguish the two.
|
|
64
|
+
*
|
|
65
|
+
* Callers on a shared render loop must read every element before any of them writes style; see
|
|
66
|
+
* `SharedShaderRenderer`'s `inputReaders` pass for why the ordering matters.
|
|
67
|
+
*
|
|
68
|
+
* @complexity O(1) time (one inline read, at most one computed-style read); O(1) space.
|
|
69
|
+
*/
|
|
70
|
+
export declare function readAudioBand(el: HTMLElement, band: AudioBand): number;
|
|
71
|
+
export interface AudioSourceOptions {
|
|
72
|
+
/** Where the samples come from, not which element: the page's own media, or the microphone. */
|
|
73
|
+
source?: 'media' | 'mic';
|
|
74
|
+
/** The author's `target:` selector for the media element to analyse. */
|
|
75
|
+
target?: string;
|
|
76
|
+
fftSize?: number;
|
|
77
|
+
smoothing?: number;
|
|
78
|
+
}
|
|
79
|
+
export declare function computeFrequencyBands(data: Uint8Array, sampleRate: number): AudioBands;
|
|
80
|
+
/**
|
|
81
|
+
* The nearest legal `fftSize`.
|
|
82
|
+
*
|
|
83
|
+
* `AnalyserNode.fftSize` must be a power of two and throws `IndexSizeError` for anything else. The
|
|
84
|
+
* parameter schema bounds the range but `clamp` cannot snap, so an authored `fft:300` threw inside
|
|
85
|
+
* initialisation, left an open `AudioContext` with no analyser behind it, and then wrote `0.000`
|
|
86
|
+
* for all five properties every frame — a silent dead effect with a running audio thread.
|
|
87
|
+
*/
|
|
88
|
+
export declare function snapFftSize(requested: number): number;
|
|
89
|
+
export declare class AudioSourceController {
|
|
90
|
+
element: HTMLElement;
|
|
91
|
+
options: AudioSourceOptions;
|
|
92
|
+
env: AdvancedEnv;
|
|
93
|
+
window: AnyWindow;
|
|
94
|
+
document: AnyDocument;
|
|
95
|
+
raf: RafFunction;
|
|
96
|
+
caf: CafFunction;
|
|
97
|
+
audioCtx: AudioContext | null;
|
|
98
|
+
analyser: AnalyserNode | null;
|
|
99
|
+
sourceNode: MediaElementAudioSourceNode | MediaStreamAudioSourceNode | null;
|
|
100
|
+
stream: MediaStream | null;
|
|
101
|
+
freqData: Uint8Array<ArrayBuffer> | null;
|
|
102
|
+
rafId: number | null;
|
|
103
|
+
isActive: boolean;
|
|
104
|
+
/** The window-wide graph this instance is currently counted against. */
|
|
105
|
+
private graph;
|
|
106
|
+
/**
|
|
107
|
+
* Whether `sourceNode` belongs to the shared graph rather than to this instance.
|
|
108
|
+
*
|
|
109
|
+
* True for `source: media` — the node feeds the page's speakers as well as this analyser, so
|
|
110
|
+
* teardown may only cut its edge to *this* analyser. False for `source: mic`, where the node and
|
|
111
|
+
* its stream are this instance's alone and must be released in full.
|
|
112
|
+
*/
|
|
113
|
+
private sourceIsShared;
|
|
114
|
+
/**
|
|
115
|
+
* The author's inline custom properties, and what this module replaced them with.
|
|
116
|
+
*
|
|
117
|
+
* Not a snapshot taken here: the ledger for `element` is opened at the first write in
|
|
118
|
+
* `updateFrame`, so what it restores is whatever the author had at that instant. The field it
|
|
119
|
+
* replaced captured all five properties in this constructor and restored them on destroy, which
|
|
120
|
+
* meant an author who wrote `--kui-audio-bass` any time after `prepare` had that write silently
|
|
121
|
+
* reverted to a value from before their own.
|
|
122
|
+
*
|
|
123
|
+
* Shared with every other controller writing to this element — see `createAdvancedLedgers`. Two
|
|
124
|
+
* `audio-source` effects on one element (`audio-reactive` plus `audio-mic`, say) would otherwise
|
|
125
|
+
* open a ledger each, and the second would capture the first's `0.000` as the author's value.
|
|
126
|
+
*/
|
|
127
|
+
private ledgers;
|
|
128
|
+
/**
|
|
129
|
+
* Which microphone request is the live one.
|
|
130
|
+
*
|
|
131
|
+
* `getUserMedia` cannot be cancelled — the permission prompt belongs to the browser, and the
|
|
132
|
+
* promise settles whenever the visitor answers it. Every `stop()` bumps this, so a request the
|
|
133
|
+
* visitor grants *after* the effect was cancelled resolves into a handler that no longer
|
|
134
|
+
* recognises its own generation and stops the tracks instead of connecting them. Without it,
|
|
135
|
+
* cancelling while the prompt is open and then granting leaves the microphone recording until
|
|
136
|
+
* the element is eventually destroyed.
|
|
137
|
+
*/
|
|
138
|
+
private micRequestToken;
|
|
139
|
+
/** Detaches the one-shot gesture listeners armed by {@link armGestureResume}. */
|
|
140
|
+
private releaseGestureResume;
|
|
141
|
+
constructor(element: HTMLElement, options?: AudioSourceOptions, env?: AdvancedEnv);
|
|
142
|
+
private connectMicSource;
|
|
143
|
+
private connectMediaSource;
|
|
144
|
+
/**
|
|
145
|
+
* This instance's analyser, already on a live path to the destination.
|
|
146
|
+
*
|
|
147
|
+
* @returns The analyser, or `null` when the context refused to build one.
|
|
148
|
+
*/
|
|
149
|
+
private buildAnalyser;
|
|
150
|
+
/**
|
|
151
|
+
* Join the window's audio graph and give this instance an analyser on it.
|
|
152
|
+
*
|
|
153
|
+
* `this.analyser`, not `this.audioCtx`, is the "already initialised" test, and nothing is
|
|
154
|
+
* recorded on `this` until the analyser exists. Assigning the context first is what left a
|
|
155
|
+
* half-built instance behind — an open context, no analyser, and a loop writing zeros — whenever
|
|
156
|
+
* `createAnalyser` or `fftSize` threw.
|
|
157
|
+
*/
|
|
158
|
+
initAudio(): boolean;
|
|
159
|
+
/**
|
|
160
|
+
* Go live — but only run a frame loop once there is something for it to read.
|
|
161
|
+
*
|
|
162
|
+
* The loop used to start unconditionally, and both ways that can be wrong were reachable:
|
|
163
|
+
*
|
|
164
|
+
* - **Initialisation failed.** No Web Audio, or an `AudioContext` the browser refused to build.
|
|
165
|
+
* `initAudio()` is only ever called from here and here early-returns on `isActive`, so there is
|
|
166
|
+
* no retry path at all — the loop sampled nothing, wrote the same `0.000` forever and could
|
|
167
|
+
* never recover.
|
|
168
|
+
* - **The context is suspended.** `defaultActivation` is `'load'`, so this normally runs before
|
|
169
|
+
* the visitor has touched anything and the context starts suspended. The gesture retry below
|
|
170
|
+
* is the fix for *that*, but the loop does not have to run while it waits: a suspended context
|
|
171
|
+
* fills zeros, and {@link GESTURE_EVENTS} is `pointerdown`/`keydown`/`touchend` — a visitor who
|
|
172
|
+
* only ever scrolls with a wheel fires none of them, so "while it waits" was the rest of the
|
|
173
|
+
* session at 60fps.
|
|
174
|
+
*
|
|
175
|
+
* - **There is nothing to read.** `initAudio()` answers `true` as soon as the analyser exists,
|
|
176
|
+
* and the analyser can exist with nothing connected to it: `audio-source target:#missing`, or a
|
|
177
|
+
* page with no media under the element, leaves `connectMediaSource` with no node to attach;
|
|
178
|
+
* `audio-mic` leaves `connectMicSource` waiting on a permission prompt the visitor may close,
|
|
179
|
+
* refuse, or never answer. A loop over a disconnected analyser is the first case again — the
|
|
180
|
+
* same `0.000` at 60fps, for the life of the page, with nothing coming to change it.
|
|
181
|
+
*
|
|
182
|
+
* One frame of silence covers all three, and it is all any of them needs: nothing is going to
|
|
183
|
+
* change these five values until a resume or a stream lands, and writing them once still says
|
|
184
|
+
* "there is a driver on this element and it is silent" to a consumer that would otherwise inherit
|
|
185
|
+
* an ancestor's live band. The loop is then started by whichever arrives last — the `resume()`
|
|
186
|
+
* that succeeds, or the microphone the visitor grants — see {@link startLoopIfReady}.
|
|
187
|
+
*/
|
|
188
|
+
start(): void;
|
|
189
|
+
/**
|
|
190
|
+
* Wake a context the browser suspended for autoplay policy.
|
|
191
|
+
*
|
|
192
|
+
* `defaultActivation` is `'load'`, so the context is very often constructed before the visitor
|
|
193
|
+
* has touched anything, and a context built outside a user gesture starts `suspended`. A bare
|
|
194
|
+
* `resume()` there is rejected or left pending — WebKit is strict about it, and iOS is this
|
|
195
|
+
* repo's main audience — after which `getByteFrequencyData` fills zeros and all five properties
|
|
196
|
+
* sit at `0.000` for the rest of the session. `on:click` only worked by luck, because it happens
|
|
197
|
+
* to run inside a gesture.
|
|
198
|
+
*
|
|
199
|
+
* So: try immediately, and arm a one-shot retry on the visitor's first gesture. The `on:click`
|
|
200
|
+
* path still succeeds on the first attempt and the listeners are never needed.
|
|
201
|
+
*
|
|
202
|
+
* @returns `true` when the context is already live and {@link start} may run its loop now,
|
|
203
|
+
* `false` when a resume has been arranged and the loop is that resume's job to start.
|
|
204
|
+
*/
|
|
205
|
+
private resumeContext;
|
|
206
|
+
/**
|
|
207
|
+
* Start the loop, unless the effect was torn down while the context was still waking up — or
|
|
208
|
+
* there is still nothing connected for it to read.
|
|
209
|
+
*
|
|
210
|
+
* `resume()` settles whenever the browser gets to it, which can be long after a `cancel()` — the
|
|
211
|
+
* same race {@link micRequestToken} closes for `getUserMedia`, and with the same consequence if
|
|
212
|
+
* it is left open: a resume landing after teardown would start a frame loop on a stopped
|
|
213
|
+
* instance, and nothing would ever come back to stop it.
|
|
214
|
+
*
|
|
215
|
+
* The source check is the other half of the gate {@link start} applies: a resume that lands
|
|
216
|
+
* before the microphone is granted, or on an element with no media to bind, has nothing to start
|
|
217
|
+
* a loop over. When the stream does arrive, `connectMicSource` comes back through here.
|
|
218
|
+
*/
|
|
219
|
+
private startLoopIfReady;
|
|
220
|
+
private armGestureResume;
|
|
221
|
+
startLoop(): void;
|
|
222
|
+
updateFrame(): void;
|
|
223
|
+
/**
|
|
224
|
+
* One channel, written only when it would actually change anything.
|
|
225
|
+
*
|
|
226
|
+
* These are unregistered custom properties, so they inherit: five unconditional `setProperty`
|
|
227
|
+
* calls per frame per instance dirty the whole subtree's style 60 times a second even on a page
|
|
228
|
+
* whose audio is silent or whose context never resumed, where all five values are the identical
|
|
229
|
+
* `0.000`.
|
|
230
|
+
*
|
|
231
|
+
* The comparison reads the live inline value rather than a remembered one on purpose. A cache
|
|
232
|
+
* would go stale the moment the author wrote the property themselves — this module would agree
|
|
233
|
+
* with its own record, skip the write, and look dead. Reading the CSSOM's own map is a lookup,
|
|
234
|
+
* not a style resolution, so it costs nothing a `setProperty` would not already cost.
|
|
235
|
+
*
|
|
236
|
+
* `claim()` first and unconditionally, because the very first frame can legitimately skip its
|
|
237
|
+
* write (the author happened to have written the same string), and the ledger still has to have
|
|
238
|
+
* captured what was there to restore it.
|
|
239
|
+
*
|
|
240
|
+
* @complexity O(1).
|
|
241
|
+
*/
|
|
242
|
+
private writeChannel;
|
|
243
|
+
/**
|
|
244
|
+
* Give back everything this instance owns: the frame loop, its analyser, the microphone.
|
|
245
|
+
*
|
|
246
|
+
* This is what `cancel()` and `finish()` reach, and it is deliberately a full release of the
|
|
247
|
+
* *instance's* half of the graph. A cancelled `audio-mic` that only stopped its loop left the
|
|
248
|
+
* stream connected and the recording indicator lit until the element was eventually destroyed —
|
|
249
|
+
* the visitor stopped the effect and the microphone stayed on.
|
|
250
|
+
*
|
|
251
|
+
* What it deliberately does **not** do is touch the page's own audio or the author's styles.
|
|
252
|
+
* The shared media source keeps its edge to the destination (see {@link SharedAudioGraph}), and
|
|
253
|
+
* the ledger is left as it is because `EffectInstance.cancel` means "stop where it is, leaving
|
|
254
|
+
* the element mid-effect" — unwinding the five custom properties here would snap every rule
|
|
255
|
+
* reading `var(--kui-audio-bass, 0)` back to its fallback on a pause, which is not what the
|
|
256
|
+
* other five modules in this directory do. `destroy()` is where the styles go back.
|
|
257
|
+
*
|
|
258
|
+
* Idempotent, and safe on a controller that was never started — every step below no-ops on an
|
|
259
|
+
* empty graph. It runs unguarded for that reason: the old `isActive` early-return meant a
|
|
260
|
+
* controller cancelled twice, or destroyed without ever activating, skipped the parts that had
|
|
261
|
+
* nothing to do with the loop.
|
|
262
|
+
*/
|
|
263
|
+
stop(): void;
|
|
264
|
+
private disconnectAudioNodes;
|
|
265
|
+
/**
|
|
266
|
+
* Everything `stop()` gives back, plus the author's inline styles.
|
|
267
|
+
*
|
|
268
|
+
* `try`/`finally` because the restore must not be hostage to the graph teardown: the animator
|
|
269
|
+
* swallows a throwing `instance.destroy()` (`runQuietly`), and an element this module reached on
|
|
270
|
+
* its own — a `camera-layer`, a `scene-step` — is in no ledger the animator will ever restore.
|
|
271
|
+
* A single throw on the way out would otherwise leave the library's values on it permanently.
|
|
272
|
+
*/
|
|
273
|
+
destroy(): void;
|
|
274
|
+
}
|
|
275
|
+
export declare function prepareAudioSource(el: Element, params: EffectParams, ctx?: PrepareContext | null): EffectInstance;
|
|
276
|
+
export declare const AUDIO_PARAMETERS: {
|
|
277
|
+
source: {
|
|
278
|
+
type: "keyword";
|
|
279
|
+
default: string;
|
|
280
|
+
keywords: string[];
|
|
281
|
+
cssProperty: string;
|
|
282
|
+
};
|
|
283
|
+
/**
|
|
284
|
+
* Which media element to analyse — the library's one spelling for "this effect names another
|
|
285
|
+
* element", declared exactly as every other primitive that owns the key declares it — see
|
|
286
|
+
* `compile.ts`'s `liftTarget` for the current set — down to the shared `--kui-target`.
|
|
287
|
+
*
|
|
288
|
+
* It was `media:`, which was both a second word for `target:`'s job and a live footgun:
|
|
289
|
+
* `compile.ts`'s `liftTarget` only leaves `target:` in a primitive's own parameters when that
|
|
290
|
+
* primitive declares it, and otherwise *relocates the whole effect* onto the elements the
|
|
291
|
+
* selector matched. So `audio-source target:#track` used to move the analyser onto the `<audio>`
|
|
292
|
+
* element itself — which happens to work, silently writing the five custom properties on the
|
|
293
|
+
* wrong element. Declaring the key here claims it and closes that.
|
|
294
|
+
*
|
|
295
|
+
* No `scope: SCOPE_PARAM` alongside it, unlike its peers: this resolves its own two-step search
|
|
296
|
+
* (`findMediaElement` — the host's own subtree first, the document only for an authored
|
|
297
|
+
* selector), and importing core's shared declaration would be a value import from `src/effects`
|
|
298
|
+
* into a tier whose bundle weight is measured (see `base.ts`'s `asRegistry`).
|
|
299
|
+
*/
|
|
300
|
+
target: {
|
|
301
|
+
type: "text";
|
|
302
|
+
default: string;
|
|
303
|
+
cssProperty: string;
|
|
304
|
+
};
|
|
305
|
+
smoothing: {
|
|
306
|
+
type: "number";
|
|
307
|
+
default: string;
|
|
308
|
+
minimum: number;
|
|
309
|
+
maximum: number;
|
|
310
|
+
cssProperty: string;
|
|
311
|
+
};
|
|
312
|
+
fft: {
|
|
313
|
+
type: "number";
|
|
314
|
+
default: string;
|
|
315
|
+
minimum: number;
|
|
316
|
+
maximum: number;
|
|
317
|
+
cssProperty: string;
|
|
318
|
+
};
|
|
319
|
+
};
|
|
320
|
+
export declare const AUDIO_PRIMITIVES: Primitive[];
|
|
321
|
+
export declare const AUDIO_PRESETS: Preset[];
|
|
322
|
+
export declare function registerAudio(target: unknown): Registry | Animator;
|