@tsogtoodev/shingen-metal 1.0.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.
@@ -0,0 +1,321 @@
1
+ import { ComponentOptionsMixin } from 'vue';
2
+ import { ComponentProvideOptions } from 'vue';
3
+ import { DefineComponent } from 'vue';
4
+ import { ExtractPropTypes } from 'vue';
5
+ import { PropType } from 'vue';
6
+ import { PublicProps } from 'vue';
7
+ import { Ref } from 'vue';
8
+
9
+ declare type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
10
+
11
+ declare type __VLS_Prettify<T> = {
12
+ [K in keyof T]: T[K];
13
+ } & {};
14
+
15
+ declare type __VLS_TypePropsToRuntimeProps<T> = {
16
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
17
+ type: PropType<__VLS_NonUndefinedable<T[K]>>;
18
+ } : {
19
+ type: PropType<T[K]>;
20
+ required: true;
21
+ };
22
+ };
23
+
24
+ declare type __VLS_WithDefaults<P, D> = {
25
+ [K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_Prettify<P[K] & {
26
+ default: D[K];
27
+ }> : P[K];
28
+ };
29
+
30
+ declare type __VLS_WithTemplateSlots<T, S> = T & {
31
+ new (): {
32
+ $slots: S;
33
+ };
34
+ };
35
+
36
+ export declare function createInstance(opts: CreateInstanceOptions): MetalFxInstance;
37
+
38
+ declare interface CreateInstanceOptions {
39
+ hostCanvas: HTMLCanvasElement;
40
+ cssWidth: number;
41
+ cssHeight: number;
42
+ cornerRadius: number;
43
+ kind: 'pill' | 'circle';
44
+ shaderScale?: number;
45
+ ringCssPx?: number;
46
+ opacityMul?: number;
47
+ paused?: boolean;
48
+ scale?: number;
49
+ onAfterFrame?: () => void;
50
+ onFirstCopy?: () => void;
51
+ }
52
+
53
+ export declare function destroyInstance(inst: MetalFxInstance): void;
54
+
55
+ /** Converts `#rrggbb` (or `#rgb`) to a normalized `[r, g, b]` triple (0–1). */
56
+ export declare function hexToRgb(hex: string): [number, number, number];
57
+
58
+ export declare const MetalFx: __VLS_WithTemplateSlots<DefineComponent<ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<MetalFxProps>, {
59
+ variant: string;
60
+ preset: string;
61
+ theme: string;
62
+ strength: number;
63
+ paused: boolean;
64
+ normalizeHostStyles: boolean;
65
+ disableGlow: boolean;
66
+ scale: number;
67
+ }>>, {
68
+ /** The wrapper element, mirroring the React version's forwarded ref. */
69
+ rootEl: Ref<HTMLDivElement | null, HTMLDivElement | null>;
70
+ }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<MetalFxProps>, {
71
+ variant: string;
72
+ preset: string;
73
+ theme: string;
74
+ strength: number;
75
+ paused: boolean;
76
+ normalizeHostStyles: boolean;
77
+ disableGlow: boolean;
78
+ scale: number;
79
+ }>>> & Readonly<{}>, {
80
+ preset: MetalFxPreset;
81
+ paused: boolean;
82
+ scale: number;
83
+ variant: MetalFxVariant;
84
+ theme: MetalFxTheme;
85
+ strength: number;
86
+ normalizeHostStyles: boolean;
87
+ disableGlow: boolean;
88
+ }, {}, {}, {}, string, ComponentProvideOptions, true, {}, any>, {
89
+ default?(_: {}): any;
90
+ }>;
91
+
92
+ export declare interface MetalFxInstance {
93
+ canvas: HTMLCanvasElement;
94
+ ctx: CanvasRenderingContext2D;
95
+ cssWidth: number;
96
+ cssHeight: number;
97
+ cornerRadius: number;
98
+ kind: 'pill' | 'circle';
99
+ ringCssPx: number;
100
+ shaderScale: number;
101
+ opacityMul: number;
102
+ visible: boolean;
103
+ /** Per-instance freeze flag. When true the instance's 2D canvas keeps the
104
+ * last copied frame; the shared GL loop continues for any other unpaused
105
+ * instance. */
106
+ paused: boolean;
107
+ /** Set to true after the first successful copyShaderToInstance — so an
108
+ * instance that mounts already paused still gets one frame painted before
109
+ * it freezes (otherwise it would render a blank canvas). */
110
+ everCopied: boolean;
111
+ dpr: number;
112
+ /** Master scale multiplier for absolute-pixel internals (glow stroke
113
+ * widths/blurs, reflection stroke band, etc.). 1 is the baseline. Set to
114
+ * 2 for a CSS-zoomed 2× hero so glow + reflection grow with the layout. */
115
+ scale: number;
116
+ onAfterFrame?: () => void;
117
+ /** One-shot callback fired after the very first copyShaderToInstance.
118
+ * Auto-cleared by the loop so it never fires twice. */
119
+ onFirstCopy?: () => void;
120
+ }
121
+
122
+ /**
123
+ * Bundled preset names. Each preset ships both a dark and light mode block.
124
+ */
125
+ export declare type MetalFxPreset = 'chromatic' | 'silver' | 'gold';
126
+
127
+ /**
128
+ * Props for the MetalFx Vue component. The single host element to wrap is
129
+ * passed as the default slot (button, anchor, div, ...). MetalFx measures it
130
+ * via `ResizeObserver` and paints its canvas + glow on top. Extra attributes
131
+ * (class, style, event listeners, ...) fall through to the wrapper element.
132
+ */
133
+ export declare interface MetalFxProps {
134
+ /**
135
+ * Variant — controls the shader sampling scale + ring width.
136
+ * - `button` (default): pill-style ring at 1 px wide, scale 1.6
137
+ * - `circle`: compact circle with a 2 px ring, scale 1.3
138
+ */
139
+ variant?: MetalFxVariant;
140
+ /**
141
+ * Color preset. All three presets ship both dark and light mode tunings —
142
+ * `theme` picks the right side at runtime.
143
+ * @default 'chromatic'
144
+ */
145
+ preset?: MetalFxPreset;
146
+ /**
147
+ * Theme mode. `'auto'` (default) resolves via
148
+ * `matchMedia('(prefers-color-scheme: dark)')` and switches live when the
149
+ * OS theme changes. Pass `'dark'` or `'light'` to pin a specific mode.
150
+ * @default 'auto'
151
+ */
152
+ theme?: MetalFxTheme;
153
+ /**
154
+ * Effect strength (0..1). Multiplies the shader bitmap opacity and the glow
155
+ * SVG alpha. The shader continues to animate at full intensity at any value;
156
+ * only the rendered alpha onto the host is scaled. Lighter values let the
157
+ * underlying child surface show through more strongly.
158
+ * @default 1
159
+ */
160
+ strength?: number;
161
+ /**
162
+ * Pause the shader animation. The visible canvas keeps the last painted
163
+ * frame so the metal silhouette stays on screen.
164
+ * @default false
165
+ */
166
+ paused?: boolean;
167
+ /**
168
+ * Optional explicit border radius (CSS px). When omitted, MetalFx reads the
169
+ * computed border-radius of the wrapped child each resize.
170
+ */
171
+ borderRadius?: number;
172
+ /**
173
+ * When true, MetalFx normalizes the host element's outer chrome (border /
174
+ * outline / box-shadow) so user-provided component styles don't clash with
175
+ * the metal ring. Inner fills, typography, and content remain untouched.
176
+ * @default true
177
+ */
178
+ normalizeHostStyles?: boolean;
179
+ /**
180
+ * Neighbour elements that should receive a soft proximity reflection of the
181
+ * metal effect. Reflections only render when the resolved theme is `dark` —
182
+ * pass-through in light mode (no DOM scan, no per-frame work).
183
+ *
184
+ * Pass template refs to the sibling DOM elements you want to receive the
185
+ * reflection (chips next to a send button, search field next to an Upgrade
186
+ * pill, ...).
187
+ */
188
+ reflectionTargets?: ReadonlyArray<MetalFxReflectionTarget>;
189
+ /**
190
+ * Disable the wandering halo overlay. The shader ring still renders.
191
+ * @default false
192
+ */
193
+ disableGlow?: boolean;
194
+ /**
195
+ * Override the shader sampling scale. Larger values zoom into the shared
196
+ * shader (visibly bigger pattern features); smaller values zoom out.
197
+ * Defaults to the variant's baseline (1.6 for `'button'`, 1.3 for
198
+ * `'circle'`) multiplied by `scale`.
199
+ */
200
+ shaderScale?: number;
201
+ /**
202
+ * Override the ring thickness in CSS pixels. Defaults to the variant's
203
+ * baseline (1 for `'button'`, 2 for `'circle'`) multiplied by `scale`.
204
+ */
205
+ ringCssPx?: number;
206
+ /**
207
+ * Master scale multiplier for every absolute-pixel constant the engine
208
+ * uses internally. Set this when you render the wrapped element at a
209
+ * non-1× size (e.g. inside a CSS `zoom: 2` container, or when you've
210
+ * doubled all your Tailwind sizes by hand). It scales:
211
+ * - shader sampling (so pattern features grow proportionally)
212
+ * - ring thickness on the canvas
213
+ * - glow SVG stroke widths, blur radii, fade-circle radius, and the
214
+ * small inset/outward offsets that position the catch-light
215
+ * - reflection canvas stroke band, border-highlight thickness, and the
216
+ * reference draw width baseline
217
+ * @default 1
218
+ */
219
+ scale?: number;
220
+ }
221
+
222
+ /**
223
+ * A reflection target: a Vue template ref holding the sibling DOM element
224
+ * (or `null` before mount), or the element itself.
225
+ */
226
+ export declare type MetalFxReflectionTarget = Ref<HTMLElement | null> | HTMLElement | null;
227
+
228
+ /**
229
+ * Theme mode for the metal effect.
230
+ *
231
+ * - `auto` (default): follows the user's `prefers-color-scheme` and updates
232
+ * live when the OS / browser theme changes (also gracefully falls back to
233
+ * `dark` during SSR or when `matchMedia` is unavailable).
234
+ * - `dark`: pin to the dark-mode tunings regardless of system preference.
235
+ * - `light`: pin to the light-mode tunings regardless of system preference.
236
+ *
237
+ * Drive this from your app's theme state if you have a manual toggle that
238
+ * doesn't follow the OS — otherwise `auto` is the right default.
239
+ */
240
+ export declare type MetalFxTheme = 'dark' | 'light' | 'auto';
241
+
242
+ /**
243
+ * Variant for the metal effect.
244
+ * - 'button' (default): pill-shaped 134×40 baseline with shaderScale 1.6
245
+ * - 'circle': compact 32×32 circle baseline with shaderScale 1.3
246
+ *
247
+ * In practice the wrapped child's measured dimensions drive the visible size —
248
+ * the variant only controls the shader sampling scale and ring thickness.
249
+ */
250
+ export declare type MetalFxVariant = 'button' | 'circle';
251
+
252
+ export declare function pauseShared(): void;
253
+
254
+ export declare interface Preset {
255
+ name: PresetName;
256
+ modes: Record<PresetTheme, PresetMode>;
257
+ }
258
+
259
+ export declare interface PresetMode {
260
+ /** 7-stop palette, indexed against `u_color1..u_color7`. */
261
+ colors: [string, string, string, string, string, string, string];
262
+ /** Per-stop alpha weights (0..1). */
263
+ alphas: [number, number, number, number, number, number, number];
264
+ /** Drift angle (degrees). Multiplied by π/180 before upload. */
265
+ direction: number;
266
+ /** Time multiplier applied JS-side before passing into the shader. */
267
+ speed: number;
268
+ /** Plasma intensity (wave-field amplitude). */
269
+ intensity: number;
270
+ /** Noise zoom — smaller = chunkier features. */
271
+ scale: number;
272
+ /** Edge softness (effect 1 ignores; carried for parity). */
273
+ softness: number;
274
+ /** Warp strength on the field (0..1). */
275
+ distortion: number;
276
+ /** FBM octave / frequency multiplier. */
277
+ complexity: number;
278
+ /** Reserved (effect 1 ignores). */
279
+ shape: number;
280
+ /** 9-tap blur sample radius (0 = single tap). */
281
+ blur: number;
282
+ /** Vignette range (0..1). */
283
+ vignette: number;
284
+ /** Vignette darkening strength (0..1). */
285
+ vigOpacity: number;
286
+ /** Final alpha multiplier in the fragment shader (0..1). */
287
+ shaderOpacity: number;
288
+ }
289
+
290
+ /**
291
+ * Bundled preset configurations for the metal effect.
292
+ *
293
+ * Direct ports of the three JSON files shipped alongside the canonical demo:
294
+ * • preset-chromatic-both-modes.json
295
+ * • preset-silver-both-modes.json
296
+ * • preset-gold-both-modes.json
297
+ *
298
+ * Each preset carries a `dark` and `light` mode block. Values are reproduced
299
+ * byte-for-byte (including the `chromatic.dark.scale = 1.6` quirk that gives
300
+ * the dark chromatic preset its noticeably chunkier features compared with
301
+ * the other dark-mode entries).
302
+ *
303
+ * The fragment shader only consumes uniforms 1..5 of `palette`/`alphas` for
304
+ * the Plasma effect, but the JSON ships 7 colors / alphas to stay
305
+ * forward-compatible with effect 24 (Noise Flow Wide). We keep the full 7 so
306
+ * a future variant could opt into other effects without re-importing the
307
+ * preset definitions.
308
+ */
309
+ export declare type PresetName = 'chromatic' | 'silver' | 'gold';
310
+
311
+ export declare const PRESETS: Record<PresetName, Preset>;
312
+
313
+ export declare type PresetTheme = 'dark' | 'light';
314
+
315
+ export declare function resumeShared(): void;
316
+
317
+ export declare function setSharedPreset(name: PresetName, theme: PresetTheme): void;
318
+
319
+ export declare function updateInstance(inst: MetalFxInstance, patch: Partial<Pick<MetalFxInstance, 'cssWidth' | 'cssHeight' | 'cornerRadius' | 'kind' | 'shaderScale' | 'ringCssPx' | 'opacityMul' | 'paused' | 'scale'>>): void;
320
+
321
+ export { }