@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.
- package/LICENSE +21 -0
- package/README.md +164 -0
- package/dist/index.cjs.js +421 -0
- package/dist/index.d.ts +321 -0
- package/dist/index.es.js +1605 -0
- package/package.json +60 -0
package/dist/index.d.ts
ADDED
|
@@ -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 { }
|