@shohojdhara/atomix 0.4.7 → 0.4.9

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.
Files changed (176) hide show
  1. package/atomix.config.ts +58 -1
  2. package/dist/atomix.css +172 -157
  3. package/dist/atomix.css.map +1 -1
  4. package/dist/atomix.min.css +4 -4
  5. package/dist/atomix.min.css.map +1 -1
  6. package/dist/charts.d.ts +33 -0
  7. package/dist/charts.js +1274 -164
  8. package/dist/charts.js.map +1 -1
  9. package/dist/core.d.ts +33 -10
  10. package/dist/core.js +1099 -83
  11. package/dist/core.js.map +1 -1
  12. package/dist/forms.d.ts +33 -0
  13. package/dist/forms.js +2106 -1050
  14. package/dist/forms.js.map +1 -1
  15. package/dist/heavy.d.ts +42 -1
  16. package/dist/heavy.js +1663 -638
  17. package/dist/heavy.js.map +1 -1
  18. package/dist/index.d.ts +442 -270
  19. package/dist/index.esm.js +1947 -680
  20. package/dist/index.esm.js.map +1 -1
  21. package/dist/index.js +1982 -712
  22. package/dist/index.js.map +1 -1
  23. package/dist/index.min.js +1 -1
  24. package/dist/index.min.js.map +1 -1
  25. package/package.json +6 -3
  26. package/scripts/atomix-cli.js +136 -1827
  27. package/scripts/cli/__tests__/basic.test.js +3 -2
  28. package/scripts/cli/__tests__/clean.test.js +278 -0
  29. package/scripts/cli/__tests__/component-validator.test.js +433 -0
  30. package/scripts/cli/__tests__/generator.test.js +613 -0
  31. package/scripts/cli/__tests__/glass-motion.test.js +256 -0
  32. package/scripts/cli/__tests__/integration.test.js +719 -108
  33. package/scripts/cli/__tests__/migrate.test.js +74 -0
  34. package/scripts/cli/__tests__/security.test.js +206 -0
  35. package/scripts/cli/__tests__/test-setup.js +3 -1
  36. package/scripts/cli/__tests__/theme-bridge.test.js +507 -0
  37. package/scripts/cli/__tests__/token-provider.test.js +361 -0
  38. package/scripts/cli/__tests__/utils.test.js +5 -5
  39. package/scripts/cli/commands/benchmark.js +105 -0
  40. package/scripts/cli/commands/build-theme.js +115 -0
  41. package/scripts/cli/commands/clean.js +109 -0
  42. package/scripts/cli/commands/doctor.js +88 -0
  43. package/scripts/cli/commands/generate.js +218 -0
  44. package/scripts/cli/commands/init.js +73 -0
  45. package/scripts/cli/commands/migrate.js +106 -0
  46. package/scripts/cli/commands/sync-tokens.js +206 -0
  47. package/scripts/cli/commands/theme-bridge.js +248 -0
  48. package/scripts/cli/commands/tokens.js +157 -0
  49. package/scripts/cli/commands/validate.js +194 -0
  50. package/scripts/cli/internal/ai-engine.js +156 -0
  51. package/scripts/cli/internal/compiler.js +114 -0
  52. package/scripts/cli/internal/component-validator.js +443 -0
  53. package/scripts/cli/internal/config-loader.js +162 -0
  54. package/scripts/cli/internal/filesystem.js +158 -0
  55. package/scripts/cli/internal/generator.js +430 -0
  56. package/scripts/cli/internal/glass-generator.js +398 -0
  57. package/scripts/cli/internal/hook-generator.js +369 -0
  58. package/scripts/cli/internal/hooks.js +61 -0
  59. package/scripts/cli/internal/itcss-generator.js +565 -0
  60. package/scripts/cli/internal/motion-generator.js +679 -0
  61. package/scripts/cli/internal/template-engine.js +301 -0
  62. package/scripts/cli/internal/theme-bridge.js +664 -0
  63. package/scripts/cli/internal/tokens/engine.js +122 -0
  64. package/scripts/cli/internal/tokens/provider.js +34 -0
  65. package/scripts/cli/internal/tokens/providers/figma.js +50 -0
  66. package/scripts/cli/internal/tokens/providers/style-dictionary.js +48 -0
  67. package/scripts/cli/internal/tokens/providers/w3c.js +48 -0
  68. package/scripts/cli/internal/tokens/token-provider.js +443 -0
  69. package/scripts/cli/internal/tokens/token-validator.js +513 -0
  70. package/scripts/cli/internal/validator.js +276 -0
  71. package/scripts/cli/internal/wizard.js +115 -0
  72. package/scripts/cli/mappings.js +23 -0
  73. package/scripts/cli/migration-tools.js +164 -94
  74. package/scripts/cli/plugins/style-dictionary.js +46 -0
  75. package/scripts/cli/templates/README.md +525 -95
  76. package/scripts/cli/templates/common-templates.js +40 -14
  77. package/scripts/cli/templates/components/react-component.ts +282 -0
  78. package/scripts/cli/templates/config/project-config.ts +112 -0
  79. package/scripts/cli/templates/hooks/use-component.ts +477 -0
  80. package/scripts/cli/templates/index.js +19 -4
  81. package/scripts/cli/templates/index.ts +171 -0
  82. package/scripts/cli/templates/next-templates.js +72 -0
  83. package/scripts/cli/templates/react-templates.js +70 -126
  84. package/scripts/cli/templates/scss-templates.js +35 -35
  85. package/scripts/cli/templates/stories/storybook-story.ts +241 -0
  86. package/scripts/cli/templates/styles/scss-component.ts +255 -0
  87. package/scripts/cli/templates/tests/vitest-test.ts +229 -0
  88. package/scripts/cli/templates/token-templates.js +337 -1
  89. package/scripts/cli/templates/tokens/token-generators.ts +1088 -0
  90. package/scripts/cli/templates/types/component-types.ts +145 -0
  91. package/scripts/cli/templates/utils/testing-utils.ts +144 -0
  92. package/scripts/cli/templates/vanilla-templates.js +39 -0
  93. package/scripts/cli/token-manager.js +8 -2
  94. package/scripts/cli/utils/cache-manager.js +240 -0
  95. package/scripts/cli/utils/detector.js +46 -0
  96. package/scripts/cli/utils/diagnostics.js +289 -0
  97. package/scripts/cli/utils/error.js +89 -0
  98. package/scripts/cli/utils/helpers.js +67 -0
  99. package/scripts/cli/utils/logger.js +75 -0
  100. package/scripts/cli/utils/security.js +302 -0
  101. package/scripts/cli/utils/telemetry.js +115 -0
  102. package/scripts/cli/utils/validation.js +37 -0
  103. package/scripts/cli/utils.js +28 -341
  104. package/src/components/Accordion/Accordion.stories.tsx +0 -18
  105. package/src/components/Accordion/Accordion.test.tsx +0 -17
  106. package/src/components/Accordion/Accordion.tsx +0 -4
  107. package/src/components/AtomixGlass/AtomixGlass.test.tsx +37 -3
  108. package/src/components/AtomixGlass/AtomixGlass.tsx +143 -31
  109. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +129 -31
  110. package/src/components/AtomixGlass/PerformanceDashboard.tsx +219 -0
  111. package/src/components/AtomixGlass/README.md +25 -10
  112. package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +216 -0
  113. package/src/components/AtomixGlass/animation-system.ts +578 -0
  114. package/src/components/AtomixGlass/shader-utils.ts +4 -1
  115. package/src/components/AtomixGlass/stories/Overview.stories.tsx +157 -6
  116. package/src/components/AtomixGlass/stories/Phase1-Animation.stories.tsx +653 -0
  117. package/src/components/AtomixGlass/stories/Phase1-Test.stories.tsx +95 -0
  118. package/src/components/AtomixGlass/stories/Playground.stories.tsx +51 -51
  119. package/src/components/AtomixGlass/stories/shared-components.tsx +6 -0
  120. package/src/components/Avatar/Avatar.tsx +1 -1
  121. package/src/components/Button/Button.stories.disabled-link.tsx +10 -0
  122. package/src/components/Button/Button.stories.tsx +10 -0
  123. package/src/components/Button/Button.test.tsx +16 -11
  124. package/src/components/Button/Button.tsx +4 -4
  125. package/src/components/Card/Card.tsx +1 -1
  126. package/src/components/Dropdown/Dropdown.tsx +12 -12
  127. package/src/components/Form/Select.tsx +62 -3
  128. package/src/components/Modal/Modal.tsx +14 -3
  129. package/src/components/Navigation/Navbar/Navbar.tsx +44 -0
  130. package/src/components/Slider/Slider.stories.tsx +3 -3
  131. package/src/components/Slider/Slider.tsx +38 -0
  132. package/src/components/Steps/Steps.tsx +3 -3
  133. package/src/components/Tabs/Tabs.tsx +77 -8
  134. package/src/components/Testimonial/Testimonial.tsx +1 -1
  135. package/src/components/TypedButton/TypedButton.stories.tsx +59 -0
  136. package/src/components/TypedButton/TypedButton.tsx +39 -0
  137. package/src/components/TypedButton/index.ts +2 -0
  138. package/src/components/VideoPlayer/VideoPlayer.tsx +11 -4
  139. package/src/lib/composables/index.ts +4 -7
  140. package/src/lib/composables/types.ts +45 -0
  141. package/src/lib/composables/useAccordion.ts +0 -7
  142. package/src/lib/composables/useAtomixGlass.ts +148 -6
  143. package/src/lib/composables/useAtomixGlassStyles.ts +9 -7
  144. package/src/lib/composables/useChartExport.ts +3 -13
  145. package/src/lib/composables/useDropdown.ts +66 -0
  146. package/src/lib/composables/useFocusTrap.ts +80 -0
  147. package/src/lib/composables/usePerformanceMonitor.ts +448 -0
  148. package/src/lib/composables/useResponsiveGlass.presets.ts +192 -0
  149. package/src/lib/composables/useResponsiveGlass.ts +441 -0
  150. package/src/lib/composables/useTooltip.ts +16 -0
  151. package/src/lib/composables/useTypedButton.ts +66 -0
  152. package/src/lib/config/index.ts +62 -5
  153. package/src/lib/constants/components.ts +62 -7
  154. package/src/lib/theme/devtools/__tests__/useHistory.test.tsx +150 -0
  155. package/src/lib/theme/tokens/centralized-tokens.ts +120 -0
  156. package/src/lib/theme/utils/__tests__/domUtils.test.ts +101 -0
  157. package/src/lib/types/components.ts +37 -11
  158. package/src/lib/types/glass.ts +35 -0
  159. package/src/lib/types/index.ts +1 -0
  160. package/src/lib/utils/displacement-generator.ts +1 -1
  161. package/src/styles/01-settings/_settings.testtypecheck.scss +53 -0
  162. package/src/styles/01-settings/_settings.typedbutton.scss +53 -0
  163. package/src/styles/06-components/_components.atomix-glass.scss +17 -21
  164. package/src/styles/06-components/_components.edge-panel.scss +1 -5
  165. package/src/styles/06-components/_components.modal.scss +1 -4
  166. package/src/styles/06-components/_components.navbar.scss +1 -1
  167. package/src/styles/06-components/_components.testbutton.scss +212 -0
  168. package/src/styles/06-components/_components.testtypecheck.scss +212 -0
  169. package/src/styles/06-components/_components.tooltip.scss +9 -5
  170. package/src/styles/06-components/_components.typedbutton.scss +212 -0
  171. package/src/styles/99-utilities/_index.scss +1 -0
  172. package/src/styles/99-utilities/_utilities.text.scss +1 -1
  173. package/src/styles/99-utilities/_utilities.touch-target.scss +36 -0
  174. package/scripts/cli/component-generator.js +0 -564
  175. package/scripts/cli/interactive-init.js +0 -357
  176. package/src/styles/06-components/old.chart.styles.scss +0 -2788
@@ -0,0 +1,578 @@
1
+ /**
2
+ * Animation System for AtomixGlass Component
3
+ *
4
+ * Implements Phase 1 features from the AtomixGlass Feature Implementation Roadmap:
5
+ * - Feature 1.1: Time-Based Animation System
6
+ * - Feature 1.2: Multi-Layer Distortion System (FBM)
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+
11
+ import { ATOMIX_GLASS } from '../../lib/constants/components';
12
+
13
+ // ============================================================================
14
+ // Type Definitions
15
+ // ============================================================================
16
+
17
+ /**
18
+ * Animation state interface for tracking time-based animations
19
+ */
20
+ export interface AnimationState {
21
+ /** Whether animation is currently running */
22
+ isAnimating: boolean;
23
+ /** Timestamp when animation started */
24
+ startTime: number;
25
+ /** Total elapsed time in milliseconds */
26
+ elapsedTime: number;
27
+ /** Request animation frame ID for cleanup */
28
+ animationFrameId: number | null;
29
+ }
30
+
31
+ /**
32
+ * Animation configuration options
33
+ */
34
+ export interface AnimationConfig {
35
+ /** Enable time-based animations */
36
+ withTimeAnimation: boolean;
37
+ /** Animation speed multiplier (0.1 - 5.0) */
38
+ animationSpeed: number;
39
+ /** Reduced motion preference */
40
+ reducedMotion?: boolean;
41
+ }
42
+
43
+ /**
44
+ * Fractal Brownian Motion (FBM) configuration
45
+ */
46
+ export interface FBMConfig {
47
+ /** Number of noise octaves */
48
+ octaves: number;
49
+ /** Frequency multiplier per octave (lacunarity) */
50
+ lacunarity: number;
51
+ /** Amplitude multiplier per octave (gain) */
52
+ gain: number;
53
+ /** Time value for animation */
54
+ time?: number;
55
+ }
56
+
57
+ /**
58
+ * 2D vector interface for shader calculations
59
+ */
60
+ export interface Vec2 {
61
+ x: number;
62
+ y: number;
63
+ }
64
+
65
+ /**
66
+ * Noise function type
67
+ */
68
+ export type NoiseFunction = (x: number, y: number) => number;
69
+
70
+ // ============================================================================
71
+ // Animation Loop Infrastructure (Feature 1.1)
72
+ // ============================================================================
73
+
74
+ /**
75
+ * Creates and manages the animation loop for time-based effects
76
+ *
77
+ * @param config - Animation configuration
78
+ * @param onFrameUpdate - Callback fired on each animation frame with elapsed time
79
+ * @returns Object with control methods (start, stop, updateConfig)
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * const animator = createAnimationLoop(
84
+ * { withTimeAnimation: true, animationSpeed: 1.0 },
85
+ * (elapsedTime) => {
86
+ * // Update shader uniforms or CSS variables
87
+ * console.log(`Elapsed: ${elapsedTime}ms`);
88
+ * }
89
+ * );
90
+ *
91
+ * // Start animation
92
+ * animator.start();
93
+ *
94
+ * // Stop animation
95
+ * animator.stop();
96
+ * ```
97
+ */
98
+ export function createAnimationLoop(
99
+ config: AnimationConfig,
100
+ onFrameUpdate: (elapsedTime: number, deltaTime: number) => void
101
+ ) {
102
+ let state: AnimationState = {
103
+ isAnimating: false,
104
+ startTime: 0,
105
+ elapsedTime: 0,
106
+ animationFrameId: null,
107
+ };
108
+
109
+ let lastFrameTime = 0;
110
+
111
+ /**
112
+ * Internal animation frame handler
113
+ */
114
+ const animate = (currentTime: number) => {
115
+ if (!state.isAnimating) return;
116
+
117
+ // Calculate delta time for smooth animations
118
+ const deltaTime = currentTime - lastFrameTime;
119
+ lastFrameTime = currentTime;
120
+
121
+ // Apply animation speed multiplier
122
+ const scaledDelta = deltaTime * config.animationSpeed;
123
+ state.elapsedTime += scaledDelta;
124
+
125
+ // Fire update callback
126
+ onFrameUpdate(state.elapsedTime, scaledDelta);
127
+
128
+ // Continue animation loop
129
+ state.animationFrameId = requestAnimationFrame(animate);
130
+ };
131
+
132
+ /**
133
+ * Start the animation loop
134
+ */
135
+ const start = () => {
136
+ if (state.isAnimating || !config.withTimeAnimation || config.reducedMotion) {
137
+ return;
138
+ }
139
+
140
+ state.isAnimating = true;
141
+ state.startTime = performance.now();
142
+ state.elapsedTime = 0;
143
+ lastFrameTime = state.startTime;
144
+ state.animationFrameId = requestAnimationFrame(animate);
145
+ };
146
+
147
+ /**
148
+ * Stop the animation loop and cleanup
149
+ */
150
+ const stop = () => {
151
+ if (!state.isAnimating) return;
152
+
153
+ state.isAnimating = false;
154
+ if (state.animationFrameId !== null) {
155
+ cancelAnimationFrame(state.animationFrameId);
156
+ state.animationFrameId = null;
157
+ }
158
+ };
159
+
160
+ /**
161
+ * Update animation configuration dynamically
162
+ */
163
+ const updateConfig = (newConfig: Partial<AnimationConfig>) => {
164
+ config = { ...config, ...newConfig };
165
+
166
+ // Restart if animation was stopped due to reduced motion
167
+ if (!config.reducedMotion && config.withTimeAnimation && !state.isAnimating) {
168
+ start();
169
+ } else if (config.reducedMotion && state.isAnimating) {
170
+ stop();
171
+ }
172
+ };
173
+
174
+ /**
175
+ * Get current animation state
176
+ */
177
+ const getState = (): AnimationState => ({ ...state });
178
+
179
+ /**
180
+ * Get current elapsed time
181
+ */
182
+ const getElapsedTime = (): number => state.elapsedTime;
183
+
184
+ return {
185
+ start,
186
+ stop,
187
+ updateConfig,
188
+ getState,
189
+ getElapsedTime,
190
+ };
191
+ }
192
+
193
+ // ============================================================================
194
+ // Noise Functions for FBM (Feature 1.2)
195
+ // ============================================================================
196
+
197
+ /**
198
+ * Perlin noise implementation for smooth gradient noise
199
+ *
200
+ * @param x - X coordinate
201
+ * @param y - Y coordinate
202
+ * @returns Noise value in range [0, 1]
203
+ */
204
+ export function perlinNoise(x: number, y: number): number {
205
+ // Simplified Perlin noise using pseudo-random gradients
206
+ const X = Math.floor(x) & 255;
207
+ const Y = Math.floor(y) & 255;
208
+
209
+ const xf = x - Math.floor(x);
210
+ const yf = y - Math.floor(y);
211
+
212
+ // Smoothstep interpolation
213
+ const u = fade(xf);
214
+ const v = fade(yf);
215
+
216
+ // Hash coordinates of cube corners (with bounds checking)
217
+ const A = (p[X]! + Y) & 255;
218
+ const B = (p[X + 1]! + Y) & 255;
219
+
220
+ // Get gradient values with non-null assertions (Perlin table is fully populated)
221
+ const ga = grad(p[A]!, xf, yf);
222
+ const gb = grad(p[B]!, xf - 1, yf);
223
+ const gc = grad(p[(A + 1) & 255]!, xf, yf - 1);
224
+ const gd = grad(p[(B + 1) & 255]!, xf - 1, yf - 1);
225
+
226
+ // Interpolate results
227
+ const lerpX1 = lerp(ga, gb, u);
228
+ const lerpX2 = lerp(gc, gd, u);
229
+ const result = lerp(lerpX1, lerpX2, v);
230
+
231
+ // Scale to [0, 1] range
232
+ return (result + 1) / 2;
233
+ }
234
+
235
+ /**
236
+ * Simplex noise - faster alternative to Perlin noise
237
+ * Better for mobile and low-end devices
238
+ *
239
+ * @param x - X coordinate
240
+ * @param y - Y coordinate
241
+ * @returns Noise value in range [0, 1]
242
+ */
243
+ export function simplexNoise(x: number, y: number): number {
244
+ // Skewing and unskewing factors for 2D
245
+ const F2 = 0.5 * (Math.sqrt(3) - 1);
246
+ const G2 = (3 - Math.sqrt(3)) / 6;
247
+
248
+ // Skew input space to determine which simplex cell we're in
249
+ const s = (x + y) * F2;
250
+ const i = Math.floor(x + s);
251
+ const j = Math.floor(y + s);
252
+
253
+ const t = (i + j) * G2;
254
+ const X0 = i - t;
255
+ const Y0 = j - t;
256
+
257
+ // Unskew back to (x,y) space
258
+ const x0 = x - X0;
259
+ const y0 = y - Y0;
260
+
261
+ // Determine which simplex we're in
262
+ let i1, j1;
263
+ if (x0 > y0) {
264
+ i1 = 1;
265
+ j1 = 0;
266
+ } else {
267
+ i1 = 0;
268
+ j1 = 1;
269
+ }
270
+
271
+ // Offsets for remaining corners
272
+ const x1 = x0 - i1 + G2;
273
+ const y1 = y0 - j1 + G2;
274
+ const x2 = x0 - 1 + 2 * G2;
275
+ const y2 = y0 - 1 + 2 * G2;
276
+
277
+ // Work out the hashed gradient indices
278
+ const ii = i & 255;
279
+ const jj = j & 255;
280
+
281
+ // Calculate contribution from three corners
282
+ let n0 = 0, n1 = 0, n2 = 0;
283
+
284
+ let t0 = 0.5 - x0 * x0 - y0 * y0;
285
+ if (t0 >= 0) {
286
+ const gi0 = perm[ii + perm[jj]!]! % 12;
287
+ t0 *= t0;
288
+ n0 = t0 * t0 * grad(gi0, x0, y0);
289
+ }
290
+
291
+ let t1 = 0.5 - x1 * x1 - y1 * y1;
292
+ if (t1 >= 0) {
293
+ const gi1 = perm[ii + i1 + perm[jj + j1]!]! % 12;
294
+ t1 *= t1;
295
+ n1 = t1 * t1 * grad(gi1, x1, y1);
296
+ }
297
+
298
+ let t2 = 0.5 - x2 * x2 - y2 * y2;
299
+ if (t2 >= 0) {
300
+ const gi2 = perm[ii + 1 + perm[jj + 1]!]! % 12;
301
+ t2 *= t2;
302
+ n2 = t2 * t2 * grad(gi2, x2, y2);
303
+ }
304
+
305
+ // Scale to [0, 1] range
306
+ return 70 * (n0 + n1 + n2) + 0.5;
307
+ }
308
+
309
+ /**
310
+ * Value noise - simpler but lower quality than Perlin/Simplex
311
+ * Good fallback for low-end devices
312
+ */
313
+ export function valueNoise(x: number, y: number): number {
314
+ const X = Math.floor(x);
315
+ const Y = Math.floor(y);
316
+
317
+ const xf = x - X;
318
+ const yf = y - Y;
319
+
320
+ // Smooth interpolation
321
+ const u = fade(xf);
322
+ const v = fade(yf);
323
+
324
+ // Hash grid values
325
+ const n00 = hash(X, Y);
326
+ const n01 = hash(X, Y + 1);
327
+ const n10 = hash(X + 1, Y);
328
+ const n11 = hash(X + 1, Y + 1);
329
+
330
+ // Bilinear interpolation
331
+ const nx0 = lerp(n00, n10, u);
332
+ const nx1 = lerp(n01, n11, u);
333
+ const result = lerp(nx0, nx1, v);
334
+
335
+ return result;
336
+ }
337
+
338
+ // ============================================================================
339
+ // Fractal Brownian Motion (FBM) Engine (Feature 1.2)
340
+ // ============================================================================
341
+
342
+ /**
343
+ * Creates an FBM engine with configurable parameters
344
+ *
345
+ * @param config - FBM configuration (octaves, lacunarity, gain)
346
+ * @returns Object with fbm function
347
+ *
348
+ * @example
349
+ * ```typescript
350
+ * const fbmEngine = createFBMEngine({ octaves: 5, lacunarity: 2, gain: 0.5 });
351
+ *
352
+ * // Generate noise at position (0.5, 0.5) with time animation
353
+ * const noiseValue = fbmEngine.fbm(0.5, 0.5, Date.now());
354
+ * ```
355
+ */
356
+ export function createFBMEngine(config: FBMConfig) {
357
+ /**
358
+ * Fractal Brownian Motion function
359
+ * Combines multiple octaves of noise for complex, natural patterns
360
+ *
361
+ * @param x - X coordinate
362
+ * @param y - Y coordinate
363
+ * @param time - Optional time value for animation
364
+ * @returns FBM noise value in range [0, 1]
365
+ */
366
+ const fbm = (x: number, y: number, time: number = 0): number => {
367
+ let value = 0;
368
+ let amplitude = 0.5;
369
+ let frequency = 1;
370
+ let phase = time * 0.001; // Convert to seconds for reasonable animation speed
371
+
372
+ for (let i = 0; i < config.octaves; i++) {
373
+ // Apply time-based phase shift to all octaves
374
+ value += perlinNoise(
375
+ x * frequency + phase,
376
+ y * frequency + phase
377
+ ) * amplitude;
378
+
379
+ frequency *= config.lacunarity; // Increase frequency
380
+ amplitude *= config.gain; // Decrease amplitude
381
+ }
382
+
383
+ return value;
384
+ };
385
+
386
+ /**
387
+ * Get FBM with simple time factor
388
+ */
389
+ const fbmWithTime = (x: number, y: number, time: number): number => {
390
+ return fbm(x, y, time);
391
+ };
392
+
393
+ return {
394
+ fbm,
395
+ fbmWithTime,
396
+ };
397
+ }
398
+
399
+ /**
400
+ * Gets optimal FBM config based on quality preset
401
+ *
402
+ * @param quality - Quality preset level
403
+ * @returns FBM configuration for the quality level
404
+ */
405
+ export function getFBMConfigForQuality(quality: 'low' | 'medium' | 'high' | 'ultra'): FBMConfig {
406
+ const presets = ATOMIX_GLASS.CONSTANTS.DISTORTION_QUALITY_PRESETS;
407
+ return presets[quality];
408
+ }
409
+
410
+ const fbmEngineCache = new Map<string, ReturnType<typeof createFBMEngine>>();
411
+
412
+ // ============================================================================
413
+ // Shader Utility Functions for Time-Based Effects
414
+ // ============================================================================
415
+
416
+ /**
417
+ * Liquid glass distortion with time-based animation
418
+ * Uses FBM to create organic, flowing liquid effects
419
+ *
420
+ * @param uv - UV coordinates (normalized 0-1)
421
+ * @param time - Elapsed time in milliseconds
422
+ * @param config - FBM configuration
423
+ * @returns Distorted UV coordinates
424
+ */
425
+ export function liquidGlassWithTime(uv: Vec2, time: number, config: FBMConfig): Vec2 {
426
+ const configKey = `${config.octaves}-${config.lacunarity}-${config.gain}`;
427
+ let fbmEngine = fbmEngineCache.get(configKey);
428
+ if (!fbmEngine) {
429
+ fbmEngine = createFBMEngine(config);
430
+ fbmEngineCache.set(configKey, fbmEngine);
431
+ }
432
+
433
+ // Animate noise with time
434
+ const animatedNoise = fbmEngine.fbmWithTime(
435
+ uv.x * 2 + time * 0.0001,
436
+ uv.y * 2 + time * 0.00015,
437
+ time
438
+ );
439
+
440
+ return {
441
+ x: uv.x + (animatedNoise - 0.5) * 0.04,
442
+ y: uv.y + (animatedNoise - 0.5) * 0.04,
443
+ };
444
+ }
445
+
446
+ /**
447
+ * Breathing effect - subtle scale/opacity pulsing
448
+ *
449
+ * @param time - Elapsed time in milliseconds
450
+ * @param cycle - Breathing cycle duration in ms (default: 2000ms)
451
+ * @returns Breathing factor in range [0, 1]
452
+ */
453
+ export function breathingEffect(time: number, cycle: number = 2000): number {
454
+ const phase = (time % cycle) / cycle;
455
+ // Sine wave for smooth breathing
456
+ return 0.5 + 0.5 * Math.sin(phase * Math.PI * 2);
457
+ }
458
+
459
+ /**
460
+ * Flow animation - continuous liquid movement in one direction
461
+ *
462
+ * @param uv - UV coordinates
463
+ * @param time - Elapsed time
464
+ * @param speedX - Horizontal flow speed
465
+ * @param speedY - Vertical flow speed
466
+ * @returns Animated UV coordinates
467
+ */
468
+ export function flowAnimation(uv: Vec2, time: number, speedX: number = 0.1, speedY: number = 0.15): Vec2 {
469
+ return {
470
+ x: uv.x + time * speedX * 0.0001,
471
+ y: uv.y + time * speedY * 0.0001,
472
+ };
473
+ }
474
+
475
+ /**
476
+ * Wave propagation - radial waves emanating from center
477
+ *
478
+ * @param uv - UV coordinates (centered at 0.5, 0.5)
479
+ * @param time - Elapsed time
480
+ * @param speed - Wave propagation speed
481
+ * @param amplitude - Wave height
482
+ * @returns Displaced UV coordinates
483
+ */
484
+ export function wavePropagation(
485
+ uv: Vec2,
486
+ time: number,
487
+ speed: number = 0.05,
488
+ amplitude: number = 0.02
489
+ ): Vec2 {
490
+ const center: Vec2 = { x: 0.5, y: 0.5 };
491
+ const dx = uv.x - center.x;
492
+ const dy = uv.y - center.y;
493
+ const distance = Math.sqrt(dx * dx + dy * dy);
494
+
495
+ // Radial wave
496
+ const wave = Math.sin(distance * 20 - time * speed) * amplitude;
497
+
498
+ return {
499
+ x: uv.x + dx * wave,
500
+ y: uv.y + dy * wave,
501
+ };
502
+ }
503
+
504
+ // ============================================================================
505
+ // Helper Functions
506
+ // ============================================================================
507
+
508
+ /**
509
+ * Fade curve for smooth interpolation (Perlin's fade function)
510
+ */
511
+ function fade(t: number): number {
512
+ return t * t * t * (t * (t * 6 - 15) + 10);
513
+ }
514
+
515
+ /**
516
+ * Linear interpolation
517
+ */
518
+ function lerp(a: number, b: number, t: number): number {
519
+ return a + t * (b - a);
520
+ }
521
+
522
+ /**
523
+ * Gradient calculation for Perlin noise
524
+ */
525
+ function grad(hash: number, x: number, y: number): number {
526
+ const h = hash & 15;
527
+ const u = h < 8 ? x : y;
528
+ const v = h < 4 ? y : h === 12 || h === 14 ? x : 0;
529
+ return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v);
530
+ }
531
+
532
+ /**
533
+ * Hash function for deterministic randomness
534
+ */
535
+ function hash(x: number, y: number): number {
536
+ const n = Math.sin(x * 12.9898 + y * 78.233) * 43758.5453;
537
+ return n - Math.floor(n);
538
+ }
539
+
540
+ /**
541
+ * Permutation table for Perlin noise
542
+ */
543
+ const p: number[] = (() => {
544
+ const permutation: number[] = [];
545
+ for (let i = 0; i < 256; i++) {
546
+ permutation[i] = Math.floor(Math.random() * 256);
547
+ }
548
+ // Duplicate for overflow handling
549
+ return [...permutation, ...permutation];
550
+ })();
551
+
552
+ /**
553
+ * Gradient indices for Simplex noise
554
+ */
555
+ const perm: number[] = (() => {
556
+ const permutation: number[] = [];
557
+ for (let i = 0; i < 256; i++) {
558
+ permutation[i] = Math.floor(Math.random() * 256);
559
+ }
560
+ return [...permutation, ...permutation];
561
+ })();
562
+
563
+ // ============================================================================
564
+ // Exports
565
+ // ============================================================================
566
+
567
+ export default {
568
+ createAnimationLoop,
569
+ createFBMEngine,
570
+ getFBMConfigForQuality,
571
+ liquidGlassWithTime,
572
+ breathingEffect,
573
+ flowAnimation,
574
+ wavePropagation,
575
+ perlinNoise,
576
+ simplexNoise,
577
+ valueNoise,
578
+ };
@@ -40,7 +40,7 @@ const smoothStep = (a: number, b: number, t: number): number => {
40
40
  return 0;
41
41
  }
42
42
 
43
- const clamped = Math.max(0, Math.min(1, (t - a) / (b - a)));
43
+ const clamped = Math.max(0, Math.min(1, (t - a) / (b - a));
44
44
  return clamped * clamped * (3 - 2 * clamped);
45
45
  };
46
46
 
@@ -951,3 +951,6 @@ export class ShaderDisplacementGenerator {
951
951
  return this.canvasDPI;
952
952
  }
953
953
  }
954
+
955
+ // Re-export animation system functions for convenience
956
+ export { createFBMEngine, liquidGlassWithTime } from './animation-system';