@snailicid3/gbt-scope 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,308 @@
1
+ /*
2
+ * @snailicid3/gbt-scope v0.0.1
3
+ * Module: GbtScope
4
+ * (c) 2026 Gillian Tunney
5
+ * React components and hooks for the operator user interface.
6
+ * https://github.com/gbtunney/gbt-monorepov2
7
+ * Released under the MIT License.
8
+ * Build: 9/9/2026, 7:05:01 AM
9
+ */
10
+ import { Mesh, ShaderMaterial, Vector3 } from "@babylonjs/core";
11
+ import { ReactElement } from "react";
12
+ //#region src/helpers.d.ts
13
+ type Dimensions = {
14
+ height: number;
15
+ width: number;
16
+ };
17
+ type Point = {
18
+ x: number;
19
+ y: number;
20
+ };
21
+ type XY = [number, number];
22
+ type Vector3Params = ConstructorParameters<typeof Vector3>;
23
+ type CameraConfigPosition = Partial<{
24
+ enabled: boolean;
25
+ hRotation: number; /** Alpha Math.PI / 2, // Alpha (horizontal rotation) */
26
+ /** Slow down the zoom speed */
27
+ mouseWheelSpeed: number;
28
+ position: Vector3Params;
29
+ radius: number;
30
+ target: Vector3Params;
31
+ vRotation: number; /** Beta Math.PI / 4, // Beta (vertical rotation) */
32
+ }>;
33
+ type CameraOrthoConfig = Pick<CameraConfigPosition, 'enabled' | 'target'> & {
34
+ ortho?: true;
35
+ };
36
+ //#endregion
37
+ //#region src/motion/animator.d.ts
38
+ /**
39
+ * A single declarative animation rule: read `source`, shape it through `curve`, scale by `speed * delta`, then `add` to
40
+ * (default) or `set` the `target`.
41
+ */
42
+ type GbtScopeAnimator = {
43
+ curve?: GbtScopeCurve;
44
+ mode?: 'add' | 'set';
45
+ source: GbtScopeAnimatorSource;
46
+ speed?: number;
47
+ target: GbtScopeAnimatorTarget;
48
+ };
49
+ /** Input signal an animator reads from. */
50
+ type GbtScopeAnimatorSource = 'mouseDistance' | 'scrollProgress' | 'scrollVelocity' | 'time';
51
+ /** Uniform-backed value an animator can drive. */
52
+ type GbtScopeAnimatorTarget = 'offset.x' | 'offset.y' | 'opacity' | 'rotation' | 'scaleFactor';
53
+ /**
54
+ * Fixed values that replace the live pointer/scroll signals in the driver — for mocking motion input (device-free
55
+ * testing, deterministic demos). A defined field wins over the real input; `undefined` fields fall through.
56
+ */
57
+ type GbtScopeInputOverrides = Partial<Pick<GbtScopeInputs, 'mouseDistance' | 'scrollProgress' | 'scrollVelocity'>>;
58
+ /** Per-frame inputs fed to the animators. */
59
+ type GbtScopeInputs = {
60
+ delta: number;
61
+ mouseDistance: number;
62
+ scrollProgress: number;
63
+ scrollVelocity: number;
64
+ time: number;
65
+ };
66
+ /** Mutable, uniform-facing animation state. */
67
+ type GbtScopeState = {
68
+ offset: [number, number];
69
+ opacity: number;
70
+ rotation: number;
71
+ scaleFactor: number;
72
+ };
73
+ /**
74
+ * Applies every animator to a copy of `state` for one frame and returns the new state. Each animator's source value is
75
+ * curved, scaled by `speed * delta` (frame-rate independent), then added to or set on its target.
76
+ */
77
+ declare const applyAnimators: (state: GbtScopeState, animators: Array<GbtScopeAnimator>, inputs: GbtScopeInputs) => GbtScopeState;
78
+ //#endregion
79
+ //#region src/types.d.ts
80
+ /**
81
+ * Curve parameters controlling how an input value (eg. pointer distance from center, scroll velocity) maps to an effect
82
+ * amount. Replaces the old `[min, max]` tuple form of `mouse_curve` with a richer, named shape.
83
+ *
84
+ * @see applyCurve in ./motion/curve.ts
85
+ */
86
+ type GbtScopeCurve = {
87
+ /** Input magnitude below this is treated as 0. Default 0. */
88
+ deadzone?: number;
89
+ /** Shaping exponent (1 = linear, >1 = ease-in). Default 1. */
90
+ exponent?: number;
91
+ /** Negate the result. Default false. */
92
+ invert?: boolean;
93
+ /** Upper clamp applied after curving. Default 1. */
94
+ max?: number;
95
+ /** Lower clamp applied after curving. Default 0. */
96
+ min?: number;
97
+ /** Linear gain applied before the exponent. Default 1. */
98
+ multiplier?: number;
99
+ };
100
+ /**
101
+ * Shared, serializable material props for all GbtScope viewers (flat + 3D mesh). camelCase only — animation is
102
+ * data-driven via {@link GbtScopeAnimator}, not speed fields. `rotation`/`offset`/`scaleFactor`/`opacity` are the
103
+ * resting (base) values the animators build on.
104
+ */
105
+ type GbtScopeMaterialProps = {
106
+ /** Pre-resolved texture dimensions; viewers derive this from `resolution`. */
107
+ dimensions?: Dimensions;
108
+ imageAspect?: number;
109
+ offset?: [number, number];
110
+ /** Multiplier on the offset uniform (`uOffsetAmount`). */
111
+ offsetScale?: number;
112
+ opacity?: number;
113
+ rotation?: number;
114
+ /** Multiplier on the rotation uniform (`uRotationAmount`). */
115
+ rotationScale?: number;
116
+ scaleFactor?: number;
117
+ segments?: number;
118
+ src: string;
119
+ tileMode?: GbtScopeTileMode;
120
+ tiling?: number;
121
+ };
122
+ /**
123
+ * Tiling strategy applied to the kaleidoscope pattern after the radial fold.
124
+ *
125
+ * - `none` — no wrapping; the pattern is sampled directly.
126
+ * - `repeat` — `fract(uv * tiling)` square repeats (the historical behavior).
127
+ * - `mirror` — mirrored repeats for seamless edges.
128
+ */
129
+ type GbtScopeTileMode = 'mirror' | 'none' | 'repeat';
130
+ /**
131
+ * Canonical default values for {@link GbtScopeMaterialProps}. `src` is required and has no default. Imported by
132
+ * component defaults and Storybook args so the defaults live in a single place.
133
+ */
134
+ declare const defaultGbtScopeMaterialProps: {
135
+ imageAspect: number;
136
+ offset: [number, number];
137
+ offsetScale: number;
138
+ opacity: number;
139
+ rotation: number;
140
+ rotationScale: number;
141
+ scaleFactor: number;
142
+ segments: number;
143
+ tileMode: GbtScopeTileMode;
144
+ tiling: number;
145
+ };
146
+ /**
147
+ * Viewer-level props shared by both the flat and mesh viewers. Camera config is viewer-specific and declared on each
148
+ * component. Material props are forwarded down to {@link GbtScopeMaterialProps}.
149
+ */
150
+ type GbtScopeViewerBaseProps = {
151
+ /** Declarative motion rules applied each frame. */
152
+ animators?: Array<GbtScopeAnimator>;
153
+ /** Aspect ratio of the host canvas. */
154
+ aspect_ratio?: 'parent' | number;
155
+ bg_color?: string;
156
+ /** Fixed values replacing the live pointer/scroll inputs (mock/testing). */
157
+ inputOverrides?: GbtScopeInputOverrides;
158
+ /** Canvas background; `'screen'` resolution matches the viewport. */
159
+ resolution?: 'screen' | Dimensions | null;
160
+ };
161
+ //#endregion
162
+ //#region src/components/GbtScopeFlatViewer.d.ts
163
+ type GbtScopeFlatViewerProps = GbtScopeViewerBaseProps & Omit<GbtScopeMaterialProps, 'dimensions'> & {
164
+ cameraSettings?: CameraOrthoConfig;
165
+ name?: string;
166
+ };
167
+ /** Default props for the flat viewer — single source of truth for Storybook args. */
168
+ declare const defaultGbtScopeFlatViewerProps: {
169
+ animators: never[];
170
+ aspect_ratio: "parent" | number;
171
+ bg_color: string;
172
+ cameraSettings: CameraOrthoConfig;
173
+ name: string;
174
+ resolution: "screen" | Dimensions | null;
175
+ src: string;
176
+ imageAspect: number;
177
+ offset: [number, number];
178
+ offsetScale: number;
179
+ opacity: number;
180
+ rotation: number;
181
+ rotationScale: number;
182
+ scaleFactor: number;
183
+ segments: number;
184
+ tileMode: GbtScopeTileMode;
185
+ tiling: number;
186
+ };
187
+ declare const GbtScopeFlatViewer: ({ animators, aspect_ratio, bg_color, cameraSettings, imageAspect, inputOverrides, name, offset, offsetScale, opacity, resolution, rotation, rotationScale, scaleFactor, segments, src, tileMode, tiling }: GbtScopeFlatViewerProps) => ReactElement;
188
+ //#endregion
189
+ //#region src/motion/pointer.d.ts
190
+ /** Current normalized pointer position, centered on the canvas, range [-1, 1]. */
191
+ type PointerState = {
192
+ readonly x: number;
193
+ readonly y: number;
194
+ };
195
+ type PointerStateHandle = {
196
+ /** Attach pointerdown/pointermove/pointerleave listeners to a canvas. */
197
+ attach: (canvas: HTMLCanvasElement) => void;
198
+ /** Remove the listeners. Call from the scene's onDisposeObservable. */
199
+ detach: (canvas: HTMLCanvasElement) => void;
200
+ /** Live pointer position. Mutated internally; read it inside a render loop. */
201
+ state: PointerState;
202
+ };
203
+ /**
204
+ * Creates a mutable pointer-state object for use inside a Babylon.js scene setup callback. Intentionally NOT a React
205
+ * hook: `onSceneReady` runs outside React's render cycle, so a hook's state would be stale inside the render
206
+ * observable. The returned `state` object is mutated in place and is safe to read every frame.
207
+ *
208
+ * Position is normalized to [-1, 1] on both axes (canvas-relative). Uses pointer events so mouse and touch behave
209
+ * uniformly: a mouse resets to [0, 0] on leaving the canvas, while a touch latches at the last tap/drag position (tap
210
+ * center to zero it) — hover-less devices would otherwise never produce input.
211
+ */
212
+ declare const createPointerState: () => PointerStateHandle;
213
+ //#endregion
214
+ //#region src/motion/scroll.d.ts
215
+ /** Current scroll signals. `progress` is [0,1]; `velocity` decays toward 0. */
216
+ type ScrollState = {
217
+ readonly progress: number;
218
+ readonly velocity: number;
219
+ };
220
+ type ScrollStateHandle = {
221
+ /** Attach scroll/wheel listeners (defaults to window). */
222
+ attach: (target?: HTMLElement | Window) => void;
223
+ /**
224
+ * Decay the velocity by one frame's worth (call once per frame from the driver after reading). `factor` in [0,1];
225
+ * lower = faster decay.
226
+ */
227
+ decay: (factor?: number) => void;
228
+ /** Remove listeners. Call from the scene's onDisposeObservable. */
229
+ detach: (target?: HTMLElement | Window) => void;
230
+ /** Live scroll signals. Mutated internally; read inside a render loop. */
231
+ state: ScrollState;
232
+ };
233
+ /**
234
+ * Creates a mutable scroll-state object for use inside a Babylon.js scene setup callback. Tracks page scroll `progress`
235
+ * [0,1] and a wheel-driven `velocity` that the driver decays each frame. Plain factory (not a React hook) — mirrors
236
+ * {@link ./pointer.createPointerState} so it can be read from the render observable.
237
+ */
238
+ declare const createScrollState: () => ScrollStateHandle;
239
+ //#endregion
240
+ //#region src/components/GbtScopeMaterial.d.ts
241
+ type GbtScopeMaterialComponentProps = GbtScopeMaterialProps & {
242
+ /** Declarative motion rules driven each frame. */
243
+ animators?: Array<GbtScopeAnimator>;
244
+ /** Fixed values replacing the live pointer/scroll inputs (mock/testing). */
245
+ inputOverrides?: GbtScopeInputOverrides;
246
+ /** Mesh the material is applied to. */
247
+ mesh: Mesh | null;
248
+ name?: string;
249
+ onInit?: (material: ShaderMaterial) => void;
250
+ onUpdate?: (material: ShaderMaterial) => void;
251
+ /** Live pointer + scroll inputs (created by the viewer). */
252
+ pointer: PointerStateHandle;
253
+ scroll: ScrollStateHandle;
254
+ };
255
+ /**
256
+ * Kaleidoscope shader material applied to a Babylon mesh. Static uniforms update reactively from props; the animated
257
+ * uniforms (rotation/offset/scaleFactor/ opacity) are driven each frame by {@link createGbtScopeDriver} from the
258
+ * `animators` + live pointer/scroll inputs. No Babylon Animation is used.
259
+ */
260
+ declare const GbtScopeMaterial: ({ animators, dimensions, imageAspect, inputOverrides, mesh, name, offset, offsetScale, onInit, onUpdate, opacity, pointer, rotation, rotationScale, scaleFactor, scroll, segments, src, tileMode, tiling }: GbtScopeMaterialComponentProps) => null | ReactElement;
261
+ //#endregion
262
+ //#region src/components/GbtScopeMeshViewer.d.ts
263
+ type GbtScopeMeshViewerProps = GbtScopeViewerBaseProps & Omit<GbtScopeMaterialProps, 'dimensions'> & {
264
+ cameraSettings?: CameraConfigPosition;
265
+ name?: string;
266
+ };
267
+ /** Default props for the 3D mesh viewer — single source of truth for Storybook args. */
268
+ declare const defaultGbtScopeMeshViewerProps: {
269
+ animators: never[];
270
+ aspect_ratio: "parent" | number;
271
+ bg_color: string;
272
+ cameraSettings: CameraConfigPosition;
273
+ name: string;
274
+ resolution: "screen" | Dimensions | null;
275
+ src: string;
276
+ imageAspect: number;
277
+ offset: [number, number];
278
+ offsetScale: number;
279
+ opacity: number;
280
+ rotation: number;
281
+ rotationScale: number;
282
+ scaleFactor: number;
283
+ segments: number;
284
+ tileMode: GbtScopeTileMode;
285
+ tiling: number;
286
+ };
287
+ declare const GbtScopeMeshViewer: ({ animators, aspect_ratio, bg_color, cameraSettings, imageAspect, inputOverrides, name, offset, offsetScale, opacity, resolution, rotation, rotationScale, scaleFactor, segments, src, tileMode, tiling }: GbtScopeMeshViewerProps) => ReactElement;
288
+ //#endregion
289
+ //#region src/motion/curve.d.ts
290
+ /**
291
+ * Maps an input value through a {@link GbtScopeCurve}: deadzone → gain → exponent → clamp → optional invert. The input
292
+ * is treated by magnitude (`Math.abs`), so direction is supplied by `invert`, not the sign of `value`.
293
+ */
294
+ declare const applyCurve: (value: number, curve?: GbtScopeCurve) => number;
295
+ /**
296
+ * Type guard distinguishing the legacy `[min, max]` tuple form of `mouse_curve` from the richer {@link GbtScopeCurve}
297
+ * object form.
298
+ */
299
+ declare const isTupleCurve: (value: [number, number] | GbtScopeCurve) => value is [number, number];
300
+ /**
301
+ * Bridges the legacy `[min, max]` tuple (plus a separate `mouse_multiplier`) into an equivalent {@link GbtScopeCurve}.
302
+ * With the historical defaults `[0, 0.015]` and multiplier `0.01`, `applyCurve` reproduces the old inline
303
+ * `Math.min(Math.max(dist * mult, min), max)` clamp exactly.
304
+ */
305
+ declare const tupleToGbtScopeCurve: (tuple: [number, number], multiplier?: number) => GbtScopeCurve;
306
+ //#endregion
307
+ export { type Dimensions, type GbtScopeAnimator, type GbtScopeAnimatorSource, type GbtScopeAnimatorTarget, type GbtScopeCurve, GbtScopeFlatViewer, type GbtScopeFlatViewerProps, type GbtScopeInputOverrides, type GbtScopeInputs, GbtScopeMaterial, type GbtScopeMaterialComponentProps, type GbtScopeMaterialProps, GbtScopeMeshViewer, type GbtScopeMeshViewerProps, type GbtScopeState, type GbtScopeTileMode, type GbtScopeViewerBaseProps, type Point, type PointerState, type PointerStateHandle, type ScrollState, type ScrollStateHandle, type XY, applyAnimators, applyCurve, createPointerState, createScrollState, defaultGbtScopeFlatViewerProps, defaultGbtScopeMaterialProps, defaultGbtScopeMeshViewerProps, isTupleCurve, tupleToGbtScopeCurve };
308
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/helpers.ts","../src/motion/animator.ts","../src/types.ts","../src/components/GbtScopeFlatViewer.tsx","../src/motion/pointer.ts","../src/motion/scroll.ts","../src/components/GbtScopeMaterial.tsx","../src/components/GbtScopeMeshViewer.tsx","../src/motion/curve.ts"],"mappings":";;;;;;;;;;;;KAWY;EACR;EACA;;KAEQ;EAAU;EAAW;;KACrB;KAYA,gBAAgB,6BAA6B;KAI7C,uBAAuB;EAC/B;EACA;;EAEA;EACA,UAAU;EACV;EACA,QAAQ;EACR;;KAEQ,oBAAoB,KAC5B;EAEE;;;;;;;;KCtCM;EACR,QAAQ;EACR;EACA,QAAQ;EACR;EACA,QAAQ;;;KAIA;;KAIA;;;;;KAOA,yBAAyB,QACjC,KAAK;;KAIG;EACR;EACA;EACA;EACA;EACA;;;KAIQ;EACR;EACA;EACA;EACA;;;;;;cAOS,iBACT,OAAO,eACP,WAAW,MAAM,mBACjB,QAAQ,mBACT;;;;;;;;;KC5CS;;EAER;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;;KAQQ;;EAER,aAAa;EACb;EACA;;EAEA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA,WAAW;EACX;;;;;;;;;KAUQ;;;;;cAMC;;EAES;;;;;;;EAOI,UAAA;;;;;;;KAQd;;EAER,YAAY,MAAM;;EAElB;EACA;;EAEA,iBAAiB;;EAEjB,wBAAwB;;;;KC/DhB,0BAA0B,0BAClC,KAAK;EACD,iBAAiB;EACjB;;;cAKK;;EAGU;;EAMd,gBAAA;;EAEmB,uBAAW;;;;;;;;;;YAAA;;;cAIjC,uBAAsB,WAAA,cAAA,UAAA,gBAAA,aAAA,gBAAA,MAAA,QAAA,aAAA,SAAA,YAAA,UAAA,eAAA,aAAA,UAAA,KAAA,UAAA,UAmBzB,4BAA0B;;;;KCnEjB;WACC;WACA;;KAGD;;EAER,SAAS,QAAQ;;EAEjB,SAAS,QAAQ;;EAEjB,OAAO;;;;;;;;;;;cAYE,0BAAyB;;;;KCvB1B;WACC;WACA;;KAGD;;EAER,SAAS,SAAS,cAAc;;;;;EAKhC,QAAQ;;EAER,SAAS,SAAS,cAAc;;EAEhC,OAAO;;;;;;;cAgBE,yBAAwB;;;KCZzB,iCAAiC;;EAEzC,YAAY,MAAM;;EAElB,iBAAiB;;EAEjB,MAAM;EACN;EACA,UAAU,UAAU;EACpB,YAAY,UAAU;;EAEtB,SAAS;EACT,QAAQ;;;;;;;cA8BN,qBAAoB,WAAA,YAAA,aAAA,gBAAA,MAAA,MAAA,QAAA,aAAA,QAAA,UAAA,SAAA,SAAA,UAAA,eAAA,aAAA,QAAA,UAAA,KAAA,UAAA,UAqBvB,0CAAwC;;;KC1D/B,0BAA0B,0BAClC,KAAK;EACD,iBAAiB;EACjB;;;cAKK;;EAGU;;EAMd,gBAAA;;EAEe,uBAAW;;;;;;;;;;YAAA;;;cAI7B,uBAAsB,WAAA,cAAA,UAAA,gBAAA,aAAA,gBAAA,MAAA,QAAA,aAAA,SAAA,YAAA,UAAA,eAAA,aAAA,UAAA,KAAA,UAAA,UAuBzB,4BAA0B;;;;;;;cClEhB,aACT,eACA,QAAO;;;;;cAoBE,eACT,0BAA0B,kBAC3B;;;;;;cAgBU,uBACT,yBACA,wBACD"}
@@ -0,0 +1,308 @@
1
+ /*
2
+ * @snailicid3/gbt-scope v0.0.1
3
+ * Module: GbtScope
4
+ * (c) 2026 Gillian Tunney
5
+ * React components and hooks for the operator user interface.
6
+ * https://github.com/gbtunney/gbt-monorepov2
7
+ * Released under the MIT License.
8
+ * Build: 9/9/2026, 7:05:01 AM
9
+ */
10
+ import { ArcRotateCamera, FreeCamera, Mesh, ShaderMaterial, Vector2, Vector3, Vector4 } from "@babylonjs/core";
11
+ import { ReactElement } from "react";
12
+ //#region src/helpers.d.ts
13
+ type Dimensions = {
14
+ height: number;
15
+ width: number;
16
+ };
17
+ type Point = {
18
+ x: number;
19
+ y: number;
20
+ };
21
+ type XY = [number, number];
22
+ type Vector3Params = ConstructorParameters<typeof Vector3>;
23
+ type CameraConfigPosition = Partial<{
24
+ enabled: boolean;
25
+ hRotation: number; /** Alpha Math.PI / 2, // Alpha (horizontal rotation) */
26
+ /** Slow down the zoom speed */
27
+ mouseWheelSpeed: number;
28
+ position: Vector3Params;
29
+ radius: number;
30
+ target: Vector3Params;
31
+ vRotation: number; /** Beta Math.PI / 4, // Beta (vertical rotation) */
32
+ }>;
33
+ type CameraOrthoConfig = Pick<CameraConfigPosition, 'enabled' | 'target'> & {
34
+ ortho?: true;
35
+ };
36
+ //#endregion
37
+ //#region src/motion/animator.d.ts
38
+ /**
39
+ * A single declarative animation rule: read `source`, shape it through `curve`, scale by `speed * delta`, then `add` to
40
+ * (default) or `set` the `target`.
41
+ */
42
+ type GbtScopeAnimator = {
43
+ curve?: GbtScopeCurve;
44
+ mode?: 'add' | 'set';
45
+ source: GbtScopeAnimatorSource;
46
+ speed?: number;
47
+ target: GbtScopeAnimatorTarget;
48
+ };
49
+ /** Input signal an animator reads from. */
50
+ type GbtScopeAnimatorSource = 'mouseDistance' | 'scrollProgress' | 'scrollVelocity' | 'time';
51
+ /** Uniform-backed value an animator can drive. */
52
+ type GbtScopeAnimatorTarget = 'offset.x' | 'offset.y' | 'opacity' | 'rotation' | 'scaleFactor';
53
+ /**
54
+ * Fixed values that replace the live pointer/scroll signals in the driver — for mocking motion input (device-free
55
+ * testing, deterministic demos). A defined field wins over the real input; `undefined` fields fall through.
56
+ */
57
+ type GbtScopeInputOverrides = Partial<Pick<GbtScopeInputs, 'mouseDistance' | 'scrollProgress' | 'scrollVelocity'>>;
58
+ /** Per-frame inputs fed to the animators. */
59
+ type GbtScopeInputs = {
60
+ delta: number;
61
+ mouseDistance: number;
62
+ scrollProgress: number;
63
+ scrollVelocity: number;
64
+ time: number;
65
+ };
66
+ /** Mutable, uniform-facing animation state. */
67
+ type GbtScopeState = {
68
+ offset: [number, number];
69
+ opacity: number;
70
+ rotation: number;
71
+ scaleFactor: number;
72
+ };
73
+ /**
74
+ * Applies every animator to a copy of `state` for one frame and returns the new state. Each animator's source value is
75
+ * curved, scaled by `speed * delta` (frame-rate independent), then added to or set on its target.
76
+ */
77
+ declare const applyAnimators: (state: GbtScopeState, animators: Array<GbtScopeAnimator>, inputs: GbtScopeInputs) => GbtScopeState;
78
+ //#endregion
79
+ //#region src/types.d.ts
80
+ /**
81
+ * Curve parameters controlling how an input value (eg. pointer distance from center, scroll velocity) maps to an effect
82
+ * amount. Replaces the old `[min, max]` tuple form of `mouse_curve` with a richer, named shape.
83
+ *
84
+ * @see applyCurve in ./motion/curve.ts
85
+ */
86
+ type GbtScopeCurve = {
87
+ /** Input magnitude below this is treated as 0. Default 0. */
88
+ deadzone?: number;
89
+ /** Shaping exponent (1 = linear, >1 = ease-in). Default 1. */
90
+ exponent?: number;
91
+ /** Negate the result. Default false. */
92
+ invert?: boolean;
93
+ /** Upper clamp applied after curving. Default 1. */
94
+ max?: number;
95
+ /** Lower clamp applied after curving. Default 0. */
96
+ min?: number;
97
+ /** Linear gain applied before the exponent. Default 1. */
98
+ multiplier?: number;
99
+ };
100
+ /**
101
+ * Shared, serializable material props for all GbtScope viewers (flat + 3D mesh). camelCase only — animation is
102
+ * data-driven via {@link GbtScopeAnimator}, not speed fields. `rotation`/`offset`/`scaleFactor`/`opacity` are the
103
+ * resting (base) values the animators build on.
104
+ */
105
+ type GbtScopeMaterialProps = {
106
+ /** Pre-resolved texture dimensions; viewers derive this from `resolution`. */
107
+ dimensions?: Dimensions;
108
+ imageAspect?: number;
109
+ offset?: [number, number];
110
+ /** Multiplier on the offset uniform (`uOffsetAmount`). */
111
+ offsetScale?: number;
112
+ opacity?: number;
113
+ rotation?: number;
114
+ /** Multiplier on the rotation uniform (`uRotationAmount`). */
115
+ rotationScale?: number;
116
+ scaleFactor?: number;
117
+ segments?: number;
118
+ src: string;
119
+ tileMode?: GbtScopeTileMode;
120
+ tiling?: number;
121
+ };
122
+ /**
123
+ * Tiling strategy applied to the kaleidoscope pattern after the radial fold.
124
+ *
125
+ * - `none` — no wrapping; the pattern is sampled directly.
126
+ * - `repeat` — `fract(uv * tiling)` square repeats (the historical behavior).
127
+ * - `mirror` — mirrored repeats for seamless edges.
128
+ */
129
+ type GbtScopeTileMode = 'mirror' | 'none' | 'repeat';
130
+ /**
131
+ * Canonical default values for {@link GbtScopeMaterialProps}. `src` is required and has no default. Imported by
132
+ * component defaults and Storybook args so the defaults live in a single place.
133
+ */
134
+ declare const defaultGbtScopeMaterialProps: {
135
+ imageAspect: number;
136
+ offset: [number, number];
137
+ offsetScale: number;
138
+ opacity: number;
139
+ rotation: number;
140
+ rotationScale: number;
141
+ scaleFactor: number;
142
+ segments: number;
143
+ tileMode: GbtScopeTileMode;
144
+ tiling: number;
145
+ };
146
+ /**
147
+ * Viewer-level props shared by both the flat and mesh viewers. Camera config is viewer-specific and declared on each
148
+ * component. Material props are forwarded down to {@link GbtScopeMaterialProps}.
149
+ */
150
+ type GbtScopeViewerBaseProps = {
151
+ /** Declarative motion rules applied each frame. */
152
+ animators?: Array<GbtScopeAnimator>;
153
+ /** Aspect ratio of the host canvas. */
154
+ aspect_ratio?: 'parent' | number;
155
+ bg_color?: string;
156
+ /** Fixed values replacing the live pointer/scroll inputs (mock/testing). */
157
+ inputOverrides?: GbtScopeInputOverrides;
158
+ /** Canvas background; `'screen'` resolution matches the viewport. */
159
+ resolution?: 'screen' | Dimensions | null;
160
+ };
161
+ //#endregion
162
+ //#region src/components/GbtScopeFlatViewer.d.ts
163
+ type GbtScopeFlatViewerProps = GbtScopeViewerBaseProps & Omit<GbtScopeMaterialProps, 'dimensions'> & {
164
+ cameraSettings?: CameraOrthoConfig;
165
+ name?: string;
166
+ };
167
+ /** Default props for the flat viewer — single source of truth for Storybook args. */
168
+ declare const defaultGbtScopeFlatViewerProps: {
169
+ animators: never[];
170
+ aspect_ratio: "parent" | number;
171
+ bg_color: string;
172
+ cameraSettings: CameraOrthoConfig;
173
+ name: string;
174
+ resolution: "screen" | Dimensions | null;
175
+ src: string;
176
+ imageAspect: number;
177
+ offset: [number, number];
178
+ offsetScale: number;
179
+ opacity: number;
180
+ rotation: number;
181
+ rotationScale: number;
182
+ scaleFactor: number;
183
+ segments: number;
184
+ tileMode: GbtScopeTileMode;
185
+ tiling: number;
186
+ };
187
+ declare const GbtScopeFlatViewer: ({ animators, aspect_ratio, bg_color, cameraSettings, imageAspect, inputOverrides, name, offset, offsetScale, opacity, resolution, rotation, rotationScale, scaleFactor, segments, src, tileMode, tiling }: GbtScopeFlatViewerProps) => ReactElement;
188
+ //#endregion
189
+ //#region src/motion/pointer.d.ts
190
+ /** Current normalized pointer position, centered on the canvas, range [-1, 1]. */
191
+ type PointerState = {
192
+ readonly x: number;
193
+ readonly y: number;
194
+ };
195
+ type PointerStateHandle = {
196
+ /** Attach pointerdown/pointermove/pointerleave listeners to a canvas. */
197
+ attach: (canvas: HTMLCanvasElement) => void;
198
+ /** Remove the listeners. Call from the scene's onDisposeObservable. */
199
+ detach: (canvas: HTMLCanvasElement) => void;
200
+ /** Live pointer position. Mutated internally; read it inside a render loop. */
201
+ state: PointerState;
202
+ };
203
+ /**
204
+ * Creates a mutable pointer-state object for use inside a Babylon.js scene setup callback. Intentionally NOT a React
205
+ * hook: `onSceneReady` runs outside React's render cycle, so a hook's state would be stale inside the render
206
+ * observable. The returned `state` object is mutated in place and is safe to read every frame.
207
+ *
208
+ * Position is normalized to [-1, 1] on both axes (canvas-relative). Uses pointer events so mouse and touch behave
209
+ * uniformly: a mouse resets to [0, 0] on leaving the canvas, while a touch latches at the last tap/drag position (tap
210
+ * center to zero it) — hover-less devices would otherwise never produce input.
211
+ */
212
+ declare const createPointerState: () => PointerStateHandle;
213
+ //#endregion
214
+ //#region src/motion/scroll.d.ts
215
+ /** Current scroll signals. `progress` is [0,1]; `velocity` decays toward 0. */
216
+ type ScrollState = {
217
+ readonly progress: number;
218
+ readonly velocity: number;
219
+ };
220
+ type ScrollStateHandle = {
221
+ /** Attach scroll/wheel listeners (defaults to window). */
222
+ attach: (target?: HTMLElement | Window) => void;
223
+ /**
224
+ * Decay the velocity by one frame's worth (call once per frame from the driver after reading). `factor` in [0,1];
225
+ * lower = faster decay.
226
+ */
227
+ decay: (factor?: number) => void;
228
+ /** Remove listeners. Call from the scene's onDisposeObservable. */
229
+ detach: (target?: HTMLElement | Window) => void;
230
+ /** Live scroll signals. Mutated internally; read inside a render loop. */
231
+ state: ScrollState;
232
+ };
233
+ /**
234
+ * Creates a mutable scroll-state object for use inside a Babylon.js scene setup callback. Tracks page scroll `progress`
235
+ * [0,1] and a wheel-driven `velocity` that the driver decays each frame. Plain factory (not a React hook) — mirrors
236
+ * {@link ./pointer.createPointerState} so it can be read from the render observable.
237
+ */
238
+ declare const createScrollState: () => ScrollStateHandle;
239
+ //#endregion
240
+ //#region src/components/GbtScopeMaterial.d.ts
241
+ type GbtScopeMaterialComponentProps = GbtScopeMaterialProps & {
242
+ /** Declarative motion rules driven each frame. */
243
+ animators?: Array<GbtScopeAnimator>;
244
+ /** Fixed values replacing the live pointer/scroll inputs (mock/testing). */
245
+ inputOverrides?: GbtScopeInputOverrides;
246
+ /** Mesh the material is applied to. */
247
+ mesh: Mesh | null;
248
+ name?: string;
249
+ onInit?: (material: ShaderMaterial) => void;
250
+ onUpdate?: (material: ShaderMaterial) => void;
251
+ /** Live pointer + scroll inputs (created by the viewer). */
252
+ pointer: PointerStateHandle;
253
+ scroll: ScrollStateHandle;
254
+ };
255
+ /**
256
+ * Kaleidoscope shader material applied to a Babylon mesh. Static uniforms update reactively from props; the animated
257
+ * uniforms (rotation/offset/scaleFactor/ opacity) are driven each frame by {@link createGbtScopeDriver} from the
258
+ * `animators` + live pointer/scroll inputs. No Babylon Animation is used.
259
+ */
260
+ declare const GbtScopeMaterial: ({ animators, dimensions, imageAspect, inputOverrides, mesh, name, offset, offsetScale, onInit, onUpdate, opacity, pointer, rotation, rotationScale, scaleFactor, scroll, segments, src, tileMode, tiling }: GbtScopeMaterialComponentProps) => null | ReactElement;
261
+ //#endregion
262
+ //#region src/components/GbtScopeMeshViewer.d.ts
263
+ type GbtScopeMeshViewerProps = GbtScopeViewerBaseProps & Omit<GbtScopeMaterialProps, 'dimensions'> & {
264
+ cameraSettings?: CameraConfigPosition;
265
+ name?: string;
266
+ };
267
+ /** Default props for the 3D mesh viewer — single source of truth for Storybook args. */
268
+ declare const defaultGbtScopeMeshViewerProps: {
269
+ animators: never[];
270
+ aspect_ratio: "parent" | number;
271
+ bg_color: string;
272
+ cameraSettings: CameraConfigPosition;
273
+ name: string;
274
+ resolution: "screen" | Dimensions | null;
275
+ src: string;
276
+ imageAspect: number;
277
+ offset: [number, number];
278
+ offsetScale: number;
279
+ opacity: number;
280
+ rotation: number;
281
+ rotationScale: number;
282
+ scaleFactor: number;
283
+ segments: number;
284
+ tileMode: GbtScopeTileMode;
285
+ tiling: number;
286
+ };
287
+ declare const GbtScopeMeshViewer: ({ animators, aspect_ratio, bg_color, cameraSettings, imageAspect, inputOverrides, name, offset, offsetScale, opacity, resolution, rotation, rotationScale, scaleFactor, segments, src, tileMode, tiling }: GbtScopeMeshViewerProps) => ReactElement;
288
+ //#endregion
289
+ //#region src/motion/curve.d.ts
290
+ /**
291
+ * Maps an input value through a {@link GbtScopeCurve}: deadzone → gain → exponent → clamp → optional invert. The input
292
+ * is treated by magnitude (`Math.abs`), so direction is supplied by `invert`, not the sign of `value`.
293
+ */
294
+ declare const applyCurve: (value: number, curve?: GbtScopeCurve) => number;
295
+ /**
296
+ * Type guard distinguishing the legacy `[min, max]` tuple form of `mouse_curve` from the richer {@link GbtScopeCurve}
297
+ * object form.
298
+ */
299
+ declare const isTupleCurve: (value: [number, number] | GbtScopeCurve) => value is [number, number];
300
+ /**
301
+ * Bridges the legacy `[min, max]` tuple (plus a separate `mouse_multiplier`) into an equivalent {@link GbtScopeCurve}.
302
+ * With the historical defaults `[0, 0.015]` and multiplier `0.01`, `applyCurve` reproduces the old inline
303
+ * `Math.min(Math.max(dist * mult, min), max)` clamp exactly.
304
+ */
305
+ declare const tupleToGbtScopeCurve: (tuple: [number, number], multiplier?: number) => GbtScopeCurve;
306
+ //#endregion
307
+ export { type Dimensions, type GbtScopeAnimator, type GbtScopeAnimatorSource, type GbtScopeAnimatorTarget, type GbtScopeCurve, GbtScopeFlatViewer, type GbtScopeFlatViewerProps, type GbtScopeInputOverrides, type GbtScopeInputs, GbtScopeMaterial, type GbtScopeMaterialComponentProps, type GbtScopeMaterialProps, GbtScopeMeshViewer, type GbtScopeMeshViewerProps, type GbtScopeState, type GbtScopeTileMode, type GbtScopeViewerBaseProps, type Point, type PointerState, type PointerStateHandle, type ScrollState, type ScrollStateHandle, type XY, applyAnimators, applyCurve, createPointerState, createScrollState, defaultGbtScopeFlatViewerProps, defaultGbtScopeMaterialProps, defaultGbtScopeMeshViewerProps, isTupleCurve, tupleToGbtScopeCurve };
308
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/helpers.ts","../src/motion/animator.ts","../src/types.ts","../src/components/GbtScopeFlatViewer.tsx","../src/motion/pointer.ts","../src/motion/scroll.ts","../src/components/GbtScopeMaterial.tsx","../src/components/GbtScopeMeshViewer.tsx","../src/motion/curve.ts"],"mappings":";;;;;;;;;;;;KAWY;EACR;EACA;;KAEQ;EAAU;EAAW;;KACrB;KAYA,gBAAgB,6BAA6B;KAI7C,uBAAuB;EAC/B;EACA;;EAEA;EACA,UAAU;EACV;EACA,QAAQ;EACR;;KAEQ,oBAAoB,KAC5B;EAEE;;;;;;;;KCtCM;EACR,QAAQ;EACR;EACA,QAAQ;EACR;EACA,QAAQ;;;KAIA;;KAIA;;;;;KAOA,yBAAyB,QACjC,KAAK;;KAIG;EACR;EACA;EACA;EACA;EACA;;;KAIQ;EACR;EACA;EACA;EACA;;;;;;cAOS,iBACT,OAAO,eACP,WAAW,MAAM,mBACjB,QAAQ,mBACT;;;;;;;;;KC5CS;;EAER;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;;KAQQ;;EAER,aAAa;EACb;EACA;;EAEA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA,WAAW;EACX;;;;;;;;;KAUQ;;;;;cAMC;;EAES;;;;;;;EAOI,UAAA;;;;;;;KAQd;;EAER,YAAY,MAAM;;EAElB;EACA;;EAEA,iBAAiB;;EAEjB,wBAAwB;;;;KC/DhB,0BAA0B,0BAClC,KAAK;EACD,iBAAiB;EACjB;;;cAKK;;EAGU;;EAMd,gBAAA;;EAEmB,uBAAW;;;;;;;;;;YAAA;;;cAIjC,uBAAsB,WAAA,cAAA,UAAA,gBAAA,aAAA,gBAAA,MAAA,QAAA,aAAA,SAAA,YAAA,UAAA,eAAA,aAAA,UAAA,KAAA,UAAA,UAmBzB,4BAA0B;;;;KCnEjB;WACC;WACA;;KAGD;;EAER,SAAS,QAAQ;;EAEjB,SAAS,QAAQ;;EAEjB,OAAO;;;;;;;;;;;cAYE,0BAAyB;;;;KCvB1B;WACC;WACA;;KAGD;;EAER,SAAS,SAAS,cAAc;;;;;EAKhC,QAAQ;;EAER,SAAS,SAAS,cAAc;;EAEhC,OAAO;;;;;;;cAgBE,yBAAwB;;;KCZzB,iCAAiC;;EAEzC,YAAY,MAAM;;EAElB,iBAAiB;;EAEjB,MAAM;EACN;EACA,UAAU,UAAU;EACpB,YAAY,UAAU;;EAEtB,SAAS;EACT,QAAQ;;;;;;;cA8BN,qBAAoB,WAAA,YAAA,aAAA,gBAAA,MAAA,MAAA,QAAA,aAAA,QAAA,UAAA,SAAA,SAAA,UAAA,eAAA,aAAA,QAAA,UAAA,KAAA,UAAA,UAqBvB,0CAAwC;;;KC1D/B,0BAA0B,0BAClC,KAAK;EACD,iBAAiB;EACjB;;;cAKK;;EAGU;;EAMd,gBAAA;;EAEe,uBAAW;;;;;;;;;;YAAA;;;cAI7B,uBAAsB,WAAA,cAAA,UAAA,gBAAA,aAAA,gBAAA,MAAA,QAAA,aAAA,SAAA,YAAA,UAAA,eAAA,aAAA,UAAA,KAAA,UAAA,UAuBzB,4BAA0B;;;;;;;cClEhB,aACT,eACA,QAAO;;;;;cAoBE,eACT,0BAA0B,kBAC3B;;;;;;cAgBU,uBACT,yBACA,wBACD"}