@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/forms.js
CHANGED
|
@@ -157,6 +157,11 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
|
|
|
157
157
|
MIN_BLUR: .1,
|
|
158
158
|
MOUSE_INFLUENCE_DIVISOR: 100,
|
|
159
159
|
EDGE_FADE_PIXELS: 2,
|
|
160
|
+
// Interaction intensity multipliers shared by the hook and the imperative style updater
|
|
161
|
+
INTERACTION: {
|
|
162
|
+
HOVER_INTENSITY: 1.4,
|
|
163
|
+
ACTIVE_INTENSITY: 1.6
|
|
164
|
+
},
|
|
160
165
|
// Elasticity physics constants — Apple-tuned: soft springs, fast settling, minimal stretch
|
|
161
166
|
ELASTICITY_TRANSLATION_FACTOR: .06,
|
|
162
167
|
// Subtler elastic shift (was 0.1)
|
|
@@ -354,7 +359,7 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
|
|
|
354
359
|
},
|
|
355
360
|
// Container shadows — hairline inner catch + soft floating lift (Apple player bar)
|
|
356
361
|
CONTAINER_SHADOW: {
|
|
357
|
-
LIGHT: "inset 0 0.5px 0 rgba(255, 255, 255, 0.32), inset 0 1px 2px rgba(255, 255, 255, 0.06), 0
|
|
362
|
+
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)"
|
|
358
363
|
},
|
|
359
364
|
// Phase 1: Animation System Constants
|
|
360
365
|
ANIMATION: {
|
|
@@ -786,7 +791,28 @@ const {CONSTANTS: CONSTANTS$3} = ATOMIX_GLASS, calculateElementCenter = rect =>
|
|
|
786
791
|
}, smoothstep = t => {
|
|
787
792
|
const clamped = Math.max(0, Math.min(1, t));
|
|
788
793
|
return clamped * clamped * (3 - 2 * clamped);
|
|
789
|
-
}, lerp
|
|
794
|
+
}, 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 => {
|
|
795
|
+
if ("number" != typeof t || isNaN(t)) return 0;
|
|
796
|
+
const clamped = Math.max(0, Math.min(1, t));
|
|
797
|
+
return clamped < .5 ? 4 * clamped * clamped * clamped : 1 - Math.pow(-2 * clamped + 2, 3) / 2;
|
|
798
|
+
}, easeOutQuart = t => {
|
|
799
|
+
if ("number" != typeof t || isNaN(t)) return 0;
|
|
800
|
+
const clamped = Math.max(0, Math.min(1, t));
|
|
801
|
+
return 1 - Math.pow(1 - clamped, 4);
|
|
802
|
+
}, vec2Length = (x, y) => {
|
|
803
|
+
if ("number" != typeof x || "number" != typeof y || isNaN(x) || isNaN(y)) return 0;
|
|
804
|
+
const maxComponent = Math.max(Math.abs(x), Math.abs(y));
|
|
805
|
+
if (0 === maxComponent) return 0;
|
|
806
|
+
const scaledX = x / maxComponent, scaledY = y / maxComponent;
|
|
807
|
+
return maxComponent * Math.sqrt(scaledX * scaledX + scaledY * scaledY);
|
|
808
|
+
}, getInteractionIntensity = (isHovered, isActive) => ({
|
|
809
|
+
hoverIntensity: isHovered ? CONSTANTS$3.INTERACTION.HOVER_INTENSITY : 1,
|
|
810
|
+
activeIntensity: isActive ? CONSTANTS$3.INTERACTION.ACTIVE_INTENSITY : 1
|
|
811
|
+
})
|
|
812
|
+
/**
|
|
813
|
+
* Spring-damper integration helper
|
|
814
|
+
* Calculates the next value based on velocity, stiffness, and damping.
|
|
815
|
+
*/ , calculateSpring = (current, target, velocity, stiffness = .1, damping = .8) => {
|
|
790
816
|
const newVelocity = (velocity + (target - current) * stiffness) * damping;
|
|
791
817
|
return {
|
|
792
818
|
value: current + newVelocity,
|
|
@@ -992,7 +1018,7 @@ const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevP
|
|
|
992
1018
|
}, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, isActive: isActive = !1, overLight: overLight = !1, overLightConfig: overLightConfig = {}, borderRadius: borderRadius = 0, glassSize: glassSize = {
|
|
993
1019
|
width: 0,
|
|
994
1020
|
height: 0
|
|
995
|
-
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1, isFixedOrSticky: isFixedOrSticky = !1,
|
|
1021
|
+
}, 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) => {
|
|
996
1022
|
// React 18 useId — stable, unique, and SSR-safe (no module-level counter)
|
|
997
1023
|
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);
|
|
998
1024
|
// Lazy load shader utilities only when shader mode is needed
|
|
@@ -1290,7 +1316,7 @@ class {
|
|
|
1290
1316
|
}, {BORDER: BORDER, CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, BORDER_GRADIENT = BORDER.GRADIENT, WHITE = CONSTANTS$2.PALETTE.WHITE, updateAtomixGlassStyles = (wrapperElement, containerElement, params) => {
|
|
1291
1317
|
if (!wrapperElement && !containerElement) return;
|
|
1292
1318
|
if (!validateGlassSize(params.glassSize)) return;
|
|
1293
|
-
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
|
|
1319
|
+
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 = {
|
|
1294
1320
|
opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
|
|
1295
1321
|
contrast: Math.min(1.6, baseOverLightConfig.contrast + .1 * mouseInfluence),
|
|
1296
1322
|
brightness: Math.min(1.1, baseOverLightConfig.brightness + .05 * mouseInfluence),
|
|
@@ -1421,140 +1447,9 @@ class {
|
|
|
1421
1447
|
style.setProperty("--atomix-glass-container-shadow-opacity", effectiveWithoutEffects ? "0" : "1"),
|
|
1422
1448
|
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"),
|
|
1423
1449
|
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)"),
|
|
1424
|
-
style.setProperty("--atomix-glass-container-box-shadow", isOverLight ? "0px 16px 70px rgba(0, 0, 0, 0.75)" : "0
|
|
1450
|
+
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)");
|
|
1425
1451
|
}
|
|
1426
|
-
};
|
|
1427
|
-
|
|
1428
|
-
/**
|
|
1429
|
-
* Animation System for AtomixGlass Component
|
|
1430
|
-
*
|
|
1431
|
-
* Implements Phase 1 features from the AtomixGlass Feature Implementation Roadmap:
|
|
1432
|
-
* - Feature 1.1: Time-Based Animation System
|
|
1433
|
-
* - Feature 1.2: Multi-Layer Distortion System (FBM)
|
|
1434
|
-
*
|
|
1435
|
-
* @packageDocumentation
|
|
1436
|
-
*/
|
|
1437
|
-
// ============================================================================
|
|
1438
|
-
// Noise Functions for FBM (Feature 1.2)
|
|
1439
|
-
// ============================================================================
|
|
1440
|
-
/**
|
|
1441
|
-
* Perlin noise implementation for smooth gradient noise
|
|
1442
|
-
*
|
|
1443
|
-
* @param x - X coordinate
|
|
1444
|
-
* @param y - Y coordinate
|
|
1445
|
-
* @returns Noise value in range [0, 1]
|
|
1446
|
-
*/
|
|
1447
|
-
function perlinNoise(x, y) {
|
|
1448
|
-
// Simplified Perlin noise using pseudo-random gradients
|
|
1449
|
-
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);
|
|
1450
|
-
// Scale to [0, 1] range
|
|
1451
|
-
return (lerp(lerpX1, lerpX2, v) + 1) / 2;
|
|
1452
|
-
}
|
|
1453
|
-
|
|
1454
|
-
// ============================================================================
|
|
1455
|
-
// Fractal Brownian Motion (FBM) Engine (Feature 1.2)
|
|
1456
|
-
// ============================================================================
|
|
1457
|
-
/**
|
|
1458
|
-
* Creates an FBM engine with configurable parameters
|
|
1459
|
-
*
|
|
1460
|
-
* @param config - FBM configuration (octaves, lacunarity, gain)
|
|
1461
|
-
* @returns Object with fbm function
|
|
1462
|
-
*
|
|
1463
|
-
* @example
|
|
1464
|
-
* ```typescript
|
|
1465
|
-
* const fbmEngine = createFBMEngine({ octaves: 5, lacunarity: 2, gain: 0.5 });
|
|
1466
|
-
*
|
|
1467
|
-
* // Generate noise at position (0.5, 0.5) with time animation
|
|
1468
|
-
* const noiseValue = fbmEngine.fbm(0.5, 0.5, Date.now());
|
|
1469
|
-
* ```
|
|
1470
|
-
*/ function createFBMEngine(config) {
|
|
1471
|
-
/**
|
|
1472
|
-
* Fractal Brownian Motion function
|
|
1473
|
-
* Combines multiple octaves of noise for complex, natural patterns
|
|
1474
|
-
*
|
|
1475
|
-
* @param x - X coordinate
|
|
1476
|
-
* @param y - Y coordinate
|
|
1477
|
-
* @param time - Optional time value for animation
|
|
1478
|
-
* @returns FBM noise value in range [0, 1]
|
|
1479
|
-
*/
|
|
1480
|
-
const fbm = (x, y, time = 0) => {
|
|
1481
|
-
let value = 0, amplitude = .5, frequency = 1, phase = .001 * time;
|
|
1482
|
-
// Convert to seconds for reasonable animation speed
|
|
1483
|
-
for (let i = 0; i < config.octaves; i++)
|
|
1484
|
-
// Apply time-based phase shift to all octaves
|
|
1485
|
-
value += perlinNoise(x * frequency + phase, y * frequency + phase) * amplitude,
|
|
1486
|
-
frequency *= config.lacunarity, // Increase frequency
|
|
1487
|
-
amplitude *= config.gain;
|
|
1488
|
-
return value;
|
|
1489
|
-
};
|
|
1490
|
-
/**
|
|
1491
|
-
* Get FBM with simple time factor
|
|
1492
|
-
*/ return {
|
|
1493
|
-
fbm: fbm,
|
|
1494
|
-
fbmWithTime: (x, y, time) => fbm(x, y, time)
|
|
1495
|
-
};
|
|
1496
|
-
}
|
|
1497
|
-
|
|
1498
|
-
/**
|
|
1499
|
-
* Gets optimal FBM config based on quality preset
|
|
1500
|
-
*
|
|
1501
|
-
* @param quality - Quality preset level
|
|
1502
|
-
* @returns FBM configuration for the quality level
|
|
1503
|
-
*/ const fbmEngineCache = new Map;
|
|
1504
|
-
|
|
1505
|
-
// ============================================================================
|
|
1506
|
-
// Shader Utility Functions for Time-Based Effects
|
|
1507
|
-
// ============================================================================
|
|
1508
|
-
/**
|
|
1509
|
-
* Liquid glass distortion with time-based animation
|
|
1510
|
-
* Uses FBM to create organic, flowing liquid effects
|
|
1511
|
-
*
|
|
1512
|
-
* @param uv - UV coordinates (normalized 0-1)
|
|
1513
|
-
* @param time - Elapsed time in milliseconds
|
|
1514
|
-
* @param config - FBM configuration
|
|
1515
|
-
* @returns Distorted UV coordinates
|
|
1516
|
-
*/ function liquidGlassWithTime(uv, time, config) {
|
|
1517
|
-
const configKey = `${config.octaves}-${config.lacunarity}-${config.gain}`;
|
|
1518
|
-
let fbmEngine = fbmEngineCache.get(configKey);
|
|
1519
|
-
fbmEngine || (fbmEngine = createFBMEngine(config), fbmEngineCache.set(configKey, fbmEngine));
|
|
1520
|
-
// Animate noise with time
|
|
1521
|
-
const animatedNoise = fbmEngine.fbmWithTime(2 * uv.x + 1e-4 * time, 2 * uv.y + 15e-5 * time, time);
|
|
1522
|
-
return {
|
|
1523
|
-
x: uv.x + .04 * (animatedNoise - .5),
|
|
1524
|
-
y: uv.y + .04 * (animatedNoise - .5)
|
|
1525
|
-
};
|
|
1526
|
-
}
|
|
1527
|
-
|
|
1528
|
-
// ============================================================================
|
|
1529
|
-
// Helper Functions
|
|
1530
|
-
// ============================================================================
|
|
1531
|
-
/**
|
|
1532
|
-
* Fade curve for smooth interpolation (Perlin's fade function)
|
|
1533
|
-
*/ function fade(t) {
|
|
1534
|
-
return t * t * t * (t * (6 * t - 15) + 10);
|
|
1535
|
-
}
|
|
1536
|
-
|
|
1537
|
-
/**
|
|
1538
|
-
* Linear interpolation
|
|
1539
|
-
*/ function lerp(a, b, t) {
|
|
1540
|
-
return a + t * (b - a);
|
|
1541
|
-
}
|
|
1542
|
-
|
|
1543
|
-
/**
|
|
1544
|
-
* Gradient calculation for Perlin noise
|
|
1545
|
-
*/ function grad(hash, x, y) {
|
|
1546
|
-
const h = 15 & hash, u = h < 8 ? x : y, v = h < 4 ? y : 12 === h || 14 === h ? x : 0;
|
|
1547
|
-
return (1 & h ? -u : u) + (2 & h ? -v : v);
|
|
1548
|
-
}
|
|
1549
|
-
|
|
1550
|
-
/**
|
|
1551
|
-
* Permutation table for Perlin noise
|
|
1552
|
-
*/ const p = (() => {
|
|
1553
|
-
const permutation = [];
|
|
1554
|
-
for (let i = 0; i < 256; i++) permutation[i] = Math.floor(256 * Math.random());
|
|
1555
|
-
// Duplicate for overflow handling
|
|
1556
|
-
return [ ...permutation, ...permutation ];
|
|
1557
|
-
})(), {CONSTANTS: CONSTANTS$1} = ATOMIX_GLASS;
|
|
1452
|
+
}, {CONSTANTS: CONSTANTS$1} = ATOMIX_GLASS;
|
|
1558
1453
|
|
|
1559
1454
|
const {CONSTANTS: CONSTANTS} = ATOMIX_GLASS, backgroundDetectionCache = new WeakMap, setCachedBackgroundDetection = (parentElement, overLightConfig, result, threshold) => {
|
|
1560
1455
|
parentElement && backgroundDetectionCache.set(parentElement, {
|
|
@@ -1569,10 +1464,7 @@ const {CONSTANTS: CONSTANTS} = ATOMIX_GLASS, backgroundDetectionCache = new Weak
|
|
|
1569
1464
|
* Composable hook for AtomixGlass component logic
|
|
1570
1465
|
* Manages all state, calculations, and event handlers
|
|
1571
1466
|
*/
|
|
1572
|
-
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
|
|
1573
|
-
// Default priority
|
|
1574
|
-
// Phase 1: Animation System Props
|
|
1575
|
-
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}) {
|
|
1467
|
+
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}) {
|
|
1576
1468
|
// State
|
|
1577
1469
|
const [isHovered, setIsHovered] = useState(!1), [isActive, setIsActive] = useState(!1), resolvedBorder = useMemo((() =>
|
|
1578
1470
|
/**
|
|
@@ -1624,52 +1516,10 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1624
1516
|
}), scaleVelocityRef = useRef({
|
|
1625
1517
|
x: 0,
|
|
1626
1518
|
y: 0
|
|
1627
|
-
})
|
|
1628
|
-
useRef(0);
|
|
1629
|
-
const mouseVelocityRef = useRef({
|
|
1519
|
+
}), mouseVelocityRef = useRef({
|
|
1630
1520
|
x: 0,
|
|
1631
1521
|
y: 0
|
|
1632
|
-
}), [userPrefersReducedMotion, setUserPrefersReducedMotion] = useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = useState(!1), [detectedOverLight, setDetectedOverLight] = useState(!1),
|
|
1633
|
-
// If quality preset is provided, use it as base
|
|
1634
|
-
const preset = (quality = distortionQuality, ATOMIX_GLASS.CONSTANTS.DISTORTION_QUALITY_PRESETS[quality]);
|
|
1635
|
-
// Override with custom values if provided
|
|
1636
|
-
var quality;
|
|
1637
|
-
return {
|
|
1638
|
-
octaves: distortionOctaves ?? preset.octaves,
|
|
1639
|
-
lacunarity: distortionLacunarity ?? preset.lacunarity,
|
|
1640
|
-
gain: distortionGain ?? preset.gain
|
|
1641
|
-
};
|
|
1642
|
-
}), [ distortionQuality, distortionOctaves, distortionLacunarity, distortionGain ]), fbmEngine = useMemo((() => withMultiLayerDistortion ? createFBMEngine(fbmConfig) : null), [ withMultiLayerDistortion, fbmConfig ]), effectiveReducedMotion = useMemo((() => reducedMotion || userPrefersReducedMotion), [ reducedMotion, userPrefersReducedMotion ]), effectiveWithTimeAnimation = useMemo((() => withTimeAnimation && !effectiveReducedMotion), [ withTimeAnimation, effectiveReducedMotion ]);
|
|
1643
|
-
/**
|
|
1644
|
-
* Animation loop for time-based effects
|
|
1645
|
-
*/
|
|
1646
|
-
useEffect((() => {
|
|
1647
|
-
if (!effectiveWithTimeAnimation || "undefined" == typeof window) return;
|
|
1648
|
-
let lastFrameTime = performance.now();
|
|
1649
|
-
/**
|
|
1650
|
-
* Animation frame handler
|
|
1651
|
-
*/ const animate = currentTime => {
|
|
1652
|
-
// Calculate delta time
|
|
1653
|
-
const deltaTime = currentTime - lastFrameTime;
|
|
1654
|
-
lastFrameTime = currentTime;
|
|
1655
|
-
// Apply animation speed multiplier
|
|
1656
|
-
const scaledDelta = deltaTime * animationSpeed;
|
|
1657
|
-
elapsedTimeRef.current += scaledDelta, shaderTimeRef.current = elapsedTimeRef.current,
|
|
1658
|
-
// Continue animation loop
|
|
1659
|
-
animationFrameIdRef.current = requestAnimationFrame(animate);
|
|
1660
|
-
};
|
|
1661
|
-
// Start animation
|
|
1662
|
-
// Cleanup
|
|
1663
|
-
return animationStartTimeRef.current = performance.now(), animationFrameIdRef.current = requestAnimationFrame(animate),
|
|
1664
|
-
() => {
|
|
1665
|
-
null !== animationFrameIdRef.current && (cancelAnimationFrame(animationFrameIdRef.current),
|
|
1666
|
-
animationFrameIdRef.current = null);
|
|
1667
|
-
};
|
|
1668
|
-
}), [ effectiveWithTimeAnimation, animationSpeed ]);
|
|
1669
|
-
/**
|
|
1670
|
-
* Get current shader time for animations
|
|
1671
|
-
*/
|
|
1672
|
-
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}) {
|
|
1522
|
+
}), [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}) {
|
|
1673
1523
|
const [glassSize, setGlassSize] = useState({
|
|
1674
1524
|
width: 270,
|
|
1675
1525
|
height: 69
|
|
@@ -1729,9 +1579,6 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1729
1579
|
effectiveBorderRadius: effectiveBorderRadius,
|
|
1730
1580
|
cachedRectRef: cachedRectRef
|
|
1731
1581
|
}), effectiveHighContrast = useMemo((() => highContrast || userPrefersHighContrast), [ highContrast, userPrefersHighContrast ]), effectiveWithoutEffects = useMemo((() => withoutEffects || effectiveReducedMotion), [ withoutEffects, effectiveReducedMotion ]), globalMousePosition = externalGlobalMousePosition || internalGlobalMousePositionRef.current, mouseOffset = externalMouseOffset || internalMouseOffsetRef.current;
|
|
1732
|
-
/**
|
|
1733
|
-
* Apply time-based distortion to UV coordinates
|
|
1734
|
-
*/
|
|
1735
1582
|
// Extract border-radius from children
|
|
1736
1583
|
useEffect((() => {
|
|
1737
1584
|
const extractRadius = () => {
|
|
@@ -1891,7 +1738,7 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1891
1738
|
* Get effective overLight value based on configuration
|
|
1892
1739
|
*/
|
|
1893
1740
|
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((() => {
|
|
1894
|
-
const isOverLight = getEffectiveOverLight(), hoverIntensity
|
|
1741
|
+
const isOverLight = getEffectiveOverLight(), {hoverIntensity: hoverIntensity, activeIntensity: activeIntensity} = getInteractionIntensity(isHovered, isActive), baseConfig = {
|
|
1895
1742
|
isOverLight: isOverLight,
|
|
1896
1743
|
threshold: .7,
|
|
1897
1744
|
opacity: isOverLight ? Math.min(.6, Math.max(.2, .5 * hoverIntensity * activeIntensity)) : 0,
|
|
@@ -1935,8 +1782,8 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1935
1782
|
};
|
|
1936
1783
|
const curG = internalGlobalMousePositionRef.current, tgtG = targetGlobalMousePositionRef.current;
|
|
1937
1784
|
internalGlobalMousePositionRef.current = {
|
|
1938
|
-
x: lerp
|
|
1939
|
-
y: lerp
|
|
1785
|
+
x: lerp(curG.x, tgtG.x, CONSTANTS.LERP_FACTOR),
|
|
1786
|
+
y: lerp(curG.y, tgtG.y, CONSTANTS.LERP_FACTOR)
|
|
1940
1787
|
};
|
|
1941
1788
|
// ── Calculate Elastic Physics ─────────────────────────────────────
|
|
1942
1789
|
let targetElasticTranslation = {
|
|
@@ -2103,8 +1950,6 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2103
1950
|
overLightConfig: overLightConfig,
|
|
2104
1951
|
resolvedBorder: resolvedBorder,
|
|
2105
1952
|
transformStyle: transformStyle,
|
|
2106
|
-
getShaderTime: getShaderTime,
|
|
2107
|
-
applyTimeBasedDistortion: applyTimeBasedDistortion,
|
|
2108
1953
|
handleMouseEnter: handleMouseEnter,
|
|
2109
1954
|
handleMouseLeave: handleMouseLeave,
|
|
2110
1955
|
handleMouseDown: handleMouseDown,
|
|
@@ -2380,7 +2225,7 @@ const PERFORMANCE_PRESET = {
|
|
|
2380
2225
|
var explicit, position;
|
|
2381
2226
|
/**
|
|
2382
2227
|
* Extracts layout-related properties from a React `CSSProperties` object.
|
|
2383
|
-
*/ const {isHovered: isHovered, isActive: isActive, glassSize: glassSize, effectiveBorderRadius: effectiveBorderRadius, effectiveReducedMotion: effectiveReducedMotion, effectiveHighContrast: effectiveHighContrast, effectiveWithoutEffects: effectiveWithoutEffects, overLightConfig: overLightConfig, globalMousePosition: globalMousePosition, mouseOffset: mouseOffset, transformStyle: transformStyle,
|
|
2228
|
+
*/ 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({
|
|
2384
2229
|
glassRef: glassRef,
|
|
2385
2230
|
contentRef: contentRef,
|
|
2386
2231
|
wrapperRef: internalWrapperRef,
|
|
@@ -2404,14 +2249,7 @@ const PERFORMANCE_PRESET = {
|
|
|
2404
2249
|
withBorder: withBorder,
|
|
2405
2250
|
debugBorderRadius: debugBorderRadius,
|
|
2406
2251
|
style: style,
|
|
2407
|
-
isFixedOrSticky: isFixedOrSticky
|
|
2408
|
-
withTimeAnimation: withTimeAnimation,
|
|
2409
|
-
animationSpeed: animationSpeed,
|
|
2410
|
-
withMultiLayerDistortion: withMultiLayerDistortion,
|
|
2411
|
-
distortionOctaves: distortionOctaves,
|
|
2412
|
-
distortionLacunarity: distortionLacunarity,
|
|
2413
|
-
distortionGain: distortionGain,
|
|
2414
|
-
distortionQuality: distortionQuality
|
|
2252
|
+
isFixedOrSticky: isFixedOrSticky
|
|
2415
2253
|
});
|
|
2416
2254
|
(
|
|
2417
2255
|
/**
|
|
@@ -2986,7 +2824,6 @@ const PERFORMANCE_PRESET = {
|
|
|
2986
2824
|
shaderVariant: shaderVariant,
|
|
2987
2825
|
withLiquidBlur: withLiquidBlur,
|
|
2988
2826
|
isFixedOrSticky: isFixedOrSticky,
|
|
2989
|
-
shaderTime: getShaderTime(),
|
|
2990
2827
|
withTimeAnimation: withTimeAnimation,
|
|
2991
2828
|
animationSpeed: animationSpeed,
|
|
2992
2829
|
withMultiLayerDistortion: withMultiLayerDistortion,
|
|
@@ -3792,40 +3629,15 @@ Textarea.displayName = "Textarea";
|
|
|
3792
3629
|
|
|
3793
3630
|
// Adapted from https://github.com/shuding/liquid-glass
|
|
3794
3631
|
// Constants
|
|
3795
|
-
const
|
|
3796
|
-
// Add input validation
|
|
3797
|
-
if ("number" != typeof a || "number" != typeof b || "number" != typeof t) return 0;
|
|
3798
|
-
const clamped = Math.max(0, Math.min(1, (t - a) / (b - a)));
|
|
3799
|
-
return clamped * clamped * (3 - 2 * clamped);
|
|
3800
|
-
}, calculateLength = (x, y) => {
|
|
3801
|
-
// Add input validation and error handling
|
|
3802
|
-
if ("number" != typeof x || "number" != typeof y || isNaN(x) || isNaN(y)) return 0;
|
|
3803
|
-
// Prevent potential overflow
|
|
3804
|
-
const maxX = Math.max(Math.abs(x), Math.abs(y));
|
|
3805
|
-
if (0 === maxX) return 0;
|
|
3806
|
-
const scaledX = x / maxX, scaledY = y / maxX;
|
|
3807
|
-
return maxX * Math.sqrt(scaledX * scaledX + scaledY * scaledY);
|
|
3808
|
-
}, roundedRectSDF = (x, y, width, height, radius) => {
|
|
3632
|
+
const roundedRectSDF = (x, y, width, height, radius) => {
|
|
3809
3633
|
// Add input validation
|
|
3810
3634
|
if ("number" != typeof x || "number" != typeof y || "number" != typeof width || "number" != typeof height || "number" != typeof radius) return 0;
|
|
3811
3635
|
const qx = Math.abs(x) - width + radius, qy = Math.abs(y) - height + radius;
|
|
3812
|
-
return Math.min(Math.max(qx, qy), 0) +
|
|
3636
|
+
return Math.min(Math.max(qx, qy), 0) + vec2Length(Math.max(qx, 0), Math.max(qy, 0)) - radius;
|
|
3813
3637
|
}, createTexture = (x, y) => ({
|
|
3814
3638
|
x: "number" != typeof x || isNaN(x) ? .5 : Math.max(0, Math.min(1, x)),
|
|
3815
3639
|
y: "number" != typeof y || isNaN(y) ? .5 : Math.max(0, Math.min(1, y))
|
|
3816
|
-
}), validateVec2 = vec => vec && "number" == typeof vec.x && "number" == typeof vec.y && !isNaN(vec.x) && !isNaN(vec.y),
|
|
3817
|
-
// Add input validation
|
|
3818
|
-
"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 => {
|
|
3819
|
-
// Add input validation
|
|
3820
|
-
if ("number" != typeof t || isNaN(t)) return 0;
|
|
3821
|
-
const clampedT = Math.max(0, Math.min(1, t));
|
|
3822
|
-
return clampedT < .5 ? 4 * clampedT * clampedT * clampedT : 1 - Math.pow(-2 * clampedT + 2, 3) / 2;
|
|
3823
|
-
}, easeOutQuart = t => {
|
|
3824
|
-
// Add input validation
|
|
3825
|
-
if ("number" != typeof t || isNaN(t)) return 0;
|
|
3826
|
-
const clampedT = Math.max(0, Math.min(1, t));
|
|
3827
|
-
return 1 - Math.pow(1 - clampedT, 4);
|
|
3828
|
-
}, noise2D = (x, y) => {
|
|
3640
|
+
}), validateVec2 = vec => vec && "number" == typeof vec.x && "number" == typeof vec.y && !isNaN(vec.x) && !isNaN(vec.y), noise2D = (x, y) => {
|
|
3829
3641
|
// Add input validation
|
|
3830
3642
|
if ("number" != typeof x || "number" != typeof y || isNaN(x) || isNaN(y)) return 0;
|
|
3831
3643
|
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) => {
|
|
@@ -3864,13 +3676,13 @@ const smoothStep = (a, b, t) => {
|
|
|
3864
3676
|
x: .5,
|
|
3865
3677
|
y: .5
|
|
3866
3678
|
};
|
|
3867
|
-
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 =
|
|
3679
|
+
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) => {
|
|
3868
3680
|
// Add input validation
|
|
3869
3681
|
if ("number" != typeof x || "number" != typeof y || isNaN(x) || isNaN(y) || isNaN(strength)) return {
|
|
3870
3682
|
x: 0,
|
|
3871
3683
|
y: 0
|
|
3872
3684
|
};
|
|
3873
|
-
const distance =
|
|
3685
|
+
const distance = vec2Length(x, y), distortion = Math.pow(Math.min(distance, 10), 2) * strength;
|
|
3874
3686
|
// Limit distance to prevent extreme values
|
|
3875
3687
|
return {
|
|
3876
3688
|
x: x * (1 + distortion),
|
|
@@ -3882,7 +3694,7 @@ const smoothStep = (a, b, t) => {
|
|
|
3882
3694
|
x: 0,
|
|
3883
3695
|
y: 0
|
|
3884
3696
|
};
|
|
3885
|
-
const distance =
|
|
3697
|
+
const distance = vec2Length(x, y);
|
|
3886
3698
|
// Prevent division by zero and extreme values
|
|
3887
3699
|
if (0 === distance) return {
|
|
3888
3700
|
x: 0,
|
|
@@ -3893,8 +3705,8 @@ const smoothStep = (a, b, t) => {
|
|
|
3893
3705
|
x: Math.cos(angle) * distance * intensity,
|
|
3894
3706
|
y: Math.sin(angle) * distance * intensity
|
|
3895
3707
|
};
|
|
3896
|
-
})(ix, iy, .015 * baseDisplacement), scaled =
|
|
3897
|
-
return createTexture(
|
|
3708
|
+
})(ix, iy, .015 * baseDisplacement), scaled = smoothstepEdge(0, 1, 1.15 * baseDisplacement), finalX = ix + totalDistortionX + .5 * chromaticOffset.x, finalY = iy + totalDistortionY + .5 * chromaticOffset.y;
|
|
3709
|
+
return createTexture(clamp(finalX * scaled + .5, 0, 1), clamp(finalY * scaled + .5, 0, 1));
|
|
3898
3710
|
},
|
|
3899
3711
|
// Premium Apple-style fluid glass with enhanced organic flow
|
|
3900
3712
|
appleFluid: (uv, mousePosition) => {
|
|
@@ -3902,8 +3714,8 @@ const smoothStep = (a, b, t) => {
|
|
|
3902
3714
|
x: .5,
|
|
3903
3715
|
y: .5
|
|
3904
3716
|
};
|
|
3905
|
-
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 =
|
|
3906
|
-
return createTexture(
|
|
3717
|
+
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;
|
|
3718
|
+
return createTexture(clamp(ix + (.035 * organicX + fluidVelocityX + vortexX) * mask + .5, 0, 1), clamp(totalY + .5, 0, 1));
|
|
3907
3719
|
},
|
|
3908
3720
|
// High-end glass with advanced refraction and depth
|
|
3909
3721
|
premiumGlass: (uv, mousePosition) => {
|
|
@@ -3911,7 +3723,7 @@ const smoothStep = (a, b, t) => {
|
|
|
3911
3723
|
x: .5,
|
|
3912
3724
|
y: .5
|
|
3913
3725
|
};
|
|
3914
|
-
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 =
|
|
3726
|
+
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);
|
|
3915
3727
|
// Multi-layer depth effect
|
|
3916
3728
|
let depthX = 0, depthY = 0;
|
|
3917
3729
|
for (let layer = 0; layer < 3; layer++) {
|
|
@@ -3919,8 +3731,8 @@ const smoothStep = (a, b, t) => {
|
|
|
3919
3731
|
depthX += Math.sin(ix * layerScale + layerTime) * layerStrength, depthY += Math.cos(iy * layerScale - layerTime) * layerStrength;
|
|
3920
3732
|
}
|
|
3921
3733
|
// Glass refraction with mouse influence
|
|
3922
|
-
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 =
|
|
3923
|
-
return createTexture(
|
|
3734
|
+
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;
|
|
3735
|
+
return createTexture(clamp(ix + (refractionX + depthX + .015 * organicNoise) * edgeMask + .5, 0, 1), clamp(finalY + .5, 0, 1));
|
|
3924
3736
|
},
|
|
3925
3737
|
// Metallic liquid effect with shimmer
|
|
3926
3738
|
liquidMetal: (uv, mousePosition) => {
|
|
@@ -3928,8 +3740,8 @@ const smoothStep = (a, b, t) => {
|
|
|
3928
3740
|
x: .5,
|
|
3929
3741
|
y: .5
|
|
3930
3742
|
};
|
|
3931
|
-
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 =
|
|
3932
|
-
return createTexture(
|
|
3743
|
+
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;
|
|
3744
|
+
return createTexture(clamp(totalX + .5, 0, 1), clamp(totalY + .5, 0, 1));
|
|
3933
3745
|
},
|
|
3934
3746
|
// basiBasi - Expert Premium Glass Shader
|
|
3935
3747
|
// The most advanced shader with caustics, spectral dispersion, parallax depth, and volumetric effects
|
|
@@ -3938,7 +3750,7 @@ const smoothStep = (a, b, t) => {
|
|
|
3938
3750
|
x: .5,
|
|
3939
3751
|
y: .5
|
|
3940
3752
|
};
|
|
3941
|
-
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 =
|
|
3753
|
+
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) =>
|
|
3942
3754
|
// Add input validation
|
|
3943
3755
|
"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) => {
|
|
3944
3756
|
// Add input validation
|
|
@@ -3956,7 +3768,7 @@ const smoothStep = (a, b, t) => {
|
|
|
3956
3768
|
y: 0
|
|
3957
3769
|
}
|
|
3958
3770
|
};
|
|
3959
|
-
const distance =
|
|
3771
|
+
const distance = vec2Length(x, y), dispersionStrength = Math.min(.025 * distance, 1), redOffset = .8 * dispersionStrength, greenOffset = 1 * dispersionStrength, blueOffset = 1.2 * dispersionStrength;
|
|
3960
3772
|
return {
|
|
3961
3773
|
r: {
|
|
3962
3774
|
x: Math.cos(angle) * redOffset,
|
|
@@ -3996,8 +3808,8 @@ const smoothStep = (a, b, t) => {
|
|
|
3996
3808
|
return turbulence;
|
|
3997
3809
|
})(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) =>
|
|
3998
3810
|
// Add input validation
|
|
3999
|
-
"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 =
|
|
4000
|
-
return createTexture(
|
|
3811
|
+
"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;
|
|
3812
|
+
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));
|
|
4001
3813
|
},
|
|
4002
3814
|
// Aliases for compatibility
|
|
4003
3815
|
plasma: (uv, mousePosition) => fragmentShaders.premiumGlass(uv, mousePosition),
|
|
@@ -4039,8 +3851,8 @@ const smoothStep = (a, b, t) => {
|
|
|
4039
3851
|
let dx = pos.x * w - x, dy = pos.y * h - y;
|
|
4040
3852
|
// Apply edge smoothing for Apple-like effect
|
|
4041
3853
|
const edgeX = 2 * Math.min(x / w, (w - x) / w), edgeY = 2 * Math.min(y / h, (h - y) / h), edgeFactor = Math.min(edgeX, edgeY);
|
|
4042
|
-
dx *=
|
|
4043
|
-
rawValues.push(dx, dy);
|
|
3854
|
+
dx *= smoothstepEdge(0, .2, edgeFactor), dy *= smoothstepEdge(0, .2, edgeFactor),
|
|
3855
|
+
maxScale = Math.max(maxScale, Math.abs(dx), Math.abs(dy)), rawValues.push(dx, dy);
|
|
4044
3856
|
}
|
|
4045
3857
|
// Improved normalization to prevent artifacts while maintaining intensity
|
|
4046
3858
|
maxScale = Math.max(maxScale, 1);
|
|
@@ -4050,9 +3862,9 @@ const smoothStep = (a, b, t) => {
|
|
|
4050
3862
|
let rawIndex = 0;
|
|
4051
3863
|
for (let y = 0; y < h; y++) for (let x = 0; x < w; x++) {
|
|
4052
3864
|
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);
|
|
4053
|
-
data[pixelIndex] =
|
|
4054
|
-
data[pixelIndex + 1] =
|
|
4055
|
-
data[pixelIndex + 2] =
|
|
3865
|
+
data[pixelIndex] = clamp(255 * r, 0, 255), // Red channel (X displacement)
|
|
3866
|
+
data[pixelIndex + 1] = clamp(255 * g, 0, 255), // Green channel (Y displacement)
|
|
3867
|
+
data[pixelIndex + 2] = clamp(255 * g, 0, 255), // Blue channel (Y displacement for SVG filter compatibility)
|
|
4056
3868
|
data[pixelIndex + 3] = 255;
|
|
4057
3869
|
}
|
|
4058
3870
|
return this.context.putImageData(imageData, 0, 0), this.canvas.toDataURL();
|
|
@@ -4080,9 +3892,7 @@ const smoothStep = (a, b, t) => {
|
|
|
4080
3892
|
return this.canvasDPI;
|
|
4081
3893
|
}
|
|
4082
3894
|
},
|
|
4083
|
-
|
|
4084
|
-
fragmentShaders: fragmentShaders,
|
|
4085
|
-
liquidGlassWithTime: liquidGlassWithTime
|
|
3895
|
+
fragmentShaders: fragmentShaders
|
|
4086
3896
|
}, Symbol.toStringTag, {
|
|
4087
3897
|
value: "Module"
|
|
4088
3898
|
}));
|