@shohojdhara/atomix 0.6.1 → 0.6.3
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/README.md +510 -106
- package/dist/atomix.css +30 -24
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +6 -6
- 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.d.ts +11 -2
- package/dist/charts.js +294 -139
- package/dist/charts.js.map +1 -1
- package/dist/core.d.ts +14 -39
- package/dist/core.js +297 -145
- package/dist/core.js.map +1 -1
- package/dist/forms.d.ts +11 -1
- package/dist/forms.js +385 -185
- package/dist/forms.js.map +1 -1
- package/dist/heavy.d.ts +9 -0
- package/dist/heavy.js +297 -143
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +156 -164
- package/dist/index.esm.js +391 -203
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +391 -203
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/theme.d.ts +14 -6
- package/dist/theme.js +2 -9
- package/dist/theme.js.map +1 -1
- package/package.json +26 -26
- package/src/components/AtomixGlass/AtomixGlass.tsx +1 -1
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +8 -1
- package/src/components/AtomixGlass/deprecated/AtomixGlass.deprecated.tsx +390 -0
- package/src/components/AtomixGlass/glass-utils.ts +29 -0
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +32 -1
- package/src/components/Button/Button.stories.tsx +1 -1
- package/src/components/Button/Button.tsx +6 -5
- package/src/components/Card/Card.tsx +2 -2
- package/src/components/Dropdown/Dropdown.tsx +1 -0
- package/src/components/EdgePanel/EdgePanel.tsx +1 -3
- package/src/components/Form/Select.test.tsx +75 -0
- package/src/components/Form/Select.tsx +348 -252
- package/src/components/Form/SelectOption.tsx +16 -10
- package/src/components/index.ts +1 -1
- package/src/layouts/CssGrid/index.ts +1 -0
- package/src/lib/composables/shared-mouse-tracker.ts +62 -6
- package/src/lib/composables/useAtomixGlass.ts +241 -139
- package/src/lib/composables/useAtomixGlassStyles.ts +201 -149
- package/src/lib/constants/components.ts +54 -35
- package/src/lib/theme/config/configLoader.ts +1 -1
- package/src/lib/theme/test/testTheme.ts +2 -2
- package/src/lib/theme/utils/themeUtils.ts +98 -110
- package/src/lib/types/components.ts +29 -65
- package/src/styles/01-settings/_settings.spacing.scss +6 -1
- package/src/styles/03-generic/_generic.reset.scss +1 -1
- package/src/styles/06-components/_components.atomix-glass.scss +20 -29
- package/src/styles/06-components/_components.data-table.scss +5 -4
- package/src/styles/06-components/_components.dynamic-background.scss +9 -8
- package/src/styles/06-components/_components.footer.scss +8 -7
- package/src/styles/06-components/_components.hero.scss +2 -2
- package/src/styles/06-components/_components.messages.scss +16 -16
- package/src/styles/06-components/_components.navbar.scss +2 -0
- package/src/styles/06-components/_components.select.scss +15 -2
- package/src/styles/06-components/_components.upload.scss +3 -3
- package/CHANGELOG.md +0 -165
- package/src/lib/theme/devtools/DesignTokensCustomizer.stories.tsx +0 -215
package/dist/charts.js
CHANGED
|
@@ -502,12 +502,23 @@ const _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
502
502
|
},
|
|
503
503
|
DEFAULTS: {
|
|
504
504
|
DISPLACEMENT_SCALE: 70,
|
|
505
|
-
BLUR_AMOUNT
|
|
506
|
-
|
|
507
|
-
|
|
505
|
+
get BLUR_AMOUNT() {
|
|
506
|
+
return .15 * this.DISPLACEMENT_SCALE;
|
|
507
|
+
// Dynamically computed based on displacement
|
|
508
|
+
},
|
|
509
|
+
get SATURATION() {
|
|
510
|
+
return 100 + .5 * this.DISPLACEMENT_SCALE;
|
|
511
|
+
// Saturate relative to intensity
|
|
512
|
+
},
|
|
513
|
+
get ABERRATION_INTENSITY() {
|
|
514
|
+
return .03 * this.DISPLACEMENT_SCALE;
|
|
515
|
+
// Scale aberration with displacement
|
|
516
|
+
},
|
|
508
517
|
ELASTICITY: .15,
|
|
509
|
-
CORNER_RADIUS
|
|
510
|
-
|
|
518
|
+
get CORNER_RADIUS() {
|
|
519
|
+
return 16;
|
|
520
|
+
// Use 16 to match SCSS design system (was 20)
|
|
521
|
+
},
|
|
511
522
|
PADDING: "0",
|
|
512
523
|
MODE: "standard",
|
|
513
524
|
OVER_LIGHT: !1,
|
|
@@ -529,6 +540,15 @@ const _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
529
540
|
MIN_BLUR: .1,
|
|
530
541
|
MOUSE_INFLUENCE_DIVISOR: 100,
|
|
531
542
|
EDGE_FADE_PIXELS: 2,
|
|
543
|
+
// Elasticity physics constants
|
|
544
|
+
ELASTICITY_TRANSLATION_FACTOR: .1,
|
|
545
|
+
ELASTICITY_DISTANCE_THRESHOLD: 200,
|
|
546
|
+
ELASTICITY_COMPRESSION_FACTOR: .3,
|
|
547
|
+
ELASTICITY_STIFFNESS: .1,
|
|
548
|
+
ELASTICITY_DAMPING: .76,
|
|
549
|
+
ELASTICITY_VELOCITY_FACTOR: .65,
|
|
550
|
+
ELASTICITY_STRETCH_RATIO: .45,
|
|
551
|
+
ELASTICITY_MAGNIFICATION_BASE: 1.02,
|
|
532
552
|
// Note: This default must match the SCSS variable --atomix-radius-md
|
|
533
553
|
// @see src/styles/01-settings/_settings.global.scss
|
|
534
554
|
DEFAULT_CORNER_RADIUS: 16,
|
|
@@ -545,84 +565,126 @@ const _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
545
565
|
// Base angle for border gradients (degrees)
|
|
546
566
|
ANGLE_MULTIPLIER: 1.2,
|
|
547
567
|
// Multiplier for mouse influence on angle
|
|
568
|
+
VELOCITY_ANGLE_MULTIPLIER: 2.5,
|
|
569
|
+
// How much velocity affects gradient rotation
|
|
570
|
+
CHROMATIC_OFFSET: 1.5,
|
|
571
|
+
// Degree offset for chromatic rim layers
|
|
548
572
|
BORDER_STOP_1: {
|
|
549
573
|
MIN: 10,
|
|
550
574
|
// Minimum percentage for border stop 1
|
|
551
575
|
BASE: 33,
|
|
552
576
|
// Base percentage for border stop 1
|
|
553
|
-
MULTIPLIER
|
|
577
|
+
get MULTIPLIER() {
|
|
578
|
+
return .009 * this.BASE;
|
|
579
|
+
}
|
|
554
580
|
},
|
|
555
581
|
BORDER_STOP_2: {
|
|
556
582
|
MAX: 90,
|
|
557
583
|
// Maximum percentage for border stop 2
|
|
558
584
|
BASE: 66,
|
|
559
585
|
// Base percentage for border stop 2
|
|
560
|
-
MULTIPLIER
|
|
586
|
+
get MULTIPLIER() {
|
|
587
|
+
return .006 * this.BASE;
|
|
588
|
+
}
|
|
561
589
|
},
|
|
562
590
|
BORDER_OPACITY: {
|
|
563
591
|
BASE_1: .12,
|
|
564
592
|
// Base opacity for border gradient 1
|
|
565
|
-
BASE_2
|
|
593
|
+
get BASE_2() {
|
|
594
|
+
return 3.33 * this.BASE_1;
|
|
595
|
+
},
|
|
566
596
|
// Base opacity for border gradient 2
|
|
567
|
-
BASE_3
|
|
597
|
+
get BASE_3() {
|
|
598
|
+
return 2.66 * this.BASE_1;
|
|
599
|
+
},
|
|
568
600
|
// Base opacity for border gradient 3
|
|
569
|
-
BASE_4
|
|
601
|
+
get BASE_4() {
|
|
602
|
+
return 5 * this.BASE_1;
|
|
603
|
+
},
|
|
570
604
|
// Base opacity for border gradient 4
|
|
571
|
-
MULTIPLIER_LOW
|
|
605
|
+
get MULTIPLIER_LOW() {
|
|
606
|
+
return .066 * this.BASE_1;
|
|
607
|
+
},
|
|
572
608
|
// Low multiplier for mouse influence on opacity
|
|
573
|
-
MULTIPLIER_HIGH
|
|
609
|
+
get MULTIPLIER_HIGH() {
|
|
610
|
+
return .1 * this.BASE_1;
|
|
611
|
+
}
|
|
574
612
|
},
|
|
575
613
|
CENTER_POSITION: 50,
|
|
576
614
|
// Center position percentage (50%)
|
|
577
615
|
HOVER_POSITION: {
|
|
578
616
|
DIVISOR_1: 2,
|
|
579
617
|
// Divisor for hover 1 position calculation
|
|
580
|
-
DIVISOR_2
|
|
618
|
+
get DIVISOR_2() {
|
|
619
|
+
return .75 * this.DIVISOR_1;
|
|
620
|
+
},
|
|
581
621
|
// Divisor for hover 2 position calculation
|
|
582
|
-
MULTIPLIER_3
|
|
622
|
+
get MULTIPLIER_3() {
|
|
623
|
+
return .5 * this.DIVISOR_1;
|
|
624
|
+
}
|
|
583
625
|
},
|
|
584
|
-
BASE_LAYER_MULTIPLIER
|
|
626
|
+
get BASE_LAYER_MULTIPLIER() {
|
|
627
|
+
return .5;
|
|
628
|
+
}
|
|
585
629
|
},
|
|
586
630
|
// Gradient opacity values for hover effects
|
|
587
631
|
GRADIENT_OPACITY: {
|
|
588
632
|
HOVER_1: {
|
|
589
633
|
BLACK_START: .3,
|
|
590
634
|
// Start opacity for black hover 1
|
|
591
|
-
BLACK_MID
|
|
635
|
+
get BLACK_MID() {
|
|
636
|
+
return this.BLACK_START / 3;
|
|
637
|
+
},
|
|
592
638
|
// Mid opacity for black hover 1
|
|
593
639
|
BLACK_STOP: 30,
|
|
594
640
|
// Stop percentage for black hover 1
|
|
595
|
-
BLACK_END
|
|
641
|
+
get BLACK_END() {
|
|
642
|
+
return 2 * this.BLACK_STOP;
|
|
643
|
+
},
|
|
596
644
|
// End percentage for black hover 1
|
|
597
645
|
WHITE_START: .5,
|
|
598
646
|
// Start opacity for white hover 1
|
|
599
|
-
WHITE_STOP
|
|
647
|
+
get WHITE_STOP() {
|
|
648
|
+
return this.BLACK_END - 10;
|
|
649
|
+
}
|
|
600
650
|
},
|
|
601
651
|
HOVER_2: {
|
|
602
652
|
BLACK_START: .4,
|
|
603
653
|
// Start opacity for black hover 2
|
|
604
|
-
BLACK_MID
|
|
654
|
+
get BLACK_MID() {
|
|
655
|
+
return .375 * this.BLACK_START;
|
|
656
|
+
},
|
|
605
657
|
// Mid opacity for black hover 2
|
|
606
658
|
BLACK_STOP: 40,
|
|
607
659
|
// Stop percentage for black hover 2
|
|
608
|
-
BLACK_END
|
|
660
|
+
get BLACK_END() {
|
|
661
|
+
return 2 * this.BLACK_STOP;
|
|
662
|
+
},
|
|
609
663
|
// End percentage for black hover 2
|
|
610
664
|
WHITE_START: 1,
|
|
611
665
|
// Start opacity for white hover 2
|
|
612
|
-
WHITE_STOP
|
|
666
|
+
get WHITE_STOP() {
|
|
667
|
+
return this.BLACK_END;
|
|
668
|
+
}
|
|
613
669
|
},
|
|
614
670
|
HOVER_3: {
|
|
615
671
|
BLACK_START: .5,
|
|
616
672
|
// Start opacity for black hover 3
|
|
617
|
-
BLACK_MID
|
|
673
|
+
get BLACK_MID() {
|
|
674
|
+
return .4 * this.BLACK_START;
|
|
675
|
+
},
|
|
618
676
|
// Mid opacity for black hover 3
|
|
619
677
|
BLACK_STOP: 50,
|
|
620
678
|
// Stop percentage for black hover 3
|
|
621
|
-
BLACK_END
|
|
679
|
+
get BLACK_END() {
|
|
680
|
+
return 2 * this.BLACK_STOP;
|
|
681
|
+
},
|
|
622
682
|
// End percentage for black hover 3
|
|
623
683
|
WHITE_START: 1,
|
|
624
684
|
// Start opacity for white hover 3
|
|
625
|
-
WHITE_STOP
|
|
685
|
+
get WHITE_STOP() {
|
|
686
|
+
return this.BLACK_END;
|
|
687
|
+
}
|
|
626
688
|
}
|
|
627
689
|
},
|
|
628
690
|
// Base and overlay gradient constants
|
|
@@ -631,34 +693,54 @@ const _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
631
693
|
// Gradient angle in degrees
|
|
632
694
|
BLACK_START_BASE: .15,
|
|
633
695
|
// Base start opacity for black
|
|
634
|
-
BLACK_START_MULTIPLIER
|
|
696
|
+
get BLACK_START_MULTIPLIER() {
|
|
697
|
+
return .02 * this.BLACK_START_BASE;
|
|
698
|
+
},
|
|
635
699
|
// Multiplier for mouse X influence on start
|
|
636
700
|
BLACK_MID_BASE: .1,
|
|
637
701
|
// Base mid opacity for black
|
|
638
|
-
BLACK_MID_MULTIPLIER
|
|
702
|
+
get BLACK_MID_MULTIPLIER() {
|
|
703
|
+
return .02 * this.BLACK_MID_BASE;
|
|
704
|
+
},
|
|
639
705
|
// Multiplier for mouse Y influence on mid
|
|
640
706
|
BLACK_MID_STOP: 50,
|
|
641
707
|
// Mid stop percentage
|
|
642
|
-
BLACK_END_BASE
|
|
708
|
+
get BLACK_END_BASE() {
|
|
709
|
+
return 1.2 * this.BLACK_START_BASE;
|
|
710
|
+
},
|
|
643
711
|
// Base end opacity for black
|
|
644
|
-
BLACK_END_MULTIPLIER
|
|
712
|
+
get BLACK_END_MULTIPLIER() {
|
|
713
|
+
return .022 * this.BLACK_END_BASE;
|
|
714
|
+
},
|
|
645
715
|
// Multiplier for mouse X influence on end
|
|
646
|
-
WHITE_OPACITY
|
|
716
|
+
get WHITE_OPACITY() {
|
|
717
|
+
return .666 * this.BLACK_START_BASE;
|
|
718
|
+
}
|
|
647
719
|
},
|
|
648
720
|
OVERLAY_GRADIENT: {
|
|
649
721
|
BLACK_START_BASE: .12,
|
|
650
722
|
// Base start opacity for black overlay
|
|
651
|
-
BLACK_START_MULTIPLIER
|
|
723
|
+
get BLACK_START_MULTIPLIER() {
|
|
724
|
+
return .025 * this.BLACK_START_BASE;
|
|
725
|
+
},
|
|
652
726
|
// Multiplier for mouse X influence on start
|
|
653
|
-
BLACK_MID
|
|
727
|
+
get BLACK_MID() {
|
|
728
|
+
return .5 * this.BLACK_START_BASE;
|
|
729
|
+
},
|
|
654
730
|
// Mid opacity for black overlay
|
|
655
731
|
BLACK_MID_STOP: 40,
|
|
656
732
|
// Mid stop percentage
|
|
657
|
-
BLACK_END_BASE
|
|
733
|
+
get BLACK_END_BASE() {
|
|
734
|
+
return 1.25 * this.BLACK_START_BASE;
|
|
735
|
+
},
|
|
658
736
|
// Base end opacity for black overlay
|
|
659
|
-
BLACK_END_MULTIPLIER
|
|
737
|
+
get BLACK_END_MULTIPLIER() {
|
|
738
|
+
return .02 * this.BLACK_END_BASE;
|
|
739
|
+
},
|
|
660
740
|
// Multiplier for mouse Y influence on end
|
|
661
|
-
WHITE_OPACITY
|
|
741
|
+
get WHITE_OPACITY() {
|
|
742
|
+
return .416 * this.BLACK_START_BASE;
|
|
743
|
+
}
|
|
662
744
|
},
|
|
663
745
|
// Overlay highlight constants
|
|
664
746
|
OVERLAY_HIGHLIGHT: {
|
|
@@ -668,9 +750,13 @@ const _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
668
750
|
// Y position percentage
|
|
669
751
|
WHITE_OPACITY: .4,
|
|
670
752
|
// White opacity in gradient
|
|
671
|
-
STOP
|
|
753
|
+
get STOP() {
|
|
754
|
+
return 150 * this.WHITE_OPACITY;
|
|
755
|
+
},
|
|
672
756
|
// Stop percentage
|
|
673
|
-
OPACITY_MULTIPLIER
|
|
757
|
+
get OPACITY_MULTIPLIER() {
|
|
758
|
+
return 1.75 * this.WHITE_OPACITY;
|
|
759
|
+
}
|
|
674
760
|
},
|
|
675
761
|
// Displacement and aberration multipliers
|
|
676
762
|
MULTIPLIERS: {
|
|
@@ -1580,11 +1666,7 @@ const ChartToolbar = memo( forwardRef((({chartType: chartType = "line", groups:
|
|
|
1580
1666
|
|
|
1581
1667
|
ChartToolbar.displayName = "ChartToolbar";
|
|
1582
1668
|
|
|
1583
|
-
const {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS,
|
|
1584
|
-
if (!pos1 || !pos2 || "number" != typeof pos1.x || "number" != typeof pos1.y || "number" != typeof pos2.x || "number" != typeof pos2.y) return 0;
|
|
1585
|
-
const deltaX = pos1.x - pos2.x, deltaY = pos1.y - pos2.y;
|
|
1586
|
-
return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
1587
|
-
}, calculateElementCenter = rect => rect ? {
|
|
1669
|
+
const {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateElementCenter = rect => rect ? {
|
|
1588
1670
|
x: rect.left + rect.width / 2,
|
|
1589
1671
|
y: rect.top + rect.height / 2
|
|
1590
1672
|
} : {
|
|
@@ -1656,7 +1738,16 @@ const {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
|
|
|
1656
1738
|
// Silently handle errors
|
|
1657
1739
|
}
|
|
1658
1740
|
return CONSTANTS$2.DEFAULT_CORNER_RADIUS;
|
|
1659
|
-
},
|
|
1741
|
+
}, smoothstep = t => {
|
|
1742
|
+
const clamped = Math.max(0, Math.min(1, t));
|
|
1743
|
+
return clamped * clamped * (3 - 2 * clamped);
|
|
1744
|
+
}, lerp$1 = (a, b, t) => a + (b - a) * t, softClamp = (value, max) => max <= 0 ? 0 : max * (1 - Math.exp(-value / max)), calculateSpring = (current, target, velocity, stiffness = .1, damping = .8) => {
|
|
1745
|
+
const newVelocity = (velocity + (target - current) * stiffness) * damping;
|
|
1746
|
+
return {
|
|
1747
|
+
value: current + newVelocity,
|
|
1748
|
+
velocity: newVelocity
|
|
1749
|
+
};
|
|
1750
|
+
}, getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
|
|
1660
1751
|
switch (mode) {
|
|
1661
1752
|
case "standard":
|
|
1662
1753
|
return displacementMap;
|
|
@@ -2047,6 +2138,9 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
2047
2138
|
}), jsx("div", {
|
|
2048
2139
|
ref: contentRef,
|
|
2049
2140
|
className: ATOMIX_GLASS.CONTENT_CLASS,
|
|
2141
|
+
style: {
|
|
2142
|
+
transform: "var(--atomix-glass-child-parallax, none)"
|
|
2143
|
+
},
|
|
2050
2144
|
children: children
|
|
2051
2145
|
}) ]
|
|
2052
2146
|
})
|
|
@@ -2081,9 +2175,21 @@ class {
|
|
|
2081
2175
|
y: this.lastEvent.clientY
|
|
2082
2176
|
},
|
|
2083
2177
|
// Notify all subscribers
|
|
2084
|
-
this.listeners.forEach((
|
|
2178
|
+
this.listeners.forEach((listener => {
|
|
2085
2179
|
try {
|
|
2086
|
-
|
|
2180
|
+
// If the listener has an element, calculate distance-based attenuation
|
|
2181
|
+
if (listener.element) {
|
|
2182
|
+
const elementRect = listener.element.getBoundingClientRect(), elementCenter = {
|
|
2183
|
+
x: elementRect.left + elementRect.width / 2,
|
|
2184
|
+
y: elementRect.top + elementRect.height / 2
|
|
2185
|
+
}, distance = this.calculateDistance(this.position, elementCenter), maxDistance = listener.maxDistance || 300, attenuation = Math.max(0, 1 - distance / maxDistance), attenuatedRelativePosition = {
|
|
2186
|
+
x: (this.position.x - elementCenter.x) / elementRect.width * 100 * attenuation,
|
|
2187
|
+
y: (this.position.y - elementCenter.y) / elementRect.height * 100 * attenuation
|
|
2188
|
+
};
|
|
2189
|
+
listener.callback(attenuatedRelativePosition);
|
|
2190
|
+
} else
|
|
2191
|
+
// Send original position for listeners without distance-based attenuation
|
|
2192
|
+
listener.callback(this.position);
|
|
2087
2193
|
} catch (error) {
|
|
2088
2194
|
console.error("GlobalMouseTracker: Error in subscriber callback", error);
|
|
2089
2195
|
}
|
|
@@ -2094,10 +2200,17 @@ class {
|
|
|
2094
2200
|
/**
|
|
2095
2201
|
* Subscribe to mouse position updates
|
|
2096
2202
|
* @param callback Function to call when mouse position changes
|
|
2203
|
+
* @param element Optional element for distance-based attenuation
|
|
2204
|
+
* @param maxDistance Optional maximum distance for full effect
|
|
2097
2205
|
* @returns Unsubscribe function
|
|
2098
|
-
*/ subscribe(callback) {
|
|
2206
|
+
*/ subscribe(callback, element, maxDistance) {
|
|
2207
|
+
const listener = {
|
|
2208
|
+
callback: callback,
|
|
2209
|
+
element: element,
|
|
2210
|
+
maxDistance: maxDistance
|
|
2211
|
+
};
|
|
2099
2212
|
// Return unsubscribe function
|
|
2100
|
-
return this.listeners.add(
|
|
2213
|
+
return this.listeners.add(listener),
|
|
2101
2214
|
// Start tracking if this is the first subscriber
|
|
2102
2215
|
1 === this.listeners.size && this.startTracking(),
|
|
2103
2216
|
// Immediately notify with current position
|
|
@@ -2108,9 +2221,13 @@ class {
|
|
|
2108
2221
|
/**
|
|
2109
2222
|
* Unsubscribe from mouse position updates
|
|
2110
2223
|
*/ unsubscribe(callback) {
|
|
2111
|
-
|
|
2224
|
+
// Find and remove the listener with the given callback
|
|
2225
|
+
for (const listener of this.listeners) if (listener.callback === callback) {
|
|
2226
|
+
this.listeners.delete(listener);
|
|
2227
|
+
break;
|
|
2228
|
+
}
|
|
2112
2229
|
// Stop tracking if no more subscribers
|
|
2113
|
-
|
|
2230
|
+
0 === this.listeners.size && this.stopTracking();
|
|
2114
2231
|
}
|
|
2115
2232
|
/**
|
|
2116
2233
|
* Start tracking mouse movement
|
|
@@ -2129,6 +2246,12 @@ class {
|
|
|
2129
2246
|
null !== this.rafId && (cancelAnimationFrame(this.rafId), this.rafId = null), this.lastEvent = null);
|
|
2130
2247
|
}
|
|
2131
2248
|
/**
|
|
2249
|
+
* Calculate distance between two points
|
|
2250
|
+
*/ calculateDistance(point1, point2) {
|
|
2251
|
+
const dx = point1.x - point2.x, dy = point1.y - point2.y;
|
|
2252
|
+
return Math.sqrt(dx * dx + dy * dy);
|
|
2253
|
+
}
|
|
2254
|
+
/**
|
|
2132
2255
|
* Get current mouse position (synchronous)
|
|
2133
2256
|
*/ getPosition() {
|
|
2134
2257
|
return {
|
|
@@ -2142,51 +2265,26 @@ class {
|
|
|
2142
2265
|
}
|
|
2143
2266
|
}, updateAtomixGlassStyles = (wrapperElement, containerElement, params) => {
|
|
2144
2267
|
if (!wrapperElement && !containerElement) return;
|
|
2145
|
-
|
|
2268
|
+
if (!validateGlassSize(params.glassSize)) return;
|
|
2269
|
+
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, padding: padding = ATOMIX_GLASS.DEFAULTS.PADDING, isFixedOrSticky: isFixedOrSticky = !1} = params, mouseInfluence = calculateMouseInfluence(mouseOffset), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1, overLightConfig = {
|
|
2146
2270
|
opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
|
|
2147
2271
|
contrast: Math.min(1.6, baseOverLightConfig.contrast + .1 * mouseInfluence),
|
|
2148
2272
|
brightness: Math.min(1.1, baseOverLightConfig.brightness + .05 * mouseInfluence),
|
|
2149
2273
|
shadowIntensity: Math.min(1.2, Math.max(.5, baseOverLightConfig.shadowIntensity + .2 * mouseInfluence)),
|
|
2150
2274
|
borderOpacity: Math.min(1, Math.max(.3, baseOverLightConfig.borderOpacity + .1 * mouseInfluence)),
|
|
2151
2275
|
saturationBoost: baseOverLightConfig.saturationBoost
|
|
2152
|
-
}
|
|
2153
|
-
|
|
2154
|
-
|
|
2276
|
+
}, scaleX = directionalScale.x * scaleBase, scaleY = directionalScale.y * scaleBase, transformStyle = effectiveWithoutEffects ? `scale(${scaleBase})` : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) scaleX(${scaleX}) scaleY(${scaleY})`, stretchMagnitude = ((pos1, pos2) => {
|
|
2277
|
+
if (!pos1 || !pos2 || "number" != typeof pos1.x || "number" != typeof pos1.y || "number" != typeof pos2.x || "number" != typeof pos2.y) return 0;
|
|
2278
|
+
const deltaX = pos1.x - pos2.x, deltaY = pos1.y - pos2.y;
|
|
2279
|
+
return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
2280
|
+
})({
|
|
2155
2281
|
x: 0,
|
|
2156
2282
|
y: 0
|
|
2157
|
-
};
|
|
2158
|
-
// Calculate
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
if (globalMousePosition.x && globalMousePosition.y && validateGlassSize(glassSize)) {
|
|
2163
|
-
const deltaX = globalMousePosition.x - center.x, deltaY = globalMousePosition.y - center.y, edgeDistanceX = Math.max(0, Math.abs(deltaX) - glassSize.width / 2), edgeDistanceY = Math.max(0, Math.abs(deltaY) - glassSize.height / 2), edgeDistance = calculateDistance({
|
|
2164
|
-
x: edgeDistanceX,
|
|
2165
|
-
y: edgeDistanceY
|
|
2166
|
-
}, {
|
|
2167
|
-
x: 0,
|
|
2168
|
-
y: 0
|
|
2169
|
-
}), rawT = edgeDistance > ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE, fadeInFactor = (t => {
|
|
2170
|
-
const clamped = Math.max(0, Math.min(1, t));
|
|
2171
|
-
return clamped * clamped * (3 - 2 * clamped);
|
|
2172
|
-
})(rawT);
|
|
2173
|
-
// Directional scale
|
|
2174
|
-
if (elasticTranslation = {
|
|
2175
|
-
x: deltaX * elasticity * .1 * fadeInFactor,
|
|
2176
|
-
y: deltaY * elasticity * .1 * fadeInFactor
|
|
2177
|
-
}, !isOverLight && edgeDistance <= ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE) {
|
|
2178
|
-
const centerDistance = calculateDistance(globalMousePosition, center);
|
|
2179
|
-
if (centerDistance > 0) {
|
|
2180
|
-
const normalizedX = deltaX / centerDistance, normalizedY = deltaY / centerDistance, stretchIntensity = Math.min(centerDistance / 300, 1) * elasticity * rawT, scaleX = 1 + Math.abs(normalizedX) * stretchIntensity * .3 - Math.abs(normalizedY) * stretchIntensity * .15, scaleY = 1 + Math.abs(normalizedY) * stretchIntensity * .3 - Math.abs(normalizedX) * stretchIntensity * .15, softScaleX = 1 - softClamp(Math.max(0, 1 - scaleX), .2), softScaleY = 1 - softClamp(Math.max(0, 1 - scaleY), .2);
|
|
2181
|
-
computedDirectionalScale = `scaleX(${Math.max(.85, softScaleX)}) scaleY(${Math.max(.85, softScaleY)})`;
|
|
2182
|
-
}
|
|
2183
|
-
}
|
|
2184
|
-
}
|
|
2185
|
-
}
|
|
2186
|
-
const transformStyle = effectiveWithoutEffects ? isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)" : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) ${isActive && Boolean(onClick) ? "scale(0.96)" : computedDirectionalScale}`;
|
|
2187
|
-
// Update Wrapper Styles (glassVars)
|
|
2188
|
-
if (wrapperElement) {
|
|
2189
|
-
const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT, borderGradientAngle = GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER, borderStop1 = Math.max(GRADIENT.BORDER_STOP_1.MIN, GRADIENT.BORDER_STOP_1.BASE + my * GRADIENT.BORDER_STOP_1.MULTIPLIER), borderStop2 = Math.min(GRADIENT.BORDER_STOP_2.MAX, GRADIENT.BORDER_STOP_2.BASE + my * GRADIENT.BORDER_STOP_2.MULTIPLIER), borderOpacities = [ GRADIENT.BORDER_OPACITY.BASE_1 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW, GRADIENT.BORDER_OPACITY.BASE_2 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH, GRADIENT.BORDER_OPACITY.BASE_3 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW, GRADIENT.BORDER_OPACITY.BASE_4 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH ], configBorderOpacity = overLightConfig.borderOpacity, whiteColor = ATOMIX_GLASS.CONSTANTS.PALETTE.WHITE, blackColor = ATOMIX_GLASS.CONSTANTS.PALETTE.BLACK, hoverPositions = {
|
|
2283
|
+
}, elasticTranslation), tensionFactor = smoothstep(stretchMagnitude / 80), lightingContrast = Math.min(1.8, overLightConfig.contrast + .2 * tensionFactor), lightingBrightness = Math.min(1.2, overLightConfig.brightness + .1 * tensionFactor);
|
|
2284
|
+
// Calculate mouse influence
|
|
2285
|
+
// Update Wrapper Styles (glassVars)
|
|
2286
|
+
if (wrapperElement) {
|
|
2287
|
+
const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT, velocityRotation = (mouseVelocity.x + elasticVelocity.x) * (GRADIENT.VELOCITY_ANGLE_MULTIPLIER || 2.5), borderGradientAngle = GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER + velocityRotation, chromaticOffset = GRADIENT.CHROMATIC_OFFSET || 1.5, angleR = borderGradientAngle - chromaticOffset, angleB = borderGradientAngle + chromaticOffset, borderStop1 = Math.max(GRADIENT.BORDER_STOP_1.MIN, GRADIENT.BORDER_STOP_1.BASE + my * GRADIENT.BORDER_STOP_1.MULTIPLIER), borderStop2 = Math.min(GRADIENT.BORDER_STOP_2.MAX, GRADIENT.BORDER_STOP_2.BASE + my * GRADIENT.BORDER_STOP_2.MULTIPLIER), tensionGlow = 1 + .5 * tensionFactor, borderOpacities = [ (GRADIENT.BORDER_OPACITY.BASE_1 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW) * tensionGlow, (GRADIENT.BORDER_OPACITY.BASE_2 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH) * tensionGlow, (GRADIENT.BORDER_OPACITY.BASE_3 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW) * tensionGlow, (GRADIENT.BORDER_OPACITY.BASE_4 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH) * tensionGlow ], configBorderOpacity = overLightConfig.borderOpacity, whiteColor = ATOMIX_GLASS.CONSTANTS.PALETTE.WHITE, blackColor = ATOMIX_GLASS.CONSTANTS.PALETTE.BLACK, hoverPositions = {
|
|
2190
2288
|
hover1: {
|
|
2191
2289
|
x: GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_1,
|
|
2192
2290
|
y: GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_1
|
|
@@ -2209,10 +2307,16 @@ class {
|
|
|
2209
2307
|
base: isOverLight ? overLightConfig.opacity : 0,
|
|
2210
2308
|
over: isOverLight ? 1.1 * overLightConfig.opacity : 0
|
|
2211
2309
|
}, style = wrapperElement.style;
|
|
2212
|
-
style.setProperty("--atomix-glass-transform", transformStyle || "none")
|
|
2213
|
-
//
|
|
2214
|
-
|
|
2215
|
-
style.setProperty("--atomix-glass-
|
|
2310
|
+
style.setProperty("--atomix-glass-transform", transformStyle || "none");
|
|
2311
|
+
// Parallax for content (liquid refraction feel)
|
|
2312
|
+
const parallaxFactor = .38 + .12 * tensionFactor;
|
|
2313
|
+
style.setProperty("--atomix-glass-child-parallax", `translate(${elasticTranslation.x * -parallaxFactor}px, ${elasticTranslation.y * -parallaxFactor}px)`),
|
|
2314
|
+
style.setProperty("--atomix-glass-contrast", lightingContrast.toString()), style.setProperty("--atomix-glass-brightness", lightingBrightness.toString()),
|
|
2315
|
+
// ── Chromatic Rim Lighting ──────────────────────────────────────
|
|
2316
|
+
// Layer 1: Core White/Blue highlight
|
|
2317
|
+
style.setProperty("--atomix-glass-border-gradient-1", `linear-gradient(${angleB}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[0] ?? 1) * configBorderOpacity}) ${borderStop1}%, rgba(${whiteColor}, ${(borderOpacities[1] ?? 1) * configBorderOpacity}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`),
|
|
2318
|
+
// Layer 2: Subtle Red/Warm highlight (offset angle)
|
|
2319
|
+
style.setProperty("--atomix-glass-border-gradient-2", `linear-gradient(${angleR}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[2] ?? 1) * configBorderOpacity}) ${borderStop1}%, rgba(${whiteColor}, ${(borderOpacities[3] ?? 1) * configBorderOpacity}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`),
|
|
2216
2320
|
// Hover gradients
|
|
2217
2321
|
style.setProperty("--atomix-glass-hover-1-gradient", isOverLight ? `radial-gradient(circle at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_START}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_STOP}%, rgba(${blackColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_END}%)` : `radial-gradient(circle at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_STOP}%)`),
|
|
2218
2322
|
style.setProperty("--atomix-glass-hover-2-gradient", isOverLight ? `radial-gradient(circle at ${hoverPositions.hover2.x}% ${hoverPositions.hover2.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_START}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_STOP}%, rgba(${blackColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_END}%)` : `radial-gradient(circle at ${hoverPositions.hover2.x}% ${hoverPositions.hover2.y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_STOP}%)`),
|
|
@@ -2240,7 +2344,7 @@ class {
|
|
|
2240
2344
|
flowBlur: blurAmount * FLOW_BLUR_MULTIPLIER
|
|
2241
2345
|
};
|
|
2242
2346
|
if (withLiquidBlur && rect) {
|
|
2243
|
-
const mouseInfluence = calculateMouseInfluence(mouseOffset), maxBlur = blurAmount * MAX_BLUR_RELATIVE, baseBlur =
|
|
2347
|
+
const mouseInfluence = calculateMouseInfluence(mouseOffset), maxBlur = blurAmount * MAX_BLUR_RELATIVE, baseBlur = softClamp(blurAmount + mouseInfluence * blurAmount * MOUSE_INFLUENCE_BLUR_FACTOR, maxBlur), edgeBlur = softClamp(baseBlur * (.8 + mouseInfluence * EDGE_INTENSITY_MOUSE_FACTOR * .4), maxBlur), centerBlur = softClamp(baseBlur * (.3 + mouseInfluence * CENTER_INTENSITY_MOUSE_FACTOR * .3), maxBlur), flowBlur = softClamp(baseBlur * FLOW_BLUR_MULTIPLIER, maxBlur);
|
|
2244
2348
|
liquidBlur = {
|
|
2245
2349
|
baseBlur: clampBlur(baseBlur),
|
|
2246
2350
|
edgeBlur: clampBlur(edgeBlur),
|
|
@@ -2249,9 +2353,10 @@ class {
|
|
|
2249
2353
|
};
|
|
2250
2354
|
}
|
|
2251
2355
|
// Backdrop filter
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2356
|
+
const dynamicSaturation = saturation + 40 * tensionFactor + 15 * (liquidBlur.baseBlur || 0);
|
|
2357
|
+
let backdropFilterString = "";
|
|
2358
|
+
const area = rect ? rect.width * rect.height : 0;
|
|
2359
|
+
backdropFilterString = !withLiquidBlur || effectiveReducedMotion || effectiveWithoutEffects || area > 18e4 ? `blur(${clampBlur(Math.max(liquidBlur.baseBlur, .8 * liquidBlur.edgeBlur, 1.1 * liquidBlur.centerBlur, .9 * liquidBlur.flowBlur))}px) saturate(${Math.min(dynamicSaturation, 250)}%) contrast(${lightingContrast}) brightness(${lightingBrightness})` : `blur(${clampBlur(.4 * liquidBlur.baseBlur + .25 * liquidBlur.edgeBlur + .15 * liquidBlur.centerBlur + .2 * liquidBlur.flowBlur)}px) saturate(${Math.min(dynamicSaturation, 250)}%) contrast(${lightingContrast}) brightness(${lightingBrightness})`;
|
|
2255
2360
|
// Container variables
|
|
2256
2361
|
const style = containerElement.style;
|
|
2257
2362
|
style.setProperty("--atomix-glass-container-padding", padding), style.setProperty("--atomix-glass-container-radius", `${effectiveBorderRadius}px`),
|
|
@@ -2413,7 +2518,8 @@ const {CONSTANTS: CONSTANTS} = ATOMIX_GLASS, backgroundDetectionCache = new Weak
|
|
|
2413
2518
|
* Composable hook for AtomixGlass component logic
|
|
2414
2519
|
* Manages all state, calculations, and event handlers
|
|
2415
2520
|
*/
|
|
2416
|
-
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, elasticity: elasticity = .
|
|
2521
|
+
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, elasticity: elasticity = ATOMIX_GLASS.DEFAULTS.ELASTICITY, onClick: onClick, debugBorderRadius: debugBorderRadius = !1, debugOverLight: debugOverLight = !1, children: children, blurAmount: blurAmount, saturation: saturation, padding: padding, withLiquidBlur: withLiquidBlur, isFixedOrSticky: isFixedOrSticky = !1, priority: priority = 1, withTimeAnimation:
|
|
2522
|
+
// Default priority
|
|
2417
2523
|
// Phase 1: Animation System Props
|
|
2418
2524
|
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}) {
|
|
2419
2525
|
// State
|
|
@@ -2429,7 +2535,24 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2429
2535
|
}), targetGlobalMousePositionRef = useRef({
|
|
2430
2536
|
x: 0,
|
|
2431
2537
|
y: 0
|
|
2432
|
-
}), lerpRafRef = useRef(null), lerpActiveRef = useRef(!1), [dynamicBorderRadius, setDynamicCornerRadius] = useState(CONSTANTS.DEFAULT_CORNER_RADIUS),
|
|
2538
|
+
}), lerpRafRef = useRef(null), lerpActiveRef = useRef(!1), [dynamicBorderRadius, setDynamicCornerRadius] = useState(CONSTANTS.DEFAULT_CORNER_RADIUS), elasticTranslationRef = useRef({
|
|
2539
|
+
x: 0,
|
|
2540
|
+
y: 0
|
|
2541
|
+
}), elasticVelocityRef = useRef({
|
|
2542
|
+
x: 0,
|
|
2543
|
+
y: 0
|
|
2544
|
+
}), directionalScaleRef = useRef({
|
|
2545
|
+
x: 1,
|
|
2546
|
+
y: 1
|
|
2547
|
+
}), scaleVelocityRef = useRef({
|
|
2548
|
+
x: 0,
|
|
2549
|
+
y: 0
|
|
2550
|
+
});
|
|
2551
|
+
useRef(0);
|
|
2552
|
+
const mouseVelocityRef = useRef({
|
|
2553
|
+
x: 0,
|
|
2554
|
+
y: 0
|
|
2555
|
+
}), [userPrefersReducedMotion, setUserPrefersReducedMotion] = useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = useState(!1), [detectedOverLight, setDetectedOverLight] = useState(!1), animationFrameIdRef = useRef(null), animationStartTimeRef = useRef(0), elapsedTimeRef = useRef(0), shaderTimeRef = useRef(0), fbmConfig = useMemo((() => {
|
|
2433
2556
|
// If quality preset is provided, use it as base
|
|
2434
2557
|
const preset = (quality = distortionQuality, ATOMIX_GLASS.CONSTANTS.DISTORTION_QUALITY_PRESETS[quality]);
|
|
2435
2558
|
// Override with custom values if provided
|
|
@@ -2714,57 +2837,85 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2714
2837
|
return "undefined" == typeof process || process.env, finalConfig;
|
|
2715
2838
|
}
|
|
2716
2839
|
return "undefined" == typeof process || process.env, baseConfig;
|
|
2717
|
-
}), [ overLight, getEffectiveOverLight, isHovered, isActive, validateConfigValue, debugOverLight ]), transformStyle = useMemo((() => effectiveWithoutEffects || isActive && Boolean(onClick) ? "scale(0.
|
|
2840
|
+
}), [ overLight, getEffectiveOverLight, isHovered, isActive, validateConfigValue, debugOverLight ]), transformStyle = useMemo((() => effectiveWithoutEffects || isActive && Boolean(onClick) ? "scale(0.99)" : "scale(1)"), [ effectiveWithoutEffects, isActive, onClick ]), updateRectRef = useRef(null), stopLerpLoop = useCallback((() => {
|
|
2718
2841
|
lerpActiveRef.current = !1, null !== lerpRafRef.current && (cancelAnimationFrame(lerpRafRef.current),
|
|
2719
2842
|
lerpRafRef.current = null);
|
|
2720
2843
|
}), []), startLerpLoop = useCallback((() => {
|
|
2721
2844
|
if (lerpActiveRef.current) return;
|
|
2722
|
-
lerpActiveRef.current = !0;
|
|
2723
|
-
|
|
2845
|
+
lerpActiveRef.current = !0, CONSTANTS.LERP_FACTOR;
|
|
2846
|
+
// 0.08 – lower = more viscous
|
|
2847
|
+
const tick = () => {
|
|
2724
2848
|
if (!lerpActiveRef.current) return;
|
|
2725
2849
|
if (!glassRef.current) return void (lerpActiveRef.current = !1);
|
|
2726
|
-
const cur = internalMouseOffsetRef.current, tgt = targetMouseOffsetRef.current,
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
},
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
// Final update and stop
|
|
2734
|
-
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
2735
|
-
mouseOffset: internalMouseOffsetRef.current,
|
|
2736
|
-
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
2737
|
-
glassSize: glassSize,
|
|
2738
|
-
isHovered: isHovered,
|
|
2739
|
-
isActive: isActive,
|
|
2740
|
-
isOverLight: overLightConfig.isOverLight,
|
|
2741
|
-
baseOverLightConfig: overLightConfig,
|
|
2742
|
-
effectiveBorderRadius: effectiveBorderRadius,
|
|
2743
|
-
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
2744
|
-
effectiveReducedMotion: effectiveReducedMotion,
|
|
2745
|
-
elasticity: elasticity,
|
|
2746
|
-
directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
|
|
2747
|
-
onClick: onClick,
|
|
2748
|
-
withLiquidBlur: withLiquidBlur,
|
|
2749
|
-
blurAmount: blurAmount,
|
|
2750
|
-
saturation: saturation,
|
|
2751
|
-
padding: padding,
|
|
2752
|
-
isFixedOrSticky: isFixedOrSticky
|
|
2753
|
-
}), void stopLerpLoop();
|
|
2754
|
-
// Smooth step
|
|
2755
|
-
internalMouseOffsetRef.current = {
|
|
2756
|
-
x: lerp$1(cur.x, tgt.x, LERP_T),
|
|
2757
|
-
y: lerp$1(cur.y, tgt.y, LERP_T)
|
|
2850
|
+
const cur = internalMouseOffsetRef.current, tgt = targetMouseOffsetRef.current, springX = calculateSpring(cur.x, tgt.x, mouseVelocityRef.current.x, CONSTANTS.LERP_FACTOR, CONSTANTS.ELASTICITY_DAMPING), springY = calculateSpring(cur.y, tgt.y, mouseVelocityRef.current.y, CONSTANTS.LERP_FACTOR, CONSTANTS.ELASTICITY_DAMPING);
|
|
2851
|
+
internalMouseOffsetRef.current = {
|
|
2852
|
+
x: springX.value,
|
|
2853
|
+
y: springY.value
|
|
2854
|
+
}, mouseVelocityRef.current = {
|
|
2855
|
+
x: springX.velocity,
|
|
2856
|
+
y: springY.velocity
|
|
2758
2857
|
};
|
|
2759
2858
|
const curG = internalGlobalMousePositionRef.current, tgtG = targetGlobalMousePositionRef.current;
|
|
2760
2859
|
internalGlobalMousePositionRef.current = {
|
|
2761
|
-
x: lerp$1(curG.x, tgtG.x,
|
|
2762
|
-
y: lerp$1(curG.y, tgtG.y,
|
|
2860
|
+
x: lerp$1(curG.x, tgtG.x, CONSTANTS.LERP_FACTOR),
|
|
2861
|
+
y: lerp$1(curG.y, tgtG.y, CONSTANTS.LERP_FACTOR)
|
|
2862
|
+
};
|
|
2863
|
+
// ── Calculate Elastic Physics ─────────────────────────────────────
|
|
2864
|
+
let targetElasticTranslation = {
|
|
2865
|
+
x: 0,
|
|
2866
|
+
y: 0
|
|
2867
|
+
}, targetScale = {
|
|
2868
|
+
x: 1,
|
|
2869
|
+
y: 1
|
|
2870
|
+
};
|
|
2871
|
+
if (!effectiveWithoutEffects && glassRef.current) {
|
|
2872
|
+
const rect = cachedRectRef.current || glassRef.current.getBoundingClientRect(), center = calculateElementCenter(rect), globalPos = internalGlobalMousePositionRef.current;
|
|
2873
|
+
if (globalPos.x && globalPos.y) {
|
|
2874
|
+
const deltaX = globalPos.x - center.x, deltaY = globalPos.y - center.y, edgeDistanceX = Math.max(0, Math.abs(deltaX) - rect.width / 2), edgeDistanceY = Math.max(0, Math.abs(deltaY) - rect.height / 2), edgeDistance = Math.sqrt(edgeDistanceX * edgeDistanceX + edgeDistanceY * edgeDistanceY), activationZone = CONSTANTS.ACTIVATION_ZONE, rawT = edgeDistance > activationZone ? 0 : 1 - edgeDistance / activationZone, fadeInFactor = smoothstep(rawT);
|
|
2875
|
+
// Scale stretch logic (liquid surface tension)
|
|
2876
|
+
if (targetElasticTranslation = {
|
|
2877
|
+
x: deltaX * elasticity * CONSTANTS.ELASTICITY_TRANSLATION_FACTOR * fadeInFactor,
|
|
2878
|
+
y: deltaY * elasticity * CONSTANTS.ELASTICITY_TRANSLATION_FACTOR * fadeInFactor
|
|
2879
|
+
}, edgeDistance <= activationZone) {
|
|
2880
|
+
const centerDistance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
2881
|
+
if (centerDistance > 0) {
|
|
2882
|
+
const nx = deltaX / centerDistance, ny = deltaY / centerDistance, stretchIntensity = Math.min(centerDistance / 350, 1) * elasticity * rawT, mag = 1 + .06 * stretchIntensity;
|
|
2883
|
+
targetScale = {
|
|
2884
|
+
x: mag + Math.abs(nx) * stretchIntensity * CONSTANTS.ELASTICITY_STRETCH_RATIO,
|
|
2885
|
+
y: mag + Math.abs(ny) * stretchIntensity * CONSTANTS.ELASTICITY_STRETCH_RATIO
|
|
2886
|
+
},
|
|
2887
|
+
// Maintain liquid volume by compressing the perpendicular axis
|
|
2888
|
+
targetScale.x -= Math.abs(ny) * stretchIntensity * .15, targetScale.y -= Math.abs(nx) * stretchIntensity * .15;
|
|
2889
|
+
}
|
|
2890
|
+
}
|
|
2891
|
+
}
|
|
2892
|
+
}
|
|
2893
|
+
// Integrate Elastic Translation Spring
|
|
2894
|
+
const springTX = calculateSpring(elasticTranslationRef.current.x, targetElasticTranslation.x, elasticVelocityRef.current.x, CONSTANTS.ELASTICITY_STIFFNESS, CONSTANTS.ELASTICITY_DAMPING), springTY = calculateSpring(elasticTranslationRef.current.y, targetElasticTranslation.y, elasticVelocityRef.current.y, CONSTANTS.ELASTICITY_STIFFNESS, CONSTANTS.ELASTICITY_DAMPING);
|
|
2895
|
+
elasticTranslationRef.current = {
|
|
2896
|
+
x: springTX.value,
|
|
2897
|
+
y: springTY.value
|
|
2898
|
+
}, elasticVelocityRef.current = {
|
|
2899
|
+
x: springTX.velocity,
|
|
2900
|
+
y: springTY.velocity
|
|
2901
|
+
};
|
|
2902
|
+
// Integrate Scale Spring
|
|
2903
|
+
const springSX = calculateSpring(directionalScaleRef.current.x, targetScale.x, scaleVelocityRef.current.x, CONSTANTS.ELASTICITY_STIFFNESS, CONSTANTS.ELASTICITY_DAMPING), springSY = calculateSpring(directionalScaleRef.current.y, targetScale.y, scaleVelocityRef.current.y, CONSTANTS.ELASTICITY_STIFFNESS, CONSTANTS.ELASTICITY_DAMPING);
|
|
2904
|
+
directionalScaleRef.current = {
|
|
2905
|
+
x: springSX.value,
|
|
2906
|
+
y: springSY.value
|
|
2907
|
+
}, scaleVelocityRef.current = {
|
|
2908
|
+
x: springSX.velocity,
|
|
2909
|
+
y: springSY.velocity
|
|
2763
2910
|
},
|
|
2764
2911
|
// Imperative style update
|
|
2765
2912
|
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
2766
2913
|
mouseOffset: internalMouseOffsetRef.current,
|
|
2767
2914
|
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
2915
|
+
elasticTranslation: elasticTranslationRef.current,
|
|
2916
|
+
elasticVelocity: elasticVelocityRef.current,
|
|
2917
|
+
mouseVelocity: mouseVelocityRef.current,
|
|
2918
|
+
directionalScale: directionalScaleRef.current,
|
|
2768
2919
|
glassSize: glassSize,
|
|
2769
2920
|
isHovered: isHovered,
|
|
2770
2921
|
isActive: isActive,
|
|
@@ -2774,17 +2925,16 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2774
2925
|
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
2775
2926
|
effectiveReducedMotion: effectiveReducedMotion,
|
|
2776
2927
|
elasticity: elasticity,
|
|
2777
|
-
|
|
2928
|
+
scaleBase: isActive && Boolean(onClick) ? .99 : 1,
|
|
2778
2929
|
onClick: onClick,
|
|
2779
2930
|
withLiquidBlur: withLiquidBlur,
|
|
2780
2931
|
blurAmount: blurAmount,
|
|
2781
2932
|
saturation: saturation,
|
|
2782
2933
|
padding: padding,
|
|
2783
2934
|
isFixedOrSticky: isFixedOrSticky
|
|
2784
|
-
}), lerpRafRef.current = requestAnimationFrame(tick);
|
|
2935
|
+
}), Math.abs(mouseVelocityRef.current.x) < .001 && Math.abs(mouseVelocityRef.current.y) < .001 && Math.abs(elasticVelocityRef.current.x) < .001 && Math.abs(elasticVelocityRef.current.y) < .001 && Math.abs(scaleVelocityRef.current.x) < .001 && Math.abs(scaleVelocityRef.current.y) < .001 && Math.abs(internalMouseOffsetRef.current.x - targetMouseOffsetRef.current.x) < .001 && Math.abs(internalMouseOffsetRef.current.y - targetMouseOffsetRef.current.y) < .001 ? stopLerpLoop() : lerpRafRef.current = requestAnimationFrame(tick);
|
|
2785
2936
|
};
|
|
2786
|
-
|
|
2787
|
-
lerpRafRef.current = requestAnimationFrame(tick);
|
|
2937
|
+
lerpRafRef.current = requestAnimationFrame(tick);
|
|
2788
2938
|
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding, isFixedOrSticky, stopLerpLoop ]), handleGlobalMousePosition = useCallback((globalPos => {
|
|
2789
2939
|
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
2790
2940
|
if (effectiveWithoutEffects) return;
|
|
@@ -2810,7 +2960,8 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2810
2960
|
useEffect((() => {
|
|
2811
2961
|
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
2812
2962
|
if (effectiveWithoutEffects) return;
|
|
2813
|
-
const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition);
|
|
2963
|
+
const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition, glassRef.current || void 0, 300);
|
|
2964
|
+
// 300px max distance for full effect
|
|
2814
2965
|
// Initial start
|
|
2815
2966
|
startLerpLoop();
|
|
2816
2967
|
const container = mouseContainer?.current || glassRef.current;
|
|
@@ -2830,6 +2981,11 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2830
2981
|
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
2831
2982
|
mouseOffset: externalMouseOffset || internalMouseOffsetRef.current,
|
|
2832
2983
|
globalMousePosition: externalGlobalMousePosition || internalGlobalMousePositionRef.current,
|
|
2984
|
+
elasticTranslation: elasticTranslationRef.current,
|
|
2985
|
+
elasticVelocity: elasticVelocityRef.current,
|
|
2986
|
+
mouseVelocity: mouseVelocityRef.current,
|
|
2987
|
+
directionalScale: directionalScaleRef.current,
|
|
2988
|
+
scaleBase: isActive && Boolean(onClick) ? .96 : 1,
|
|
2833
2989
|
glassSize: glassSize,
|
|
2834
2990
|
isHovered: isHovered,
|
|
2835
2991
|
isActive: isActive,
|
|
@@ -2839,7 +2995,6 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2839
2995
|
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
2840
2996
|
effectiveReducedMotion: effectiveReducedMotion,
|
|
2841
2997
|
elasticity: elasticity,
|
|
2842
|
-
directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
|
|
2843
2998
|
onClick: onClick,
|
|
2844
2999
|
withLiquidBlur: withLiquidBlur,
|
|
2845
3000
|
blurAmount: blurAmount,
|
|
@@ -3823,7 +3978,7 @@ const PERFORMANCE_PRESET = {
|
|
|
3823
3978
|
"aria-label": ariaLabel,
|
|
3824
3979
|
"aria-describedby": ariaDescribedBy,
|
|
3825
3980
|
"aria-disabled": !(!onClick || !effectiveWithoutEffects) || !onClick && void 0,
|
|
3826
|
-
"aria-pressed": void 0,
|
|
3981
|
+
"aria-pressed": onClick ? isActive : void 0,
|
|
3827
3982
|
onKeyDown: onClick ? handleKeyDown : void 0,
|
|
3828
3983
|
children: [ jsx(AtomixGlassContainer, {
|
|
3829
3984
|
ref: glassRef,
|