@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/core.js
CHANGED
|
@@ -556,12 +556,23 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
556
556
|
},
|
|
557
557
|
DEFAULTS: {
|
|
558
558
|
DISPLACEMENT_SCALE: 70,
|
|
559
|
-
BLUR_AMOUNT
|
|
560
|
-
|
|
561
|
-
|
|
559
|
+
get BLUR_AMOUNT() {
|
|
560
|
+
return .15 * this.DISPLACEMENT_SCALE;
|
|
561
|
+
// Dynamically computed based on displacement
|
|
562
|
+
},
|
|
563
|
+
get SATURATION() {
|
|
564
|
+
return 100 + .5 * this.DISPLACEMENT_SCALE;
|
|
565
|
+
// Saturate relative to intensity
|
|
566
|
+
},
|
|
567
|
+
get ABERRATION_INTENSITY() {
|
|
568
|
+
return .03 * this.DISPLACEMENT_SCALE;
|
|
569
|
+
// Scale aberration with displacement
|
|
570
|
+
},
|
|
562
571
|
ELASTICITY: .15,
|
|
563
|
-
CORNER_RADIUS
|
|
564
|
-
|
|
572
|
+
get CORNER_RADIUS() {
|
|
573
|
+
return 16;
|
|
574
|
+
// Use 16 to match SCSS design system (was 20)
|
|
575
|
+
},
|
|
565
576
|
PADDING: "0",
|
|
566
577
|
MODE: "standard",
|
|
567
578
|
OVER_LIGHT: !1,
|
|
@@ -583,6 +594,15 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
583
594
|
MIN_BLUR: .1,
|
|
584
595
|
MOUSE_INFLUENCE_DIVISOR: 100,
|
|
585
596
|
EDGE_FADE_PIXELS: 2,
|
|
597
|
+
// Elasticity physics constants
|
|
598
|
+
ELASTICITY_TRANSLATION_FACTOR: .1,
|
|
599
|
+
ELASTICITY_DISTANCE_THRESHOLD: 200,
|
|
600
|
+
ELASTICITY_COMPRESSION_FACTOR: .3,
|
|
601
|
+
ELASTICITY_STIFFNESS: .1,
|
|
602
|
+
ELASTICITY_DAMPING: .76,
|
|
603
|
+
ELASTICITY_VELOCITY_FACTOR: .65,
|
|
604
|
+
ELASTICITY_STRETCH_RATIO: .45,
|
|
605
|
+
ELASTICITY_MAGNIFICATION_BASE: 1.02,
|
|
586
606
|
// Note: This default must match the SCSS variable --atomix-radius-md
|
|
587
607
|
// @see src/styles/01-settings/_settings.global.scss
|
|
588
608
|
DEFAULT_CORNER_RADIUS: 16,
|
|
@@ -599,84 +619,126 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
599
619
|
// Base angle for border gradients (degrees)
|
|
600
620
|
ANGLE_MULTIPLIER: 1.2,
|
|
601
621
|
// Multiplier for mouse influence on angle
|
|
622
|
+
VELOCITY_ANGLE_MULTIPLIER: 2.5,
|
|
623
|
+
// How much velocity affects gradient rotation
|
|
624
|
+
CHROMATIC_OFFSET: 1.5,
|
|
625
|
+
// Degree offset for chromatic rim layers
|
|
602
626
|
BORDER_STOP_1: {
|
|
603
627
|
MIN: 10,
|
|
604
628
|
// Minimum percentage for border stop 1
|
|
605
629
|
BASE: 33,
|
|
606
630
|
// Base percentage for border stop 1
|
|
607
|
-
MULTIPLIER
|
|
631
|
+
get MULTIPLIER() {
|
|
632
|
+
return .009 * this.BASE;
|
|
633
|
+
}
|
|
608
634
|
},
|
|
609
635
|
BORDER_STOP_2: {
|
|
610
636
|
MAX: 90,
|
|
611
637
|
// Maximum percentage for border stop 2
|
|
612
638
|
BASE: 66,
|
|
613
639
|
// Base percentage for border stop 2
|
|
614
|
-
MULTIPLIER
|
|
640
|
+
get MULTIPLIER() {
|
|
641
|
+
return .006 * this.BASE;
|
|
642
|
+
}
|
|
615
643
|
},
|
|
616
644
|
BORDER_OPACITY: {
|
|
617
645
|
BASE_1: .12,
|
|
618
646
|
// Base opacity for border gradient 1
|
|
619
|
-
BASE_2
|
|
647
|
+
get BASE_2() {
|
|
648
|
+
return 3.33 * this.BASE_1;
|
|
649
|
+
},
|
|
620
650
|
// Base opacity for border gradient 2
|
|
621
|
-
BASE_3
|
|
651
|
+
get BASE_3() {
|
|
652
|
+
return 2.66 * this.BASE_1;
|
|
653
|
+
},
|
|
622
654
|
// Base opacity for border gradient 3
|
|
623
|
-
BASE_4
|
|
655
|
+
get BASE_4() {
|
|
656
|
+
return 5 * this.BASE_1;
|
|
657
|
+
},
|
|
624
658
|
// Base opacity for border gradient 4
|
|
625
|
-
MULTIPLIER_LOW
|
|
659
|
+
get MULTIPLIER_LOW() {
|
|
660
|
+
return .066 * this.BASE_1;
|
|
661
|
+
},
|
|
626
662
|
// Low multiplier for mouse influence on opacity
|
|
627
|
-
MULTIPLIER_HIGH
|
|
663
|
+
get MULTIPLIER_HIGH() {
|
|
664
|
+
return .1 * this.BASE_1;
|
|
665
|
+
}
|
|
628
666
|
},
|
|
629
667
|
CENTER_POSITION: 50,
|
|
630
668
|
// Center position percentage (50%)
|
|
631
669
|
HOVER_POSITION: {
|
|
632
670
|
DIVISOR_1: 2,
|
|
633
671
|
// Divisor for hover 1 position calculation
|
|
634
|
-
DIVISOR_2
|
|
672
|
+
get DIVISOR_2() {
|
|
673
|
+
return .75 * this.DIVISOR_1;
|
|
674
|
+
},
|
|
635
675
|
// Divisor for hover 2 position calculation
|
|
636
|
-
MULTIPLIER_3
|
|
676
|
+
get MULTIPLIER_3() {
|
|
677
|
+
return .5 * this.DIVISOR_1;
|
|
678
|
+
}
|
|
637
679
|
},
|
|
638
|
-
BASE_LAYER_MULTIPLIER
|
|
680
|
+
get BASE_LAYER_MULTIPLIER() {
|
|
681
|
+
return .5;
|
|
682
|
+
}
|
|
639
683
|
},
|
|
640
684
|
// Gradient opacity values for hover effects
|
|
641
685
|
GRADIENT_OPACITY: {
|
|
642
686
|
HOVER_1: {
|
|
643
687
|
BLACK_START: .3,
|
|
644
688
|
// Start opacity for black hover 1
|
|
645
|
-
BLACK_MID
|
|
689
|
+
get BLACK_MID() {
|
|
690
|
+
return this.BLACK_START / 3;
|
|
691
|
+
},
|
|
646
692
|
// Mid opacity for black hover 1
|
|
647
693
|
BLACK_STOP: 30,
|
|
648
694
|
// Stop percentage for black hover 1
|
|
649
|
-
BLACK_END
|
|
695
|
+
get BLACK_END() {
|
|
696
|
+
return 2 * this.BLACK_STOP;
|
|
697
|
+
},
|
|
650
698
|
// End percentage for black hover 1
|
|
651
699
|
WHITE_START: .5,
|
|
652
700
|
// Start opacity for white hover 1
|
|
653
|
-
WHITE_STOP
|
|
701
|
+
get WHITE_STOP() {
|
|
702
|
+
return this.BLACK_END - 10;
|
|
703
|
+
}
|
|
654
704
|
},
|
|
655
705
|
HOVER_2: {
|
|
656
706
|
BLACK_START: .4,
|
|
657
707
|
// Start opacity for black hover 2
|
|
658
|
-
BLACK_MID
|
|
708
|
+
get BLACK_MID() {
|
|
709
|
+
return .375 * this.BLACK_START;
|
|
710
|
+
},
|
|
659
711
|
// Mid opacity for black hover 2
|
|
660
712
|
BLACK_STOP: 40,
|
|
661
713
|
// Stop percentage for black hover 2
|
|
662
|
-
BLACK_END
|
|
714
|
+
get BLACK_END() {
|
|
715
|
+
return 2 * this.BLACK_STOP;
|
|
716
|
+
},
|
|
663
717
|
// End percentage for black hover 2
|
|
664
718
|
WHITE_START: 1,
|
|
665
719
|
// Start opacity for white hover 2
|
|
666
|
-
WHITE_STOP
|
|
720
|
+
get WHITE_STOP() {
|
|
721
|
+
return this.BLACK_END;
|
|
722
|
+
}
|
|
667
723
|
},
|
|
668
724
|
HOVER_3: {
|
|
669
725
|
BLACK_START: .5,
|
|
670
726
|
// Start opacity for black hover 3
|
|
671
|
-
BLACK_MID
|
|
727
|
+
get BLACK_MID() {
|
|
728
|
+
return .4 * this.BLACK_START;
|
|
729
|
+
},
|
|
672
730
|
// Mid opacity for black hover 3
|
|
673
731
|
BLACK_STOP: 50,
|
|
674
732
|
// Stop percentage for black hover 3
|
|
675
|
-
BLACK_END
|
|
733
|
+
get BLACK_END() {
|
|
734
|
+
return 2 * this.BLACK_STOP;
|
|
735
|
+
},
|
|
676
736
|
// End percentage for black hover 3
|
|
677
737
|
WHITE_START: 1,
|
|
678
738
|
// Start opacity for white hover 3
|
|
679
|
-
WHITE_STOP
|
|
739
|
+
get WHITE_STOP() {
|
|
740
|
+
return this.BLACK_END;
|
|
741
|
+
}
|
|
680
742
|
}
|
|
681
743
|
},
|
|
682
744
|
// Base and overlay gradient constants
|
|
@@ -685,34 +747,54 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
685
747
|
// Gradient angle in degrees
|
|
686
748
|
BLACK_START_BASE: .15,
|
|
687
749
|
// Base start opacity for black
|
|
688
|
-
BLACK_START_MULTIPLIER
|
|
750
|
+
get BLACK_START_MULTIPLIER() {
|
|
751
|
+
return .02 * this.BLACK_START_BASE;
|
|
752
|
+
},
|
|
689
753
|
// Multiplier for mouse X influence on start
|
|
690
754
|
BLACK_MID_BASE: .1,
|
|
691
755
|
// Base mid opacity for black
|
|
692
|
-
BLACK_MID_MULTIPLIER
|
|
756
|
+
get BLACK_MID_MULTIPLIER() {
|
|
757
|
+
return .02 * this.BLACK_MID_BASE;
|
|
758
|
+
},
|
|
693
759
|
// Multiplier for mouse Y influence on mid
|
|
694
760
|
BLACK_MID_STOP: 50,
|
|
695
761
|
// Mid stop percentage
|
|
696
|
-
BLACK_END_BASE
|
|
762
|
+
get BLACK_END_BASE() {
|
|
763
|
+
return 1.2 * this.BLACK_START_BASE;
|
|
764
|
+
},
|
|
697
765
|
// Base end opacity for black
|
|
698
|
-
BLACK_END_MULTIPLIER
|
|
766
|
+
get BLACK_END_MULTIPLIER() {
|
|
767
|
+
return .022 * this.BLACK_END_BASE;
|
|
768
|
+
},
|
|
699
769
|
// Multiplier for mouse X influence on end
|
|
700
|
-
WHITE_OPACITY
|
|
770
|
+
get WHITE_OPACITY() {
|
|
771
|
+
return .666 * this.BLACK_START_BASE;
|
|
772
|
+
}
|
|
701
773
|
},
|
|
702
774
|
OVERLAY_GRADIENT: {
|
|
703
775
|
BLACK_START_BASE: .12,
|
|
704
776
|
// Base start opacity for black overlay
|
|
705
|
-
BLACK_START_MULTIPLIER
|
|
777
|
+
get BLACK_START_MULTIPLIER() {
|
|
778
|
+
return .025 * this.BLACK_START_BASE;
|
|
779
|
+
},
|
|
706
780
|
// Multiplier for mouse X influence on start
|
|
707
|
-
BLACK_MID
|
|
781
|
+
get BLACK_MID() {
|
|
782
|
+
return .5 * this.BLACK_START_BASE;
|
|
783
|
+
},
|
|
708
784
|
// Mid opacity for black overlay
|
|
709
785
|
BLACK_MID_STOP: 40,
|
|
710
786
|
// Mid stop percentage
|
|
711
|
-
BLACK_END_BASE
|
|
787
|
+
get BLACK_END_BASE() {
|
|
788
|
+
return 1.25 * this.BLACK_START_BASE;
|
|
789
|
+
},
|
|
712
790
|
// Base end opacity for black overlay
|
|
713
|
-
BLACK_END_MULTIPLIER
|
|
791
|
+
get BLACK_END_MULTIPLIER() {
|
|
792
|
+
return .02 * this.BLACK_END_BASE;
|
|
793
|
+
},
|
|
714
794
|
// Multiplier for mouse Y influence on end
|
|
715
|
-
WHITE_OPACITY
|
|
795
|
+
get WHITE_OPACITY() {
|
|
796
|
+
return .416 * this.BLACK_START_BASE;
|
|
797
|
+
}
|
|
716
798
|
},
|
|
717
799
|
// Overlay highlight constants
|
|
718
800
|
OVERLAY_HIGHLIGHT: {
|
|
@@ -722,9 +804,13 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
722
804
|
// Y position percentage
|
|
723
805
|
WHITE_OPACITY: .4,
|
|
724
806
|
// White opacity in gradient
|
|
725
|
-
STOP
|
|
807
|
+
get STOP() {
|
|
808
|
+
return 150 * this.WHITE_OPACITY;
|
|
809
|
+
},
|
|
726
810
|
// Stop percentage
|
|
727
|
-
OPACITY_MULTIPLIER
|
|
811
|
+
get OPACITY_MULTIPLIER() {
|
|
812
|
+
return 1.75 * this.WHITE_OPACITY;
|
|
813
|
+
}
|
|
728
814
|
},
|
|
729
815
|
// Displacement and aberration multipliers
|
|
730
816
|
MULTIPLIERS: {
|
|
@@ -777,11 +863,7 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
777
863
|
}
|
|
778
864
|
}
|
|
779
865
|
}
|
|
780
|
-
}, {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS,
|
|
781
|
-
if (!pos1 || !pos2 || "number" != typeof pos1.x || "number" != typeof pos1.y || "number" != typeof pos2.x || "number" != typeof pos2.y) return 0;
|
|
782
|
-
const deltaX = pos1.x - pos2.x, deltaY = pos1.y - pos2.y;
|
|
783
|
-
return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
784
|
-
}, calculateElementCenter = rect => rect ? {
|
|
866
|
+
}, {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateElementCenter = rect => rect ? {
|
|
785
867
|
x: rect.left + rect.width / 2,
|
|
786
868
|
y: rect.top + rect.height / 2
|
|
787
869
|
} : {
|
|
@@ -853,7 +935,16 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
853
935
|
// Silently handle errors
|
|
854
936
|
}
|
|
855
937
|
return CONSTANTS$2.DEFAULT_CORNER_RADIUS;
|
|
856
|
-
},
|
|
938
|
+
}, smoothstep = t => {
|
|
939
|
+
const clamped = Math.max(0, Math.min(1, t));
|
|
940
|
+
return clamped * clamped * (3 - 2 * clamped);
|
|
941
|
+
}, 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) => {
|
|
942
|
+
const newVelocity = (velocity + (target - current) * stiffness) * damping;
|
|
943
|
+
return {
|
|
944
|
+
value: current + newVelocity,
|
|
945
|
+
velocity: newVelocity
|
|
946
|
+
};
|
|
947
|
+
}, getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
|
|
857
948
|
switch (mode) {
|
|
858
949
|
case "standard":
|
|
859
950
|
return displacementMap;
|
|
@@ -1247,6 +1338,9 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
1247
1338
|
}), jsx("div", {
|
|
1248
1339
|
ref: contentRef,
|
|
1249
1340
|
className: ATOMIX_GLASS.CONTENT_CLASS,
|
|
1341
|
+
style: {
|
|
1342
|
+
transform: "var(--atomix-glass-child-parallax, none)"
|
|
1343
|
+
},
|
|
1250
1344
|
children: children
|
|
1251
1345
|
}) ]
|
|
1252
1346
|
})
|
|
@@ -1281,9 +1375,21 @@ class {
|
|
|
1281
1375
|
y: this.lastEvent.clientY
|
|
1282
1376
|
},
|
|
1283
1377
|
// Notify all subscribers
|
|
1284
|
-
this.listeners.forEach((
|
|
1378
|
+
this.listeners.forEach((listener => {
|
|
1285
1379
|
try {
|
|
1286
|
-
|
|
1380
|
+
// If the listener has an element, calculate distance-based attenuation
|
|
1381
|
+
if (listener.element) {
|
|
1382
|
+
const elementRect = listener.element.getBoundingClientRect(), elementCenter = {
|
|
1383
|
+
x: elementRect.left + elementRect.width / 2,
|
|
1384
|
+
y: elementRect.top + elementRect.height / 2
|
|
1385
|
+
}, distance = this.calculateDistance(this.position, elementCenter), maxDistance = listener.maxDistance || 300, attenuation = Math.max(0, 1 - distance / maxDistance), attenuatedRelativePosition = {
|
|
1386
|
+
x: (this.position.x - elementCenter.x) / elementRect.width * 100 * attenuation,
|
|
1387
|
+
y: (this.position.y - elementCenter.y) / elementRect.height * 100 * attenuation
|
|
1388
|
+
};
|
|
1389
|
+
listener.callback(attenuatedRelativePosition);
|
|
1390
|
+
} else
|
|
1391
|
+
// Send original position for listeners without distance-based attenuation
|
|
1392
|
+
listener.callback(this.position);
|
|
1287
1393
|
} catch (error) {
|
|
1288
1394
|
console.error("GlobalMouseTracker: Error in subscriber callback", error);
|
|
1289
1395
|
}
|
|
@@ -1294,10 +1400,17 @@ class {
|
|
|
1294
1400
|
/**
|
|
1295
1401
|
* Subscribe to mouse position updates
|
|
1296
1402
|
* @param callback Function to call when mouse position changes
|
|
1403
|
+
* @param element Optional element for distance-based attenuation
|
|
1404
|
+
* @param maxDistance Optional maximum distance for full effect
|
|
1297
1405
|
* @returns Unsubscribe function
|
|
1298
|
-
*/ subscribe(callback) {
|
|
1406
|
+
*/ subscribe(callback, element, maxDistance) {
|
|
1407
|
+
const listener = {
|
|
1408
|
+
callback: callback,
|
|
1409
|
+
element: element,
|
|
1410
|
+
maxDistance: maxDistance
|
|
1411
|
+
};
|
|
1299
1412
|
// Return unsubscribe function
|
|
1300
|
-
return this.listeners.add(
|
|
1413
|
+
return this.listeners.add(listener),
|
|
1301
1414
|
// Start tracking if this is the first subscriber
|
|
1302
1415
|
1 === this.listeners.size && this.startTracking(),
|
|
1303
1416
|
// Immediately notify with current position
|
|
@@ -1308,9 +1421,13 @@ class {
|
|
|
1308
1421
|
/**
|
|
1309
1422
|
* Unsubscribe from mouse position updates
|
|
1310
1423
|
*/ unsubscribe(callback) {
|
|
1311
|
-
|
|
1424
|
+
// Find and remove the listener with the given callback
|
|
1425
|
+
for (const listener of this.listeners) if (listener.callback === callback) {
|
|
1426
|
+
this.listeners.delete(listener);
|
|
1427
|
+
break;
|
|
1428
|
+
}
|
|
1312
1429
|
// Stop tracking if no more subscribers
|
|
1313
|
-
|
|
1430
|
+
0 === this.listeners.size && this.stopTracking();
|
|
1314
1431
|
}
|
|
1315
1432
|
/**
|
|
1316
1433
|
* Start tracking mouse movement
|
|
@@ -1329,6 +1446,12 @@ class {
|
|
|
1329
1446
|
null !== this.rafId && (cancelAnimationFrame(this.rafId), this.rafId = null), this.lastEvent = null);
|
|
1330
1447
|
}
|
|
1331
1448
|
/**
|
|
1449
|
+
* Calculate distance between two points
|
|
1450
|
+
*/ calculateDistance(point1, point2) {
|
|
1451
|
+
const dx = point1.x - point2.x, dy = point1.y - point2.y;
|
|
1452
|
+
return Math.sqrt(dx * dx + dy * dy);
|
|
1453
|
+
}
|
|
1454
|
+
/**
|
|
1332
1455
|
* Get current mouse position (synchronous)
|
|
1333
1456
|
*/ getPosition() {
|
|
1334
1457
|
return {
|
|
@@ -1342,51 +1465,26 @@ class {
|
|
|
1342
1465
|
}
|
|
1343
1466
|
}, updateAtomixGlassStyles = (wrapperElement, containerElement, params) => {
|
|
1344
1467
|
if (!wrapperElement && !containerElement) return;
|
|
1345
|
-
|
|
1468
|
+
if (!validateGlassSize(params.glassSize)) return;
|
|
1469
|
+
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 = {
|
|
1346
1470
|
opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
|
|
1347
1471
|
contrast: Math.min(1.6, baseOverLightConfig.contrast + .1 * mouseInfluence),
|
|
1348
1472
|
brightness: Math.min(1.1, baseOverLightConfig.brightness + .05 * mouseInfluence),
|
|
1349
1473
|
shadowIntensity: Math.min(1.2, Math.max(.5, baseOverLightConfig.shadowIntensity + .2 * mouseInfluence)),
|
|
1350
1474
|
borderOpacity: Math.min(1, Math.max(.3, baseOverLightConfig.borderOpacity + .1 * mouseInfluence)),
|
|
1351
1475
|
saturationBoost: baseOverLightConfig.saturationBoost
|
|
1352
|
-
}
|
|
1353
|
-
|
|
1354
|
-
|
|
1476
|
+
}, 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) => {
|
|
1477
|
+
if (!pos1 || !pos2 || "number" != typeof pos1.x || "number" != typeof pos1.y || "number" != typeof pos2.x || "number" != typeof pos2.y) return 0;
|
|
1478
|
+
const deltaX = pos1.x - pos2.x, deltaY = pos1.y - pos2.y;
|
|
1479
|
+
return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
1480
|
+
})({
|
|
1355
1481
|
x: 0,
|
|
1356
1482
|
y: 0
|
|
1357
|
-
};
|
|
1358
|
-
// Calculate
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
if (globalMousePosition.x && globalMousePosition.y && validateGlassSize(glassSize)) {
|
|
1363
|
-
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({
|
|
1364
|
-
x: edgeDistanceX,
|
|
1365
|
-
y: edgeDistanceY
|
|
1366
|
-
}, {
|
|
1367
|
-
x: 0,
|
|
1368
|
-
y: 0
|
|
1369
|
-
}), rawT = edgeDistance > ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE, fadeInFactor = (t => {
|
|
1370
|
-
const clamped = Math.max(0, Math.min(1, t));
|
|
1371
|
-
return clamped * clamped * (3 - 2 * clamped);
|
|
1372
|
-
})(rawT);
|
|
1373
|
-
// Directional scale
|
|
1374
|
-
if (elasticTranslation = {
|
|
1375
|
-
x: deltaX * elasticity * .1 * fadeInFactor,
|
|
1376
|
-
y: deltaY * elasticity * .1 * fadeInFactor
|
|
1377
|
-
}, !isOverLight && edgeDistance <= ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE) {
|
|
1378
|
-
const centerDistance = calculateDistance(globalMousePosition, center);
|
|
1379
|
-
if (centerDistance > 0) {
|
|
1380
|
-
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);
|
|
1381
|
-
computedDirectionalScale = `scaleX(${Math.max(.85, softScaleX)}) scaleY(${Math.max(.85, softScaleY)})`;
|
|
1382
|
-
}
|
|
1383
|
-
}
|
|
1384
|
-
}
|
|
1385
|
-
}
|
|
1386
|
-
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}`;
|
|
1387
|
-
// Update Wrapper Styles (glassVars)
|
|
1388
|
-
if (wrapperElement) {
|
|
1389
|
-
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 = {
|
|
1483
|
+
}, elasticTranslation), tensionFactor = smoothstep(stretchMagnitude / 80), lightingContrast = Math.min(1.8, overLightConfig.contrast + .2 * tensionFactor), lightingBrightness = Math.min(1.2, overLightConfig.brightness + .1 * tensionFactor);
|
|
1484
|
+
// Calculate mouse influence
|
|
1485
|
+
// Update Wrapper Styles (glassVars)
|
|
1486
|
+
if (wrapperElement) {
|
|
1487
|
+
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 = {
|
|
1390
1488
|
hover1: {
|
|
1391
1489
|
x: GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_1,
|
|
1392
1490
|
y: GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_1
|
|
@@ -1409,10 +1507,16 @@ class {
|
|
|
1409
1507
|
base: isOverLight ? overLightConfig.opacity : 0,
|
|
1410
1508
|
over: isOverLight ? 1.1 * overLightConfig.opacity : 0
|
|
1411
1509
|
}, style = wrapperElement.style;
|
|
1412
|
-
style.setProperty("--atomix-glass-transform", transformStyle || "none")
|
|
1413
|
-
//
|
|
1414
|
-
|
|
1415
|
-
style.setProperty("--atomix-glass-
|
|
1510
|
+
style.setProperty("--atomix-glass-transform", transformStyle || "none");
|
|
1511
|
+
// Parallax for content (liquid refraction feel)
|
|
1512
|
+
const parallaxFactor = .38 + .12 * tensionFactor;
|
|
1513
|
+
style.setProperty("--atomix-glass-child-parallax", `translate(${elasticTranslation.x * -parallaxFactor}px, ${elasticTranslation.y * -parallaxFactor}px)`),
|
|
1514
|
+
style.setProperty("--atomix-glass-contrast", lightingContrast.toString()), style.setProperty("--atomix-glass-brightness", lightingBrightness.toString()),
|
|
1515
|
+
// ── Chromatic Rim Lighting ──────────────────────────────────────
|
|
1516
|
+
// Layer 1: Core White/Blue highlight
|
|
1517
|
+
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%)`),
|
|
1518
|
+
// Layer 2: Subtle Red/Warm highlight (offset angle)
|
|
1519
|
+
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%)`),
|
|
1416
1520
|
// Hover gradients
|
|
1417
1521
|
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}%)`),
|
|
1418
1522
|
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}%)`),
|
|
@@ -1440,7 +1544,7 @@ class {
|
|
|
1440
1544
|
flowBlur: blurAmount * FLOW_BLUR_MULTIPLIER
|
|
1441
1545
|
};
|
|
1442
1546
|
if (withLiquidBlur && rect) {
|
|
1443
|
-
const mouseInfluence = calculateMouseInfluence(mouseOffset), maxBlur = blurAmount * MAX_BLUR_RELATIVE, baseBlur =
|
|
1547
|
+
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);
|
|
1444
1548
|
liquidBlur = {
|
|
1445
1549
|
baseBlur: clampBlur(baseBlur),
|
|
1446
1550
|
edgeBlur: clampBlur(edgeBlur),
|
|
@@ -1449,9 +1553,10 @@ class {
|
|
|
1449
1553
|
};
|
|
1450
1554
|
}
|
|
1451
1555
|
// Backdrop filter
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1556
|
+
const dynamicSaturation = saturation + 40 * tensionFactor + 15 * (liquidBlur.baseBlur || 0);
|
|
1557
|
+
let backdropFilterString = "";
|
|
1558
|
+
const area = rect ? rect.width * rect.height : 0;
|
|
1559
|
+
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})`;
|
|
1455
1560
|
// Container variables
|
|
1456
1561
|
const style = containerElement.style;
|
|
1457
1562
|
style.setProperty("--atomix-glass-container-padding", padding), style.setProperty("--atomix-glass-container-radius", `${effectiveBorderRadius}px`),
|
|
@@ -1613,7 +1718,8 @@ const {CONSTANTS: CONSTANTS} = ATOMIX_GLASS, backgroundDetectionCache = new Weak
|
|
|
1613
1718
|
* Composable hook for AtomixGlass component logic
|
|
1614
1719
|
* Manages all state, calculations, and event handlers
|
|
1615
1720
|
*/
|
|
1616
|
-
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 = .
|
|
1721
|
+
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:
|
|
1722
|
+
// Default priority
|
|
1617
1723
|
// Phase 1: Animation System Props
|
|
1618
1724
|
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}) {
|
|
1619
1725
|
// State
|
|
@@ -1629,7 +1735,24 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1629
1735
|
}), targetGlobalMousePositionRef = useRef({
|
|
1630
1736
|
x: 0,
|
|
1631
1737
|
y: 0
|
|
1632
|
-
}), lerpRafRef = useRef(null), lerpActiveRef = useRef(!1), [dynamicBorderRadius, setDynamicCornerRadius] = useState(CONSTANTS.DEFAULT_CORNER_RADIUS),
|
|
1738
|
+
}), lerpRafRef = useRef(null), lerpActiveRef = useRef(!1), [dynamicBorderRadius, setDynamicCornerRadius] = useState(CONSTANTS.DEFAULT_CORNER_RADIUS), elasticTranslationRef = useRef({
|
|
1739
|
+
x: 0,
|
|
1740
|
+
y: 0
|
|
1741
|
+
}), elasticVelocityRef = useRef({
|
|
1742
|
+
x: 0,
|
|
1743
|
+
y: 0
|
|
1744
|
+
}), directionalScaleRef = useRef({
|
|
1745
|
+
x: 1,
|
|
1746
|
+
y: 1
|
|
1747
|
+
}), scaleVelocityRef = useRef({
|
|
1748
|
+
x: 0,
|
|
1749
|
+
y: 0
|
|
1750
|
+
});
|
|
1751
|
+
useRef(0);
|
|
1752
|
+
const mouseVelocityRef = useRef({
|
|
1753
|
+
x: 0,
|
|
1754
|
+
y: 0
|
|
1755
|
+
}), [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((() => {
|
|
1633
1756
|
// If quality preset is provided, use it as base
|
|
1634
1757
|
const preset = (quality = distortionQuality, ATOMIX_GLASS.CONSTANTS.DISTORTION_QUALITY_PRESETS[quality]);
|
|
1635
1758
|
// Override with custom values if provided
|
|
@@ -1914,57 +2037,85 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1914
2037
|
return "undefined" == typeof process || process.env, finalConfig;
|
|
1915
2038
|
}
|
|
1916
2039
|
return "undefined" == typeof process || process.env, baseConfig;
|
|
1917
|
-
}), [ overLight, getEffectiveOverLight, isHovered, isActive, validateConfigValue, debugOverLight ]), transformStyle = useMemo((() => effectiveWithoutEffects || isActive && Boolean(onClick) ? "scale(0.
|
|
2040
|
+
}), [ 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((() => {
|
|
1918
2041
|
lerpActiveRef.current = !1, null !== lerpRafRef.current && (cancelAnimationFrame(lerpRafRef.current),
|
|
1919
2042
|
lerpRafRef.current = null);
|
|
1920
2043
|
}), []), startLerpLoop = useCallback((() => {
|
|
1921
2044
|
if (lerpActiveRef.current) return;
|
|
1922
|
-
lerpActiveRef.current = !0;
|
|
1923
|
-
|
|
2045
|
+
lerpActiveRef.current = !0, CONSTANTS.LERP_FACTOR;
|
|
2046
|
+
// 0.08 – lower = more viscous
|
|
2047
|
+
const tick = () => {
|
|
1924
2048
|
if (!lerpActiveRef.current) return;
|
|
1925
2049
|
if (!glassRef.current) return void (lerpActiveRef.current = !1);
|
|
1926
|
-
const cur = internalMouseOffsetRef.current, tgt = targetMouseOffsetRef.current,
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
},
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
// Final update and stop
|
|
1934
|
-
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
1935
|
-
mouseOffset: internalMouseOffsetRef.current,
|
|
1936
|
-
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
1937
|
-
glassSize: glassSize,
|
|
1938
|
-
isHovered: isHovered,
|
|
1939
|
-
isActive: isActive,
|
|
1940
|
-
isOverLight: overLightConfig.isOverLight,
|
|
1941
|
-
baseOverLightConfig: overLightConfig,
|
|
1942
|
-
effectiveBorderRadius: effectiveBorderRadius,
|
|
1943
|
-
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
1944
|
-
effectiveReducedMotion: effectiveReducedMotion,
|
|
1945
|
-
elasticity: elasticity,
|
|
1946
|
-
directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
|
|
1947
|
-
onClick: onClick,
|
|
1948
|
-
withLiquidBlur: withLiquidBlur,
|
|
1949
|
-
blurAmount: blurAmount,
|
|
1950
|
-
saturation: saturation,
|
|
1951
|
-
padding: padding,
|
|
1952
|
-
isFixedOrSticky: isFixedOrSticky
|
|
1953
|
-
}), void stopLerpLoop();
|
|
1954
|
-
// Smooth step
|
|
1955
|
-
internalMouseOffsetRef.current = {
|
|
1956
|
-
x: lerp$1(cur.x, tgt.x, LERP_T),
|
|
1957
|
-
y: lerp$1(cur.y, tgt.y, LERP_T)
|
|
2050
|
+
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);
|
|
2051
|
+
internalMouseOffsetRef.current = {
|
|
2052
|
+
x: springX.value,
|
|
2053
|
+
y: springY.value
|
|
2054
|
+
}, mouseVelocityRef.current = {
|
|
2055
|
+
x: springX.velocity,
|
|
2056
|
+
y: springY.velocity
|
|
1958
2057
|
};
|
|
1959
2058
|
const curG = internalGlobalMousePositionRef.current, tgtG = targetGlobalMousePositionRef.current;
|
|
1960
2059
|
internalGlobalMousePositionRef.current = {
|
|
1961
|
-
x: lerp$1(curG.x, tgtG.x,
|
|
1962
|
-
y: lerp$1(curG.y, tgtG.y,
|
|
2060
|
+
x: lerp$1(curG.x, tgtG.x, CONSTANTS.LERP_FACTOR),
|
|
2061
|
+
y: lerp$1(curG.y, tgtG.y, CONSTANTS.LERP_FACTOR)
|
|
2062
|
+
};
|
|
2063
|
+
// ── Calculate Elastic Physics ─────────────────────────────────────
|
|
2064
|
+
let targetElasticTranslation = {
|
|
2065
|
+
x: 0,
|
|
2066
|
+
y: 0
|
|
2067
|
+
}, targetScale = {
|
|
2068
|
+
x: 1,
|
|
2069
|
+
y: 1
|
|
2070
|
+
};
|
|
2071
|
+
if (!effectiveWithoutEffects && glassRef.current) {
|
|
2072
|
+
const rect = cachedRectRef.current || glassRef.current.getBoundingClientRect(), center = calculateElementCenter(rect), globalPos = internalGlobalMousePositionRef.current;
|
|
2073
|
+
if (globalPos.x && globalPos.y) {
|
|
2074
|
+
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);
|
|
2075
|
+
// Scale stretch logic (liquid surface tension)
|
|
2076
|
+
if (targetElasticTranslation = {
|
|
2077
|
+
x: deltaX * elasticity * CONSTANTS.ELASTICITY_TRANSLATION_FACTOR * fadeInFactor,
|
|
2078
|
+
y: deltaY * elasticity * CONSTANTS.ELASTICITY_TRANSLATION_FACTOR * fadeInFactor
|
|
2079
|
+
}, edgeDistance <= activationZone) {
|
|
2080
|
+
const centerDistance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
2081
|
+
if (centerDistance > 0) {
|
|
2082
|
+
const nx = deltaX / centerDistance, ny = deltaY / centerDistance, stretchIntensity = Math.min(centerDistance / 350, 1) * elasticity * rawT, mag = 1 + .06 * stretchIntensity;
|
|
2083
|
+
targetScale = {
|
|
2084
|
+
x: mag + Math.abs(nx) * stretchIntensity * CONSTANTS.ELASTICITY_STRETCH_RATIO,
|
|
2085
|
+
y: mag + Math.abs(ny) * stretchIntensity * CONSTANTS.ELASTICITY_STRETCH_RATIO
|
|
2086
|
+
},
|
|
2087
|
+
// Maintain liquid volume by compressing the perpendicular axis
|
|
2088
|
+
targetScale.x -= Math.abs(ny) * stretchIntensity * .15, targetScale.y -= Math.abs(nx) * stretchIntensity * .15;
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
// Integrate Elastic Translation Spring
|
|
2094
|
+
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);
|
|
2095
|
+
elasticTranslationRef.current = {
|
|
2096
|
+
x: springTX.value,
|
|
2097
|
+
y: springTY.value
|
|
2098
|
+
}, elasticVelocityRef.current = {
|
|
2099
|
+
x: springTX.velocity,
|
|
2100
|
+
y: springTY.velocity
|
|
2101
|
+
};
|
|
2102
|
+
// Integrate Scale Spring
|
|
2103
|
+
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);
|
|
2104
|
+
directionalScaleRef.current = {
|
|
2105
|
+
x: springSX.value,
|
|
2106
|
+
y: springSY.value
|
|
2107
|
+
}, scaleVelocityRef.current = {
|
|
2108
|
+
x: springSX.velocity,
|
|
2109
|
+
y: springSY.velocity
|
|
1963
2110
|
},
|
|
1964
2111
|
// Imperative style update
|
|
1965
2112
|
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
1966
2113
|
mouseOffset: internalMouseOffsetRef.current,
|
|
1967
2114
|
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
2115
|
+
elasticTranslation: elasticTranslationRef.current,
|
|
2116
|
+
elasticVelocity: elasticVelocityRef.current,
|
|
2117
|
+
mouseVelocity: mouseVelocityRef.current,
|
|
2118
|
+
directionalScale: directionalScaleRef.current,
|
|
1968
2119
|
glassSize: glassSize,
|
|
1969
2120
|
isHovered: isHovered,
|
|
1970
2121
|
isActive: isActive,
|
|
@@ -1974,17 +2125,16 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1974
2125
|
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
1975
2126
|
effectiveReducedMotion: effectiveReducedMotion,
|
|
1976
2127
|
elasticity: elasticity,
|
|
1977
|
-
|
|
2128
|
+
scaleBase: isActive && Boolean(onClick) ? .99 : 1,
|
|
1978
2129
|
onClick: onClick,
|
|
1979
2130
|
withLiquidBlur: withLiquidBlur,
|
|
1980
2131
|
blurAmount: blurAmount,
|
|
1981
2132
|
saturation: saturation,
|
|
1982
2133
|
padding: padding,
|
|
1983
2134
|
isFixedOrSticky: isFixedOrSticky
|
|
1984
|
-
}), lerpRafRef.current = requestAnimationFrame(tick);
|
|
2135
|
+
}), 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);
|
|
1985
2136
|
};
|
|
1986
|
-
|
|
1987
|
-
lerpRafRef.current = requestAnimationFrame(tick);
|
|
2137
|
+
lerpRafRef.current = requestAnimationFrame(tick);
|
|
1988
2138
|
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding, isFixedOrSticky, stopLerpLoop ]), handleGlobalMousePosition = useCallback((globalPos => {
|
|
1989
2139
|
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
1990
2140
|
if (effectiveWithoutEffects) return;
|
|
@@ -2010,7 +2160,8 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2010
2160
|
useEffect((() => {
|
|
2011
2161
|
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
2012
2162
|
if (effectiveWithoutEffects) return;
|
|
2013
|
-
const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition);
|
|
2163
|
+
const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition, glassRef.current || void 0, 300);
|
|
2164
|
+
// 300px max distance for full effect
|
|
2014
2165
|
// Initial start
|
|
2015
2166
|
startLerpLoop();
|
|
2016
2167
|
const container = mouseContainer?.current || glassRef.current;
|
|
@@ -2030,6 +2181,11 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2030
2181
|
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
2031
2182
|
mouseOffset: externalMouseOffset || internalMouseOffsetRef.current,
|
|
2032
2183
|
globalMousePosition: externalGlobalMousePosition || internalGlobalMousePositionRef.current,
|
|
2184
|
+
elasticTranslation: elasticTranslationRef.current,
|
|
2185
|
+
elasticVelocity: elasticVelocityRef.current,
|
|
2186
|
+
mouseVelocity: mouseVelocityRef.current,
|
|
2187
|
+
directionalScale: directionalScaleRef.current,
|
|
2188
|
+
scaleBase: isActive && Boolean(onClick) ? .96 : 1,
|
|
2033
2189
|
glassSize: glassSize,
|
|
2034
2190
|
isHovered: isHovered,
|
|
2035
2191
|
isActive: isActive,
|
|
@@ -2039,7 +2195,6 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2039
2195
|
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
2040
2196
|
effectiveReducedMotion: effectiveReducedMotion,
|
|
2041
2197
|
elasticity: elasticity,
|
|
2042
|
-
directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
|
|
2043
2198
|
onClick: onClick,
|
|
2044
2199
|
withLiquidBlur: withLiquidBlur,
|
|
2045
2200
|
blurAmount: blurAmount,
|
|
@@ -2936,7 +3091,7 @@ const PERFORMANCE_PRESET = {
|
|
|
2936
3091
|
"aria-label": ariaLabel,
|
|
2937
3092
|
"aria-describedby": ariaDescribedBy,
|
|
2938
3093
|
"aria-disabled": !(!onClick || !effectiveWithoutEffects) || !onClick && void 0,
|
|
2939
|
-
"aria-pressed": void 0,
|
|
3094
|
+
"aria-pressed": onClick ? isActive : void 0,
|
|
2940
3095
|
onKeyDown: onClick ? handleKeyDown : void 0,
|
|
2941
3096
|
children: [ jsx(AtomixGlassContainer, {
|
|
2942
3097
|
ref: glassRef,
|
|
@@ -3738,10 +3893,10 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
|
|
|
3738
3893
|
children: renderSlot(slots?.spinner, {
|
|
3739
3894
|
className: ThemeNaming.bemClass("btn", "spinner"),
|
|
3740
3895
|
size: spinnerSize,
|
|
3741
|
-
variant: "link" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "
|
|
3896
|
+
variant: "link" === variant || "ghost" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "danger" : variant
|
|
3742
3897
|
}, jsx(Spinner, {
|
|
3743
3898
|
size: spinnerSize,
|
|
3744
|
-
variant: "link" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "
|
|
3899
|
+
variant: "link" === variant || "ghost" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "danger" : variant
|
|
3745
3900
|
}))
|
|
3746
3901
|
}), iconElement && !loading && jsx("span", {
|
|
3747
3902
|
className: ThemeNaming.bemClass("btn", "icon"),
|
|
@@ -3830,8 +3985,7 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
|
|
|
3830
3985
|
const defaultGlassProps = {
|
|
3831
3986
|
displacementScale: 20,
|
|
3832
3987
|
blurAmount: 0,
|
|
3833
|
-
saturation: 200
|
|
3834
|
-
elasticity: 0
|
|
3988
|
+
saturation: 200
|
|
3835
3989
|
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
3836
3990
|
...defaultGlassProps,
|
|
3837
3991
|
...glass
|
|
@@ -4019,7 +4173,6 @@ className: className = "", style: style, ...rest}, ref) => {
|
|
|
4019
4173
|
children: cardContent
|
|
4020
4174
|
}), glass ? jsx(AtomixGlass, {
|
|
4021
4175
|
...!0 === glass ? {} : glass,
|
|
4022
|
-
elasticity: 0,
|
|
4023
4176
|
children: anchorElement
|
|
4024
4177
|
}) : anchorElement;
|
|
4025
4178
|
}
|
|
@@ -4031,7 +4184,6 @@ className: className = "", style: style, ...rest}, ref) => {
|
|
|
4031
4184
|
});
|
|
4032
4185
|
return glass ? jsx(AtomixGlass, {
|
|
4033
4186
|
...!0 === glass ? {} : glass,
|
|
4034
|
-
elasticity: 0,
|
|
4035
4187
|
children: divElement
|
|
4036
4188
|
}) : divElement;
|
|
4037
4189
|
})));
|