@shohojdhara/atomix 0.6.5 → 0.6.6
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/dist/atomix.css +2 -2
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +1 -1
- package/dist/atomix.min.css.map +1 -1
- package/dist/atomix.umd.js +1 -1
- package/dist/atomix.umd.js.map +1 -1
- package/dist/atomix.umd.min.js +1 -1
- package/dist/charts.js +65 -255
- package/dist/charts.js.map +1 -1
- package/dist/core.js +65 -255
- package/dist/core.js.map +1 -1
- package/dist/forms.js +65 -255
- package/dist/forms.js.map +1 -1
- package/dist/heavy.js +65 -255
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +6 -37
- package/dist/index.esm.js +66 -300
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +66 -300
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/package.json +1 -1
- package/src/components/AtomixGlass/AtomixGlass.tsx +0 -9
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +0 -2
- package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +1 -1
- package/src/components/AtomixGlass/glass-utils.ts +82 -53
- package/src/components/AtomixGlass/shader-utils.ts +19 -77
- package/src/components/Form/Select.test.tsx +6 -6
- package/src/components/Form/Textarea.stories.tsx +5 -5
- package/src/lib/composables/useAtomixGlass.ts +2 -134
- package/src/lib/composables/useAtomixGlassStyles.ts +3 -3
- package/src/lib/composables/usePerformanceMonitor.ts +0 -66
- package/src/lib/constants/components.ts +6 -1
- package/src/styles/01-settings/_settings.atomix-glass.scss +2 -2
- package/src/styles/02-tools/_tools.button.scss +51 -42
- package/src/styles/06-components/_components.atomix-glass.scss +2 -2
- package/src/components/AtomixGlass/PerformanceDashboard.tsx +0 -171
- package/src/components/AtomixGlass/animation-system.ts +0 -578
package/dist/charts.js
CHANGED
|
@@ -592,6 +592,11 @@ const _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
592
592
|
MIN_BLUR: .1,
|
|
593
593
|
MOUSE_INFLUENCE_DIVISOR: 100,
|
|
594
594
|
EDGE_FADE_PIXELS: 2,
|
|
595
|
+
// Interaction intensity multipliers shared by the hook and the imperative style updater
|
|
596
|
+
INTERACTION: {
|
|
597
|
+
HOVER_INTENSITY: 1.4,
|
|
598
|
+
ACTIVE_INTENSITY: 1.6
|
|
599
|
+
},
|
|
595
600
|
// Elasticity physics constants — Apple-tuned: soft springs, fast settling, minimal stretch
|
|
596
601
|
ELASTICITY_TRANSLATION_FACTOR: .06,
|
|
597
602
|
// Subtler elastic shift (was 0.1)
|
|
@@ -789,7 +794,7 @@ const _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
789
794
|
},
|
|
790
795
|
// Container shadows — hairline inner catch + soft floating lift (Apple player bar)
|
|
791
796
|
CONTAINER_SHADOW: {
|
|
792
|
-
LIGHT: "inset 0 0.5px 0 rgba(255, 255, 255, 0.32), inset 0 1px 2px rgba(255, 255, 255, 0.06), 0
|
|
797
|
+
LIGHT: "inset 0 0.5px 0 rgba(255, 255, 255, 0.32), inset 0 1px 2px rgba(255, 255, 255, 0.06), 0 4px 16px rgba(0, 0, 0, 0.12), 0 1px 4px rgba(0, 0, 0, 0.08)"
|
|
793
798
|
},
|
|
794
799
|
// Phase 1: Animation System Constants
|
|
795
800
|
ANIMATION: {
|
|
@@ -1791,7 +1796,28 @@ const {CONSTANTS: CONSTANTS$3} = ATOMIX_GLASS, calculateElementCenter = rect =>
|
|
|
1791
1796
|
}, smoothstep = t => {
|
|
1792
1797
|
const clamped = Math.max(0, Math.min(1, t));
|
|
1793
1798
|
return clamped * clamped * (3 - 2 * clamped);
|
|
1794
|
-
}, lerp
|
|
1799
|
+
}, lerp = (a, b, t) => a + (b - a) * t, softClamp = (value, max) => max <= 0 ? 0 : max * (1 - Math.exp(-value / max)), clamp = (value, min, max) => "number" != typeof value || isNaN(value) ? min : Math.max(min, Math.min(max, value)), smoothstepEdge = (edge0, edge1, x) => "number" != typeof edge0 || "number" != typeof edge1 || "number" != typeof x ? 0 : smoothstep((x - edge0) / (edge1 - edge0)), easeInOutCubic = t => {
|
|
1800
|
+
if ("number" != typeof t || isNaN(t)) return 0;
|
|
1801
|
+
const clamped = Math.max(0, Math.min(1, t));
|
|
1802
|
+
return clamped < .5 ? 4 * clamped * clamped * clamped : 1 - Math.pow(-2 * clamped + 2, 3) / 2;
|
|
1803
|
+
}, easeOutQuart = t => {
|
|
1804
|
+
if ("number" != typeof t || isNaN(t)) return 0;
|
|
1805
|
+
const clamped = Math.max(0, Math.min(1, t));
|
|
1806
|
+
return 1 - Math.pow(1 - clamped, 4);
|
|
1807
|
+
}, vec2Length = (x, y) => {
|
|
1808
|
+
if ("number" != typeof x || "number" != typeof y || isNaN(x) || isNaN(y)) return 0;
|
|
1809
|
+
const maxComponent = Math.max(Math.abs(x), Math.abs(y));
|
|
1810
|
+
if (0 === maxComponent) return 0;
|
|
1811
|
+
const scaledX = x / maxComponent, scaledY = y / maxComponent;
|
|
1812
|
+
return maxComponent * Math.sqrt(scaledX * scaledX + scaledY * scaledY);
|
|
1813
|
+
}, getInteractionIntensity = (isHovered, isActive) => ({
|
|
1814
|
+
hoverIntensity: isHovered ? CONSTANTS$3.INTERACTION.HOVER_INTENSITY : 1,
|
|
1815
|
+
activeIntensity: isActive ? CONSTANTS$3.INTERACTION.ACTIVE_INTENSITY : 1
|
|
1816
|
+
})
|
|
1817
|
+
/**
|
|
1818
|
+
* Spring-damper integration helper
|
|
1819
|
+
* Calculates the next value based on velocity, stiffness, and damping.
|
|
1820
|
+
*/ , calculateSpring = (current, target, velocity, stiffness = .1, damping = .8) => {
|
|
1795
1821
|
const newVelocity = (velocity + (target - current) * stiffness) * damping;
|
|
1796
1822
|
return {
|
|
1797
1823
|
value: current + newVelocity,
|
|
@@ -1997,7 +2023,7 @@ const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevP
|
|
|
1997
2023
|
}, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, isActive: isActive = !1, overLight: overLight = !1, overLightConfig: overLightConfig = {}, borderRadius: borderRadius = 0, glassSize: glassSize = {
|
|
1998
2024
|
width: 0,
|
|
1999
2025
|
height: 0
|
|
2000
|
-
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1, isFixedOrSticky: isFixedOrSticky = !1,
|
|
2026
|
+
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1, isFixedOrSticky: isFixedOrSticky = !1, withTimeAnimation: withTimeAnimation = !1, animationSpeed: animationSpeed = 1, withMultiLayerDistortion: withMultiLayerDistortion = !1, distortionOctaves: distortionOctaves = 3, distortionLacunarity: distortionLacunarity = 2, distortionGain: distortionGain = .5, distortionQuality: distortionQuality = "medium", contentRef: contentRef}, ref) => {
|
|
2001
2027
|
// React 18 useId — stable, unique, and SSR-safe (no module-level counter)
|
|
2002
2028
|
const rawId = useId(), filterId = useMemo((() => `atomix-glass-filter-${rawId.replace(/:/g, "")}`), [ rawId ]), containerRef = useForkRef(ref, null), [shaderMapUrl, setShaderMapUrl] = useState(""), shaderGeneratorRef = useRef(null), shaderUtilsRef = useRef(null), shaderDebounceTimeoutRef = useRef(null), shaderUpdateTimeoutRef = useRef(null), animationFrameRef = useRef(null);
|
|
2003
2029
|
// Lazy load shader utilities only when shader mode is needed
|
|
@@ -2295,7 +2321,7 @@ class {
|
|
|
2295
2321
|
}, {BORDER: BORDER, CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, BORDER_GRADIENT = BORDER.GRADIENT, WHITE = CONSTANTS$2.PALETTE.WHITE, updateAtomixGlassStyles = (wrapperElement, containerElement, params) => {
|
|
2296
2322
|
if (!wrapperElement && !containerElement) return;
|
|
2297
2323
|
if (!validateGlassSize(params.glassSize)) return;
|
|
2298
|
-
const {mouseOffset: mouseOffset, globalMousePosition: globalMousePosition, glassSize: glassSize, isHovered: isHovered, isActive: isActive, isOverLight: isOverLight, baseOverLightConfig: baseOverLightConfig, effectiveBorderRadius: effectiveBorderRadius, effectiveWithoutEffects: effectiveWithoutEffects, effectiveReducedMotion: effectiveReducedMotion, elasticity: elasticity, elasticTranslation: elasticTranslation, elasticVelocity: elasticVelocity, mouseVelocity: mouseVelocity, directionalScale: directionalScale, scaleBase: scaleBase, onClick: onClick, withLiquidBlur: withLiquidBlur, blurAmount: blurAmount = ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT, saturation: saturation = ATOMIX_GLASS.DEFAULTS.SATURATION, isFixedOrSticky: isFixedOrSticky = !1, borderAnimated: borderAnimated = !0, borderOpacityMultiplier: borderOpacityMultiplier = 1} = params, mouseInfluence = calculateMouseInfluence(mouseOffset), hoverIntensity
|
|
2324
|
+
const {mouseOffset: mouseOffset, globalMousePosition: globalMousePosition, glassSize: glassSize, isHovered: isHovered, isActive: isActive, isOverLight: isOverLight, baseOverLightConfig: baseOverLightConfig, effectiveBorderRadius: effectiveBorderRadius, effectiveWithoutEffects: effectiveWithoutEffects, effectiveReducedMotion: effectiveReducedMotion, elasticity: elasticity, elasticTranslation: elasticTranslation, elasticVelocity: elasticVelocity, mouseVelocity: mouseVelocity, directionalScale: directionalScale, scaleBase: scaleBase, onClick: onClick, withLiquidBlur: withLiquidBlur, blurAmount: blurAmount = ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT, saturation: saturation = ATOMIX_GLASS.DEFAULTS.SATURATION, isFixedOrSticky: isFixedOrSticky = !1, borderAnimated: borderAnimated = !0, borderOpacityMultiplier: borderOpacityMultiplier = 1} = params, mouseInfluence = calculateMouseInfluence(mouseOffset), {hoverIntensity: hoverIntensity, activeIntensity: activeIntensity} = getInteractionIntensity(isHovered, isActive), overLightConfig = {
|
|
2299
2325
|
opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
|
|
2300
2326
|
contrast: Math.min(1.6, baseOverLightConfig.contrast + .1 * mouseInfluence),
|
|
2301
2327
|
brightness: Math.min(1.1, baseOverLightConfig.brightness + .05 * mouseInfluence),
|
|
@@ -2426,140 +2452,9 @@ class {
|
|
|
2426
2452
|
style.setProperty("--atomix-glass-container-shadow-opacity", effectiveWithoutEffects ? "0" : "1"),
|
|
2427
2453
|
style.setProperty("--atomix-glass-container-bg", isOverLight ? `linear-gradient(${180 + .5 * mx}deg, rgba(255, 255, 255, 0.1) 0%, transparent 20%, transparent 80%, rgba(0, 0, 0, 0.05) 100%)` : "none"),
|
|
2428
2454
|
style.setProperty("--atomix-glass-container-text-shadow", isOverLight ? "0px 1px 2px rgba(255, 255, 255, 0.15)" : "0px 2px 12px rgba(0, 0, 0, 0.4)"),
|
|
2429
|
-
style.setProperty("--atomix-glass-container-box-shadow", isOverLight ? "0px 16px 70px rgba(0, 0, 0, 0.75)" : "0
|
|
2455
|
+
style.setProperty("--atomix-glass-container-box-shadow", isOverLight ? "0px 16px 70px rgba(0, 0, 0, 0.75)" : "0 4px 16px rgba(0, 0, 0, 0.14), 0 1px 4px rgba(0, 0, 0, 0.10)");
|
|
2430
2456
|
}
|
|
2431
|
-
};
|
|
2432
|
-
|
|
2433
|
-
/**
|
|
2434
|
-
* Animation System for AtomixGlass Component
|
|
2435
|
-
*
|
|
2436
|
-
* Implements Phase 1 features from the AtomixGlass Feature Implementation Roadmap:
|
|
2437
|
-
* - Feature 1.1: Time-Based Animation System
|
|
2438
|
-
* - Feature 1.2: Multi-Layer Distortion System (FBM)
|
|
2439
|
-
*
|
|
2440
|
-
* @packageDocumentation
|
|
2441
|
-
*/
|
|
2442
|
-
// ============================================================================
|
|
2443
|
-
// Noise Functions for FBM (Feature 1.2)
|
|
2444
|
-
// ============================================================================
|
|
2445
|
-
/**
|
|
2446
|
-
* Perlin noise implementation for smooth gradient noise
|
|
2447
|
-
*
|
|
2448
|
-
* @param x - X coordinate
|
|
2449
|
-
* @param y - Y coordinate
|
|
2450
|
-
* @returns Noise value in range [0, 1]
|
|
2451
|
-
*/
|
|
2452
|
-
function perlinNoise(x, y) {
|
|
2453
|
-
// Simplified Perlin noise using pseudo-random gradients
|
|
2454
|
-
const X = 255 & Math.floor(x), Y = 255 & Math.floor(y), xf = x - Math.floor(x), yf = y - Math.floor(y), u = fade(xf), v = fade(yf), A = p[X] + Y & 255, B = p[X + 1] + Y & 255, ga = grad(p[A], xf, yf), gb = grad(p[B], xf - 1, yf), gc = grad(p[A + 1 & 255], xf, yf - 1), gd = grad(p[B + 1 & 255], xf - 1, yf - 1), lerpX1 = lerp(ga, gb, u), lerpX2 = lerp(gc, gd, u);
|
|
2455
|
-
// Scale to [0, 1] range
|
|
2456
|
-
return (lerp(lerpX1, lerpX2, v) + 1) / 2;
|
|
2457
|
-
}
|
|
2458
|
-
|
|
2459
|
-
// ============================================================================
|
|
2460
|
-
// Fractal Brownian Motion (FBM) Engine (Feature 1.2)
|
|
2461
|
-
// ============================================================================
|
|
2462
|
-
/**
|
|
2463
|
-
* Creates an FBM engine with configurable parameters
|
|
2464
|
-
*
|
|
2465
|
-
* @param config - FBM configuration (octaves, lacunarity, gain)
|
|
2466
|
-
* @returns Object with fbm function
|
|
2467
|
-
*
|
|
2468
|
-
* @example
|
|
2469
|
-
* ```typescript
|
|
2470
|
-
* const fbmEngine = createFBMEngine({ octaves: 5, lacunarity: 2, gain: 0.5 });
|
|
2471
|
-
*
|
|
2472
|
-
* // Generate noise at position (0.5, 0.5) with time animation
|
|
2473
|
-
* const noiseValue = fbmEngine.fbm(0.5, 0.5, Date.now());
|
|
2474
|
-
* ```
|
|
2475
|
-
*/ function createFBMEngine(config) {
|
|
2476
|
-
/**
|
|
2477
|
-
* Fractal Brownian Motion function
|
|
2478
|
-
* Combines multiple octaves of noise for complex, natural patterns
|
|
2479
|
-
*
|
|
2480
|
-
* @param x - X coordinate
|
|
2481
|
-
* @param y - Y coordinate
|
|
2482
|
-
* @param time - Optional time value for animation
|
|
2483
|
-
* @returns FBM noise value in range [0, 1]
|
|
2484
|
-
*/
|
|
2485
|
-
const fbm = (x, y, time = 0) => {
|
|
2486
|
-
let value = 0, amplitude = .5, frequency = 1, phase = .001 * time;
|
|
2487
|
-
// Convert to seconds for reasonable animation speed
|
|
2488
|
-
for (let i = 0; i < config.octaves; i++)
|
|
2489
|
-
// Apply time-based phase shift to all octaves
|
|
2490
|
-
value += perlinNoise(x * frequency + phase, y * frequency + phase) * amplitude,
|
|
2491
|
-
frequency *= config.lacunarity, // Increase frequency
|
|
2492
|
-
amplitude *= config.gain;
|
|
2493
|
-
return value;
|
|
2494
|
-
};
|
|
2495
|
-
/**
|
|
2496
|
-
* Get FBM with simple time factor
|
|
2497
|
-
*/ return {
|
|
2498
|
-
fbm: fbm,
|
|
2499
|
-
fbmWithTime: (x, y, time) => fbm(x, y, time)
|
|
2500
|
-
};
|
|
2501
|
-
}
|
|
2502
|
-
|
|
2503
|
-
/**
|
|
2504
|
-
* Gets optimal FBM config based on quality preset
|
|
2505
|
-
*
|
|
2506
|
-
* @param quality - Quality preset level
|
|
2507
|
-
* @returns FBM configuration for the quality level
|
|
2508
|
-
*/ const fbmEngineCache = new Map;
|
|
2509
|
-
|
|
2510
|
-
// ============================================================================
|
|
2511
|
-
// Shader Utility Functions for Time-Based Effects
|
|
2512
|
-
// ============================================================================
|
|
2513
|
-
/**
|
|
2514
|
-
* Liquid glass distortion with time-based animation
|
|
2515
|
-
* Uses FBM to create organic, flowing liquid effects
|
|
2516
|
-
*
|
|
2517
|
-
* @param uv - UV coordinates (normalized 0-1)
|
|
2518
|
-
* @param time - Elapsed time in milliseconds
|
|
2519
|
-
* @param config - FBM configuration
|
|
2520
|
-
* @returns Distorted UV coordinates
|
|
2521
|
-
*/ function liquidGlassWithTime(uv, time, config) {
|
|
2522
|
-
const configKey = `${config.octaves}-${config.lacunarity}-${config.gain}`;
|
|
2523
|
-
let fbmEngine = fbmEngineCache.get(configKey);
|
|
2524
|
-
fbmEngine || (fbmEngine = createFBMEngine(config), fbmEngineCache.set(configKey, fbmEngine));
|
|
2525
|
-
// Animate noise with time
|
|
2526
|
-
const animatedNoise = fbmEngine.fbmWithTime(2 * uv.x + 1e-4 * time, 2 * uv.y + 15e-5 * time, time);
|
|
2527
|
-
return {
|
|
2528
|
-
x: uv.x + .04 * (animatedNoise - .5),
|
|
2529
|
-
y: uv.y + .04 * (animatedNoise - .5)
|
|
2530
|
-
};
|
|
2531
|
-
}
|
|
2532
|
-
|
|
2533
|
-
// ============================================================================
|
|
2534
|
-
// Helper Functions
|
|
2535
|
-
// ============================================================================
|
|
2536
|
-
/**
|
|
2537
|
-
* Fade curve for smooth interpolation (Perlin's fade function)
|
|
2538
|
-
*/ function fade(t) {
|
|
2539
|
-
return t * t * t * (t * (6 * t - 15) + 10);
|
|
2540
|
-
}
|
|
2541
|
-
|
|
2542
|
-
/**
|
|
2543
|
-
* Linear interpolation
|
|
2544
|
-
*/ function lerp(a, b, t) {
|
|
2545
|
-
return a + t * (b - a);
|
|
2546
|
-
}
|
|
2547
|
-
|
|
2548
|
-
/**
|
|
2549
|
-
* Gradient calculation for Perlin noise
|
|
2550
|
-
*/ function grad(hash, x, y) {
|
|
2551
|
-
const h = 15 & hash, u = h < 8 ? x : y, v = h < 4 ? y : 12 === h || 14 === h ? x : 0;
|
|
2552
|
-
return (1 & h ? -u : u) + (2 & h ? -v : v);
|
|
2553
|
-
}
|
|
2554
|
-
|
|
2555
|
-
/**
|
|
2556
|
-
* Permutation table for Perlin noise
|
|
2557
|
-
*/ const p = (() => {
|
|
2558
|
-
const permutation = [];
|
|
2559
|
-
for (let i = 0; i < 256; i++) permutation[i] = Math.floor(256 * Math.random());
|
|
2560
|
-
// Duplicate for overflow handling
|
|
2561
|
-
return [ ...permutation, ...permutation ];
|
|
2562
|
-
})(), {CONSTANTS: CONSTANTS$1} = ATOMIX_GLASS;
|
|
2457
|
+
}, {CONSTANTS: CONSTANTS$1} = ATOMIX_GLASS;
|
|
2563
2458
|
|
|
2564
2459
|
const {CONSTANTS: CONSTANTS} = ATOMIX_GLASS, backgroundDetectionCache = new WeakMap, setCachedBackgroundDetection = (parentElement, overLightConfig, result, threshold) => {
|
|
2565
2460
|
parentElement && backgroundDetectionCache.set(parentElement, {
|
|
@@ -2574,10 +2469,7 @@ const {CONSTANTS: CONSTANTS} = ATOMIX_GLASS, backgroundDetectionCache = new Weak
|
|
|
2574
2469
|
* Composable hook for AtomixGlass component logic
|
|
2575
2470
|
* Manages all state, calculations, and event handlers
|
|
2576
2471
|
*/
|
|
2577
|
-
function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef: wrapperRef, borderRadius: borderRadius, globalMousePosition: externalGlobalMousePosition, mouseOffset: externalMouseOffset, mouseContainer: mouseContainer, overLight: overLight = ATOMIX_GLASS.DEFAULTS.OVER_LIGHT, reducedMotion: reducedMotion = !1, highContrast: highContrast = !1, withoutEffects: withoutEffects = !1, border: border, withBorder: withBorder = !0, elasticity: elasticity = ATOMIX_GLASS.DEFAULTS.ELASTICITY, onClick: onClick, debugBorderRadius: debugBorderRadius = !1, debugOverLight: debugOverLight = !1, children: children, blurAmount: blurAmount, saturation: saturation, withLiquidBlur: withLiquidBlur, isFixedOrSticky: isFixedOrSticky = !1, priority: priority = 1
|
|
2578
|
-
// Default priority
|
|
2579
|
-
// Phase 1: Animation System Props
|
|
2580
|
-
withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: animationSpeed = ATOMIX_GLASS.DEFAULTS.ANIMATION_SPEED, withMultiLayerDistortion: withMultiLayerDistortion = ATOMIX_GLASS.DEFAULTS.WITH_MULTI_LAYER_DISTORTION, distortionOctaves: distortionOctaves = ATOMIX_GLASS.DEFAULTS.DISTORTION_OCTAVES, distortionLacunarity: distortionLacunarity = ATOMIX_GLASS.DEFAULTS.DISTORTION_LACUNARITY, distortionGain: distortionGain = ATOMIX_GLASS.DEFAULTS.DISTORTION_GAIN, distortionQuality: distortionQuality = ATOMIX_GLASS.DEFAULTS.DISTORTION_QUALITY}) {
|
|
2472
|
+
function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef: wrapperRef, borderRadius: borderRadius, globalMousePosition: externalGlobalMousePosition, mouseOffset: externalMouseOffset, mouseContainer: mouseContainer, overLight: overLight = ATOMIX_GLASS.DEFAULTS.OVER_LIGHT, reducedMotion: reducedMotion = !1, highContrast: highContrast = !1, withoutEffects: withoutEffects = !1, border: border, withBorder: withBorder = !0, elasticity: elasticity = ATOMIX_GLASS.DEFAULTS.ELASTICITY, onClick: onClick, debugBorderRadius: debugBorderRadius = !1, debugOverLight: debugOverLight = !1, children: children, blurAmount: blurAmount, saturation: saturation, withLiquidBlur: withLiquidBlur, isFixedOrSticky: isFixedOrSticky = !1, priority: priority = 1}) {
|
|
2581
2473
|
// State
|
|
2582
2474
|
const [isHovered, setIsHovered] = useState(!1), [isActive, setIsActive] = useState(!1), resolvedBorder = useMemo((() =>
|
|
2583
2475
|
/**
|
|
@@ -2629,52 +2521,10 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2629
2521
|
}), scaleVelocityRef = useRef({
|
|
2630
2522
|
x: 0,
|
|
2631
2523
|
y: 0
|
|
2632
|
-
})
|
|
2633
|
-
useRef(0);
|
|
2634
|
-
const mouseVelocityRef = useRef({
|
|
2524
|
+
}), mouseVelocityRef = useRef({
|
|
2635
2525
|
x: 0,
|
|
2636
2526
|
y: 0
|
|
2637
|
-
}), [userPrefersReducedMotion, setUserPrefersReducedMotion] = useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = useState(!1), [detectedOverLight, setDetectedOverLight] = useState(!1),
|
|
2638
|
-
// If quality preset is provided, use it as base
|
|
2639
|
-
const preset = (quality = distortionQuality, ATOMIX_GLASS.CONSTANTS.DISTORTION_QUALITY_PRESETS[quality]);
|
|
2640
|
-
// Override with custom values if provided
|
|
2641
|
-
var quality;
|
|
2642
|
-
return {
|
|
2643
|
-
octaves: distortionOctaves ?? preset.octaves,
|
|
2644
|
-
lacunarity: distortionLacunarity ?? preset.lacunarity,
|
|
2645
|
-
gain: distortionGain ?? preset.gain
|
|
2646
|
-
};
|
|
2647
|
-
}), [ distortionQuality, distortionOctaves, distortionLacunarity, distortionGain ]), fbmEngine = useMemo((() => withMultiLayerDistortion ? createFBMEngine(fbmConfig) : null), [ withMultiLayerDistortion, fbmConfig ]), effectiveReducedMotion = useMemo((() => reducedMotion || userPrefersReducedMotion), [ reducedMotion, userPrefersReducedMotion ]), effectiveWithTimeAnimation = useMemo((() => withTimeAnimation && !effectiveReducedMotion), [ withTimeAnimation, effectiveReducedMotion ]);
|
|
2648
|
-
/**
|
|
2649
|
-
* Animation loop for time-based effects
|
|
2650
|
-
*/
|
|
2651
|
-
useEffect((() => {
|
|
2652
|
-
if (!effectiveWithTimeAnimation || "undefined" == typeof window) return;
|
|
2653
|
-
let lastFrameTime = performance.now();
|
|
2654
|
-
/**
|
|
2655
|
-
* Animation frame handler
|
|
2656
|
-
*/ const animate = currentTime => {
|
|
2657
|
-
// Calculate delta time
|
|
2658
|
-
const deltaTime = currentTime - lastFrameTime;
|
|
2659
|
-
lastFrameTime = currentTime;
|
|
2660
|
-
// Apply animation speed multiplier
|
|
2661
|
-
const scaledDelta = deltaTime * animationSpeed;
|
|
2662
|
-
elapsedTimeRef.current += scaledDelta, shaderTimeRef.current = elapsedTimeRef.current,
|
|
2663
|
-
// Continue animation loop
|
|
2664
|
-
animationFrameIdRef.current = requestAnimationFrame(animate);
|
|
2665
|
-
};
|
|
2666
|
-
// Start animation
|
|
2667
|
-
// Cleanup
|
|
2668
|
-
return animationStartTimeRef.current = performance.now(), animationFrameIdRef.current = requestAnimationFrame(animate),
|
|
2669
|
-
() => {
|
|
2670
|
-
null !== animationFrameIdRef.current && (cancelAnimationFrame(animationFrameIdRef.current),
|
|
2671
|
-
animationFrameIdRef.current = null);
|
|
2672
|
-
};
|
|
2673
|
-
}), [ effectiveWithTimeAnimation, animationSpeed ]);
|
|
2674
|
-
/**
|
|
2675
|
-
* Get current shader time for animations
|
|
2676
|
-
*/
|
|
2677
|
-
const getShaderTime = useCallback((() => shaderTimeRef.current), []), applyTimeBasedDistortion = useCallback((uv => effectiveWithTimeAnimation && fbmEngine ? liquidGlassWithTime(uv, shaderTimeRef.current, fbmConfig) : uv), [ effectiveWithTimeAnimation, fbmEngine, fbmConfig ]), effectiveBorderRadius = useMemo((() => void 0 !== borderRadius ? Math.max(0, borderRadius) : Math.max(0, dynamicBorderRadius)), [ borderRadius, dynamicBorderRadius ]), {glassSize: glassSize} = function({glassRef: glassRef, effectiveBorderRadius: effectiveBorderRadius, cachedRectRef: cachedRectRef}) {
|
|
2527
|
+
}), [userPrefersReducedMotion, setUserPrefersReducedMotion] = useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = useState(!1), [detectedOverLight, setDetectedOverLight] = useState(!1), effectiveReducedMotion = useMemo((() => reducedMotion || userPrefersReducedMotion), [ reducedMotion, userPrefersReducedMotion ]), effectiveBorderRadius = useMemo((() => void 0 !== borderRadius ? Math.max(0, borderRadius) : Math.max(0, dynamicBorderRadius)), [ borderRadius, dynamicBorderRadius ]), {glassSize: glassSize} = function({glassRef: glassRef, effectiveBorderRadius: effectiveBorderRadius, cachedRectRef: cachedRectRef}) {
|
|
2678
2528
|
const [glassSize, setGlassSize] = useState({
|
|
2679
2529
|
width: 270,
|
|
2680
2530
|
height: 69
|
|
@@ -2734,9 +2584,6 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2734
2584
|
effectiveBorderRadius: effectiveBorderRadius,
|
|
2735
2585
|
cachedRectRef: cachedRectRef
|
|
2736
2586
|
}), effectiveHighContrast = useMemo((() => highContrast || userPrefersHighContrast), [ highContrast, userPrefersHighContrast ]), effectiveWithoutEffects = useMemo((() => withoutEffects || effectiveReducedMotion), [ withoutEffects, effectiveReducedMotion ]), globalMousePosition = externalGlobalMousePosition || internalGlobalMousePositionRef.current, mouseOffset = externalMouseOffset || internalMouseOffsetRef.current;
|
|
2737
|
-
/**
|
|
2738
|
-
* Apply time-based distortion to UV coordinates
|
|
2739
|
-
*/
|
|
2740
2587
|
// Extract border-radius from children
|
|
2741
2588
|
useEffect((() => {
|
|
2742
2589
|
const extractRadius = () => {
|
|
@@ -2896,7 +2743,7 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2896
2743
|
* Get effective overLight value based on configuration
|
|
2897
2744
|
*/
|
|
2898
2745
|
const getEffectiveOverLight = useCallback((() => "boolean" == typeof overLight ? overLight : ("auto" === overLight || "object" == typeof overLight && null !== overLight) && detectedOverLight), [ overLight, detectedOverLight ]), validateConfigValue = useCallback(((value, min, max, defaultValue) => "number" != typeof value || isNaN(value) || !isFinite(value) ? defaultValue : Math.min(max, Math.max(min, value))), []), overLightConfig = useMemo((() => {
|
|
2899
|
-
const isOverLight = getEffectiveOverLight(), hoverIntensity
|
|
2746
|
+
const isOverLight = getEffectiveOverLight(), {hoverIntensity: hoverIntensity, activeIntensity: activeIntensity} = getInteractionIntensity(isHovered, isActive), baseConfig = {
|
|
2900
2747
|
isOverLight: isOverLight,
|
|
2901
2748
|
threshold: .7,
|
|
2902
2749
|
opacity: isOverLight ? Math.min(.6, Math.max(.2, .5 * hoverIntensity * activeIntensity)) : 0,
|
|
@@ -2940,8 +2787,8 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2940
2787
|
};
|
|
2941
2788
|
const curG = internalGlobalMousePositionRef.current, tgtG = targetGlobalMousePositionRef.current;
|
|
2942
2789
|
internalGlobalMousePositionRef.current = {
|
|
2943
|
-
x: lerp
|
|
2944
|
-
y: lerp
|
|
2790
|
+
x: lerp(curG.x, tgtG.x, CONSTANTS.LERP_FACTOR),
|
|
2791
|
+
y: lerp(curG.y, tgtG.y, CONSTANTS.LERP_FACTOR)
|
|
2945
2792
|
};
|
|
2946
2793
|
// ── Calculate Elastic Physics ─────────────────────────────────────
|
|
2947
2794
|
let targetElasticTranslation = {
|
|
@@ -3108,8 +2955,6 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
3108
2955
|
overLightConfig: overLightConfig,
|
|
3109
2956
|
resolvedBorder: resolvedBorder,
|
|
3110
2957
|
transformStyle: transformStyle,
|
|
3111
|
-
getShaderTime: getShaderTime,
|
|
3112
|
-
applyTimeBasedDistortion: applyTimeBasedDistortion,
|
|
3113
2958
|
handleMouseEnter: handleMouseEnter,
|
|
3114
2959
|
handleMouseLeave: handleMouseLeave,
|
|
3115
2960
|
handleMouseDown: handleMouseDown,
|
|
@@ -3382,7 +3227,7 @@ const PERFORMANCE_PRESET = {
|
|
|
3382
3227
|
var explicit, position;
|
|
3383
3228
|
/**
|
|
3384
3229
|
* Extracts layout-related properties from a React `CSSProperties` object.
|
|
3385
|
-
*/ const {isHovered: isHovered, isActive: isActive, glassSize: glassSize, effectiveBorderRadius: effectiveBorderRadius, effectiveReducedMotion: effectiveReducedMotion, effectiveHighContrast: effectiveHighContrast, effectiveWithoutEffects: effectiveWithoutEffects, overLightConfig: overLightConfig, globalMousePosition: globalMousePosition, mouseOffset: mouseOffset, transformStyle: transformStyle,
|
|
3230
|
+
*/ const {isHovered: isHovered, isActive: isActive, glassSize: glassSize, effectiveBorderRadius: effectiveBorderRadius, effectiveReducedMotion: effectiveReducedMotion, effectiveHighContrast: effectiveHighContrast, effectiveWithoutEffects: effectiveWithoutEffects, overLightConfig: overLightConfig, globalMousePosition: globalMousePosition, mouseOffset: mouseOffset, transformStyle: transformStyle, handleMouseEnter: handleMouseEnter, handleMouseLeave: handleMouseLeave, handleMouseDown: handleMouseDown, handleMouseUp: handleMouseUp, handleKeyDown: handleKeyDown, resolvedBorder: resolvedBorder} = useAtomixGlass({
|
|
3386
3231
|
glassRef: glassRef,
|
|
3387
3232
|
contentRef: contentRef,
|
|
3388
3233
|
wrapperRef: internalWrapperRef,
|
|
@@ -3406,14 +3251,7 @@ const PERFORMANCE_PRESET = {
|
|
|
3406
3251
|
withBorder: withBorder,
|
|
3407
3252
|
debugBorderRadius: debugBorderRadius,
|
|
3408
3253
|
style: style,
|
|
3409
|
-
isFixedOrSticky: isFixedOrSticky
|
|
3410
|
-
withTimeAnimation: withTimeAnimation,
|
|
3411
|
-
animationSpeed: animationSpeed,
|
|
3412
|
-
withMultiLayerDistortion: withMultiLayerDistortion,
|
|
3413
|
-
distortionOctaves: distortionOctaves,
|
|
3414
|
-
distortionLacunarity: distortionLacunarity,
|
|
3415
|
-
distortionGain: distortionGain,
|
|
3416
|
-
distortionQuality: distortionQuality
|
|
3254
|
+
isFixedOrSticky: isFixedOrSticky
|
|
3417
3255
|
});
|
|
3418
3256
|
(
|
|
3419
3257
|
/**
|
|
@@ -3988,7 +3826,6 @@ const PERFORMANCE_PRESET = {
|
|
|
3988
3826
|
shaderVariant: shaderVariant,
|
|
3989
3827
|
withLiquidBlur: withLiquidBlur,
|
|
3990
3828
|
isFixedOrSticky: isFixedOrSticky,
|
|
3991
|
-
shaderTime: getShaderTime(),
|
|
3992
3829
|
withTimeAnimation: withTimeAnimation,
|
|
3993
3830
|
animationSpeed: animationSpeed,
|
|
3994
3831
|
withMultiLayerDistortion: withMultiLayerDistortion,
|
|
@@ -7357,40 +7194,15 @@ WaterfallChart.displayName = "WaterfallChart";
|
|
|
7357
7194
|
|
|
7358
7195
|
// Adapted from https://github.com/shuding/liquid-glass
|
|
7359
7196
|
// Constants
|
|
7360
|
-
const
|
|
7361
|
-
// Add input validation
|
|
7362
|
-
if ("number" != typeof a || "number" != typeof b || "number" != typeof t) return 0;
|
|
7363
|
-
const clamped = Math.max(0, Math.min(1, (t - a) / (b - a)));
|
|
7364
|
-
return clamped * clamped * (3 - 2 * clamped);
|
|
7365
|
-
}, calculateLength = (x, y) => {
|
|
7366
|
-
// Add input validation and error handling
|
|
7367
|
-
if ("number" != typeof x || "number" != typeof y || isNaN(x) || isNaN(y)) return 0;
|
|
7368
|
-
// Prevent potential overflow
|
|
7369
|
-
const maxX = Math.max(Math.abs(x), Math.abs(y));
|
|
7370
|
-
if (0 === maxX) return 0;
|
|
7371
|
-
const scaledX = x / maxX, scaledY = y / maxX;
|
|
7372
|
-
return maxX * Math.sqrt(scaledX * scaledX + scaledY * scaledY);
|
|
7373
|
-
}, roundedRectSDF = (x, y, width, height, radius) => {
|
|
7197
|
+
const roundedRectSDF = (x, y, width, height, radius) => {
|
|
7374
7198
|
// Add input validation
|
|
7375
7199
|
if ("number" != typeof x || "number" != typeof y || "number" != typeof width || "number" != typeof height || "number" != typeof radius) return 0;
|
|
7376
7200
|
const qx = Math.abs(x) - width + radius, qy = Math.abs(y) - height + radius;
|
|
7377
|
-
return Math.min(Math.max(qx, qy), 0) +
|
|
7201
|
+
return Math.min(Math.max(qx, qy), 0) + vec2Length(Math.max(qx, 0), Math.max(qy, 0)) - radius;
|
|
7378
7202
|
}, createTexture = (x, y) => ({
|
|
7379
7203
|
x: "number" != typeof x || isNaN(x) ? .5 : Math.max(0, Math.min(1, x)),
|
|
7380
7204
|
y: "number" != typeof y || isNaN(y) ? .5 : Math.max(0, Math.min(1, y))
|
|
7381
|
-
}), validateVec2 = vec => vec && "number" == typeof vec.x && "number" == typeof vec.y && !isNaN(vec.x) && !isNaN(vec.y),
|
|
7382
|
-
// Add input validation
|
|
7383
|
-
"number" != typeof value || "number" != typeof min || "number" != typeof max || isNaN(value) ? min : isNaN(min) ? 0 : isNaN(max) ? 1 : Math.max(min, Math.min(max, value)), easeInOutCubic = t => {
|
|
7384
|
-
// Add input validation
|
|
7385
|
-
if ("number" != typeof t || isNaN(t)) return 0;
|
|
7386
|
-
const clampedT = Math.max(0, Math.min(1, t));
|
|
7387
|
-
return clampedT < .5 ? 4 * clampedT * clampedT * clampedT : 1 - Math.pow(-2 * clampedT + 2, 3) / 2;
|
|
7388
|
-
}, easeOutQuart = t => {
|
|
7389
|
-
// Add input validation
|
|
7390
|
-
if ("number" != typeof t || isNaN(t)) return 0;
|
|
7391
|
-
const clampedT = Math.max(0, Math.min(1, t));
|
|
7392
|
-
return 1 - Math.pow(1 - clampedT, 4);
|
|
7393
|
-
}, noise2D = (x, y) => {
|
|
7205
|
+
}), validateVec2 = vec => vec && "number" == typeof vec.x && "number" == typeof vec.y && !isNaN(vec.x) && !isNaN(vec.y), noise2D = (x, y) => {
|
|
7394
7206
|
// Add input validation
|
|
7395
7207
|
if ("number" != typeof x || "number" != typeof y || isNaN(x) || isNaN(y)) return 0;
|
|
7396
7208
|
const X = 255 & Math.floor(x), Y = 255 & Math.floor(y), xf = x - Math.floor(x), yf = y - Math.floor(y), u = easeInOutCubic(xf), v = easeInOutCubic(yf), hash = (i, j) => {
|
|
@@ -7429,13 +7241,13 @@ const smoothStep = (a, b, t) => {
|
|
|
7429
7241
|
x: .5,
|
|
7430
7242
|
y: .5
|
|
7431
7243
|
};
|
|
7432
|
-
const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now(), mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance =
|
|
7244
|
+
const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now(), mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance = vec2Length(mouseX, mouseY), mouseFalloff = easeOutQuart(1 - Math.min(2 * mouseDistance, 1)), organicFlow = fbm(12 * (ix + .5 * mouseX) + time, 12 * (iy + .5 * mouseY) + .7 * time, 3) - .5, distanceToEdge = roundedRectSDF(ix, iy, .4, .3, .35), baseDisplacement = smoothstepEdge(.8, 0, distanceToEdge - .05), radialDist = ((x, y, strength) => {
|
|
7433
7245
|
// Add input validation
|
|
7434
7246
|
if ("number" != typeof x || "number" != typeof y || isNaN(x) || isNaN(y) || isNaN(strength)) return {
|
|
7435
7247
|
x: 0,
|
|
7436
7248
|
y: 0
|
|
7437
7249
|
};
|
|
7438
|
-
const distance =
|
|
7250
|
+
const distance = vec2Length(x, y), distortion = Math.pow(Math.min(distance, 10), 2) * strength;
|
|
7439
7251
|
// Limit distance to prevent extreme values
|
|
7440
7252
|
return {
|
|
7441
7253
|
x: x * (1 + distortion),
|
|
@@ -7447,7 +7259,7 @@ const smoothStep = (a, b, t) => {
|
|
|
7447
7259
|
x: 0,
|
|
7448
7260
|
y: 0
|
|
7449
7261
|
};
|
|
7450
|
-
const distance =
|
|
7262
|
+
const distance = vec2Length(x, y);
|
|
7451
7263
|
// Prevent division by zero and extreme values
|
|
7452
7264
|
if (0 === distance) return {
|
|
7453
7265
|
x: 0,
|
|
@@ -7458,8 +7270,8 @@ const smoothStep = (a, b, t) => {
|
|
|
7458
7270
|
x: Math.cos(angle) * distance * intensity,
|
|
7459
7271
|
y: Math.sin(angle) * distance * intensity
|
|
7460
7272
|
};
|
|
7461
|
-
})(ix, iy, .015 * baseDisplacement), scaled =
|
|
7462
|
-
return createTexture(
|
|
7273
|
+
})(ix, iy, .015 * baseDisplacement), scaled = smoothstepEdge(0, 1, 1.15 * baseDisplacement), finalX = ix + totalDistortionX + .5 * chromaticOffset.x, finalY = iy + totalDistortionY + .5 * chromaticOffset.y;
|
|
7274
|
+
return createTexture(clamp(finalX * scaled + .5, 0, 1), clamp(finalY * scaled + .5, 0, 1));
|
|
7463
7275
|
},
|
|
7464
7276
|
// Premium Apple-style fluid glass with enhanced organic flow
|
|
7465
7277
|
appleFluid: (uv, mousePosition) => {
|
|
@@ -7467,8 +7279,8 @@ const smoothStep = (a, b, t) => {
|
|
|
7467
7279
|
x: .5,
|
|
7468
7280
|
y: .5
|
|
7469
7281
|
};
|
|
7470
|
-
const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * .6, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance =
|
|
7471
|
-
return createTexture(
|
|
7282
|
+
const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * .6, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance = vec2Length(mouseX, mouseY), mouseFalloff = easeOutQuart(1 - Math.min(1.5 * mouseDistance, 1)), organicX = fbm(10 * (ix + .3 * mouseX) + time, 10 * (iy + .3 * mouseY), 5) - .5, organicY = fbm(10 * (ix - .3 * mouseX), 10 * (iy - .3 * mouseY) + .8 * time, 5) - .5, distanceToEdge = roundedRectSDF(ix, iy, .42, .32, .38), mask = smoothstepEdge(.85, -.1, distanceToEdge), fluidVelocityX = Math.sin(6 * ix + 2 * time) * Math.cos(4 * iy - time) * .025, fluidVelocityY = Math.cos(4 * ix - time) * Math.sin(6 * iy + 2 * time) * .025, vortexAngle = Math.atan2(iy - mouseY, ix - mouseX), vortexStrength = mouseFalloff * mouseDistance * .08, vortexX = Math.cos(vortexAngle + time) * vortexStrength, totalY = iy + (.035 * organicY + fluidVelocityY + Math.sin(vortexAngle + time) * vortexStrength) * mask;
|
|
7283
|
+
return createTexture(clamp(ix + (.035 * organicX + fluidVelocityX + vortexX) * mask + .5, 0, 1), clamp(totalY + .5, 0, 1));
|
|
7472
7284
|
},
|
|
7473
7285
|
// High-end glass with advanced refraction and depth
|
|
7474
7286
|
premiumGlass: (uv, mousePosition) => {
|
|
@@ -7476,7 +7288,7 @@ const smoothStep = (a, b, t) => {
|
|
|
7476
7288
|
x: .5,
|
|
7477
7289
|
y: .5
|
|
7478
7290
|
};
|
|
7479
|
-
const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * .4, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance =
|
|
7291
|
+
const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * .4, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance = vec2Length(mouseX, mouseY), centerDistance = vec2Length(ix, iy), refractionStrength = .3 * Math.pow(Math.min(centerDistance, 1), 1.5), refractionAngle = Math.atan2(iy, ix);
|
|
7480
7292
|
// Multi-layer depth effect
|
|
7481
7293
|
let depthX = 0, depthY = 0;
|
|
7482
7294
|
for (let layer = 0; layer < 3; layer++) {
|
|
@@ -7484,8 +7296,8 @@ const smoothStep = (a, b, t) => {
|
|
|
7484
7296
|
depthX += Math.sin(ix * layerScale + layerTime) * layerStrength, depthY += Math.cos(iy * layerScale - layerTime) * layerStrength;
|
|
7485
7297
|
}
|
|
7486
7298
|
// Glass refraction with mouse influence
|
|
7487
|
-
const refractionX = Math.cos(refractionAngle) * refractionStrength * (1 + .5 * mouseDistance), refractionY = Math.sin(refractionAngle) * refractionStrength * (1 + .5 * mouseDistance), organicNoise = fbm(8 * ix + time, 8 * iy - time, 2) - .5, distanceToEdge = roundedRectSDF(ix, iy, .43, .33, .36), edgeMask =
|
|
7488
|
-
return createTexture(
|
|
7299
|
+
const refractionX = Math.cos(refractionAngle) * refractionStrength * (1 + .5 * mouseDistance), refractionY = Math.sin(refractionAngle) * refractionStrength * (1 + .5 * mouseDistance), organicNoise = fbm(8 * ix + time, 8 * iy - time, 2) - .5, distanceToEdge = roundedRectSDF(ix, iy, .43, .33, .36), edgeMask = smoothstepEdge(.9, -.05, distanceToEdge), finalY = iy + (refractionY + depthY + .015 * organicNoise) * edgeMask;
|
|
7300
|
+
return createTexture(clamp(ix + (refractionX + depthX + .015 * organicNoise) * edgeMask + .5, 0, 1), clamp(finalY + .5, 0, 1));
|
|
7489
7301
|
},
|
|
7490
7302
|
// Metallic liquid effect with shimmer
|
|
7491
7303
|
liquidMetal: (uv, mousePosition) => {
|
|
@@ -7493,8 +7305,8 @@ const smoothStep = (a, b, t) => {
|
|
|
7493
7305
|
x: .5,
|
|
7494
7306
|
y: .5
|
|
7495
7307
|
};
|
|
7496
|
-
const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * 1.2, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, wave1 = Math.sin(20 * ix + 4 * time) * Math.cos(15 * iy - 3 * time) * .02, wave2 = Math.cos(15 * ix - 2 * time) * Math.sin(20 * iy + 5 * time) * .015, shimmer = .025 * fbm(25 * ix + 2 * time, 25 * iy - 2 * time, 4), flowAngle = Math.atan2(iy - mouseY, ix - mouseX), flowDistance =
|
|
7497
|
-
return createTexture(
|
|
7308
|
+
const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * 1.2, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, wave1 = Math.sin(20 * ix + 4 * time) * Math.cos(15 * iy - 3 * time) * .02, wave2 = Math.cos(15 * ix - 2 * time) * Math.sin(20 * iy + 5 * time) * .015, shimmer = .025 * fbm(25 * ix + 2 * time, 25 * iy - 2 * time, 4), flowAngle = Math.atan2(iy - mouseY, ix - mouseX), flowDistance = vec2Length(ix - mouseX, iy - mouseY), flowEffect = .02 * Math.sin(15 * flowDistance - 6 * time) * easeOutQuart(1 - Math.min(2 * flowDistance, 1)), distanceToEdge = roundedRectSDF(ix, iy, .41, .31, .37), mask = smoothstepEdge(.88, -.08, distanceToEdge), totalX = ix + (wave1 + shimmer + Math.cos(flowAngle) * flowEffect) * mask, totalY = iy + (wave2 + .8 * shimmer + Math.sin(flowAngle) * flowEffect) * mask;
|
|
7309
|
+
return createTexture(clamp(totalX + .5, 0, 1), clamp(totalY + .5, 0, 1));
|
|
7498
7310
|
},
|
|
7499
7311
|
// basiBasi - Expert Premium Glass Shader
|
|
7500
7312
|
// The most advanced shader with caustics, spectral dispersion, parallax depth, and volumetric effects
|
|
@@ -7503,7 +7315,7 @@ const smoothStep = (a, b, t) => {
|
|
|
7503
7315
|
x: .5,
|
|
7504
7316
|
y: .5
|
|
7505
7317
|
};
|
|
7506
|
-
const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * .5, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance =
|
|
7318
|
+
const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * .5, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance = vec2Length(mouseX, mouseY), mouseFalloff = easeOutQuart(1 - Math.min(1.2 * mouseDistance, 1)), causticIntensity = ((x, y, time, intensity = 1) =>
|
|
7507
7319
|
// Add input validation
|
|
7508
7320
|
"number" != typeof x || "number" != typeof y || "number" != typeof time || "number" != typeof intensity || isNaN(x) || isNaN(y) || isNaN(time) || isNaN(intensity) ? .5 : .5 * (Math.sin(8 * x + 2 * time) * Math.cos(8 * y - 2 * time) * .5 + Math.sin(8 * (x + .5) * 1.3 - 2 * time * .8) * Math.cos(8 * (y - .3) * 1.3 + 2 * time * .8) * .3 + Math.sin(8 * (x - .3) * .7 + 2 * time * 1.2) * Math.cos(8 * (y + .4) * .7 - 2 * time * 1.2) * .2 + 1) * intensity)(ix, iy, time, .8), causticDistortion = .02 * (causticIntensity - .5), refractionAngle = Math.atan2(iy, ix), spectralDispersion = ((x, y, angle) => {
|
|
7509
7321
|
// Add input validation
|
|
@@ -7521,7 +7333,7 @@ const smoothStep = (a, b, t) => {
|
|
|
7521
7333
|
y: 0
|
|
7522
7334
|
}
|
|
7523
7335
|
};
|
|
7524
|
-
const distance =
|
|
7336
|
+
const distance = vec2Length(x, y), dispersionStrength = Math.min(.025 * distance, 1), redOffset = .8 * dispersionStrength, greenOffset = 1 * dispersionStrength, blueOffset = 1.2 * dispersionStrength;
|
|
7525
7337
|
return {
|
|
7526
7338
|
r: {
|
|
7527
7339
|
x: Math.cos(angle) * redOffset,
|
|
@@ -7561,8 +7373,8 @@ const smoothStep = (a, b, t) => {
|
|
|
7561
7373
|
return turbulence;
|
|
7562
7374
|
})(6 * ix, 6 * iy, time, 6), turbulenceX = .012 * Math.cos(turbulence * Math.PI * 2), turbulenceY = .012 * Math.sin(turbulence * Math.PI * 2), microSurface = ((x, y, time) =>
|
|
7563
7375
|
// Add input validation
|
|
7564
|
-
"number" != typeof x || "number" != typeof y || "number" != typeof time || isNaN(x) || isNaN(y) || isNaN(time) ? .5 : .5 * (.7 * fbm(40 * x + .3 * time, 40 * y - .3 * time, 6) + .3 * fbm(80 * x, 80 * y, 4)))(ix, iy, time), microDetailX = .008 * (microSurface - .5), microDetailY = .008 * (microSurface - .5), centerDistance =
|
|
7565
|
-
return createTexture(
|
|
7376
|
+
"number" != typeof x || "number" != typeof y || "number" != typeof time || isNaN(x) || isNaN(y) || isNaN(time) ? .5 : .5 * (.7 * fbm(40 * x + .3 * time, 40 * y - .3 * time, 6) + .3 * fbm(80 * x, 80 * y, 4)))(ix, iy, time), microDetailX = .008 * (microSurface - .5), microDetailY = .008 * (microSurface - .5), centerDistance = vec2Length(ix, iy), dynamicRefraction = .35 * Math.pow(Math.min(centerDistance, 1), 1.8) * (1 + mouseFalloff * mouseDistance * .8), refractionX = Math.cos(refractionAngle) * dynamicRefraction, refractionY = Math.sin(refractionAngle) * dynamicRefraction, vortexAngle = Math.atan2(iy - mouseY, ix - mouseX), vortexDistance = vec2Length(ix - mouseX, iy - mouseY), vortexStrength = mouseFalloff * Math.sin(10 * vortexDistance - 3 * time) * .025, vortexX = Math.cos(vortexAngle + 2 * time) * vortexStrength, vortexY = Math.sin(vortexAngle + 2 * time) * vortexStrength, fluidX = Math.sin(10 * ix + 5 * mouseX + 2.5 * time) * Math.cos(8 * iy - 2 * time) * .018, fluidY = Math.cos(8 * ix - 2 * time) * Math.sin(10 * iy + 5 * mouseY + 2.5 * time) * .018, rippleEffect = (.012 * Math.sin(15 * Math.min(centerDistance, 10) - 4 * time) + .008 * Math.cos(20 * Math.min(centerDistance, 10) + 3 * time)) * mouseFalloff, rippleX = Math.cos(refractionAngle) * rippleEffect, rippleY = Math.sin(refractionAngle) * rippleEffect, distanceToEdge = roundedRectSDF(ix, iy, .44, .34, .39), edgeMask = smoothstepEdge(.92, -.12, distanceToEdge), edgeSoftness = smoothstepEdge(.85, .1, distanceToEdge), finalY = iy + (1.2 * refractionY + .8 * spectralY + 1.5 * parallaxY + .9 * scatteringY + 1 * turbulenceY + .6 * microDetailY + 1.3 * vortexY + 1.1 * fluidY + .7 * rippleY + .8 * causticDistortion) * edgeMask * edgeSoftness * .85;
|
|
7377
|
+
return createTexture(clamp(ix + (1.2 * refractionX + .8 * spectralX + 1.5 * parallaxX + .9 * scatteringX + 1 * turbulenceX + .6 * microDetailX + 1.3 * vortexX + 1.1 * fluidX + .7 * rippleX + causticDistortion) * edgeMask * edgeSoftness * .85 + .5, 0, 1), clamp(finalY + .5, 0, 1));
|
|
7566
7378
|
},
|
|
7567
7379
|
// Aliases for compatibility
|
|
7568
7380
|
plasma: (uv, mousePosition) => fragmentShaders.premiumGlass(uv, mousePosition),
|
|
@@ -7604,8 +7416,8 @@ const smoothStep = (a, b, t) => {
|
|
|
7604
7416
|
let dx = pos.x * w - x, dy = pos.y * h - y;
|
|
7605
7417
|
// Apply edge smoothing for Apple-like effect
|
|
7606
7418
|
const edgeX = 2 * Math.min(x / w, (w - x) / w), edgeY = 2 * Math.min(y / h, (h - y) / h), edgeFactor = Math.min(edgeX, edgeY);
|
|
7607
|
-
dx *=
|
|
7608
|
-
rawValues.push(dx, dy);
|
|
7419
|
+
dx *= smoothstepEdge(0, .2, edgeFactor), dy *= smoothstepEdge(0, .2, edgeFactor),
|
|
7420
|
+
maxScale = Math.max(maxScale, Math.abs(dx), Math.abs(dy)), rawValues.push(dx, dy);
|
|
7609
7421
|
}
|
|
7610
7422
|
// Improved normalization to prevent artifacts while maintaining intensity
|
|
7611
7423
|
maxScale = Math.max(maxScale, 1);
|
|
@@ -7615,9 +7427,9 @@ const smoothStep = (a, b, t) => {
|
|
|
7615
7427
|
let rawIndex = 0;
|
|
7616
7428
|
for (let y = 0; y < h; y++) for (let x = 0; x < w; x++) {
|
|
7617
7429
|
const dx = rawValues[rawIndex++] || 0, dy = rawValues[rawIndex++] || 0, edgeDistance = Math.min(x, y, w - x - 1, h - y - 1), edgeFactor = Math.min(1, edgeDistance / 2), r = dx * edgeFactor / maxScale + .5, g = dy * edgeFactor / maxScale + .5, pixelIndex = 4 * (y * w + x);
|
|
7618
|
-
data[pixelIndex] =
|
|
7619
|
-
data[pixelIndex + 1] =
|
|
7620
|
-
data[pixelIndex + 2] =
|
|
7430
|
+
data[pixelIndex] = clamp(255 * r, 0, 255), // Red channel (X displacement)
|
|
7431
|
+
data[pixelIndex + 1] = clamp(255 * g, 0, 255), // Green channel (Y displacement)
|
|
7432
|
+
data[pixelIndex + 2] = clamp(255 * g, 0, 255), // Blue channel (Y displacement for SVG filter compatibility)
|
|
7621
7433
|
data[pixelIndex + 3] = 255;
|
|
7622
7434
|
}
|
|
7623
7435
|
return this.context.putImageData(imageData, 0, 0), this.canvas.toDataURL();
|
|
@@ -7645,9 +7457,7 @@ const smoothStep = (a, b, t) => {
|
|
|
7645
7457
|
return this.canvasDPI;
|
|
7646
7458
|
}
|
|
7647
7459
|
},
|
|
7648
|
-
|
|
7649
|
-
fragmentShaders: fragmentShaders,
|
|
7650
|
-
liquidGlassWithTime: liquidGlassWithTime
|
|
7460
|
+
fragmentShaders: fragmentShaders
|
|
7651
7461
|
}, Symbol.toStringTag, {
|
|
7652
7462
|
value: "Module"
|
|
7653
7463
|
}));
|