@shohojdhara/atomix 0.6.4 → 0.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/atomix.css +117 -38
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +1 -1
- package/dist/atomix.min.css.map +1 -1
- package/dist/atomix.umd.js +1 -1
- package/dist/atomix.umd.js.map +1 -1
- package/dist/atomix.umd.min.js +1 -1
- package/dist/charts.d.ts +30 -1
- package/dist/charts.js +625 -846
- package/dist/charts.js.map +1 -1
- package/dist/core.d.ts +30 -1
- package/dist/core.js +659 -873
- package/dist/core.js.map +1 -1
- package/dist/forms.d.ts +30 -1
- package/dist/forms.js +1171 -1402
- package/dist/forms.js.map +1 -1
- package/dist/heavy.d.ts +31 -89
- package/dist/heavy.js +975 -1195
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +383 -140
- package/dist/index.esm.js +1567 -1679
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1556 -1667
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Accordion/Accordion.tsx +2 -5
- package/src/components/AtomixGlass/AtomixGlass.test.tsx +14 -16
- package/src/components/AtomixGlass/AtomixGlass.tsx +137 -364
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +32 -251
- package/src/components/AtomixGlass/GlassFilter.tsx +62 -68
- package/src/components/AtomixGlass/README.md +2 -1
- package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +19 -18
- package/src/components/AtomixGlass/glass-border-styles.test.ts +58 -0
- package/src/components/AtomixGlass/glass-border-styles.ts +136 -0
- package/src/components/AtomixGlass/glass-utils.ts +456 -22
- package/src/components/AtomixGlass/shader-utils.ts +19 -77
- package/src/components/AtomixGlass/stories/AnimationFeatures.stories.tsx +158 -537
- package/src/components/AtomixGlass/stories/Border.stories.tsx +149 -0
- package/src/components/AtomixGlass/stories/Examples.stories.tsx +229 -89
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +29 -340
- package/src/components/AtomixGlass/stories/argTypes.ts +30 -13
- package/src/components/AtomixGlass/stories/premium-presets.ts +206 -0
- package/src/components/AtomixGlass/stories/shared-components.tsx +52 -8
- package/src/components/Badge/Badge.tsx +4 -4
- package/src/components/Button/Button.tsx +2 -6
- package/src/components/Callout/Callout.test.tsx +4 -3
- package/src/components/Callout/Callout.tsx +2 -5
- package/src/components/Dropdown/Dropdown.tsx +3 -7
- package/src/components/Form/Checkbox.tsx +2 -8
- package/src/components/Form/Input.tsx +2 -9
- package/src/components/Form/Radio.tsx +2 -9
- package/src/components/Form/Select.test.tsx +6 -6
- package/src/components/Form/Select.tsx +2 -7
- package/src/components/Form/Textarea.stories.tsx +5 -5
- package/src/components/Form/Textarea.tsx +2 -9
- package/src/components/Messages/Messages.tsx +2 -8
- package/src/components/Modal/Modal.tsx +4 -5
- package/src/components/Navigation/Nav/Nav.tsx +2 -6
- package/src/components/Navigation/Navbar/Navbar.tsx +2 -9
- package/src/components/Navigation/SideMenu/SideMenu.tsx +2 -6
- package/src/components/Pagination/Pagination.tsx +2 -10
- package/src/components/Popover/Popover.tsx +2 -9
- package/src/components/Progress/Progress.tsx +2 -7
- package/src/components/Rating/Rating.tsx +2 -10
- package/src/components/Spinner/Spinner.tsx +2 -7
- package/src/components/Steps/Steps.tsx +2 -10
- package/src/components/Tabs/Tabs.tsx +2 -9
- package/src/components/Toggle/Toggle.tsx +2 -10
- package/src/components/Tooltip/Tooltip.tsx +2 -5
- package/src/lib/composables/useAtomixGlass.ts +42 -143
- package/src/lib/composables/useAtomixGlassStyles.ts +61 -77
- package/src/lib/composables/usePerformanceMonitor.ts +5 -66
- package/src/lib/constants/components.ts +363 -46
- package/src/lib/types/components.ts +33 -1
- package/src/styles/01-settings/_settings.atomix-glass.scss +66 -28
- package/src/styles/02-tools/_tools.button.scss +51 -42
- package/src/styles/02-tools/_tools.glass.scss +45 -3
- package/src/styles/06-components/_components.atomix-glass.scss +116 -79
- package/src/components/AtomixGlass/PerformanceDashboard.tsx +0 -171
- package/src/components/AtomixGlass/animation-system.ts +0 -578
- package/src/components/AtomixGlass/deprecated/AtomixGlass.deprecated.tsx +0 -390
package/dist/heavy.js
CHANGED
|
@@ -25,7 +25,56 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
25
25
|
ACTIVE: "c-btn--active",
|
|
26
26
|
SELECTED: "c-btn--selected"
|
|
27
27
|
}
|
|
28
|
-
}, VIDEO_PLAYER_CLASSES_BASE = "c-video-player", VIDEO_PLAYER_CLASSES_VIDEO = "c-video-player__video", VIDEO_PLAYER_CLASSES_YOUTUBE = "c-video-player--youtube", VIDEO_PLAYER_CLASSES_LOADING = "c-video-player__loading", VIDEO_PLAYER_CLASSES_SPINNER = "c-video-player__spinner", VIDEO_PLAYER_CLASSES_CONTROLS = "c-video-player__controls", VIDEO_PLAYER_CLASSES_CONTROLS_VISIBLE = "c-video-player__controls--visible", VIDEO_PLAYER_CLASSES_PROGRESS_CONTAINER = "c-video-player__progress-container", VIDEO_PLAYER_CLASSES_PROGRESS_BAR = "c-video-player__progress-bar", VIDEO_PLAYER_CLASSES_PROGRESS_BUFFERED = "c-video-player__progress-buffered", VIDEO_PLAYER_CLASSES_PROGRESS_PLAYED = "c-video-player__progress-played", VIDEO_PLAYER_CLASSES_PROGRESS_THUMB = "c-video-player__progress-thumb", VIDEO_PLAYER_CLASSES_CONTROLS_ROW = "c-video-player__controls-row", VIDEO_PLAYER_CLASSES_CONTROLS_LEFT = "c-video-player__controls-left", VIDEO_PLAYER_CLASSES_CONTROLS_RIGHT = "c-video-player__controls-right", VIDEO_PLAYER_CLASSES_CONTROL_BUTTON = "c-video-player__control-button", VIDEO_PLAYER_CLASSES_VOLUME_CONTAINER = "c-video-player__volume-container", VIDEO_PLAYER_CLASSES_VOLUME_SLIDER = "c-video-player__volume-slider", VIDEO_PLAYER_CLASSES_VOLUME_BAR = "c-video-player__volume-bar", VIDEO_PLAYER_CLASSES_VOLUME_FILL = "c-video-player__volume-fill", VIDEO_PLAYER_CLASSES_TIME_DISPLAY = "c-video-player__time-display", VIDEO_PLAYER_CLASSES_SETTINGS_CONTAINER = "c-video-player__settings-container", VIDEO_PLAYER_CLASSES_SETTINGS_MENU = "c-video-player__settings-menu", VIDEO_PLAYER_CLASSES_SETTINGS_TABS = "c-video-player__settings-tabs", VIDEO_PLAYER_CLASSES_SETTINGS_TAB = "c-video-player__settings-tab", VIDEO_PLAYER_CLASSES_SETTINGS_TAB_ACTIVE = "c-video-player__settings-tab--active", VIDEO_PLAYER_CLASSES_SETTINGS_CONTENT = "c-video-player__settings-content", VIDEO_PLAYER_CLASSES_SETTINGS_OPTIONS = "c-video-player__settings-options", VIDEO_PLAYER_CLASSES_SETTINGS_OPTION = "c-video-player__settings-option", VIDEO_PLAYER_CLASSES_SETTINGS_OPTION_ACTIVE = "c-video-player__settings-option--active", VIDEO_PLAYER_CLASSES_AMBIENT = "c-video-player--ambient", VIDEO_PLAYER_CLASSES_AMBIENT_CANVAS = "c-video-player__ambient-canvas", VIDEO_PLAYER_CLASSES_GLASS = "c-video-player--glass", VIDEO_PLAYER_CLASSES_GLASS_OVERLAY = "c-video-player__glass-overlay", VIDEO_PLAYER_CLASSES_GLASS_CONTENT = "c-video-player__glass-content",
|
|
28
|
+
}, VIDEO_PLAYER_CLASSES_BASE = "c-video-player", VIDEO_PLAYER_CLASSES_VIDEO = "c-video-player__video", VIDEO_PLAYER_CLASSES_YOUTUBE = "c-video-player--youtube", VIDEO_PLAYER_CLASSES_LOADING = "c-video-player__loading", VIDEO_PLAYER_CLASSES_SPINNER = "c-video-player__spinner", VIDEO_PLAYER_CLASSES_CONTROLS = "c-video-player__controls", VIDEO_PLAYER_CLASSES_CONTROLS_VISIBLE = "c-video-player__controls--visible", VIDEO_PLAYER_CLASSES_PROGRESS_CONTAINER = "c-video-player__progress-container", VIDEO_PLAYER_CLASSES_PROGRESS_BAR = "c-video-player__progress-bar", VIDEO_PLAYER_CLASSES_PROGRESS_BUFFERED = "c-video-player__progress-buffered", VIDEO_PLAYER_CLASSES_PROGRESS_PLAYED = "c-video-player__progress-played", VIDEO_PLAYER_CLASSES_PROGRESS_THUMB = "c-video-player__progress-thumb", VIDEO_PLAYER_CLASSES_CONTROLS_ROW = "c-video-player__controls-row", VIDEO_PLAYER_CLASSES_CONTROLS_LEFT = "c-video-player__controls-left", VIDEO_PLAYER_CLASSES_CONTROLS_RIGHT = "c-video-player__controls-right", VIDEO_PLAYER_CLASSES_CONTROL_BUTTON = "c-video-player__control-button", VIDEO_PLAYER_CLASSES_VOLUME_CONTAINER = "c-video-player__volume-container", VIDEO_PLAYER_CLASSES_VOLUME_SLIDER = "c-video-player__volume-slider", VIDEO_PLAYER_CLASSES_VOLUME_BAR = "c-video-player__volume-bar", VIDEO_PLAYER_CLASSES_VOLUME_FILL = "c-video-player__volume-fill", VIDEO_PLAYER_CLASSES_TIME_DISPLAY = "c-video-player__time-display", VIDEO_PLAYER_CLASSES_SETTINGS_CONTAINER = "c-video-player__settings-container", VIDEO_PLAYER_CLASSES_SETTINGS_MENU = "c-video-player__settings-menu", VIDEO_PLAYER_CLASSES_SETTINGS_TABS = "c-video-player__settings-tabs", VIDEO_PLAYER_CLASSES_SETTINGS_TAB = "c-video-player__settings-tab", VIDEO_PLAYER_CLASSES_SETTINGS_TAB_ACTIVE = "c-video-player__settings-tab--active", VIDEO_PLAYER_CLASSES_SETTINGS_CONTENT = "c-video-player__settings-content", VIDEO_PLAYER_CLASSES_SETTINGS_OPTIONS = "c-video-player__settings-options", VIDEO_PLAYER_CLASSES_SETTINGS_OPTION = "c-video-player__settings-option", VIDEO_PLAYER_CLASSES_SETTINGS_OPTION_ACTIVE = "c-video-player__settings-option--active", VIDEO_PLAYER_CLASSES_AMBIENT = "c-video-player--ambient", VIDEO_PLAYER_CLASSES_AMBIENT_CANVAS = "c-video-player__ambient-canvas", VIDEO_PLAYER_CLASSES_GLASS = "c-video-player--glass", VIDEO_PLAYER_CLASSES_GLASS_OVERLAY = "c-video-player__glass-overlay", VIDEO_PLAYER_CLASSES_GLASS_CONTENT = "c-video-player__glass-content", GLASS_DEFAULTS_BUTTON = {
|
|
29
|
+
displacementScale: 16,
|
|
30
|
+
saturation: 180,
|
|
31
|
+
elasticity: 0
|
|
32
|
+
}, GLASS_DEFAULTS_BADGE = {
|
|
33
|
+
displacementScale: 14,
|
|
34
|
+
borderRadius: 16,
|
|
35
|
+
elasticity: 0
|
|
36
|
+
}, GLASS_DEFAULTS_SPINNER = {
|
|
37
|
+
displacementScale: 12,
|
|
38
|
+
elasticity: 0
|
|
39
|
+
}, GLASS_BORDER_GRADIENT = {
|
|
40
|
+
BASE_ANGLE: 135,
|
|
41
|
+
ANGLE_MULTIPLIER: .5,
|
|
42
|
+
VELOCITY_ANGLE_MULTIPLIER: .5,
|
|
43
|
+
CHROMATIC_OFFSET: 1.5,
|
|
44
|
+
STOP_1: {
|
|
45
|
+
MIN: 10,
|
|
46
|
+
BASE: 33,
|
|
47
|
+
get MULTIPLIER() {
|
|
48
|
+
return .009 * this.BASE;
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
STOP_2: {
|
|
52
|
+
MAX: 90,
|
|
53
|
+
BASE: 66,
|
|
54
|
+
get MULTIPLIER() {
|
|
55
|
+
return .006 * this.BASE;
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
OPACITY: {
|
|
59
|
+
/** Matches $glass-border-1-opacity (0.08) */
|
|
60
|
+
BASE_1: .08,
|
|
61
|
+
get BASE_2() {
|
|
62
|
+
return 3.33 * this.BASE_1;
|
|
63
|
+
},
|
|
64
|
+
get BASE_3() {
|
|
65
|
+
return 2.66 * this.BASE_1;
|
|
66
|
+
},
|
|
67
|
+
get BASE_4() {
|
|
68
|
+
return 5 * this.BASE_1;
|
|
69
|
+
},
|
|
70
|
+
get MULTIPLIER_LOW() {
|
|
71
|
+
return .066 * this.BASE_1;
|
|
72
|
+
},
|
|
73
|
+
get MULTIPLIER_HIGH() {
|
|
74
|
+
return .1 * this.BASE_1;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}, ATOMIX_GLASS = {
|
|
29
78
|
BASE_CLASS: "c-atomix-glass",
|
|
30
79
|
CONTAINER_CLASS: "c-atomix-glass__container",
|
|
31
80
|
INNER_CLASS: "c-atomix-glass__inner",
|
|
@@ -36,6 +85,22 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
36
85
|
BORDER_BACKDROP_CLASS: "c-atomix-glass__border-backdrop",
|
|
37
86
|
BORDER_1_CLASS: "c-atomix-glass__border-1",
|
|
38
87
|
BORDER_2_CLASS: "c-atomix-glass__border-2",
|
|
88
|
+
/** Centralized liquid glass rim configuration */
|
|
89
|
+
BORDER: {
|
|
90
|
+
WIDTH_CSS_VAR: "--atomix-glass-border-width",
|
|
91
|
+
DEFAULT_WIDTH: "0.5px",
|
|
92
|
+
GRADIENT_CSS_VARS: {
|
|
93
|
+
GRADIENT_1: "--atomix-glass-border-gradient-1",
|
|
94
|
+
GRADIENT_2: "--atomix-glass-border-gradient-2"
|
|
95
|
+
},
|
|
96
|
+
GRADIENT: GLASS_BORDER_GRADIENT,
|
|
97
|
+
OVER_LIGHT: {
|
|
98
|
+
opacity: .7
|
|
99
|
+
},
|
|
100
|
+
DARK: {
|
|
101
|
+
opacity: .35
|
|
102
|
+
}
|
|
103
|
+
},
|
|
39
104
|
HOVER_1_CLASS: "c-atomix-glass__hover-1",
|
|
40
105
|
HOVER_2_CLASS: "c-atomix-glass__hover-2",
|
|
41
106
|
HOVER_3_CLASS: "c-atomix-glass__hover-3",
|
|
@@ -64,25 +129,22 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
64
129
|
SHADER: "c-atomix-glass--shader"
|
|
65
130
|
},
|
|
66
131
|
DEFAULTS: {
|
|
67
|
-
|
|
132
|
+
/** Subtle refraction — Apple UI chrome avoids heavy liquid distortion */
|
|
133
|
+
DISPLACEMENT_SCALE: 28,
|
|
68
134
|
get BLUR_AMOUNT() {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
// Saturate relative to intensity
|
|
75
|
-
},
|
|
135
|
+
// Apple Music sidebar / player bar: ~20–40px frost (see $glass-backdrop-filter)
|
|
136
|
+
return Math.max(20, .72 * this.DISPLACEMENT_SCALE);
|
|
137
|
+
},
|
|
138
|
+
/** Fixed 180% matches Apple's saturate(180%) backdrop recipe */
|
|
139
|
+
SATURATION: 180,
|
|
76
140
|
get ABERRATION_INTENSITY() {
|
|
77
|
-
return .
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
ELASTICITY: .15,
|
|
141
|
+
return .02 * this.DISPLACEMENT_SCALE;
|
|
142
|
+
},
|
|
143
|
+
ELASTICITY: .05,
|
|
81
144
|
get CORNER_RADIUS() {
|
|
82
145
|
return 16;
|
|
83
146
|
// Use 16 to match SCSS design system (was 20)
|
|
84
147
|
},
|
|
85
|
-
PADDING: "0",
|
|
86
148
|
MODE: "standard",
|
|
87
149
|
OVER_LIGHT: !1,
|
|
88
150
|
ENABLE_OVER_LIGHT_LAYERS: !0,
|
|
@@ -98,19 +160,29 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
98
160
|
},
|
|
99
161
|
CONSTANTS: {
|
|
100
162
|
ACTIVATION_ZONE: 200,
|
|
101
|
-
LERP_FACTOR: .
|
|
163
|
+
LERP_FACTOR: .05,
|
|
164
|
+
// Lower = more viscous, liquid-smooth tracking (Apple feel)
|
|
102
165
|
SMOOTHSTEP_POWER: 2.5,
|
|
103
166
|
MIN_BLUR: .1,
|
|
104
167
|
MOUSE_INFLUENCE_DIVISOR: 100,
|
|
105
168
|
EDGE_FADE_PIXELS: 2,
|
|
106
|
-
//
|
|
107
|
-
|
|
169
|
+
// Interaction intensity multipliers shared by the hook and the imperative style updater
|
|
170
|
+
INTERACTION: {
|
|
171
|
+
HOVER_INTENSITY: 1.4,
|
|
172
|
+
ACTIVE_INTENSITY: 1.6
|
|
173
|
+
},
|
|
174
|
+
// Elasticity physics constants — Apple-tuned: soft springs, fast settling, minimal stretch
|
|
175
|
+
ELASTICITY_TRANSLATION_FACTOR: .06,
|
|
176
|
+
// Subtler elastic shift (was 0.1)
|
|
108
177
|
ELASTICITY_DISTANCE_THRESHOLD: 200,
|
|
109
178
|
ELASTICITY_COMPRESSION_FACTOR: .3,
|
|
110
|
-
ELASTICITY_STIFFNESS: .
|
|
111
|
-
|
|
179
|
+
ELASTICITY_STIFFNESS: .06,
|
|
180
|
+
// Softer springs = gentler motion (was 0.1)
|
|
181
|
+
ELASTICITY_DAMPING: .88,
|
|
182
|
+
// Fast settling, no wobble (was 0.76)
|
|
112
183
|
ELASTICITY_VELOCITY_FACTOR: .65,
|
|
113
|
-
ELASTICITY_STRETCH_RATIO: .
|
|
184
|
+
ELASTICITY_STRETCH_RATIO: .25,
|
|
185
|
+
// Less visible surface tension stretch (was 0.45)
|
|
114
186
|
ELASTICITY_MAGNIFICATION_BASE: 1.02,
|
|
115
187
|
// Note: This default must match the SCSS variable --atomix-radius-md
|
|
116
188
|
// @see src/styles/01-settings/_settings.global.scss
|
|
@@ -124,55 +196,16 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
124
196
|
},
|
|
125
197
|
// Gradient calculation constants
|
|
126
198
|
GRADIENT: {
|
|
127
|
-
BASE_ANGLE:
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
// Minimum percentage for border stop 1
|
|
138
|
-
BASE: 33,
|
|
139
|
-
// Base percentage for border stop 1
|
|
140
|
-
get MULTIPLIER() {
|
|
141
|
-
return .009 * this.BASE;
|
|
142
|
-
}
|
|
143
|
-
},
|
|
144
|
-
BORDER_STOP_2: {
|
|
145
|
-
MAX: 90,
|
|
146
|
-
// Maximum percentage for border stop 2
|
|
147
|
-
BASE: 66,
|
|
148
|
-
// Base percentage for border stop 2
|
|
149
|
-
get MULTIPLIER() {
|
|
150
|
-
return .006 * this.BASE;
|
|
151
|
-
}
|
|
152
|
-
},
|
|
153
|
-
BORDER_OPACITY: {
|
|
154
|
-
BASE_1: .12,
|
|
155
|
-
// Base opacity for border gradient 1
|
|
156
|
-
get BASE_2() {
|
|
157
|
-
return 3.33 * this.BASE_1;
|
|
158
|
-
},
|
|
159
|
-
// Base opacity for border gradient 2
|
|
160
|
-
get BASE_3() {
|
|
161
|
-
return 2.66 * this.BASE_1;
|
|
162
|
-
},
|
|
163
|
-
// Base opacity for border gradient 3
|
|
164
|
-
get BASE_4() {
|
|
165
|
-
return 5 * this.BASE_1;
|
|
166
|
-
},
|
|
167
|
-
// Base opacity for border gradient 4
|
|
168
|
-
get MULTIPLIER_LOW() {
|
|
169
|
-
return .066 * this.BASE_1;
|
|
170
|
-
},
|
|
171
|
-
// Low multiplier for mouse influence on opacity
|
|
172
|
-
get MULTIPLIER_HIGH() {
|
|
173
|
-
return .1 * this.BASE_1;
|
|
174
|
-
}
|
|
175
|
-
},
|
|
199
|
+
BASE_ANGLE: GLASS_BORDER_GRADIENT.BASE_ANGLE,
|
|
200
|
+
ANGLE_MULTIPLIER: GLASS_BORDER_GRADIENT.ANGLE_MULTIPLIER,
|
|
201
|
+
VELOCITY_ANGLE_MULTIPLIER: GLASS_BORDER_GRADIENT.VELOCITY_ANGLE_MULTIPLIER,
|
|
202
|
+
CHROMATIC_OFFSET: GLASS_BORDER_GRADIENT.CHROMATIC_OFFSET,
|
|
203
|
+
/** @deprecated Use ATOMIX_GLASS.BORDER.GRADIENT.STOP_1 */
|
|
204
|
+
BORDER_STOP_1: GLASS_BORDER_GRADIENT.STOP_1,
|
|
205
|
+
/** @deprecated Use ATOMIX_GLASS.BORDER.GRADIENT.STOP_2 */
|
|
206
|
+
BORDER_STOP_2: GLASS_BORDER_GRADIENT.STOP_2,
|
|
207
|
+
/** @deprecated Use ATOMIX_GLASS.BORDER.GRADIENT.OPACITY */
|
|
208
|
+
BORDER_OPACITY: GLASS_BORDER_GRADIENT.OPACITY,
|
|
176
209
|
CENTER_POSITION: 50,
|
|
177
210
|
// Center position percentage (50%)
|
|
178
211
|
HOVER_POSITION: {
|
|
@@ -205,8 +238,8 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
205
238
|
return 2 * this.BLACK_STOP;
|
|
206
239
|
},
|
|
207
240
|
// End percentage for black hover 1
|
|
208
|
-
WHITE_START: .
|
|
209
|
-
//
|
|
241
|
+
WHITE_START: .35,
|
|
242
|
+
// Gentler hover flash — Apple hover is barely visible
|
|
210
243
|
get WHITE_STOP() {
|
|
211
244
|
return this.BLACK_END - 10;
|
|
212
245
|
}
|
|
@@ -224,8 +257,8 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
224
257
|
return 2 * this.BLACK_STOP;
|
|
225
258
|
},
|
|
226
259
|
// End percentage for black hover 2
|
|
227
|
-
WHITE_START:
|
|
228
|
-
//
|
|
260
|
+
WHITE_START: .7,
|
|
261
|
+
// Gentler hover flash
|
|
229
262
|
get WHITE_STOP() {
|
|
230
263
|
return this.BLACK_END;
|
|
231
264
|
}
|
|
@@ -243,8 +276,8 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
243
276
|
return 2 * this.BLACK_STOP;
|
|
244
277
|
},
|
|
245
278
|
// End percentage for black hover 3
|
|
246
|
-
WHITE_START:
|
|
247
|
-
//
|
|
279
|
+
WHITE_START: .7,
|
|
280
|
+
// Gentler hover flash
|
|
248
281
|
get WHITE_STOP() {
|
|
249
282
|
return this.BLACK_END;
|
|
250
283
|
}
|
|
@@ -254,13 +287,13 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
254
287
|
BASE_GRADIENT: {
|
|
255
288
|
ANGLE: 135,
|
|
256
289
|
// Gradient angle in degrees
|
|
257
|
-
BLACK_START_BASE: .
|
|
290
|
+
BLACK_START_BASE: .1,
|
|
258
291
|
// Base start opacity for black
|
|
259
292
|
get BLACK_START_MULTIPLIER() {
|
|
260
293
|
return .02 * this.BLACK_START_BASE;
|
|
261
294
|
},
|
|
262
295
|
// Multiplier for mouse X influence on start
|
|
263
|
-
BLACK_MID_BASE: .
|
|
296
|
+
BLACK_MID_BASE: .07,
|
|
264
297
|
// Base mid opacity for black
|
|
265
298
|
get BLACK_MID_MULTIPLIER() {
|
|
266
299
|
return .02 * this.BLACK_MID_BASE;
|
|
@@ -281,7 +314,7 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
281
314
|
}
|
|
282
315
|
},
|
|
283
316
|
OVERLAY_GRADIENT: {
|
|
284
|
-
BLACK_START_BASE: .
|
|
317
|
+
BLACK_START_BASE: .08,
|
|
285
318
|
// Base start opacity for black overlay
|
|
286
319
|
get BLACK_START_MULTIPLIER() {
|
|
287
320
|
return .025 * this.BLACK_START_BASE;
|
|
@@ -305,14 +338,14 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
305
338
|
return .416 * this.BLACK_START_BASE;
|
|
306
339
|
}
|
|
307
340
|
},
|
|
308
|
-
// Overlay highlight constants
|
|
341
|
+
// Overlay highlight constants — Apple places specular at the top-center
|
|
309
342
|
OVERLAY_HIGHLIGHT: {
|
|
310
|
-
POSITION_X:
|
|
311
|
-
//
|
|
312
|
-
POSITION_Y:
|
|
313
|
-
//
|
|
314
|
-
WHITE_OPACITY: .
|
|
315
|
-
//
|
|
343
|
+
POSITION_X: 50,
|
|
344
|
+
// Centered horizontal — Apple's top-center specular
|
|
345
|
+
POSITION_Y: 5,
|
|
346
|
+
// Very top — catches light like a curved glass surface
|
|
347
|
+
WHITE_OPACITY: .28,
|
|
348
|
+
// Softer specular — visible but not glaring
|
|
316
349
|
get STOP() {
|
|
317
350
|
return 150 * this.WHITE_OPACITY;
|
|
318
351
|
},
|
|
@@ -333,6 +366,10 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
333
366
|
SATURATION: {
|
|
334
367
|
HIGH_CONTRAST: 200
|
|
335
368
|
},
|
|
369
|
+
// Container shadows — hairline inner catch + soft floating lift (Apple player bar)
|
|
370
|
+
CONTAINER_SHADOW: {
|
|
371
|
+
LIGHT: "inset 0 0.5px 0 rgba(255, 255, 255, 0.32), inset 0 1px 2px rgba(255, 255, 255, 0.06), 0 4px 16px rgba(0, 0, 0, 0.12), 0 1px 4px rgba(0, 0, 0, 0.08)"
|
|
372
|
+
},
|
|
336
373
|
// Phase 1: Animation System Constants
|
|
337
374
|
ANIMATION: {
|
|
338
375
|
// Breathing effect timing (in milliseconds)
|
|
@@ -372,7 +409,331 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
372
409
|
}
|
|
373
410
|
}
|
|
374
411
|
}
|
|
375
|
-
}
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
var commonjsGlobal = "undefined" != typeof globalThis ? globalThis : "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof self ? self : {};
|
|
415
|
+
|
|
416
|
+
function getDefaultExportFromCjs(x) {
|
|
417
|
+
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x.default : x;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
var fails$8 = function(exec) {
|
|
421
|
+
try {
|
|
422
|
+
return !!exec();
|
|
423
|
+
} catch (error) {
|
|
424
|
+
return !0;
|
|
425
|
+
}
|
|
426
|
+
}, functionBindNative = !fails$8((function() {
|
|
427
|
+
// eslint-disable-next-line es/no-function-prototype-bind -- safe
|
|
428
|
+
var test = function() {/* empty */}.bind();
|
|
429
|
+
// eslint-disable-next-line no-prototype-builtins -- safe
|
|
430
|
+
return "function" != typeof test || test.hasOwnProperty("prototype");
|
|
431
|
+
})), NATIVE_BIND$3 = functionBindNative, FunctionPrototype$1 = Function.prototype, call$5 = FunctionPrototype$1.call, uncurryThisWithBind = NATIVE_BIND$3 && FunctionPrototype$1.bind.bind(call$5, call$5), functionUncurryThis = NATIVE_BIND$3 ? uncurryThisWithBind : function(fn) {
|
|
432
|
+
return function() {
|
|
433
|
+
return call$5.apply(fn, arguments);
|
|
434
|
+
};
|
|
435
|
+
}, objectIsPrototypeOf = functionUncurryThis({}.isPrototypeOf), check = function(it) {
|
|
436
|
+
return it && it.Math === Math && it;
|
|
437
|
+
}, globalThis_1 =
|
|
438
|
+
// eslint-disable-next-line es/no-global-this -- safe
|
|
439
|
+
check("object" == typeof globalThis && globalThis) || check("object" == typeof window && window) ||
|
|
440
|
+
// eslint-disable-next-line no-restricted-globals -- safe
|
|
441
|
+
check("object" == typeof self && self) || check("object" == typeof commonjsGlobal && commonjsGlobal) || check("object" == typeof commonjsGlobal && commonjsGlobal) ||
|
|
442
|
+
// eslint-disable-next-line no-new-func -- fallback
|
|
443
|
+
function() {
|
|
444
|
+
return this;
|
|
445
|
+
}() || Function("return this")(), NATIVE_BIND$2 = functionBindNative, FunctionPrototype = Function.prototype, apply$1 = FunctionPrototype.apply, call$4 = FunctionPrototype.call, functionApply = "object" == typeof Reflect && Reflect.apply || (NATIVE_BIND$2 ? call$4.bind(apply$1) : function() {
|
|
446
|
+
return call$4.apply(apply$1, arguments);
|
|
447
|
+
}), uncurryThis$7 = functionUncurryThis, toString$3 = uncurryThis$7({}.toString), stringSlice = uncurryThis$7("".slice), classofRaw$2 = function(it) {
|
|
448
|
+
return stringSlice(toString$3(it), 8, -1);
|
|
449
|
+
}, classofRaw$1 = classofRaw$2, uncurryThis$6 = functionUncurryThis, functionUncurryThisClause = function(fn) {
|
|
450
|
+
// Nashorn bug:
|
|
451
|
+
// https://github.com/zloirock/core-js/issues/1128
|
|
452
|
+
// https://github.com/zloirock/core-js/issues/1130
|
|
453
|
+
if ("Function" === classofRaw$1(fn)) return uncurryThis$6(fn);
|
|
454
|
+
}, documentAll = "object" == typeof document && document.all, isCallable$8 = void 0 === documentAll && void 0 !== documentAll ? function(argument) {
|
|
455
|
+
return "function" == typeof argument || argument === documentAll;
|
|
456
|
+
} : function(argument) {
|
|
457
|
+
return "function" == typeof argument;
|
|
458
|
+
}, objectGetOwnPropertyDescriptor = {}, descriptors = !fails$8((function() {
|
|
459
|
+
// eslint-disable-next-line es/no-object-defineproperty -- required for testing
|
|
460
|
+
return 7 !== Object.defineProperty({}, 1, {
|
|
461
|
+
get: function() {
|
|
462
|
+
return 7;
|
|
463
|
+
}
|
|
464
|
+
})[1];
|
|
465
|
+
})), NATIVE_BIND$1 = functionBindNative, call$3 = Function.prototype.call, functionCall = NATIVE_BIND$1 ? call$3.bind(call$3) : function() {
|
|
466
|
+
return call$3.apply(call$3, arguments);
|
|
467
|
+
}, objectPropertyIsEnumerable = {}, $propertyIsEnumerable = {}.propertyIsEnumerable, getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor, NASHORN_BUG = getOwnPropertyDescriptor$1 && !$propertyIsEnumerable.call({
|
|
468
|
+
1: 2
|
|
469
|
+
}, 1);
|
|
470
|
+
|
|
471
|
+
// `Object.prototype.propertyIsEnumerable` method implementation
|
|
472
|
+
// https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable
|
|
473
|
+
objectPropertyIsEnumerable.f = NASHORN_BUG ? function(V) {
|
|
474
|
+
var descriptor = getOwnPropertyDescriptor$1(this, V);
|
|
475
|
+
return !!descriptor && descriptor.enumerable;
|
|
476
|
+
} : $propertyIsEnumerable;
|
|
477
|
+
|
|
478
|
+
var match, version, createPropertyDescriptor$2 = function(bitmap, value) {
|
|
479
|
+
return {
|
|
480
|
+
enumerable: !(1 & bitmap),
|
|
481
|
+
configurable: !(2 & bitmap),
|
|
482
|
+
writable: !(4 & bitmap),
|
|
483
|
+
value: value
|
|
484
|
+
};
|
|
485
|
+
}, fails$5 = fails$8, classof$3 = classofRaw$2, $Object$3 = Object, split = functionUncurryThis("".split), indexedObject = fails$5((function() {
|
|
486
|
+
// throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
|
|
487
|
+
// eslint-disable-next-line no-prototype-builtins -- safe
|
|
488
|
+
return !$Object$3("z").propertyIsEnumerable(0);
|
|
489
|
+
})) ? function(it) {
|
|
490
|
+
return "String" === classof$3(it) ? split(it, "") : $Object$3(it);
|
|
491
|
+
} : $Object$3, isNullOrUndefined$2 = function(it) {
|
|
492
|
+
return null == it;
|
|
493
|
+
}, isNullOrUndefined$1 = isNullOrUndefined$2, $TypeError$6 = TypeError, requireObjectCoercible$3 = function(it) {
|
|
494
|
+
if (isNullOrUndefined$1(it)) throw new $TypeError$6("Can't call method on " + it);
|
|
495
|
+
return it;
|
|
496
|
+
}, IndexedObject = indexedObject, requireObjectCoercible$2 = requireObjectCoercible$3, toIndexedObject$2 = function(it) {
|
|
497
|
+
return IndexedObject(requireObjectCoercible$2(it));
|
|
498
|
+
}, isCallable$7 = isCallable$8, isObject$5 = function(it) {
|
|
499
|
+
return "object" == typeof it ? null !== it : isCallable$7(it);
|
|
500
|
+
}, path$3 = {}, path$2 = path$3, globalThis$a = globalThis_1, isCallable$6 = isCallable$8, aFunction = function(variable) {
|
|
501
|
+
return isCallable$6(variable) ? variable : void 0;
|
|
502
|
+
}, navigator$1 = globalThis_1.navigator, userAgent$1 = navigator$1 && navigator$1.userAgent, globalThis$8 = globalThis_1, userAgent = userAgent$1 ? String(userAgent$1) : "", process$1 = globalThis$8.process, Deno = globalThis$8.Deno, versions = process$1 && process$1.versions || Deno && Deno.version, v8 = versions && versions.v8;
|
|
503
|
+
|
|
504
|
+
v8 && (
|
|
505
|
+
// in old Chrome, versions of V8 isn't V8 = Chrome / 10
|
|
506
|
+
// but their correct versions are not interesting for us
|
|
507
|
+
version = (match = v8.split("."))[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1])),
|
|
508
|
+
// BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0`
|
|
509
|
+
// so check `userAgent` even if `.v8` exists, but 0
|
|
510
|
+
!version && userAgent && (!(match = userAgent.match(/Edge\/(\d+)/)) || match[1] >= 74) && (match = userAgent.match(/Chrome\/(\d+)/)) && (version = +match[1]);
|
|
511
|
+
|
|
512
|
+
var V8_VERSION = version, fails$4 = fails$8, $String$3 = globalThis_1.String, symbolConstructorDetection = !!Object.getOwnPropertySymbols && !fails$4((function() {
|
|
513
|
+
var symbol = Symbol("symbol detection");
|
|
514
|
+
// Chrome 38 Symbol has incorrect toString conversion
|
|
515
|
+
// `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances
|
|
516
|
+
// nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will,
|
|
517
|
+
// of course, fail.
|
|
518
|
+
return !$String$3(symbol) || !(Object(symbol) instanceof Symbol) ||
|
|
519
|
+
// Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances
|
|
520
|
+
!Symbol.sham && V8_VERSION && V8_VERSION < 41;
|
|
521
|
+
})), useSymbolAsUid = symbolConstructorDetection && !Symbol.sham && "symbol" == typeof Symbol.iterator, isCallable$5 = isCallable$8, isPrototypeOf$1 = objectIsPrototypeOf, $Object$2 = Object, isSymbol$2 = useSymbolAsUid ? function(it) {
|
|
522
|
+
return "symbol" == typeof it;
|
|
523
|
+
} : function(it) {
|
|
524
|
+
var $Symbol = function(namespace, method) {
|
|
525
|
+
return arguments.length < 2 ? aFunction(path$2[namespace]) || aFunction(globalThis$a[namespace]) : path$2[namespace] && path$2[namespace][method] || globalThis$a[namespace] && globalThis$a[namespace][method];
|
|
526
|
+
}("Symbol");
|
|
527
|
+
return isCallable$5($Symbol) && isPrototypeOf$1($Symbol.prototype, $Object$2(it));
|
|
528
|
+
}, $String$2 = String, isCallable$4 = isCallable$8, $TypeError$5 = TypeError, aCallable$2 = function(argument) {
|
|
529
|
+
if (isCallable$4(argument)) return argument;
|
|
530
|
+
throw new $TypeError$5(function(argument) {
|
|
531
|
+
try {
|
|
532
|
+
return $String$2(argument);
|
|
533
|
+
} catch (error) {
|
|
534
|
+
return "Object";
|
|
535
|
+
}
|
|
536
|
+
}(argument) + " is not a function");
|
|
537
|
+
}, aCallable$1 = aCallable$2, isNullOrUndefined = isNullOrUndefined$2, call$2 = functionCall, isCallable$3 = isCallable$8, isObject$4 = isObject$5, $TypeError$4 = TypeError, sharedStore = {
|
|
538
|
+
exports: {}
|
|
539
|
+
}, globalThis$6 = globalThis_1, defineProperty = Object.defineProperty, globalThis$5 = globalThis_1, store$1 = sharedStore.exports = globalThis$5["__core-js_shared__"] || function(key, value) {
|
|
540
|
+
try {
|
|
541
|
+
defineProperty(globalThis$6, key, {
|
|
542
|
+
value: value,
|
|
543
|
+
configurable: !0,
|
|
544
|
+
writable: !0
|
|
545
|
+
});
|
|
546
|
+
} catch (error) {
|
|
547
|
+
globalThis$6[key] = value;
|
|
548
|
+
}
|
|
549
|
+
return value;
|
|
550
|
+
}("__core-js_shared__", {});
|
|
551
|
+
|
|
552
|
+
/* eslint-disable es/no-symbol -- required for testing */ (store$1.versions || (store$1.versions = [])).push({
|
|
553
|
+
version: "3.43.0",
|
|
554
|
+
mode: "pure",
|
|
555
|
+
copyright: "© 2014-2025 Denis Pushkarev (zloirock.ru)",
|
|
556
|
+
license: "https://github.com/zloirock/core-js/blob/v3.43.0/LICENSE",
|
|
557
|
+
source: "https://github.com/zloirock/core-js"
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
var key, value, store = sharedStore.exports, requireObjectCoercible$1 = requireObjectCoercible$3, $Object$1 = Object, hasOwnProperty = functionUncurryThis({}.hasOwnProperty), hasOwnProperty_1 = Object.hasOwn || function(it, key) {
|
|
561
|
+
return hasOwnProperty($Object$1(requireObjectCoercible$1(it)), key);
|
|
562
|
+
}, uncurryThis$3 = functionUncurryThis, id = 0, postfix = Math.random(), toString$2 = uncurryThis$3(1.1.toString), hasOwn$2 = hasOwnProperty_1, NATIVE_SYMBOL = symbolConstructorDetection, USE_SYMBOL_AS_UID = useSymbolAsUid, Symbol$1 = globalThis_1.Symbol, WellKnownSymbolsStore = store[key = "wks"] || (store[key] = value || {}), createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol$1.for || Symbol$1 : Symbol$1 && Symbol$1.withoutSetter || function(key) {
|
|
563
|
+
return "Symbol(" + (void 0 === key ? "" : key) + ")_" + toString$2(++id + postfix, 36);
|
|
564
|
+
}, wellKnownSymbol$5 = function(name) {
|
|
565
|
+
return hasOwn$2(WellKnownSymbolsStore, name) || (WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn$2(Symbol$1, name) ? Symbol$1[name] : createWellKnownSymbol("Symbol." + name)),
|
|
566
|
+
WellKnownSymbolsStore[name];
|
|
567
|
+
}, call$1 = functionCall, isObject$3 = isObject$5, isSymbol$1 = isSymbol$2, $TypeError$3 = TypeError, TO_PRIMITIVE = wellKnownSymbol$5("toPrimitive"), toPrimitive = function(input, pref) {
|
|
568
|
+
if (!isObject$3(input) || isSymbol$1(input)) return input;
|
|
569
|
+
var result, func, exoticToPrim = (func = input[TO_PRIMITIVE], isNullOrUndefined(func) ? void 0 : aCallable$1(func));
|
|
570
|
+
if (exoticToPrim) {
|
|
571
|
+
if (void 0 === pref && (pref = "default"), result = call$1(exoticToPrim, input, pref),
|
|
572
|
+
!isObject$3(result) || isSymbol$1(result)) return result;
|
|
573
|
+
throw new $TypeError$3("Can't convert object to primitive value");
|
|
574
|
+
}
|
|
575
|
+
return void 0 === pref && (pref = "number"), function(input, pref) {
|
|
576
|
+
var fn, val;
|
|
577
|
+
if ("string" === pref && isCallable$3(fn = input.toString) && !isObject$4(val = call$2(fn, input))) return val;
|
|
578
|
+
if (isCallable$3(fn = input.valueOf) && !isObject$4(val = call$2(fn, input))) return val;
|
|
579
|
+
if ("string" !== pref && isCallable$3(fn = input.toString) && !isObject$4(val = call$2(fn, input))) return val;
|
|
580
|
+
throw new $TypeError$4("Can't convert object to primitive value");
|
|
581
|
+
}(input, pref);
|
|
582
|
+
}, isSymbol = isSymbol$2, toPropertyKey$2 = function(argument) {
|
|
583
|
+
var key = toPrimitive(argument, "string");
|
|
584
|
+
return isSymbol(key) ? key : key + "";
|
|
585
|
+
}, isObject$2 = isObject$5, document$1 = globalThis_1.document, EXISTS = isObject$2(document$1) && isObject$2(document$1.createElement), ie8DomDefine = !descriptors && !fails$8((function() {
|
|
586
|
+
// eslint-disable-next-line es/no-object-defineproperty -- required for testing
|
|
587
|
+
return 7 !== Object.defineProperty((it = "div", EXISTS ? document$1.createElement(it) : {}), "a", {
|
|
588
|
+
get: function() {
|
|
589
|
+
return 7;
|
|
590
|
+
}
|
|
591
|
+
}).a;
|
|
592
|
+
var it;
|
|
593
|
+
})), DESCRIPTORS$3 = descriptors, call = functionCall, propertyIsEnumerableModule = objectPropertyIsEnumerable, createPropertyDescriptor$1 = createPropertyDescriptor$2, toIndexedObject$1 = toIndexedObject$2, toPropertyKey$1 = toPropertyKey$2, hasOwn$1 = hasOwnProperty_1, IE8_DOM_DEFINE$1 = ie8DomDefine, $getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor;
|
|
594
|
+
|
|
595
|
+
// `Object.getOwnPropertyDescriptor` method
|
|
596
|
+
// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
|
|
597
|
+
objectGetOwnPropertyDescriptor.f = DESCRIPTORS$3 ? $getOwnPropertyDescriptor$1 : function(O, P) {
|
|
598
|
+
if (O = toIndexedObject$1(O), P = toPropertyKey$1(P), IE8_DOM_DEFINE$1) try {
|
|
599
|
+
return $getOwnPropertyDescriptor$1(O, P);
|
|
600
|
+
} catch (error) {/* empty */}
|
|
601
|
+
if (hasOwn$1(O, P)) return createPropertyDescriptor$1(!call(propertyIsEnumerableModule.f, O, P), O[P]);
|
|
602
|
+
};
|
|
603
|
+
|
|
604
|
+
var fails$2 = fails$8, isCallable$2 = isCallable$8, replacement = /#|\.prototype\./, isForced$1 = function(feature, detection) {
|
|
605
|
+
var value = data[normalize(feature)];
|
|
606
|
+
return value === POLYFILL || value !== NATIVE && (isCallable$2(detection) ? fails$2(detection) : !!detection);
|
|
607
|
+
}, normalize = isForced$1.normalize = function(string) {
|
|
608
|
+
return String(string).replace(replacement, ".").toLowerCase();
|
|
609
|
+
}, data = isForced$1.data = {}, NATIVE = isForced$1.NATIVE = "N", POLYFILL = isForced$1.POLYFILL = "P", isForced_1 = isForced$1, aCallable = aCallable$2, NATIVE_BIND = functionBindNative, bind$1 = functionUncurryThisClause(functionUncurryThisClause.bind), objectDefineProperty = {}, v8PrototypeDefineBug = descriptors && fails$8((function() {
|
|
610
|
+
// eslint-disable-next-line es/no-object-defineproperty -- required for testing
|
|
611
|
+
return 42 !== Object.defineProperty((function() {/* empty */}), "prototype", {
|
|
612
|
+
value: 42,
|
|
613
|
+
writable: !1
|
|
614
|
+
}).prototype;
|
|
615
|
+
})), isObject$1 = isObject$5, $String$1 = String, $TypeError$2 = TypeError, DESCRIPTORS$1 = descriptors, IE8_DOM_DEFINE = ie8DomDefine, V8_PROTOTYPE_DEFINE_BUG = v8PrototypeDefineBug, anObject = function(argument) {
|
|
616
|
+
if (isObject$1(argument)) return argument;
|
|
617
|
+
throw new $TypeError$2($String$1(argument) + " is not an object");
|
|
618
|
+
}, toPropertyKey = toPropertyKey$2, $TypeError$1 = TypeError, $defineProperty = Object.defineProperty, $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
|
|
619
|
+
|
|
620
|
+
// `Object.defineProperty` method
|
|
621
|
+
// https://tc39.es/ecma262/#sec-object.defineproperty
|
|
622
|
+
objectDefineProperty.f = DESCRIPTORS$1 ? V8_PROTOTYPE_DEFINE_BUG ? function(O, P, Attributes) {
|
|
623
|
+
if (anObject(O), P = toPropertyKey(P), anObject(Attributes), "function" == typeof O && "prototype" === P && "value" in Attributes && "writable" in Attributes && !Attributes.writable) {
|
|
624
|
+
var current = $getOwnPropertyDescriptor(O, P);
|
|
625
|
+
current && current.writable && (O[P] = Attributes.value, Attributes = {
|
|
626
|
+
configurable: "configurable" in Attributes ? Attributes.configurable : current.configurable,
|
|
627
|
+
enumerable: "enumerable" in Attributes ? Attributes.enumerable : current.enumerable,
|
|
628
|
+
writable: !1
|
|
629
|
+
});
|
|
630
|
+
}
|
|
631
|
+
return $defineProperty(O, P, Attributes);
|
|
632
|
+
} : $defineProperty : function(O, P, Attributes) {
|
|
633
|
+
if (anObject(O), P = toPropertyKey(P), anObject(Attributes), IE8_DOM_DEFINE) try {
|
|
634
|
+
return $defineProperty(O, P, Attributes);
|
|
635
|
+
} catch (error) {/* empty */}
|
|
636
|
+
if ("get" in Attributes || "set" in Attributes) throw new $TypeError$1("Accessors not supported");
|
|
637
|
+
return "value" in Attributes && (O[P] = Attributes.value), O;
|
|
638
|
+
};
|
|
639
|
+
|
|
640
|
+
var definePropertyModule = objectDefineProperty, createPropertyDescriptor = createPropertyDescriptor$2, createNonEnumerableProperty$1 = descriptors ? function(object, key, value) {
|
|
641
|
+
return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));
|
|
642
|
+
} : function(object, key, value) {
|
|
643
|
+
return object[key] = value, object;
|
|
644
|
+
}, globalThis$2 = globalThis_1, apply = functionApply, uncurryThis$1 = functionUncurryThisClause, isCallable$1 = isCallable$8, getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f, isForced = isForced_1, path$1 = path$3, bind = function(fn, that) {
|
|
645
|
+
return aCallable(fn), void 0 === that ? fn : NATIVE_BIND ? bind$1(fn, that) : function() {
|
|
646
|
+
return fn.apply(that, arguments);
|
|
647
|
+
};
|
|
648
|
+
}, createNonEnumerableProperty = createNonEnumerableProperty$1, hasOwn = hasOwnProperty_1, wrapConstructor = function(NativeConstructor) {
|
|
649
|
+
var Wrapper = function(a, b, c) {
|
|
650
|
+
if (this instanceof Wrapper) {
|
|
651
|
+
switch (arguments.length) {
|
|
652
|
+
case 0:
|
|
653
|
+
return new NativeConstructor;
|
|
654
|
+
|
|
655
|
+
case 1:
|
|
656
|
+
return new NativeConstructor(a);
|
|
657
|
+
|
|
658
|
+
case 2:
|
|
659
|
+
return new NativeConstructor(a, b);
|
|
660
|
+
}
|
|
661
|
+
return new NativeConstructor(a, b, c);
|
|
662
|
+
}
|
|
663
|
+
return apply(NativeConstructor, this, arguments);
|
|
664
|
+
};
|
|
665
|
+
return Wrapper.prototype = NativeConstructor.prototype, Wrapper;
|
|
666
|
+
}, _export = function(options, source) {
|
|
667
|
+
var FORCED, USE_NATIVE, VIRTUAL_PROTOTYPE, key, sourceProperty, targetProperty, nativeProperty, resultProperty, descriptor, TARGET = options.target, GLOBAL = options.global, STATIC = options.stat, PROTO = options.proto, nativeSource = GLOBAL ? globalThis$2 : STATIC ? globalThis$2[TARGET] : globalThis$2[TARGET] && globalThis$2[TARGET].prototype, target = GLOBAL ? path$1 : path$1[TARGET] || createNonEnumerableProperty(path$1, TARGET, {})[TARGET], targetPrototype = target.prototype;
|
|
668
|
+
for (key in source)
|
|
669
|
+
// contains in native
|
|
670
|
+
USE_NATIVE = !(FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? "." : "#") + key, options.forced)) && nativeSource && hasOwn(nativeSource, key),
|
|
671
|
+
targetProperty = target[key], USE_NATIVE && (nativeProperty = options.dontCallGetSet ? (descriptor = getOwnPropertyDescriptor(nativeSource, key)) && descriptor.value : nativeSource[key]),
|
|
672
|
+
// export native or implementation
|
|
673
|
+
sourceProperty = USE_NATIVE && nativeProperty ? nativeProperty : source[key], (FORCED || PROTO || typeof targetProperty != typeof sourceProperty) && (
|
|
674
|
+
// bind methods to global for calling from export context
|
|
675
|
+
resultProperty = options.bind && USE_NATIVE ? bind(sourceProperty, globalThis$2) : options.wrap && USE_NATIVE ? wrapConstructor(sourceProperty) : PROTO && isCallable$1(sourceProperty) ? uncurryThis$1(sourceProperty) : sourceProperty,
|
|
676
|
+
// add a flag to not completely full polyfills
|
|
677
|
+
(options.sham || sourceProperty && sourceProperty.sham || targetProperty && targetProperty.sham) && createNonEnumerableProperty(resultProperty, "sham", !0),
|
|
678
|
+
createNonEnumerableProperty(target, key, resultProperty), PROTO && (hasOwn(path$1, VIRTUAL_PROTOTYPE = TARGET + "Prototype") || createNonEnumerableProperty(path$1, VIRTUAL_PROTOTYPE, {}),
|
|
679
|
+
// export virtual prototype methods
|
|
680
|
+
createNonEnumerableProperty(path$1[VIRTUAL_PROTOTYPE], key, sourceProperty),
|
|
681
|
+
// export real prototype methods
|
|
682
|
+
options.real && targetPrototype && (FORCED || !targetPrototype[key]) && createNonEnumerableProperty(targetPrototype, key, sourceProperty)));
|
|
683
|
+
}, ceil = Math.ceil, floor = Math.floor, trunc = Math.trunc || function(x) {
|
|
684
|
+
var n = +x;
|
|
685
|
+
return (n > 0 ? floor : ceil)(n);
|
|
686
|
+
}, toIntegerOrInfinity$2 = function(argument) {
|
|
687
|
+
var number = +argument;
|
|
688
|
+
// eslint-disable-next-line no-self-compare -- NaN check
|
|
689
|
+
return number != number || 0 === number ? 0 : trunc(number);
|
|
690
|
+
}, toIntegerOrInfinity$1 = toIntegerOrInfinity$2, min$1 = Math.min, globalThis$1 = globalThis_1, path = path$3, getBuiltInPrototypeMethod$2 = function(CONSTRUCTOR, METHOD) {
|
|
691
|
+
var Namespace = path[CONSTRUCTOR + "Prototype"], pureMethod = Namespace && Namespace[METHOD];
|
|
692
|
+
if (pureMethod) return pureMethod;
|
|
693
|
+
var NativeConstructor = globalThis$1[CONSTRUCTOR], NativePrototype = NativeConstructor && NativeConstructor.prototype;
|
|
694
|
+
return NativePrototype && NativePrototype[METHOD];
|
|
695
|
+
};
|
|
696
|
+
|
|
697
|
+
/**
|
|
698
|
+
* Component Utilities
|
|
699
|
+
*
|
|
700
|
+
* Helper functions for component development with the new customization system
|
|
701
|
+
*/
|
|
702
|
+
/**
|
|
703
|
+
* Merge multiple class names
|
|
704
|
+
*/
|
|
705
|
+
function mergeClassNames(...classes) {
|
|
706
|
+
return classes.filter(Boolean).join(" ");
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
/**
|
|
710
|
+
* Check if a URL is a YouTube URL
|
|
711
|
+
*/ function isYouTubeUrl(url) {
|
|
712
|
+
return /^(https?:\/\/)?(www\.)?(youtube\.com|youtu\.be)\/.+/.test(url);
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* Extract YouTube video ID from URL
|
|
717
|
+
*/
|
|
718
|
+
/**
|
|
719
|
+
* Utility to merge multiple React refs into one
|
|
720
|
+
*/
|
|
721
|
+
function setRef(ref, value) {
|
|
722
|
+
"function" == typeof ref ? ref(value) : ref && (
|
|
723
|
+
// This is safe because we're checking that ref exists first
|
|
724
|
+
ref.current = value);
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* Combines two React refs into a single ref function
|
|
729
|
+
* This is used when you need to use and forward a ref at the same time
|
|
730
|
+
*/ function useForkRef(refA, refB) {
|
|
731
|
+
return React.useMemo((() => null == refA && null == refB ? null : refValue => {
|
|
732
|
+
setRef(refA, refValue), setRef(refB, refValue);
|
|
733
|
+
}), [ refA, refB ]);
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
const {CONSTANTS: CONSTANTS$3} = ATOMIX_GLASS, calculateElementCenter = rect => rect ? {
|
|
376
737
|
x: rect.left + rect.width / 2,
|
|
377
738
|
y: rect.top + rect.height / 2
|
|
378
739
|
} : {
|
|
@@ -380,37 +741,37 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
380
741
|
y: 0
|
|
381
742
|
}, calculateMouseInfluence = mouseOffset => {
|
|
382
743
|
if (!mouseOffset || "number" != typeof mouseOffset.x || "number" != typeof mouseOffset.y) return 0;
|
|
383
|
-
//
|
|
384
|
-
const influence = Math.sqrt(mouseOffset.x * mouseOffset.x + mouseOffset.y * mouseOffset.y) / CONSTANTS$
|
|
744
|
+
// Clamp influence to keep mouse response subtle and stable.
|
|
745
|
+
const influence = Math.sqrt(mouseOffset.x * mouseOffset.x + mouseOffset.y * mouseOffset.y) / CONSTANTS$3.MOUSE_INFLUENCE_DIVISOR;
|
|
385
746
|
return Math.min(.8, influence);
|
|
386
747
|
// Tighter cap to prevent blur/filter blow-out
|
|
387
|
-
}, clampBlur = value => "number" != typeof value || isNaN(value) ? CONSTANTS$
|
|
748
|
+
}, clampBlur = value => "number" != typeof value || isNaN(value) ? CONSTANTS$3.MIN_BLUR : Math.max(CONSTANTS$3.MIN_BLUR, Math.min(50, value)), validateGlassSize = size => size && "number" == typeof size.width && "number" == typeof size.height && size.width > 0 && size.height > 0 && size.width <= CONSTANTS$3.MAX_SIZE && size.height <= CONSTANTS$3.MAX_SIZE, parseBorderRadiusValue = value => {
|
|
388
749
|
if ("number" == typeof value) return Math.max(0, value);
|
|
389
|
-
if ("string" != typeof value || !value.trim()) return CONSTANTS$
|
|
750
|
+
if ("string" != typeof value || !value.trim()) return CONSTANTS$3.DEFAULT_CORNER_RADIUS;
|
|
390
751
|
const trimmedValue = value.trim();
|
|
391
752
|
// Handle px values
|
|
392
753
|
if (trimmedValue.endsWith("px")) {
|
|
393
754
|
const parsed = parseFloat(trimmedValue);
|
|
394
|
-
return isNaN(parsed) ? CONSTANTS$
|
|
755
|
+
return isNaN(parsed) ? CONSTANTS$3.DEFAULT_CORNER_RADIUS : Math.max(0, parsed);
|
|
395
756
|
}
|
|
396
757
|
// Handle rem values (assume 16px = 1rem)
|
|
397
758
|
if (trimmedValue.endsWith("rem")) {
|
|
398
759
|
const parsed = parseFloat(trimmedValue);
|
|
399
|
-
return isNaN(parsed) ? CONSTANTS$
|
|
760
|
+
return isNaN(parsed) ? CONSTANTS$3.DEFAULT_CORNER_RADIUS : Math.max(0, 16 * parsed);
|
|
400
761
|
}
|
|
401
762
|
// Handle em values (assume 16px = 1em for simplicity)
|
|
402
763
|
if (trimmedValue.endsWith("em")) {
|
|
403
764
|
const parsed = parseFloat(trimmedValue);
|
|
404
|
-
return isNaN(parsed) ? CONSTANTS$
|
|
765
|
+
return isNaN(parsed) ? CONSTANTS$3.DEFAULT_CORNER_RADIUS : Math.max(0, 16 * parsed);
|
|
405
766
|
}
|
|
406
767
|
// Handle percentage (convert to approximate px value, assuming 200px container)
|
|
407
768
|
if (trimmedValue.endsWith("%")) {
|
|
408
769
|
const parsed = parseFloat(trimmedValue);
|
|
409
|
-
return isNaN(parsed) ? CONSTANTS$
|
|
770
|
+
return isNaN(parsed) ? CONSTANTS$3.DEFAULT_CORNER_RADIUS : Math.max(0, parsed / 100 * 200);
|
|
410
771
|
}
|
|
411
772
|
// Handle unitless numbers
|
|
412
773
|
const numValue = parseFloat(trimmedValue);
|
|
413
|
-
return isNaN(numValue) ? CONSTANTS$
|
|
774
|
+
return isNaN(numValue) ? CONSTANTS$3.DEFAULT_CORNER_RADIUS : Math.max(0, numValue);
|
|
414
775
|
}, extractBorderRadiusFromElement = element => {
|
|
415
776
|
if (!element || !element.props) return null;
|
|
416
777
|
// Check inline styles first (highest priority)
|
|
@@ -426,11 +787,11 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
426
787
|
// If element has children, recursively check them
|
|
427
788
|
if (element.props.children) {
|
|
428
789
|
const childRadius = extractBorderRadiusFromChildren(element.props.children);
|
|
429
|
-
if (childRadius > 0 && childRadius !== CONSTANTS$
|
|
790
|
+
if (childRadius > 0 && childRadius !== CONSTANTS$3.DEFAULT_CORNER_RADIUS) return childRadius;
|
|
430
791
|
}
|
|
431
792
|
return null;
|
|
432
793
|
}, extractBorderRadiusFromChildren = children => {
|
|
433
|
-
if (!children) return CONSTANTS$
|
|
794
|
+
if (!children) return CONSTANTS$3.DEFAULT_CORNER_RADIUS;
|
|
434
795
|
try {
|
|
435
796
|
const childArray = React.Children.toArray(children);
|
|
436
797
|
for (let i = 0; i < childArray.length; i++) {
|
|
@@ -443,17 +804,78 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
443
804
|
} catch (error) {
|
|
444
805
|
// Silently handle errors
|
|
445
806
|
}
|
|
446
|
-
return CONSTANTS$
|
|
807
|
+
return CONSTANTS$3.DEFAULT_CORNER_RADIUS;
|
|
447
808
|
}, smoothstep = t => {
|
|
448
809
|
const clamped = Math.max(0, Math.min(1, t));
|
|
449
810
|
return clamped * clamped * (3 - 2 * clamped);
|
|
450
|
-
}, lerp
|
|
811
|
+
}, lerp = (a, b, t) => a + (b - a) * t, softClamp = (value, max) => max <= 0 ? 0 : max * (1 - Math.exp(-value / max)), clamp = (value, min, max) => "number" != typeof value || isNaN(value) ? min : Math.max(min, Math.min(max, value)), smoothstepEdge = (edge0, edge1, x) => "number" != typeof edge0 || "number" != typeof edge1 || "number" != typeof x ? 0 : smoothstep((x - edge0) / (edge1 - edge0)), easeInOutCubic = t => {
|
|
812
|
+
if ("number" != typeof t || isNaN(t)) return 0;
|
|
813
|
+
const clamped = Math.max(0, Math.min(1, t));
|
|
814
|
+
return clamped < .5 ? 4 * clamped * clamped * clamped : 1 - Math.pow(-2 * clamped + 2, 3) / 2;
|
|
815
|
+
}, easeOutQuart = t => {
|
|
816
|
+
if ("number" != typeof t || isNaN(t)) return 0;
|
|
817
|
+
const clamped = Math.max(0, Math.min(1, t));
|
|
818
|
+
return 1 - Math.pow(1 - clamped, 4);
|
|
819
|
+
}, vec2Length = (x, y) => {
|
|
820
|
+
if ("number" != typeof x || "number" != typeof y || isNaN(x) || isNaN(y)) return 0;
|
|
821
|
+
const maxComponent = Math.max(Math.abs(x), Math.abs(y));
|
|
822
|
+
if (0 === maxComponent) return 0;
|
|
823
|
+
const scaledX = x / maxComponent, scaledY = y / maxComponent;
|
|
824
|
+
return maxComponent * Math.sqrt(scaledX * scaledX + scaledY * scaledY);
|
|
825
|
+
}, getInteractionIntensity = (isHovered, isActive) => ({
|
|
826
|
+
hoverIntensity: isHovered ? CONSTANTS$3.INTERACTION.HOVER_INTENSITY : 1,
|
|
827
|
+
activeIntensity: isActive ? CONSTANTS$3.INTERACTION.ACTIVE_INTENSITY : 1
|
|
828
|
+
})
|
|
829
|
+
/**
|
|
830
|
+
* Spring-damper integration helper
|
|
831
|
+
* Calculates the next value based on velocity, stiffness, and damping.
|
|
832
|
+
*/ , calculateSpring = (current, target, velocity, stiffness = .1, damping = .8) => {
|
|
451
833
|
const newVelocity = (velocity + (target - current) * stiffness) * damping;
|
|
452
834
|
return {
|
|
453
835
|
value: current + newVelocity,
|
|
454
836
|
velocity: newVelocity
|
|
455
837
|
};
|
|
456
|
-
}
|
|
838
|
+
};
|
|
839
|
+
|
|
840
|
+
/**
|
|
841
|
+
* Calculate element center from bounding rect
|
|
842
|
+
*/
|
|
843
|
+
/**
|
|
844
|
+
* Normalizes a layout inset for use in CSS custom properties.
|
|
845
|
+
*
|
|
846
|
+
* @param value - Raw inset from `style` (number, px string, or `auto`).
|
|
847
|
+
* @param fallback - Value used when `value` is undefined.
|
|
848
|
+
*/
|
|
849
|
+
function formatGlassInsetValue(value, fallback = "auto") {
|
|
850
|
+
return void 0 === value ? "number" == typeof fallback ? `${fallback}px` : String(fallback) : "auto" === value ? "auto" : "number" == typeof value ? `${value}px` : value;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
/**
|
|
854
|
+
* Determines whether the glass should use fixed/sticky layout semantics.
|
|
855
|
+
*
|
|
856
|
+
* @param explicit - Value of the `isFixedOrSticky` prop.
|
|
857
|
+
* @param position - `position` from the consumer `style` object.
|
|
858
|
+
*/
|
|
859
|
+
/** Coerces a value to a finite number, returning `fallback` when invalid. */
|
|
860
|
+
function toSafeNumber(value, fallback = 0) {
|
|
861
|
+
return "number" != typeof value || isNaN(value) ? fallback : value;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
/**
|
|
865
|
+
* Calculates the target frame rate for shader time-animation loops.
|
|
866
|
+
*
|
|
867
|
+
* Balances visual quality against distortion complexity and `animationSpeed`.
|
|
868
|
+
*/
|
|
869
|
+
/**
|
|
870
|
+
* Computes per-channel displacement scale for the SVG chromatic-aberration filter.
|
|
871
|
+
*/
|
|
872
|
+
function getChromaticDisplacementScale(mode, displacementScale, aberrationIntensity, channelFactor) {
|
|
873
|
+
return displacementScale * (("shader" === mode ? 1 : -1) - aberrationIntensity * channelFactor);
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
/**
|
|
877
|
+
* Get displacement map URL based on mode
|
|
878
|
+
*/ const getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
|
|
457
879
|
switch (mode) {
|
|
458
880
|
case "standard":
|
|
459
881
|
return displacementMap;
|
|
@@ -470,13 +892,28 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
470
892
|
default:
|
|
471
893
|
return console.warn("AtomixGlass: Invalid displacement mode"), displacementMap;
|
|
472
894
|
}
|
|
473
|
-
}, sharedShaderCache = new Map,
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
895
|
+
}, sharedShaderCache = new Map, CHROMATIC_CHANNELS = [ {
|
|
896
|
+
result: "RED_DISPLACED",
|
|
897
|
+
channelResult: "RED_CHANNEL",
|
|
898
|
+
aberrationFactor: 0,
|
|
899
|
+
colorMatrix: "1 0 0 0 0\n0 0 0 0 0\n0 0 0 0 0\n0 0 0 1 0"
|
|
900
|
+
}, {
|
|
901
|
+
result: "GREEN_DISPLACED",
|
|
902
|
+
channelResult: "GREEN_CHANNEL",
|
|
903
|
+
aberrationFactor: .02,
|
|
904
|
+
colorMatrix: "0 0 0 0 0\n0 1 0 0 0\n0 0 0 0 0\n0 0 0 1 0"
|
|
905
|
+
}, {
|
|
906
|
+
result: "BLUE_DISPLACED",
|
|
907
|
+
channelResult: "BLUE_CHANNEL",
|
|
908
|
+
aberrationFactor: .03,
|
|
909
|
+
colorMatrix: "0 0 0 0 0\n0 0 0 0 0\n0 0 1 0 0\n0 0 0 1 0"
|
|
910
|
+
} ], FILTER_SVG_STYLE = {
|
|
911
|
+
position: "absolute",
|
|
912
|
+
width: "100%",
|
|
913
|
+
height: "100%",
|
|
914
|
+
inset: 0
|
|
915
|
+
}, GlassFilterComponent = ({id: id, displacementScale: displacementScale, aberrationIntensity: aberrationIntensity, mode: mode, shaderMapUrl: shaderMapUrl, blurAmount: blurAmount}) => jsx("svg", {
|
|
916
|
+
style: FILTER_SVG_STYLE,
|
|
480
917
|
"aria-hidden": "true",
|
|
481
918
|
children: jsxs("defs", {
|
|
482
919
|
children: [ jsxs("radialGradient", {
|
|
@@ -530,43 +967,21 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
530
967
|
dx: "0",
|
|
531
968
|
dy: "0",
|
|
532
969
|
result: "CENTER_ORIGINAL"
|
|
533
|
-
}),
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
scale: displacementScale * (("shader" === mode ? 1 : -1) - .02 * aberrationIntensity),
|
|
549
|
-
xChannelSelector: "R",
|
|
550
|
-
yChannelSelector: "B",
|
|
551
|
-
result: "GREEN_DISPLACED"
|
|
552
|
-
}), jsx("feColorMatrix", {
|
|
553
|
-
in: "GREEN_DISPLACED",
|
|
554
|
-
type: "matrix",
|
|
555
|
-
values: "0 0 0 0 0\n 0 1 0 0 0\n 0 0 0 0 0\n 0 0 0 1 0",
|
|
556
|
-
result: "GREEN_CHANNEL"
|
|
557
|
-
}), jsx("feDisplacementMap", {
|
|
558
|
-
in: "SourceGraphic",
|
|
559
|
-
in2: "DISPLACEMENT_MAP",
|
|
560
|
-
scale: displacementScale * (("shader" === mode ? 1 : -1) - .03 * aberrationIntensity),
|
|
561
|
-
xChannelSelector: "R",
|
|
562
|
-
yChannelSelector: "B",
|
|
563
|
-
result: "BLUE_DISPLACED"
|
|
564
|
-
}), jsx("feColorMatrix", {
|
|
565
|
-
in: "BLUE_DISPLACED",
|
|
566
|
-
type: "matrix",
|
|
567
|
-
values: "0 0 0 0 0\n 0 0 0 0 0\n 0 0 1 0 0\n 0 0 0 1 0",
|
|
568
|
-
result: "BLUE_CHANNEL"
|
|
569
|
-
}), jsx("feBlend", {
|
|
970
|
+
}), CHROMATIC_CHANNELS.map((channel => jsxs(React.Fragment, {
|
|
971
|
+
children: [ jsx("feDisplacementMap", {
|
|
972
|
+
in: "SourceGraphic",
|
|
973
|
+
in2: "DISPLACEMENT_MAP",
|
|
974
|
+
scale: getChromaticDisplacementScale(mode, displacementScale, aberrationIntensity, channel.aberrationFactor),
|
|
975
|
+
xChannelSelector: "R",
|
|
976
|
+
yChannelSelector: "B",
|
|
977
|
+
result: channel.result
|
|
978
|
+
}), jsx("feColorMatrix", {
|
|
979
|
+
in: channel.result,
|
|
980
|
+
type: "matrix",
|
|
981
|
+
values: channel.colorMatrix,
|
|
982
|
+
result: channel.channelResult
|
|
983
|
+
}) ]
|
|
984
|
+
}, channel.channelResult))), jsx("feBlend", {
|
|
570
985
|
in: "GREEN_CHANNEL",
|
|
571
986
|
in2: "BLUE_CHANNEL",
|
|
572
987
|
mode: "screen",
|
|
@@ -606,20 +1021,23 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
606
1021
|
})
|
|
607
1022
|
});
|
|
608
1023
|
|
|
609
|
-
|
|
1024
|
+
/**
|
|
1025
|
+
* Module-level LRU cache for shader displacement maps.
|
|
1026
|
+
*
|
|
1027
|
+
* Shared across all `AtomixGlassContainer` instances so identical size and
|
|
1028
|
+
* variant combinations are generated once.
|
|
1029
|
+
*/ GlassFilterComponent.displayName = "GlassFilter";
|
|
610
1030
|
|
|
611
|
-
|
|
1031
|
+
/** Shallow prop comparison to avoid redundant SVG filter regeneration. */
|
|
612
1032
|
const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevProps.id === nextProps.id && prevProps.displacementScale === nextProps.displacementScale && prevProps.aberrationIntensity === nextProps.aberrationIntensity && prevProps.mode === nextProps.mode && prevProps.shaderMapUrl === nextProps.shaderMapUrl && prevProps.blurAmount === nextProps.blurAmount)), AtomixGlassContainer = forwardRef((({children: children, className: className = "", style: style, displacementScale: displacementScale = 25, blurAmount: blurAmount = .0625, saturation: saturation = 180, aberrationIntensity: aberrationIntensity = 2, mouseOffset: mouseOffset = {
|
|
613
1033
|
x: 0,
|
|
614
1034
|
y: 0
|
|
615
|
-
}, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, isActive: isActive = !1, overLight: overLight = !1, overLightConfig: overLightConfig = {}, borderRadius: borderRadius = 0,
|
|
1035
|
+
}, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, isActive: isActive = !1, overLight: overLight = !1, overLightConfig: overLightConfig = {}, borderRadius: borderRadius = 0, glassSize: glassSize = {
|
|
616
1036
|
width: 0,
|
|
617
1037
|
height: 0
|
|
618
|
-
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1, isFixedOrSticky: isFixedOrSticky = !1,
|
|
619
|
-
// Phase 1: Animation System props
|
|
620
|
-
shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpeed: animationSpeed = 1, withMultiLayerDistortion: withMultiLayerDistortion = !1, distortionOctaves: distortionOctaves = 3, distortionLacunarity: distortionLacunarity = 2, distortionGain: distortionGain = .5, distortionQuality: distortionQuality = "medium", contentRef: contentRef}, ref) => {
|
|
1038
|
+
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1, isFixedOrSticky: isFixedOrSticky = !1, withTimeAnimation: withTimeAnimation = !1, animationSpeed: animationSpeed = 1, withMultiLayerDistortion: withMultiLayerDistortion = !1, distortionOctaves: distortionOctaves = 3, distortionLacunarity: distortionLacunarity = 2, distortionGain: distortionGain = .5, distortionQuality: distortionQuality = "medium", contentRef: contentRef}, ref) => {
|
|
621
1039
|
// React 18 useId — stable, unique, and SSR-safe (no module-level counter)
|
|
622
|
-
const rawId = useId(), filterId = useMemo((() => `atomix-glass-filter-${rawId.replace(/:/g, "")}`), [ rawId ]), [shaderMapUrl, setShaderMapUrl] = useState(""), shaderGeneratorRef = useRef(null), shaderUtilsRef = useRef(null), shaderDebounceTimeoutRef = useRef(null), shaderUpdateTimeoutRef = useRef(null), animationFrameRef = useRef(null);
|
|
1040
|
+
const rawId = useId(), filterId = useMemo((() => `atomix-glass-filter-${rawId.replace(/:/g, "")}`), [ rawId ]), containerRef = useForkRef(ref, null), [shaderMapUrl, setShaderMapUrl] = useState(""), shaderGeneratorRef = useRef(null), shaderUtilsRef = useRef(null), shaderDebounceTimeoutRef = useRef(null), shaderUpdateTimeoutRef = useRef(null), animationFrameRef = useRef(null);
|
|
623
1041
|
// Lazy load shader utilities only when shader mode is needed
|
|
624
1042
|
useEffect((() => {
|
|
625
1043
|
"shader" === mode ?
|
|
@@ -697,15 +1115,23 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
697
1115
|
shaderGeneratorRef.current = null;
|
|
698
1116
|
}
|
|
699
1117
|
};
|
|
700
|
-
}), [ mode, glassSize, shaderVariant ]),
|
|
701
|
-
// Phase 1: Time-Based Animation Loop - Continuous shader regeneration
|
|
702
|
-
useEffect((() => {
|
|
1118
|
+
}), [ mode, glassSize, shaderVariant ]), useEffect((() => {
|
|
703
1119
|
// Only run animations in shader mode with time animation enabled
|
|
704
1120
|
if ("shader" !== mode || !withTimeAnimation || effectiveReducedMotion || effectiveWithoutEffects)
|
|
705
1121
|
// Cancel any existing animation frame
|
|
706
1122
|
return void (null !== animationFrameRef.current && (cancelAnimationFrame(animationFrameRef.current),
|
|
707
1123
|
animationFrameRef.current = null));
|
|
708
|
-
const
|
|
1124
|
+
const targetFps = function(options) {
|
|
1125
|
+
const {distortionQuality: distortionQuality, animationSpeed: animationSpeed = 1, withMultiLayerDistortion: withMultiLayerDistortion, distortionOctaves: distortionOctaves = 3, distortionLacunarity: distortionLacunarity = 2, distortionGain: distortionGain = .5} = options, baseFps = "ultra" === distortionQuality ? 60 : "high" === distortionQuality ? 30 : "medium" === distortionQuality ? 24 : 20, effectiveSpeed = Math.max(.5, Math.min(2, animationSpeed)), complexity = withMultiLayerDistortion ? Math.max(1, distortionOctaves / 3 + .25 * Math.max(0, distortionLacunarity - 2) + Math.max(0, distortionGain - .5)) : 1;
|
|
1126
|
+
return Math.max(12, Math.min(60, Math.round(baseFps * effectiveSpeed / complexity)));
|
|
1127
|
+
}({
|
|
1128
|
+
distortionQuality: distortionQuality,
|
|
1129
|
+
animationSpeed: animationSpeed,
|
|
1130
|
+
withMultiLayerDistortion: withMultiLayerDistortion,
|
|
1131
|
+
distortionOctaves: distortionOctaves,
|
|
1132
|
+
distortionLacunarity: distortionLacunarity,
|
|
1133
|
+
distortionGain: distortionGain
|
|
1134
|
+
}), frameInterval = 1e3 / targetFps;
|
|
709
1135
|
let lastUpdate = 0, isCancelled = !1;
|
|
710
1136
|
const animate = currentTime => {
|
|
711
1137
|
if (!isCancelled) {
|
|
@@ -729,88 +1155,21 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
729
1155
|
};
|
|
730
1156
|
}), [ mode, withTimeAnimation, animationSpeed, displacementScale, withMultiLayerDistortion, distortionOctaves, distortionLacunarity, distortionGain, distortionQuality, effectiveReducedMotion, effectiveWithoutEffects, glassSize ]);
|
|
731
1157
|
// Removed forced reflow to avoid layout thrash and potential feedback sizing loops
|
|
732
|
-
const
|
|
733
|
-
useEffect((() => {
|
|
734
|
-
if (!ref || "function" == typeof ref) return;
|
|
735
|
-
const element = ref.current;
|
|
736
|
-
if (element) try {
|
|
737
|
-
setRectCache(element.getBoundingClientRect());
|
|
738
|
-
} catch (error) {
|
|
739
|
-
console.warn("AtomixGlassContainer: Error getting element bounds", error), setRectCache(null);
|
|
740
|
-
}
|
|
741
|
-
}), [ ref, glassSize ]);
|
|
742
|
-
const liquidBlur = useMemo((() => {
|
|
743
|
-
const defaultBlur = {
|
|
744
|
-
baseBlur: blurAmount,
|
|
745
|
-
edgeBlur: 1.25 * blurAmount,
|
|
746
|
-
centerBlur: 1.1 * blurAmount,
|
|
747
|
-
flowBlur: 1.2 * blurAmount
|
|
748
|
-
};
|
|
749
|
-
// Enhanced validation for liquid blur
|
|
750
|
-
if (!withLiquidBlur || !rectCache || !mouseOffset || "number" != typeof mouseOffset.x || "number" != typeof mouseOffset.y || isNaN(mouseOffset.x) || isNaN(mouseOffset.y)) return defaultBlur;
|
|
751
|
-
try {
|
|
752
|
-
const mouseInfluence = calculateMouseInfluence(mouseOffset), maxBlur = 2 * blurAmount, baseBlur = Math.min(maxBlur, blurAmount + mouseInfluence * blurAmount * .15), edgeIntensity = .15 * mouseInfluence, edgeBlur = Math.min(maxBlur, baseBlur * (.8 + .4 * edgeIntensity)), centerIntensity = .1 * mouseInfluence, centerBlur = Math.min(maxBlur, baseBlur * (.3 + .3 * centerIntensity)), flowBlur = Math.min(maxBlur, 1.2 * baseBlur);
|
|
753
|
-
// NOTE: hover/active multipliers intentionally omitted here —
|
|
754
|
-
// they belong on opacity layers, not the blur filter itself.
|
|
755
|
-
return {
|
|
756
|
-
baseBlur: clampBlur(baseBlur),
|
|
757
|
-
edgeBlur: clampBlur(edgeBlur),
|
|
758
|
-
centerBlur: clampBlur(centerBlur),
|
|
759
|
-
flowBlur: clampBlur(flowBlur)
|
|
760
|
-
};
|
|
761
|
-
} catch (error) {
|
|
762
|
-
return console.warn("AtomixGlassContainer: Error calculating liquid blur", error),
|
|
763
|
-
defaultBlur;
|
|
764
|
-
}
|
|
765
|
-
}), [ withLiquidBlur, blurAmount, mouseOffset, rectCache ]), backdropStyle = useMemo((() => {
|
|
766
|
-
try {
|
|
767
|
-
const dynamicSaturation = saturation + 20 * (liquidBlur.baseBlur || 0), validatedBaseBlur = "number" != typeof liquidBlur.baseBlur || isNaN(liquidBlur.baseBlur) ? 0 : liquidBlur.baseBlur, validatedEdgeBlur = "number" != typeof liquidBlur.edgeBlur || isNaN(liquidBlur.edgeBlur) ? 0 : liquidBlur.edgeBlur, validatedCenterBlur = "number" != typeof liquidBlur.centerBlur || isNaN(liquidBlur.centerBlur) ? 0 : liquidBlur.centerBlur, validatedFlowBlur = "number" != typeof liquidBlur.flowBlur || isNaN(liquidBlur.flowBlur) ? 0 : liquidBlur.flowBlur, area = rectCache ? rectCache.width * rectCache.height : 0;
|
|
768
|
-
// Validate blur values before using them
|
|
769
|
-
return !withLiquidBlur || effectiveReducedMotion || effectiveWithoutEffects || area > 18e4 ? {
|
|
770
|
-
backdropFilter: `blur(${clampBlur(Math.max(validatedBaseBlur, .8 * validatedEdgeBlur, 1.1 * validatedCenterBlur, .9 * validatedFlowBlur))}px) saturate(${Math.min(dynamicSaturation, 200)}%) contrast(${overLightConfig?.contrast || 1.05}) brightness(${overLightConfig?.brightness || 1.05})`
|
|
771
|
-
} : {
|
|
772
|
-
backdropFilter: `blur(${clampBlur(.4 * validatedBaseBlur + .25 * validatedEdgeBlur + .15 * validatedCenterBlur + .2 * validatedFlowBlur)}px) saturate(${Math.min(dynamicSaturation, 200)}%) contrast(${overLightConfig?.contrast || 1}) brightness(${overLightConfig?.brightness || 1})`
|
|
773
|
-
};
|
|
774
|
-
// Single-pass fallback: stronger radius to match perceived blur of multi-pass
|
|
775
|
-
} catch (error) {
|
|
776
|
-
return console.warn("AtomixGlassContainer: Error calculating backdrop style", error),
|
|
777
|
-
{
|
|
778
|
-
backdropFilter: `blur(${blurAmount}px) saturate(${saturation}%) contrast(1.05) brightness(1.05)`
|
|
779
|
-
};
|
|
780
|
-
}
|
|
781
|
-
}), [ liquidBlur, saturation, blurAmount, rectCache, effectiveReducedMotion, effectiveWithoutEffects, withLiquidBlur, overLightConfig ]), containerVars = useMemo((() => {
|
|
1158
|
+
const containerVars = useMemo((() => {
|
|
782
1159
|
try {
|
|
783
|
-
// Safe extraction of mouse offset values
|
|
784
|
-
const mx = mouseOffset && "number" == typeof mouseOffset.x && !isNaN(mouseOffset.x) ? mouseOffset.x : 0, my = mouseOffset && "number" == typeof mouseOffset.y && !isNaN(mouseOffset.y) ? mouseOffset.y : 0;
|
|
785
1160
|
return {
|
|
786
|
-
"--atomix-glass-container-radius": `${"number" != typeof borderRadius || isNaN(borderRadius) ? 0 : borderRadius}px
|
|
787
|
-
"--atomix-glass-container-backdrop": backdropStyle?.backdropFilter || "none",
|
|
788
|
-
"--atomix-glass-container-shadow": overLight ? [ `inset 0 1px 0 rgba(255, 255, 255, ${(.4 + .002 * mx) * (overLightConfig?.shadowIntensity || 1)})`, `inset 0 -1px 0 rgba(0, 0, 0, ${(.2 + .001 * Math.abs(my)) * (overLightConfig?.shadowIntensity || 1)})`, `inset 0 0 20px rgba(0, 0, 0, ${(.08 + .001 * Math.abs(mx + my)) * (overLightConfig?.shadowIntensity || 1)})`, `0 2px 12px rgba(0, 0, 0, ${(.12 + .002 * Math.abs(my)) * (overLightConfig?.shadowIntensity || 1)})` ].join(", ") : "0 0 20px rgba(0, 0, 0, 0.15) inset, 0 4px 8px rgba(0, 0, 0, 0.08) inset",
|
|
789
|
-
"--atomix-glass-container-shadow-opacity": effectiveWithoutEffects ? 0 : 1,
|
|
790
|
-
// Background and shadow values use design token-aligned RGB values
|
|
791
|
-
"--atomix-glass-container-bg": overLight ? `linear-gradient(${180 + .5 * mx}deg, rgba(255, 255, 255, 0.1) 0%, transparent 20%, transparent 80%, rgba(0, 0, 0, 0.05) 100%)` : "none",
|
|
792
|
-
"--atomix-glass-container-text-shadow": overLight ? "0px 1px 2px rgba(255, 255, 255, 0.15)" : "0px 2px 12px rgba(0, 0, 0, 0.4)",
|
|
793
|
-
"--atomix-glass-container-box-shadow": overLight ? "0px 16px 70px rgba(0, 0, 0, 0.75)" : "0px 12px 40px rgba(0, 0, 0, 0.25)"
|
|
1161
|
+
"--atomix-glass-container-radius": `${"number" != typeof borderRadius || isNaN(borderRadius) ? 0 : borderRadius}px`
|
|
794
1162
|
};
|
|
795
1163
|
} catch (error) {
|
|
796
1164
|
return console.warn("AtomixGlassContainer: Error generating container variables", error),
|
|
797
1165
|
{
|
|
798
|
-
"--atomix-glass-container-
|
|
799
|
-
"--atomix-glass-container-radius": "0px",
|
|
800
|
-
"--atomix-glass-container-backdrop": "none",
|
|
801
|
-
"--atomix-glass-container-shadow": "none",
|
|
802
|
-
"--atomix-glass-container-shadow-opacity": 1,
|
|
803
|
-
"--atomix-glass-container-bg": "none",
|
|
804
|
-
"--atomix-glass-container-text-shadow": "none"
|
|
1166
|
+
"--atomix-glass-container-radius": "0px"
|
|
805
1167
|
};
|
|
806
1168
|
}
|
|
807
|
-
}), [ borderRadius
|
|
1169
|
+
}), [ borderRadius ]);
|
|
808
1170
|
return jsx("div", {
|
|
809
|
-
ref:
|
|
810
|
-
|
|
811
|
-
"function" == typeof ref ? ref(el) : ref && (ref.current = el);
|
|
812
|
-
},
|
|
813
|
-
className: `${ATOMIX_GLASS.CONTAINER_CLASS} ${className} ${isActive ? ATOMIX_GLASS.CLASSES.ACTIVE : ""} ${overLight ? ATOMIX_GLASS.CLASSES.OVER_LIGHT : ""}`,
|
|
1171
|
+
ref: containerRef,
|
|
1172
|
+
className: mergeClassNames(ATOMIX_GLASS.CONTAINER_CLASS, className, isActive && ATOMIX_GLASS.CLASSES.ACTIVE, overLight && ATOMIX_GLASS.CLASSES.OVER_LIGHT),
|
|
814
1173
|
style: {
|
|
815
1174
|
...style,
|
|
816
1175
|
...containerVars
|
|
@@ -828,8 +1187,8 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
828
1187
|
blurAmount: blurAmount,
|
|
829
1188
|
mode: mode,
|
|
830
1189
|
id: filterId,
|
|
831
|
-
displacementScale:
|
|
832
|
-
aberrationIntensity:
|
|
1190
|
+
displacementScale: toSafeNumber(displacementScale),
|
|
1191
|
+
aberrationIntensity: toSafeNumber(aberrationIntensity),
|
|
833
1192
|
shaderMapUrl: shaderMapUrl
|
|
834
1193
|
}), jsx("div", {
|
|
835
1194
|
className: ATOMIX_GLASS.FILTER_OVERLAY_CLASS,
|
|
@@ -851,8 +1210,12 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
851
1210
|
});
|
|
852
1211
|
}));
|
|
853
1212
|
|
|
854
|
-
|
|
855
|
-
|
|
1213
|
+
/**
|
|
1214
|
+
* Internal glass surface that owns backdrop-filter, SVG distortion, and content.
|
|
1215
|
+
*
|
|
1216
|
+
* Layout and stacking styles are applied via the `style` prop from the parent.
|
|
1217
|
+
* The root wrapper supplies CSS custom properties only.
|
|
1218
|
+
*/ AtomixGlassContainer.displayName = "AtomixGlassContainer";
|
|
856
1219
|
|
|
857
1220
|
// Singleton instance
|
|
858
1221
|
const globalMouseTracker = new
|
|
@@ -967,28 +1330,32 @@ class {
|
|
|
967
1330
|
*/ getSubscriberCount() {
|
|
968
1331
|
return this.listeners.size;
|
|
969
1332
|
}
|
|
970
|
-
}, updateAtomixGlassStyles = (wrapperElement, containerElement, params) => {
|
|
1333
|
+
}, {BORDER: BORDER, CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, BORDER_GRADIENT = BORDER.GRADIENT, WHITE = CONSTANTS$2.PALETTE.WHITE, updateAtomixGlassStyles = (wrapperElement, containerElement, params) => {
|
|
971
1334
|
if (!wrapperElement && !containerElement) return;
|
|
972
1335
|
if (!validateGlassSize(params.glassSize)) return;
|
|
973
|
-
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,
|
|
1336
|
+
const {mouseOffset: mouseOffset, globalMousePosition: globalMousePosition, glassSize: glassSize, isHovered: isHovered, isActive: isActive, isOverLight: isOverLight, baseOverLightConfig: baseOverLightConfig, effectiveBorderRadius: effectiveBorderRadius, effectiveWithoutEffects: effectiveWithoutEffects, effectiveReducedMotion: effectiveReducedMotion, elasticity: elasticity, elasticTranslation: elasticTranslation, elasticVelocity: elasticVelocity, mouseVelocity: mouseVelocity, directionalScale: directionalScale, scaleBase: scaleBase, onClick: onClick, withLiquidBlur: withLiquidBlur, blurAmount: blurAmount = ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT, saturation: saturation = ATOMIX_GLASS.DEFAULTS.SATURATION, isFixedOrSticky: isFixedOrSticky = !1, borderAnimated: borderAnimated = !0, borderOpacityMultiplier: borderOpacityMultiplier = 1} = params, mouseInfluence = calculateMouseInfluence(mouseOffset), {hoverIntensity: hoverIntensity, activeIntensity: activeIntensity} = getInteractionIntensity(isHovered, isActive), overLightConfig = {
|
|
974
1337
|
opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
|
|
975
1338
|
contrast: Math.min(1.6, baseOverLightConfig.contrast + .1 * mouseInfluence),
|
|
976
1339
|
brightness: Math.min(1.1, baseOverLightConfig.brightness + .05 * mouseInfluence),
|
|
977
1340
|
shadowIntensity: Math.min(1.2, Math.max(.5, baseOverLightConfig.shadowIntensity + .2 * mouseInfluence)),
|
|
978
1341
|
borderOpacity: Math.min(1, Math.max(.3, baseOverLightConfig.borderOpacity + .1 * mouseInfluence)),
|
|
979
1342
|
saturationBoost: baseOverLightConfig.saturationBoost
|
|
980
|
-
}, scaleX = directionalScale.x * scaleBase, scaleY = directionalScale.y * scaleBase, transformStyle = effectiveWithoutEffects ? `scale(${scaleBase})` : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) scaleX(${scaleX}) scaleY(${scaleY})`,
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
x
|
|
986
|
-
|
|
987
|
-
}
|
|
1343
|
+
}, scaleX = directionalScale.x * scaleBase, scaleY = directionalScale.y * scaleBase, transformStyle = effectiveWithoutEffects ? `scale(${scaleBase})` : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) scaleX(${scaleX}) scaleY(${scaleY})`, tensionFactor =
|
|
1344
|
+
/**
|
|
1345
|
+
* Computes tension factor from elastic translation magnitude (0–1).
|
|
1346
|
+
*/
|
|
1347
|
+
function(elasticTranslation) {
|
|
1348
|
+
const magnitude = Math.hypot(elasticTranslation.x, elasticTranslation.y);
|
|
1349
|
+
return smoothstep(magnitude / 80);
|
|
1350
|
+
}
|
|
1351
|
+
/**
|
|
1352
|
+
* Updates the styles of the AtomixGlass wrapper and container elements imperatively
|
|
1353
|
+
* to avoid React re-renders on mouse movement.
|
|
1354
|
+
*/ (elasticTranslation), lightingContrast = Math.min(1.8, overLightConfig.contrast + .2 * tensionFactor), lightingBrightness = Math.min(1.2, overLightConfig.brightness + .1 * tensionFactor);
|
|
988
1355
|
// Calculate mouse influence
|
|
989
1356
|
// Update Wrapper Styles (glassVars)
|
|
990
1357
|
if (wrapperElement) {
|
|
991
|
-
const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT,
|
|
1358
|
+
const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT, whiteColor = ATOMIX_GLASS.CONSTANTS.PALETTE.WHITE, blackColor = ATOMIX_GLASS.CONSTANTS.PALETTE.BLACK, hoverPositions = {
|
|
992
1359
|
hover1: {
|
|
993
1360
|
x: GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_1,
|
|
994
1361
|
y: GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_1
|
|
@@ -1005,28 +1372,55 @@ class {
|
|
|
1005
1372
|
x: GRADIENT.CENTER_POSITION + mx * GRADIENT.BASE_LAYER_MULTIPLIER,
|
|
1006
1373
|
y: GRADIENT.CENTER_POSITION + my * GRADIENT.BASE_LAYER_MULTIPLIER
|
|
1007
1374
|
}, opacityValues = {
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1375
|
+
// hover-1: ambient highlight glow — present on hover and during press
|
|
1376
|
+
hover1: isHovered || isActive ? 1 : 0,
|
|
1377
|
+
// hover-2: press depth shadow — only fires on active (mousedown)
|
|
1378
|
+
hover2: isActive ? 1 : 0,
|
|
1379
|
+
// hover-3: global soft-light surface shift — half-strength on hover, full on press
|
|
1380
|
+
hover3: isActive ? 1 : isHovered ? .55 : 0,
|
|
1381
|
+
// Dark chrome: faint smoky tint; over-light keeps stronger fill
|
|
1382
|
+
base: isOverLight ? overLightConfig.opacity : .14,
|
|
1383
|
+
over: isOverLight ? 1.1 * overLightConfig.opacity : .1
|
|
1013
1384
|
}, style = wrapperElement.style;
|
|
1014
1385
|
style.setProperty("--atomix-glass-transform", transformStyle || "none");
|
|
1015
1386
|
// Parallax for content (liquid refraction feel)
|
|
1016
1387
|
const parallaxFactor = .38 + .12 * tensionFactor;
|
|
1017
1388
|
style.setProperty("--atomix-glass-child-parallax", `translate(${elasticTranslation.x * -parallaxFactor}px, ${elasticTranslation.y * -parallaxFactor}px)`),
|
|
1018
|
-
style.setProperty("--atomix-glass-contrast", lightingContrast.toString()), style.setProperty("--atomix-glass-brightness", lightingBrightness.toString())
|
|
1389
|
+
style.setProperty("--atomix-glass-contrast", lightingContrast.toString()), style.setProperty("--atomix-glass-brightness", lightingBrightness.toString());
|
|
1019
1390
|
// ── Chromatic Rim Lighting ──────────────────────────────────────
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1391
|
+
const borderVars = ATOMIX_GLASS.BORDER.GRADIENT_CSS_VARS;
|
|
1392
|
+
if (borderAnimated && !effectiveWithoutEffects) {
|
|
1393
|
+
const borderCssVars =
|
|
1394
|
+
/**
|
|
1395
|
+
* Builds animated chromatic rim CSS variables for border layers 1 and 2.
|
|
1396
|
+
* When empty, SCSS static conic/linear fallbacks apply.
|
|
1397
|
+
*/
|
|
1398
|
+
function(params) {
|
|
1399
|
+
const {mouseOffset: mouseOffset, mouseVelocity: mouseVelocity, elasticVelocity: elasticVelocity, borderOpacity: borderOpacity, opacityMultiplier: opacityMultiplier = 1, tensionFactor: tensionFactor = 0} = params, mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), velocityRotation = (mouseVelocity.x + elasticVelocity.x) * BORDER_GRADIENT.VELOCITY_ANGLE_MULTIPLIER, borderGradientAngle = BORDER_GRADIENT.BASE_ANGLE + mx * BORDER_GRADIENT.ANGLE_MULTIPLIER + velocityRotation, chromaticOffset = BORDER_GRADIENT.CHROMATIC_OFFSET, angleR = borderGradientAngle - chromaticOffset, angleB = borderGradientAngle + chromaticOffset, borderStop1 = Math.max(BORDER_GRADIENT.STOP_1.MIN, BORDER_GRADIENT.STOP_1.BASE + my * BORDER_GRADIENT.STOP_1.MULTIPLIER), borderStop2 = Math.min(BORDER_GRADIENT.STOP_2.MAX, BORDER_GRADIENT.STOP_2.BASE + my * BORDER_GRADIENT.STOP_2.MULTIPLIER), tensionGlow = 1 + .5 * tensionFactor, opacities = BORDER_GRADIENT.OPACITY, borderOpacities = [ (opacities.BASE_1 + absMx * opacities.MULTIPLIER_LOW) * tensionGlow, (opacities.BASE_2 + absMx * opacities.MULTIPLIER_HIGH) * tensionGlow, (opacities.BASE_3 + absMx * opacities.MULTIPLIER_LOW) * tensionGlow, (opacities.BASE_4 + absMx * opacities.MULTIPLIER_HIGH) * tensionGlow ], configBorderOpacity = borderOpacity * opacityMultiplier, gradient1 = `linear-gradient(${angleB}deg, rgba(${WHITE}, 0) 0%, rgba(${WHITE}, ${(borderOpacities[0] ?? 1) * configBorderOpacity}) ${borderStop1}%, rgba(${WHITE}, ${(borderOpacities[1] ?? 1) * configBorderOpacity}) ${borderStop2}%, rgba(${WHITE}, 0) 100%)`, gradient2 = `linear-gradient(${angleR}deg, rgba(${WHITE}, 0) 0%, rgba(${WHITE}, ${(borderOpacities[2] ?? 1) * configBorderOpacity}) ${borderStop1}%, rgba(${WHITE}, ${(borderOpacities[3] ?? 1) * configBorderOpacity}) ${borderStop2}%, rgba(${WHITE}, 0) 100%)`;
|
|
1400
|
+
return {
|
|
1401
|
+
[BORDER.GRADIENT_CSS_VARS.GRADIENT_1]: gradient1,
|
|
1402
|
+
[BORDER.GRADIENT_CSS_VARS.GRADIENT_2]: gradient2
|
|
1403
|
+
};
|
|
1404
|
+
}({
|
|
1405
|
+
mouseOffset: mouseOffset,
|
|
1406
|
+
mouseVelocity: mouseVelocity,
|
|
1407
|
+
elasticVelocity: elasticVelocity,
|
|
1408
|
+
borderOpacity: overLightConfig.borderOpacity,
|
|
1409
|
+
opacityMultiplier: borderOpacityMultiplier,
|
|
1410
|
+
tensionFactor: tensionFactor
|
|
1411
|
+
});
|
|
1412
|
+
style.setProperty(borderVars.GRADIENT_1, borderCssVars[borderVars.GRADIENT_1] ?? ""),
|
|
1413
|
+
style.setProperty(borderVars.GRADIENT_2, borderCssVars[borderVars.GRADIENT_2] ?? "");
|
|
1414
|
+
} else style.removeProperty(borderVars.GRADIENT_1), style.removeProperty(borderVars.GRADIENT_2);
|
|
1415
|
+
// Hover gradients — cursor-relative radial positions for realistic light tracking.
|
|
1416
|
+
// hover-1: white overlay highlight following cursor (works on both dark + light)
|
|
1417
|
+
style.setProperty("--atomix-glass-hover-1-gradient", `radial-gradient(65% 55% at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, rgba(${whiteColor}, 0.24) 0%, rgba(${whiteColor}, 0.06) 45%, rgba(${whiteColor}, 0) 72%)`),
|
|
1418
|
+
// hover-2: press depth — darkens at cursor with multiply blend, isOverLight uses stronger black
|
|
1419
|
+
style.setProperty("--atomix-glass-hover-2-gradient", isOverLight ? `radial-gradient(60% 50% at ${hoverPositions.hover2.x}% ${hoverPositions.hover2.y}%, rgba(${blackColor}, 0.22) 0%, rgba(${blackColor}, 0.06) 50%, rgba(${blackColor}, 0) 72%)` : `radial-gradient(60% 50% at ${hoverPositions.hover2.x}% ${hoverPositions.hover2.y}%, rgba(${blackColor}, 0.18) 0%, rgba(${blackColor}, 0.04) 50%, rgba(${blackColor}, 0) 72%)`),
|
|
1420
|
+
// hover-3: full-surface soft-light tint; linear gradient angled with cursor X
|
|
1421
|
+
style.setProperty("--atomix-glass-hover-3-gradient", `linear-gradient(${150 + .3 * mx}deg, rgba(${whiteColor}, ${isOverLight ? .08 : .12}) 0%, rgba(${whiteColor}, 0.04) 55%, rgba(${whiteColor}, 0) 100%)`),
|
|
1422
|
+
style.setProperty("--atomix-glass-base-gradient", isOverLight ? `linear-gradient(${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.ANGLE}deg, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_BASE + mx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_BASE + my * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_MULTIPLIER}) ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_STOP}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_BASE + absMx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `linear-gradient(180deg, rgba(${blackColor}, 0.42) 0%, rgba(${blackColor}, 0.22) 55%, rgba(${blackColor}, 0.12) 100%)`),
|
|
1423
|
+
style.setProperty("--atomix-glass-overlay-gradient", isOverLight ? `radial-gradient(circle at ${basePosition.x}% ${basePosition.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_BASE + absMx * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID_STOP}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_BASE + absMy * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `radial-gradient(120% 80% at 50% 0%, rgba(${whiteColor}, 0.14) 0%, rgba(${whiteColor}, 0) 55%)`),
|
|
1030
1424
|
// Opacities
|
|
1031
1425
|
style.setProperty("--atomix-glass-hover-1-opacity", opacityValues.hover1.toString()),
|
|
1032
1426
|
style.setProperty("--atomix-glass-hover-2-opacity", opacityValues.hover2.toString()),
|
|
@@ -1063,151 +1457,16 @@ class {
|
|
|
1063
1457
|
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})`;
|
|
1064
1458
|
// Container variables
|
|
1065
1459
|
const style = containerElement.style;
|
|
1066
|
-
style.setProperty("--atomix-glass-container-
|
|
1460
|
+
style.setProperty("--atomix-glass-container-radius", `${effectiveBorderRadius}px`),
|
|
1067
1461
|
style.setProperty("--atomix-glass-container-backdrop", backdropFilterString),
|
|
1068
1462
|
// Shadows
|
|
1069
|
-
style.setProperty("--atomix-glass-container-shadow", isOverLight ? [ `inset 0 1px 0 rgba(255, 255, 255, ${(.
|
|
1463
|
+
style.setProperty("--atomix-glass-container-shadow", isOverLight ? [ `inset 0 1px 0 rgba(255, 255, 255, ${(.35 + .002 * mx) * (overLightConfig.shadowIntensity || 1)})`, `inset 0 -1px 0 rgba(0, 0, 0, ${(.15 + .001 * Math.abs(my)) * (overLightConfig.shadowIntensity || 1)})`, `inset 0 0 20px rgba(0, 0, 0, ${(.06 + .001 * Math.abs(mx + my)) * (overLightConfig.shadowIntensity || 1)})`, `0 2px 12px rgba(0, 0, 0, ${(.08 + .002 * Math.abs(my)) * (overLightConfig.shadowIntensity || 1)})` ].join(", ") : ATOMIX_GLASS.CONSTANTS.CONTAINER_SHADOW.LIGHT),
|
|
1070
1464
|
style.setProperty("--atomix-glass-container-shadow-opacity", effectiveWithoutEffects ? "0" : "1"),
|
|
1071
1465
|
style.setProperty("--atomix-glass-container-bg", isOverLight ? `linear-gradient(${180 + .5 * mx}deg, rgba(255, 255, 255, 0.1) 0%, transparent 20%, transparent 80%, rgba(0, 0, 0, 0.05) 100%)` : "none"),
|
|
1072
1466
|
style.setProperty("--atomix-glass-container-text-shadow", isOverLight ? "0px 1px 2px rgba(255, 255, 255, 0.15)" : "0px 2px 12px rgba(0, 0, 0, 0.4)"),
|
|
1073
|
-
style.setProperty("--atomix-glass-container-box-shadow", isOverLight ? "0px 16px 70px rgba(0, 0, 0, 0.75)" : "
|
|
1467
|
+
style.setProperty("--atomix-glass-container-box-shadow", isOverLight ? "0px 16px 70px rgba(0, 0, 0, 0.75)" : "0 4px 16px rgba(0, 0, 0, 0.14), 0 1px 4px rgba(0, 0, 0, 0.10)");
|
|
1074
1468
|
}
|
|
1075
|
-
};
|
|
1076
|
-
|
|
1077
|
-
/**
|
|
1078
|
-
* Updates the styles of the AtomixGlass wrapper and container elements imperatively
|
|
1079
|
-
* to avoid React re-renders on mouse movement.
|
|
1080
|
-
*/
|
|
1081
|
-
/**
|
|
1082
|
-
* Animation System for AtomixGlass Component
|
|
1083
|
-
*
|
|
1084
|
-
* Implements Phase 1 features from the AtomixGlass Feature Implementation Roadmap:
|
|
1085
|
-
* - Feature 1.1: Time-Based Animation System
|
|
1086
|
-
* - Feature 1.2: Multi-Layer Distortion System (FBM)
|
|
1087
|
-
*
|
|
1088
|
-
* @packageDocumentation
|
|
1089
|
-
*/
|
|
1090
|
-
// ============================================================================
|
|
1091
|
-
// Noise Functions for FBM (Feature 1.2)
|
|
1092
|
-
// ============================================================================
|
|
1093
|
-
/**
|
|
1094
|
-
* Perlin noise implementation for smooth gradient noise
|
|
1095
|
-
*
|
|
1096
|
-
* @param x - X coordinate
|
|
1097
|
-
* @param y - Y coordinate
|
|
1098
|
-
* @returns Noise value in range [0, 1]
|
|
1099
|
-
*/
|
|
1100
|
-
function perlinNoise(x, y) {
|
|
1101
|
-
// Simplified Perlin noise using pseudo-random gradients
|
|
1102
|
-
const X = 255 & Math.floor(x), Y = 255 & Math.floor(y), xf = x - Math.floor(x), yf = y - Math.floor(y), u = fade(xf), v = fade(yf), A = p[X] + Y & 255, B = p[X + 1] + Y & 255, ga = grad(p[A], xf, yf), gb = grad(p[B], xf - 1, yf), gc = grad(p[A + 1 & 255], xf, yf - 1), gd = grad(p[B + 1 & 255], xf - 1, yf - 1), lerpX1 = lerp(ga, gb, u), lerpX2 = lerp(gc, gd, u);
|
|
1103
|
-
// Scale to [0, 1] range
|
|
1104
|
-
return (lerp(lerpX1, lerpX2, v) + 1) / 2;
|
|
1105
|
-
}
|
|
1106
|
-
|
|
1107
|
-
// ============================================================================
|
|
1108
|
-
// Fractal Brownian Motion (FBM) Engine (Feature 1.2)
|
|
1109
|
-
// ============================================================================
|
|
1110
|
-
/**
|
|
1111
|
-
* Creates an FBM engine with configurable parameters
|
|
1112
|
-
*
|
|
1113
|
-
* @param config - FBM configuration (octaves, lacunarity, gain)
|
|
1114
|
-
* @returns Object with fbm function
|
|
1115
|
-
*
|
|
1116
|
-
* @example
|
|
1117
|
-
* ```typescript
|
|
1118
|
-
* const fbmEngine = createFBMEngine({ octaves: 5, lacunarity: 2, gain: 0.5 });
|
|
1119
|
-
*
|
|
1120
|
-
* // Generate noise at position (0.5, 0.5) with time animation
|
|
1121
|
-
* const noiseValue = fbmEngine.fbm(0.5, 0.5, Date.now());
|
|
1122
|
-
* ```
|
|
1123
|
-
*/ function createFBMEngine(config) {
|
|
1124
|
-
/**
|
|
1125
|
-
* Fractal Brownian Motion function
|
|
1126
|
-
* Combines multiple octaves of noise for complex, natural patterns
|
|
1127
|
-
*
|
|
1128
|
-
* @param x - X coordinate
|
|
1129
|
-
* @param y - Y coordinate
|
|
1130
|
-
* @param time - Optional time value for animation
|
|
1131
|
-
* @returns FBM noise value in range [0, 1]
|
|
1132
|
-
*/
|
|
1133
|
-
const fbm = (x, y, time = 0) => {
|
|
1134
|
-
let value = 0, amplitude = .5, frequency = 1, phase = .001 * time;
|
|
1135
|
-
// Convert to seconds for reasonable animation speed
|
|
1136
|
-
for (let i = 0; i < config.octaves; i++)
|
|
1137
|
-
// Apply time-based phase shift to all octaves
|
|
1138
|
-
value += perlinNoise(x * frequency + phase, y * frequency + phase) * amplitude,
|
|
1139
|
-
frequency *= config.lacunarity, // Increase frequency
|
|
1140
|
-
amplitude *= config.gain;
|
|
1141
|
-
return value;
|
|
1142
|
-
};
|
|
1143
|
-
/**
|
|
1144
|
-
* Get FBM with simple time factor
|
|
1145
|
-
*/ return {
|
|
1146
|
-
fbm: fbm,
|
|
1147
|
-
fbmWithTime: (x, y, time) => fbm(x, y, time)
|
|
1148
|
-
};
|
|
1149
|
-
}
|
|
1150
|
-
|
|
1151
|
-
/**
|
|
1152
|
-
* Gets optimal FBM config based on quality preset
|
|
1153
|
-
*
|
|
1154
|
-
* @param quality - Quality preset level
|
|
1155
|
-
* @returns FBM configuration for the quality level
|
|
1156
|
-
*/ const fbmEngineCache = new Map;
|
|
1157
|
-
|
|
1158
|
-
// ============================================================================
|
|
1159
|
-
// Shader Utility Functions for Time-Based Effects
|
|
1160
|
-
// ============================================================================
|
|
1161
|
-
/**
|
|
1162
|
-
* Liquid glass distortion with time-based animation
|
|
1163
|
-
* Uses FBM to create organic, flowing liquid effects
|
|
1164
|
-
*
|
|
1165
|
-
* @param uv - UV coordinates (normalized 0-1)
|
|
1166
|
-
* @param time - Elapsed time in milliseconds
|
|
1167
|
-
* @param config - FBM configuration
|
|
1168
|
-
* @returns Distorted UV coordinates
|
|
1169
|
-
*/ function liquidGlassWithTime(uv, time, config) {
|
|
1170
|
-
const configKey = `${config.octaves}-${config.lacunarity}-${config.gain}`;
|
|
1171
|
-
let fbmEngine = fbmEngineCache.get(configKey);
|
|
1172
|
-
fbmEngine || (fbmEngine = createFBMEngine(config), fbmEngineCache.set(configKey, fbmEngine));
|
|
1173
|
-
// Animate noise with time
|
|
1174
|
-
const animatedNoise = fbmEngine.fbmWithTime(2 * uv.x + 1e-4 * time, 2 * uv.y + 15e-5 * time, time);
|
|
1175
|
-
return {
|
|
1176
|
-
x: uv.x + .04 * (animatedNoise - .5),
|
|
1177
|
-
y: uv.y + .04 * (animatedNoise - .5)
|
|
1178
|
-
};
|
|
1179
|
-
}
|
|
1180
|
-
|
|
1181
|
-
// ============================================================================
|
|
1182
|
-
// Helper Functions
|
|
1183
|
-
// ============================================================================
|
|
1184
|
-
/**
|
|
1185
|
-
* Fade curve for smooth interpolation (Perlin's fade function)
|
|
1186
|
-
*/ function fade(t) {
|
|
1187
|
-
return t * t * t * (t * (6 * t - 15) + 10);
|
|
1188
|
-
}
|
|
1189
|
-
|
|
1190
|
-
/**
|
|
1191
|
-
* Linear interpolation
|
|
1192
|
-
*/ function lerp(a, b, t) {
|
|
1193
|
-
return a + t * (b - a);
|
|
1194
|
-
}
|
|
1195
|
-
|
|
1196
|
-
/**
|
|
1197
|
-
* Gradient calculation for Perlin noise
|
|
1198
|
-
*/ function grad(hash, x, y) {
|
|
1199
|
-
const h = 15 & hash, u = h < 8 ? x : y, v = h < 4 ? y : 12 === h || 14 === h ? x : 0;
|
|
1200
|
-
return (1 & h ? -u : u) + (2 & h ? -v : v);
|
|
1201
|
-
}
|
|
1202
|
-
|
|
1203
|
-
/**
|
|
1204
|
-
* Permutation table for Perlin noise
|
|
1205
|
-
*/ const p = (() => {
|
|
1206
|
-
const permutation = [];
|
|
1207
|
-
for (let i = 0; i < 256; i++) permutation[i] = Math.floor(256 * Math.random());
|
|
1208
|
-
// Duplicate for overflow handling
|
|
1209
|
-
return [ ...permutation, ...permutation ];
|
|
1210
|
-
})(), {CONSTANTS: CONSTANTS$1} = ATOMIX_GLASS;
|
|
1469
|
+
}, {CONSTANTS: CONSTANTS$1} = ATOMIX_GLASS;
|
|
1211
1470
|
|
|
1212
1471
|
const {CONSTANTS: CONSTANTS} = ATOMIX_GLASS, backgroundDetectionCache = new WeakMap, setCachedBackgroundDetection = (parentElement, overLightConfig, result, threshold) => {
|
|
1213
1472
|
parentElement && backgroundDetectionCache.set(parentElement, {
|
|
@@ -1222,12 +1481,35 @@ const {CONSTANTS: CONSTANTS} = ATOMIX_GLASS, backgroundDetectionCache = new Weak
|
|
|
1222
1481
|
* Composable hook for AtomixGlass component logic
|
|
1223
1482
|
* Manages all state, calculations, and event handlers
|
|
1224
1483
|
*/
|
|
1225
|
-
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,
|
|
1226
|
-
//
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1484
|
+
function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef: wrapperRef, borderRadius: borderRadius, globalMousePosition: externalGlobalMousePosition, mouseOffset: externalMouseOffset, mouseContainer: mouseContainer, overLight: overLight = ATOMIX_GLASS.DEFAULTS.OVER_LIGHT, reducedMotion: reducedMotion = !1, highContrast: highContrast = !1, withoutEffects: withoutEffects = !1, border: border, withBorder: withBorder = !0, elasticity: elasticity = ATOMIX_GLASS.DEFAULTS.ELASTICITY, onClick: onClick, debugBorderRadius: debugBorderRadius = !1, debugOverLight: debugOverLight = !1, children: children, blurAmount: blurAmount, saturation: saturation, withLiquidBlur: withLiquidBlur, isFixedOrSticky: isFixedOrSticky = !1, priority: priority = 1}) {
|
|
1485
|
+
// State
|
|
1486
|
+
const [isHovered, setIsHovered] = useState(!1), [isActive, setIsActive] = useState(!1), resolvedBorder = useMemo((() =>
|
|
1487
|
+
/**
|
|
1488
|
+
* Resolves `border` and legacy `withBorder` into a single configuration object.
|
|
1489
|
+
*/
|
|
1490
|
+
function(border, withBorder) {
|
|
1491
|
+
const legacyDefault = withBorder ?? !0;
|
|
1492
|
+
return void 0 === border ? {
|
|
1493
|
+
enabled: legacyDefault,
|
|
1494
|
+
width: BORDER.DEFAULT_WIDTH,
|
|
1495
|
+
opacityMultiplier: 1,
|
|
1496
|
+
animated: !0
|
|
1497
|
+
} : "boolean" == typeof border ? {
|
|
1498
|
+
enabled: border,
|
|
1499
|
+
width: BORDER.DEFAULT_WIDTH,
|
|
1500
|
+
opacityMultiplier: 1,
|
|
1501
|
+
animated: !0
|
|
1502
|
+
} : {
|
|
1503
|
+
enabled: border.enabled ?? legacyDefault,
|
|
1504
|
+
width: (value = border.width, void 0 === value ? BORDER.DEFAULT_WIDTH : "number" == typeof value ? `${value}px` : value),
|
|
1505
|
+
opacityMultiplier: border.opacity ?? 1,
|
|
1506
|
+
animated: !1 !== border.animated
|
|
1507
|
+
};
|
|
1508
|
+
/**
|
|
1509
|
+
* Formats border width for CSS custom properties.
|
|
1510
|
+
*/
|
|
1511
|
+
var value;
|
|
1512
|
+
}(border, withBorder)), [ border, withBorder ]), cachedRectRef = useRef(null), internalGlobalMousePositionRef = useRef({
|
|
1231
1513
|
x: 0,
|
|
1232
1514
|
y: 0
|
|
1233
1515
|
}), internalMouseOffsetRef = useRef({
|
|
@@ -1251,52 +1533,10 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1251
1533
|
}), scaleVelocityRef = useRef({
|
|
1252
1534
|
x: 0,
|
|
1253
1535
|
y: 0
|
|
1254
|
-
})
|
|
1255
|
-
useRef(0);
|
|
1256
|
-
const mouseVelocityRef = useRef({
|
|
1536
|
+
}), mouseVelocityRef = useRef({
|
|
1257
1537
|
x: 0,
|
|
1258
1538
|
y: 0
|
|
1259
|
-
}), [userPrefersReducedMotion, setUserPrefersReducedMotion] = useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = useState(!1), [detectedOverLight, setDetectedOverLight] = useState(!1),
|
|
1260
|
-
// If quality preset is provided, use it as base
|
|
1261
|
-
const preset = (quality = distortionQuality, ATOMIX_GLASS.CONSTANTS.DISTORTION_QUALITY_PRESETS[quality]);
|
|
1262
|
-
// Override with custom values if provided
|
|
1263
|
-
var quality;
|
|
1264
|
-
return {
|
|
1265
|
-
octaves: distortionOctaves ?? preset.octaves,
|
|
1266
|
-
lacunarity: distortionLacunarity ?? preset.lacunarity,
|
|
1267
|
-
gain: distortionGain ?? preset.gain
|
|
1268
|
-
};
|
|
1269
|
-
}), [ distortionQuality, distortionOctaves, distortionLacunarity, distortionGain ]), fbmEngine = useMemo((() => withMultiLayerDistortion ? createFBMEngine(fbmConfig) : null), [ withMultiLayerDistortion, fbmConfig ]), effectiveReducedMotion = useMemo((() => reducedMotion || userPrefersReducedMotion), [ reducedMotion, userPrefersReducedMotion ]), effectiveWithTimeAnimation = useMemo((() => withTimeAnimation && !effectiveReducedMotion), [ withTimeAnimation, effectiveReducedMotion ]);
|
|
1270
|
-
/**
|
|
1271
|
-
* Animation loop for time-based effects
|
|
1272
|
-
*/
|
|
1273
|
-
useEffect((() => {
|
|
1274
|
-
if (!effectiveWithTimeAnimation || "undefined" == typeof window) return;
|
|
1275
|
-
let lastFrameTime = performance.now();
|
|
1276
|
-
/**
|
|
1277
|
-
* Animation frame handler
|
|
1278
|
-
*/ const animate = currentTime => {
|
|
1279
|
-
// Calculate delta time
|
|
1280
|
-
const deltaTime = currentTime - lastFrameTime;
|
|
1281
|
-
lastFrameTime = currentTime;
|
|
1282
|
-
// Apply animation speed multiplier
|
|
1283
|
-
const scaledDelta = deltaTime * animationSpeed;
|
|
1284
|
-
elapsedTimeRef.current += scaledDelta, shaderTimeRef.current = elapsedTimeRef.current,
|
|
1285
|
-
// Continue animation loop
|
|
1286
|
-
animationFrameIdRef.current = requestAnimationFrame(animate);
|
|
1287
|
-
};
|
|
1288
|
-
// Start animation
|
|
1289
|
-
// Cleanup
|
|
1290
|
-
return animationStartTimeRef.current = performance.now(), animationFrameIdRef.current = requestAnimationFrame(animate),
|
|
1291
|
-
() => {
|
|
1292
|
-
null !== animationFrameIdRef.current && (cancelAnimationFrame(animationFrameIdRef.current),
|
|
1293
|
-
animationFrameIdRef.current = null);
|
|
1294
|
-
};
|
|
1295
|
-
}), [ effectiveWithTimeAnimation, animationSpeed ]);
|
|
1296
|
-
/**
|
|
1297
|
-
* Get current shader time for animations
|
|
1298
|
-
*/
|
|
1299
|
-
const getShaderTime = useCallback((() => shaderTimeRef.current), []), applyTimeBasedDistortion = useCallback((uv => effectiveWithTimeAnimation && fbmEngine ? liquidGlassWithTime(uv, shaderTimeRef.current, fbmConfig) : uv), [ effectiveWithTimeAnimation, fbmEngine, fbmConfig ]), effectiveBorderRadius = useMemo((() => void 0 !== borderRadius ? Math.max(0, borderRadius) : Math.max(0, dynamicBorderRadius)), [ borderRadius, dynamicBorderRadius ]), {glassSize: glassSize} = function({glassRef: glassRef, effectiveBorderRadius: effectiveBorderRadius, cachedRectRef: cachedRectRef}) {
|
|
1539
|
+
}), [userPrefersReducedMotion, setUserPrefersReducedMotion] = useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = useState(!1), [detectedOverLight, setDetectedOverLight] = useState(!1), effectiveReducedMotion = useMemo((() => reducedMotion || userPrefersReducedMotion), [ reducedMotion, userPrefersReducedMotion ]), effectiveBorderRadius = useMemo((() => void 0 !== borderRadius ? Math.max(0, borderRadius) : Math.max(0, dynamicBorderRadius)), [ borderRadius, dynamicBorderRadius ]), {glassSize: glassSize} = function({glassRef: glassRef, effectiveBorderRadius: effectiveBorderRadius, cachedRectRef: cachedRectRef}) {
|
|
1300
1540
|
const [glassSize, setGlassSize] = useState({
|
|
1301
1541
|
width: 270,
|
|
1302
1542
|
height: 69
|
|
@@ -1356,9 +1596,6 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1356
1596
|
effectiveBorderRadius: effectiveBorderRadius,
|
|
1357
1597
|
cachedRectRef: cachedRectRef
|
|
1358
1598
|
}), effectiveHighContrast = useMemo((() => highContrast || userPrefersHighContrast), [ highContrast, userPrefersHighContrast ]), effectiveWithoutEffects = useMemo((() => withoutEffects || effectiveReducedMotion), [ withoutEffects, effectiveReducedMotion ]), globalMousePosition = externalGlobalMousePosition || internalGlobalMousePositionRef.current, mouseOffset = externalMouseOffset || internalMouseOffsetRef.current;
|
|
1359
|
-
/**
|
|
1360
|
-
* Apply time-based distortion to UV coordinates
|
|
1361
|
-
*/
|
|
1362
1599
|
// Extract border-radius from children
|
|
1363
1600
|
useEffect((() => {
|
|
1364
1601
|
const extractRadius = () => {
|
|
@@ -1518,25 +1755,26 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1518
1755
|
* Get effective overLight value based on configuration
|
|
1519
1756
|
*/
|
|
1520
1757
|
const getEffectiveOverLight = useCallback((() => "boolean" == typeof overLight ? overLight : ("auto" === overLight || "object" == typeof overLight && null !== overLight) && detectedOverLight), [ overLight, detectedOverLight ]), validateConfigValue = useCallback(((value, min, max, defaultValue) => "number" != typeof value || isNaN(value) || !isFinite(value) ? defaultValue : Math.min(max, Math.max(min, value))), []), overLightConfig = useMemo((() => {
|
|
1521
|
-
const isOverLight = getEffectiveOverLight(), hoverIntensity
|
|
1758
|
+
const isOverLight = getEffectiveOverLight(), {hoverIntensity: hoverIntensity, activeIntensity: activeIntensity} = getInteractionIntensity(isHovered, isActive), baseConfig = {
|
|
1522
1759
|
isOverLight: isOverLight,
|
|
1523
1760
|
threshold: .7,
|
|
1524
1761
|
opacity: isOverLight ? Math.min(.6, Math.max(.2, .5 * hoverIntensity * activeIntensity)) : 0,
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
shadowIntensity: .9,
|
|
1530
|
-
borderOpacity: .
|
|
1762
|
+
// Dark UI (Apple Music): neutral contrast + slight brightness lift
|
|
1763
|
+
contrast: isOverLight ? 1.4 : 1.02,
|
|
1764
|
+
brightness: isOverLight ? .9 : 1.02,
|
|
1765
|
+
saturationBoost: isOverLight ? 1.3 : 1,
|
|
1766
|
+
shadowIntensity: isOverLight ? .9 : 1,
|
|
1767
|
+
borderOpacity: isOverLight ? ATOMIX_GLASS.BORDER.OVER_LIGHT.opacity : ATOMIX_GLASS.BORDER.DARK.opacity
|
|
1531
1768
|
};
|
|
1532
1769
|
if ("object" == typeof overLight && null !== overLight) {
|
|
1533
|
-
const objConfig = overLight, validatedThreshold = validateConfigValue(objConfig.threshold, .1, 1, baseConfig.threshold), validatedOpacity = validateConfigValue(objConfig.opacity, .1, 1, baseConfig.opacity), validatedContrast = validateConfigValue(objConfig.contrast, .5, 2.5, baseConfig.contrast), validatedBrightness = validateConfigValue(objConfig.brightness, .5, 2, baseConfig.brightness), validatedSaturationBoost = validateConfigValue(objConfig.saturationBoost, .5, 3, baseConfig.saturationBoost), finalConfig = {
|
|
1770
|
+
const objConfig = overLight, validatedThreshold = validateConfigValue(objConfig.threshold, .1, 1, baseConfig.threshold), validatedOpacity = validateConfigValue(objConfig.opacity, .1, 1, baseConfig.opacity), validatedContrast = validateConfigValue(objConfig.contrast, .5, 2.5, baseConfig.contrast), validatedBrightness = validateConfigValue(objConfig.brightness, .5, 2, baseConfig.brightness), validatedSaturationBoost = validateConfigValue(objConfig.saturationBoost, .5, 3, baseConfig.saturationBoost), validatedBorderOpacity = validateConfigValue(objConfig.borderOpacity, .1, 1, baseConfig.borderOpacity), finalConfig = {
|
|
1534
1771
|
...baseConfig,
|
|
1535
1772
|
threshold: validatedThreshold,
|
|
1536
1773
|
opacity: validatedOpacity * hoverIntensity * activeIntensity,
|
|
1537
1774
|
contrast: validatedContrast,
|
|
1538
1775
|
brightness: validatedBrightness,
|
|
1539
|
-
saturationBoost: validatedSaturationBoost
|
|
1776
|
+
saturationBoost: validatedSaturationBoost,
|
|
1777
|
+
borderOpacity: validatedBorderOpacity
|
|
1540
1778
|
};
|
|
1541
1779
|
return "undefined" == typeof process || process.env, finalConfig;
|
|
1542
1780
|
}
|
|
@@ -1561,8 +1799,8 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1561
1799
|
};
|
|
1562
1800
|
const curG = internalGlobalMousePositionRef.current, tgtG = targetGlobalMousePositionRef.current;
|
|
1563
1801
|
internalGlobalMousePositionRef.current = {
|
|
1564
|
-
x: lerp
|
|
1565
|
-
y: lerp
|
|
1802
|
+
x: lerp(curG.x, tgtG.x, CONSTANTS.LERP_FACTOR),
|
|
1803
|
+
y: lerp(curG.y, tgtG.y, CONSTANTS.LERP_FACTOR)
|
|
1566
1804
|
};
|
|
1567
1805
|
// ── Calculate Elastic Physics ─────────────────────────────────────
|
|
1568
1806
|
let targetElasticTranslation = {
|
|
@@ -1634,12 +1872,13 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1634
1872
|
withLiquidBlur: withLiquidBlur,
|
|
1635
1873
|
blurAmount: blurAmount,
|
|
1636
1874
|
saturation: saturation,
|
|
1637
|
-
|
|
1638
|
-
|
|
1875
|
+
isFixedOrSticky: isFixedOrSticky,
|
|
1876
|
+
borderAnimated: resolvedBorder.animated,
|
|
1877
|
+
borderOpacityMultiplier: resolvedBorder.opacityMultiplier
|
|
1639
1878
|
}), 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);
|
|
1640
1879
|
};
|
|
1641
1880
|
lerpRafRef.current = requestAnimationFrame(tick);
|
|
1642
|
-
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation,
|
|
1881
|
+
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, isFixedOrSticky, resolvedBorder.animated, resolvedBorder.opacityMultiplier, stopLerpLoop ]), handleGlobalMousePosition = useCallback((globalPos => {
|
|
1643
1882
|
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
1644
1883
|
if (effectiveWithoutEffects) return;
|
|
1645
1884
|
const container = mouseContainer?.current || glassRef.current;
|
|
@@ -1703,9 +1942,10 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1703
1942
|
withLiquidBlur: withLiquidBlur,
|
|
1704
1943
|
blurAmount: blurAmount,
|
|
1705
1944
|
saturation: saturation,
|
|
1706
|
-
|
|
1945
|
+
borderAnimated: resolvedBorder.animated,
|
|
1946
|
+
borderOpacityMultiplier: resolvedBorder.opacityMultiplier
|
|
1707
1947
|
});
|
|
1708
|
-
}), [ isHovered, isActive, glassSize, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, wrapperRef, glassRef, externalMouseOffset, externalGlobalMousePosition, withLiquidBlur, blurAmount, saturation,
|
|
1948
|
+
}), [ isHovered, isActive, glassSize, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, wrapperRef, glassRef, externalMouseOffset, externalGlobalMousePosition, withLiquidBlur, blurAmount, saturation, resolvedBorder.animated, resolvedBorder.opacityMultiplier, onClick ]);
|
|
1709
1949
|
// Event handlers
|
|
1710
1950
|
const handleMouseEnter = useCallback((() => setIsHovered(!0)), []), handleMouseLeave = useCallback((() => setIsHovered(!1)), []), handleMouseDown = useCallback((() => setIsActive(!0)), []), handleMouseUp = useCallback((() => setIsActive(!1)), []), handleKeyDown = useCallback((e => {
|
|
1711
1951
|
!onClick || "Enter" !== e.key && " " !== e.key || (e.preventDefault(), onClick());
|
|
@@ -1725,9 +1965,8 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1725
1965
|
mouseOffset: mouseOffset,
|
|
1726
1966
|
// This is now static (refs or props) unless prop changes
|
|
1727
1967
|
overLightConfig: overLightConfig,
|
|
1968
|
+
resolvedBorder: resolvedBorder,
|
|
1728
1969
|
transformStyle: transformStyle,
|
|
1729
|
-
getShaderTime: getShaderTime,
|
|
1730
|
-
applyTimeBasedDistortion: applyTimeBasedDistortion,
|
|
1731
1970
|
handleMouseEnter: handleMouseEnter,
|
|
1732
1971
|
handleMouseLeave: handleMouseLeave,
|
|
1733
1972
|
handleMouseDown: handleMouseDown,
|
|
@@ -1759,317 +1998,41 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1759
1998
|
maxWidth: 1024,
|
|
1760
1999
|
params: {
|
|
1761
2000
|
distortionOctaves: 4,
|
|
1762
|
-
displacementScale: .85,
|
|
1763
|
-
blurAmount: .9,
|
|
1764
|
-
animationSpeed: .9,
|
|
1765
|
-
chromaticIntensity: .75
|
|
1766
|
-
}
|
|
1767
|
-
},
|
|
1768
|
-
desktop: {
|
|
1769
|
-
minWidth: 1025,
|
|
1770
|
-
params: {
|
|
1771
|
-
distortionOctaves: 5,
|
|
1772
|
-
displacementScale: 1,
|
|
1773
|
-
blurAmount: 1,
|
|
1774
|
-
animationSpeed: 1,
|
|
1775
|
-
chromaticIntensity: 1
|
|
1776
|
-
}
|
|
1777
|
-
}
|
|
1778
|
-
};
|
|
1779
|
-
|
|
1780
|
-
/**
|
|
1781
|
-
* Device performance tier detection
|
|
1782
|
-
*
|
|
1783
|
-
* Uses Device Memory API and Hardware Concurrency API to classify devices
|
|
1784
|
-
* into performance tiers for automatic quality adjustment.
|
|
1785
|
-
*
|
|
1786
|
-
* @returns Performance tier classification
|
|
1787
|
-
*/ var commonjsGlobal = "undefined" != typeof globalThis ? globalThis : "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof self ? self : {};
|
|
1788
|
-
|
|
1789
|
-
function getDefaultExportFromCjs(x) {
|
|
1790
|
-
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x.default : x;
|
|
1791
|
-
}
|
|
1792
|
-
|
|
1793
|
-
var fails$8 = function(exec) {
|
|
1794
|
-
try {
|
|
1795
|
-
return !!exec();
|
|
1796
|
-
} catch (error) {
|
|
1797
|
-
return !0;
|
|
1798
|
-
}
|
|
1799
|
-
}, functionBindNative = !fails$8((function() {
|
|
1800
|
-
// eslint-disable-next-line es/no-function-prototype-bind -- safe
|
|
1801
|
-
var test = function() {/* empty */}.bind();
|
|
1802
|
-
// eslint-disable-next-line no-prototype-builtins -- safe
|
|
1803
|
-
return "function" != typeof test || test.hasOwnProperty("prototype");
|
|
1804
|
-
})), NATIVE_BIND$3 = functionBindNative, FunctionPrototype$1 = Function.prototype, call$5 = FunctionPrototype$1.call, uncurryThisWithBind = NATIVE_BIND$3 && FunctionPrototype$1.bind.bind(call$5, call$5), functionUncurryThis = NATIVE_BIND$3 ? uncurryThisWithBind : function(fn) {
|
|
1805
|
-
return function() {
|
|
1806
|
-
return call$5.apply(fn, arguments);
|
|
1807
|
-
};
|
|
1808
|
-
}, objectIsPrototypeOf = functionUncurryThis({}.isPrototypeOf), check = function(it) {
|
|
1809
|
-
return it && it.Math === Math && it;
|
|
1810
|
-
}, globalThis_1 =
|
|
1811
|
-
// eslint-disable-next-line es/no-global-this -- safe
|
|
1812
|
-
check("object" == typeof globalThis && globalThis) || check("object" == typeof window && window) ||
|
|
1813
|
-
// eslint-disable-next-line no-restricted-globals -- safe
|
|
1814
|
-
check("object" == typeof self && self) || check("object" == typeof commonjsGlobal && commonjsGlobal) || check("object" == typeof commonjsGlobal && commonjsGlobal) ||
|
|
1815
|
-
// eslint-disable-next-line no-new-func -- fallback
|
|
1816
|
-
function() {
|
|
1817
|
-
return this;
|
|
1818
|
-
}() || Function("return this")(), NATIVE_BIND$2 = functionBindNative, FunctionPrototype = Function.prototype, apply$1 = FunctionPrototype.apply, call$4 = FunctionPrototype.call, functionApply = "object" == typeof Reflect && Reflect.apply || (NATIVE_BIND$2 ? call$4.bind(apply$1) : function() {
|
|
1819
|
-
return call$4.apply(apply$1, arguments);
|
|
1820
|
-
}), uncurryThis$7 = functionUncurryThis, toString$3 = uncurryThis$7({}.toString), stringSlice = uncurryThis$7("".slice), classofRaw$2 = function(it) {
|
|
1821
|
-
return stringSlice(toString$3(it), 8, -1);
|
|
1822
|
-
}, classofRaw$1 = classofRaw$2, uncurryThis$6 = functionUncurryThis, functionUncurryThisClause = function(fn) {
|
|
1823
|
-
// Nashorn bug:
|
|
1824
|
-
// https://github.com/zloirock/core-js/issues/1128
|
|
1825
|
-
// https://github.com/zloirock/core-js/issues/1130
|
|
1826
|
-
if ("Function" === classofRaw$1(fn)) return uncurryThis$6(fn);
|
|
1827
|
-
}, documentAll = "object" == typeof document && document.all, isCallable$8 = void 0 === documentAll && void 0 !== documentAll ? function(argument) {
|
|
1828
|
-
return "function" == typeof argument || argument === documentAll;
|
|
1829
|
-
} : function(argument) {
|
|
1830
|
-
return "function" == typeof argument;
|
|
1831
|
-
}, objectGetOwnPropertyDescriptor = {}, descriptors = !fails$8((function() {
|
|
1832
|
-
// eslint-disable-next-line es/no-object-defineproperty -- required for testing
|
|
1833
|
-
return 7 !== Object.defineProperty({}, 1, {
|
|
1834
|
-
get: function() {
|
|
1835
|
-
return 7;
|
|
1836
|
-
}
|
|
1837
|
-
})[1];
|
|
1838
|
-
})), NATIVE_BIND$1 = functionBindNative, call$3 = Function.prototype.call, functionCall = NATIVE_BIND$1 ? call$3.bind(call$3) : function() {
|
|
1839
|
-
return call$3.apply(call$3, arguments);
|
|
1840
|
-
}, objectPropertyIsEnumerable = {}, $propertyIsEnumerable = {}.propertyIsEnumerable, getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor, NASHORN_BUG = getOwnPropertyDescriptor$1 && !$propertyIsEnumerable.call({
|
|
1841
|
-
1: 2
|
|
1842
|
-
}, 1);
|
|
1843
|
-
|
|
1844
|
-
// `Object.prototype.propertyIsEnumerable` method implementation
|
|
1845
|
-
// https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable
|
|
1846
|
-
objectPropertyIsEnumerable.f = NASHORN_BUG ? function(V) {
|
|
1847
|
-
var descriptor = getOwnPropertyDescriptor$1(this, V);
|
|
1848
|
-
return !!descriptor && descriptor.enumerable;
|
|
1849
|
-
} : $propertyIsEnumerable;
|
|
1850
|
-
|
|
1851
|
-
var match, version, createPropertyDescriptor$2 = function(bitmap, value) {
|
|
1852
|
-
return {
|
|
1853
|
-
enumerable: !(1 & bitmap),
|
|
1854
|
-
configurable: !(2 & bitmap),
|
|
1855
|
-
writable: !(4 & bitmap),
|
|
1856
|
-
value: value
|
|
1857
|
-
};
|
|
1858
|
-
}, fails$5 = fails$8, classof$3 = classofRaw$2, $Object$3 = Object, split = functionUncurryThis("".split), indexedObject = fails$5((function() {
|
|
1859
|
-
// throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
|
|
1860
|
-
// eslint-disable-next-line no-prototype-builtins -- safe
|
|
1861
|
-
return !$Object$3("z").propertyIsEnumerable(0);
|
|
1862
|
-
})) ? function(it) {
|
|
1863
|
-
return "String" === classof$3(it) ? split(it, "") : $Object$3(it);
|
|
1864
|
-
} : $Object$3, isNullOrUndefined$2 = function(it) {
|
|
1865
|
-
return null == it;
|
|
1866
|
-
}, isNullOrUndefined$1 = isNullOrUndefined$2, $TypeError$6 = TypeError, requireObjectCoercible$3 = function(it) {
|
|
1867
|
-
if (isNullOrUndefined$1(it)) throw new $TypeError$6("Can't call method on " + it);
|
|
1868
|
-
return it;
|
|
1869
|
-
}, IndexedObject = indexedObject, requireObjectCoercible$2 = requireObjectCoercible$3, toIndexedObject$2 = function(it) {
|
|
1870
|
-
return IndexedObject(requireObjectCoercible$2(it));
|
|
1871
|
-
}, isCallable$7 = isCallable$8, isObject$5 = function(it) {
|
|
1872
|
-
return "object" == typeof it ? null !== it : isCallable$7(it);
|
|
1873
|
-
}, path$3 = {}, path$2 = path$3, globalThis$a = globalThis_1, isCallable$6 = isCallable$8, aFunction = function(variable) {
|
|
1874
|
-
return isCallable$6(variable) ? variable : void 0;
|
|
1875
|
-
}, navigator$1 = globalThis_1.navigator, userAgent$1 = navigator$1 && navigator$1.userAgent, globalThis$8 = globalThis_1, userAgent = userAgent$1 ? String(userAgent$1) : "", process$1 = globalThis$8.process, Deno = globalThis$8.Deno, versions = process$1 && process$1.versions || Deno && Deno.version, v8 = versions && versions.v8;
|
|
1876
|
-
|
|
1877
|
-
v8 && (
|
|
1878
|
-
// in old Chrome, versions of V8 isn't V8 = Chrome / 10
|
|
1879
|
-
// but their correct versions are not interesting for us
|
|
1880
|
-
version = (match = v8.split("."))[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1])),
|
|
1881
|
-
// BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0`
|
|
1882
|
-
// so check `userAgent` even if `.v8` exists, but 0
|
|
1883
|
-
!version && userAgent && (!(match = userAgent.match(/Edge\/(\d+)/)) || match[1] >= 74) && (match = userAgent.match(/Chrome\/(\d+)/)) && (version = +match[1]);
|
|
1884
|
-
|
|
1885
|
-
var V8_VERSION = version, fails$4 = fails$8, $String$3 = globalThis_1.String, symbolConstructorDetection = !!Object.getOwnPropertySymbols && !fails$4((function() {
|
|
1886
|
-
var symbol = Symbol("symbol detection");
|
|
1887
|
-
// Chrome 38 Symbol has incorrect toString conversion
|
|
1888
|
-
// `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances
|
|
1889
|
-
// nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will,
|
|
1890
|
-
// of course, fail.
|
|
1891
|
-
return !$String$3(symbol) || !(Object(symbol) instanceof Symbol) ||
|
|
1892
|
-
// Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances
|
|
1893
|
-
!Symbol.sham && V8_VERSION && V8_VERSION < 41;
|
|
1894
|
-
})), useSymbolAsUid = symbolConstructorDetection && !Symbol.sham && "symbol" == typeof Symbol.iterator, isCallable$5 = isCallable$8, isPrototypeOf$1 = objectIsPrototypeOf, $Object$2 = Object, isSymbol$2 = useSymbolAsUid ? function(it) {
|
|
1895
|
-
return "symbol" == typeof it;
|
|
1896
|
-
} : function(it) {
|
|
1897
|
-
var $Symbol = function(namespace, method) {
|
|
1898
|
-
return arguments.length < 2 ? aFunction(path$2[namespace]) || aFunction(globalThis$a[namespace]) : path$2[namespace] && path$2[namespace][method] || globalThis$a[namespace] && globalThis$a[namespace][method];
|
|
1899
|
-
}("Symbol");
|
|
1900
|
-
return isCallable$5($Symbol) && isPrototypeOf$1($Symbol.prototype, $Object$2(it));
|
|
1901
|
-
}, $String$2 = String, isCallable$4 = isCallable$8, $TypeError$5 = TypeError, aCallable$2 = function(argument) {
|
|
1902
|
-
if (isCallable$4(argument)) return argument;
|
|
1903
|
-
throw new $TypeError$5(function(argument) {
|
|
1904
|
-
try {
|
|
1905
|
-
return $String$2(argument);
|
|
1906
|
-
} catch (error) {
|
|
1907
|
-
return "Object";
|
|
1908
|
-
}
|
|
1909
|
-
}(argument) + " is not a function");
|
|
1910
|
-
}, aCallable$1 = aCallable$2, isNullOrUndefined = isNullOrUndefined$2, call$2 = functionCall, isCallable$3 = isCallable$8, isObject$4 = isObject$5, $TypeError$4 = TypeError, sharedStore = {
|
|
1911
|
-
exports: {}
|
|
1912
|
-
}, globalThis$6 = globalThis_1, defineProperty = Object.defineProperty, globalThis$5 = globalThis_1, store$1 = sharedStore.exports = globalThis$5["__core-js_shared__"] || function(key, value) {
|
|
1913
|
-
try {
|
|
1914
|
-
defineProperty(globalThis$6, key, {
|
|
1915
|
-
value: value,
|
|
1916
|
-
configurable: !0,
|
|
1917
|
-
writable: !0
|
|
1918
|
-
});
|
|
1919
|
-
} catch (error) {
|
|
1920
|
-
globalThis$6[key] = value;
|
|
1921
|
-
}
|
|
1922
|
-
return value;
|
|
1923
|
-
}("__core-js_shared__", {});
|
|
1924
|
-
|
|
1925
|
-
/* eslint-disable es/no-symbol -- required for testing */ (store$1.versions || (store$1.versions = [])).push({
|
|
1926
|
-
version: "3.43.0",
|
|
1927
|
-
mode: "pure",
|
|
1928
|
-
copyright: "© 2014-2025 Denis Pushkarev (zloirock.ru)",
|
|
1929
|
-
license: "https://github.com/zloirock/core-js/blob/v3.43.0/LICENSE",
|
|
1930
|
-
source: "https://github.com/zloirock/core-js"
|
|
1931
|
-
});
|
|
1932
|
-
|
|
1933
|
-
var key, value, store = sharedStore.exports, requireObjectCoercible$1 = requireObjectCoercible$3, $Object$1 = Object, hasOwnProperty = functionUncurryThis({}.hasOwnProperty), hasOwnProperty_1 = Object.hasOwn || function(it, key) {
|
|
1934
|
-
return hasOwnProperty($Object$1(requireObjectCoercible$1(it)), key);
|
|
1935
|
-
}, uncurryThis$3 = functionUncurryThis, id = 0, postfix = Math.random(), toString$2 = uncurryThis$3(1.1.toString), hasOwn$2 = hasOwnProperty_1, NATIVE_SYMBOL = symbolConstructorDetection, USE_SYMBOL_AS_UID = useSymbolAsUid, Symbol$1 = globalThis_1.Symbol, WellKnownSymbolsStore = store[key = "wks"] || (store[key] = value || {}), createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol$1.for || Symbol$1 : Symbol$1 && Symbol$1.withoutSetter || function(key) {
|
|
1936
|
-
return "Symbol(" + (void 0 === key ? "" : key) + ")_" + toString$2(++id + postfix, 36);
|
|
1937
|
-
}, wellKnownSymbol$5 = function(name) {
|
|
1938
|
-
return hasOwn$2(WellKnownSymbolsStore, name) || (WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn$2(Symbol$1, name) ? Symbol$1[name] : createWellKnownSymbol("Symbol." + name)),
|
|
1939
|
-
WellKnownSymbolsStore[name];
|
|
1940
|
-
}, call$1 = functionCall, isObject$3 = isObject$5, isSymbol$1 = isSymbol$2, $TypeError$3 = TypeError, TO_PRIMITIVE = wellKnownSymbol$5("toPrimitive"), toPrimitive = function(input, pref) {
|
|
1941
|
-
if (!isObject$3(input) || isSymbol$1(input)) return input;
|
|
1942
|
-
var result, func, exoticToPrim = (func = input[TO_PRIMITIVE], isNullOrUndefined(func) ? void 0 : aCallable$1(func));
|
|
1943
|
-
if (exoticToPrim) {
|
|
1944
|
-
if (void 0 === pref && (pref = "default"), result = call$1(exoticToPrim, input, pref),
|
|
1945
|
-
!isObject$3(result) || isSymbol$1(result)) return result;
|
|
1946
|
-
throw new $TypeError$3("Can't convert object to primitive value");
|
|
1947
|
-
}
|
|
1948
|
-
return void 0 === pref && (pref = "number"), function(input, pref) {
|
|
1949
|
-
var fn, val;
|
|
1950
|
-
if ("string" === pref && isCallable$3(fn = input.toString) && !isObject$4(val = call$2(fn, input))) return val;
|
|
1951
|
-
if (isCallable$3(fn = input.valueOf) && !isObject$4(val = call$2(fn, input))) return val;
|
|
1952
|
-
if ("string" !== pref && isCallable$3(fn = input.toString) && !isObject$4(val = call$2(fn, input))) return val;
|
|
1953
|
-
throw new $TypeError$4("Can't convert object to primitive value");
|
|
1954
|
-
}(input, pref);
|
|
1955
|
-
}, isSymbol = isSymbol$2, toPropertyKey$2 = function(argument) {
|
|
1956
|
-
var key = toPrimitive(argument, "string");
|
|
1957
|
-
return isSymbol(key) ? key : key + "";
|
|
1958
|
-
}, isObject$2 = isObject$5, document$1 = globalThis_1.document, EXISTS = isObject$2(document$1) && isObject$2(document$1.createElement), ie8DomDefine = !descriptors && !fails$8((function() {
|
|
1959
|
-
// eslint-disable-next-line es/no-object-defineproperty -- required for testing
|
|
1960
|
-
return 7 !== Object.defineProperty((it = "div", EXISTS ? document$1.createElement(it) : {}), "a", {
|
|
1961
|
-
get: function() {
|
|
1962
|
-
return 7;
|
|
1963
|
-
}
|
|
1964
|
-
}).a;
|
|
1965
|
-
var it;
|
|
1966
|
-
})), DESCRIPTORS$3 = descriptors, call = functionCall, propertyIsEnumerableModule = objectPropertyIsEnumerable, createPropertyDescriptor$1 = createPropertyDescriptor$2, toIndexedObject$1 = toIndexedObject$2, toPropertyKey$1 = toPropertyKey$2, hasOwn$1 = hasOwnProperty_1, IE8_DOM_DEFINE$1 = ie8DomDefine, $getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor;
|
|
1967
|
-
|
|
1968
|
-
// `Object.getOwnPropertyDescriptor` method
|
|
1969
|
-
// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
|
|
1970
|
-
objectGetOwnPropertyDescriptor.f = DESCRIPTORS$3 ? $getOwnPropertyDescriptor$1 : function(O, P) {
|
|
1971
|
-
if (O = toIndexedObject$1(O), P = toPropertyKey$1(P), IE8_DOM_DEFINE$1) try {
|
|
1972
|
-
return $getOwnPropertyDescriptor$1(O, P);
|
|
1973
|
-
} catch (error) {/* empty */}
|
|
1974
|
-
if (hasOwn$1(O, P)) return createPropertyDescriptor$1(!call(propertyIsEnumerableModule.f, O, P), O[P]);
|
|
1975
|
-
};
|
|
1976
|
-
|
|
1977
|
-
var fails$2 = fails$8, isCallable$2 = isCallable$8, replacement = /#|\.prototype\./, isForced$1 = function(feature, detection) {
|
|
1978
|
-
var value = data[normalize(feature)];
|
|
1979
|
-
return value === POLYFILL || value !== NATIVE && (isCallable$2(detection) ? fails$2(detection) : !!detection);
|
|
1980
|
-
}, normalize = isForced$1.normalize = function(string) {
|
|
1981
|
-
return String(string).replace(replacement, ".").toLowerCase();
|
|
1982
|
-
}, data = isForced$1.data = {}, NATIVE = isForced$1.NATIVE = "N", POLYFILL = isForced$1.POLYFILL = "P", isForced_1 = isForced$1, aCallable = aCallable$2, NATIVE_BIND = functionBindNative, bind$1 = functionUncurryThisClause(functionUncurryThisClause.bind), objectDefineProperty = {}, v8PrototypeDefineBug = descriptors && fails$8((function() {
|
|
1983
|
-
// eslint-disable-next-line es/no-object-defineproperty -- required for testing
|
|
1984
|
-
return 42 !== Object.defineProperty((function() {/* empty */}), "prototype", {
|
|
1985
|
-
value: 42,
|
|
1986
|
-
writable: !1
|
|
1987
|
-
}).prototype;
|
|
1988
|
-
})), isObject$1 = isObject$5, $String$1 = String, $TypeError$2 = TypeError, DESCRIPTORS$1 = descriptors, IE8_DOM_DEFINE = ie8DomDefine, V8_PROTOTYPE_DEFINE_BUG = v8PrototypeDefineBug, anObject = function(argument) {
|
|
1989
|
-
if (isObject$1(argument)) return argument;
|
|
1990
|
-
throw new $TypeError$2($String$1(argument) + " is not an object");
|
|
1991
|
-
}, toPropertyKey = toPropertyKey$2, $TypeError$1 = TypeError, $defineProperty = Object.defineProperty, $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
|
|
1992
|
-
|
|
1993
|
-
// `Object.defineProperty` method
|
|
1994
|
-
// https://tc39.es/ecma262/#sec-object.defineproperty
|
|
1995
|
-
objectDefineProperty.f = DESCRIPTORS$1 ? V8_PROTOTYPE_DEFINE_BUG ? function(O, P, Attributes) {
|
|
1996
|
-
if (anObject(O), P = toPropertyKey(P), anObject(Attributes), "function" == typeof O && "prototype" === P && "value" in Attributes && "writable" in Attributes && !Attributes.writable) {
|
|
1997
|
-
var current = $getOwnPropertyDescriptor(O, P);
|
|
1998
|
-
current && current.writable && (O[P] = Attributes.value, Attributes = {
|
|
1999
|
-
configurable: "configurable" in Attributes ? Attributes.configurable : current.configurable,
|
|
2000
|
-
enumerable: "enumerable" in Attributes ? Attributes.enumerable : current.enumerable,
|
|
2001
|
-
writable: !1
|
|
2002
|
-
});
|
|
2001
|
+
displacementScale: .85,
|
|
2002
|
+
blurAmount: .9,
|
|
2003
|
+
animationSpeed: .9,
|
|
2004
|
+
chromaticIntensity: .75
|
|
2005
|
+
}
|
|
2006
|
+
},
|
|
2007
|
+
desktop: {
|
|
2008
|
+
minWidth: 1025,
|
|
2009
|
+
params: {
|
|
2010
|
+
distortionOctaves: 5,
|
|
2011
|
+
displacementScale: 1,
|
|
2012
|
+
blurAmount: 1,
|
|
2013
|
+
animationSpeed: 1,
|
|
2014
|
+
chromaticIntensity: 1
|
|
2015
|
+
}
|
|
2003
2016
|
}
|
|
2004
|
-
return $defineProperty(O, P, Attributes);
|
|
2005
|
-
} : $defineProperty : function(O, P, Attributes) {
|
|
2006
|
-
if (anObject(O), P = toPropertyKey(P), anObject(Attributes), IE8_DOM_DEFINE) try {
|
|
2007
|
-
return $defineProperty(O, P, Attributes);
|
|
2008
|
-
} catch (error) {/* empty */}
|
|
2009
|
-
if ("get" in Attributes || "set" in Attributes) throw new $TypeError$1("Accessors not supported");
|
|
2010
|
-
return "value" in Attributes && (O[P] = Attributes.value), O;
|
|
2011
2017
|
};
|
|
2012
2018
|
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
var Wrapper = function(a, b, c) {
|
|
2023
|
-
if (this instanceof Wrapper) {
|
|
2024
|
-
switch (arguments.length) {
|
|
2025
|
-
case 0:
|
|
2026
|
-
return new NativeConstructor;
|
|
2027
|
-
|
|
2028
|
-
case 1:
|
|
2029
|
-
return new NativeConstructor(a);
|
|
2030
|
-
|
|
2031
|
-
case 2:
|
|
2032
|
-
return new NativeConstructor(a, b);
|
|
2033
|
-
}
|
|
2034
|
-
return new NativeConstructor(a, b, c);
|
|
2035
|
-
}
|
|
2036
|
-
return apply(NativeConstructor, this, arguments);
|
|
2037
|
-
};
|
|
2038
|
-
return Wrapper.prototype = NativeConstructor.prototype, Wrapper;
|
|
2039
|
-
}, _export = function(options, source) {
|
|
2040
|
-
var FORCED, USE_NATIVE, VIRTUAL_PROTOTYPE, key, sourceProperty, targetProperty, nativeProperty, resultProperty, descriptor, TARGET = options.target, GLOBAL = options.global, STATIC = options.stat, PROTO = options.proto, nativeSource = GLOBAL ? globalThis$2 : STATIC ? globalThis$2[TARGET] : globalThis$2[TARGET] && globalThis$2[TARGET].prototype, target = GLOBAL ? path$1 : path$1[TARGET] || createNonEnumerableProperty(path$1, TARGET, {})[TARGET], targetPrototype = target.prototype;
|
|
2041
|
-
for (key in source)
|
|
2042
|
-
// contains in native
|
|
2043
|
-
USE_NATIVE = !(FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? "." : "#") + key, options.forced)) && nativeSource && hasOwn(nativeSource, key),
|
|
2044
|
-
targetProperty = target[key], USE_NATIVE && (nativeProperty = options.dontCallGetSet ? (descriptor = getOwnPropertyDescriptor(nativeSource, key)) && descriptor.value : nativeSource[key]),
|
|
2045
|
-
// export native or implementation
|
|
2046
|
-
sourceProperty = USE_NATIVE && nativeProperty ? nativeProperty : source[key], (FORCED || PROTO || typeof targetProperty != typeof sourceProperty) && (
|
|
2047
|
-
// bind methods to global for calling from export context
|
|
2048
|
-
resultProperty = options.bind && USE_NATIVE ? bind(sourceProperty, globalThis$2) : options.wrap && USE_NATIVE ? wrapConstructor(sourceProperty) : PROTO && isCallable$1(sourceProperty) ? uncurryThis$1(sourceProperty) : sourceProperty,
|
|
2049
|
-
// add a flag to not completely full polyfills
|
|
2050
|
-
(options.sham || sourceProperty && sourceProperty.sham || targetProperty && targetProperty.sham) && createNonEnumerableProperty(resultProperty, "sham", !0),
|
|
2051
|
-
createNonEnumerableProperty(target, key, resultProperty), PROTO && (hasOwn(path$1, VIRTUAL_PROTOTYPE = TARGET + "Prototype") || createNonEnumerableProperty(path$1, VIRTUAL_PROTOTYPE, {}),
|
|
2052
|
-
// export virtual prototype methods
|
|
2053
|
-
createNonEnumerableProperty(path$1[VIRTUAL_PROTOTYPE], key, sourceProperty),
|
|
2054
|
-
// export real prototype methods
|
|
2055
|
-
options.real && targetPrototype && (FORCED || !targetPrototype[key]) && createNonEnumerableProperty(targetPrototype, key, sourceProperty)));
|
|
2056
|
-
}, ceil = Math.ceil, floor = Math.floor, trunc = Math.trunc || function(x) {
|
|
2057
|
-
var n = +x;
|
|
2058
|
-
return (n > 0 ? floor : ceil)(n);
|
|
2059
|
-
}, toIntegerOrInfinity$2 = function(argument) {
|
|
2060
|
-
var number = +argument;
|
|
2061
|
-
// eslint-disable-next-line no-self-compare -- NaN check
|
|
2062
|
-
return number != number || 0 === number ? 0 : trunc(number);
|
|
2063
|
-
}, toIntegerOrInfinity$1 = toIntegerOrInfinity$2, max = Math.max, min$1 = Math.min, toIntegerOrInfinity = toIntegerOrInfinity$2, min = Math.min, toIndexedObject = toIndexedObject$2, lengthOfArrayLike = function(obj) {
|
|
2064
|
-
return argument = obj.length, (len = toIntegerOrInfinity(argument)) > 0 ? min(len, 9007199254740991) : 0;
|
|
2019
|
+
/**
|
|
2020
|
+
* Device performance tier detection
|
|
2021
|
+
*
|
|
2022
|
+
* Uses Device Memory API and Hardware Concurrency API to classify devices
|
|
2023
|
+
* into performance tiers for automatic quality adjustment.
|
|
2024
|
+
*
|
|
2025
|
+
* @returns Performance tier classification
|
|
2026
|
+
*/ var toIntegerOrInfinity = toIntegerOrInfinity$2, max = Math.max, min = Math.min, toIndexedObject = toIndexedObject$2, lengthOfArrayLike = function(obj) {
|
|
2027
|
+
return argument = obj.length, (len = toIntegerOrInfinity$1(argument)) > 0 ? min$1(len, 9007199254740991) : 0;
|
|
2065
2028
|
var argument, len;
|
|
2066
2029
|
}, createMethod = function(IS_INCLUDES) {
|
|
2067
2030
|
return function($this, el, fromIndex) {
|
|
2068
2031
|
var O = toIndexedObject($this), length = lengthOfArrayLike(O);
|
|
2069
2032
|
if (0 === length) return !IS_INCLUDES && -1;
|
|
2070
2033
|
var value, index = function(index, length) {
|
|
2071
|
-
var integer = toIntegerOrInfinity
|
|
2072
|
-
return integer < 0 ? max(integer + length, 0) : min
|
|
2034
|
+
var integer = toIntegerOrInfinity(index);
|
|
2035
|
+
return integer < 0 ? max(integer + length, 0) : min(integer, length);
|
|
2073
2036
|
}(fromIndex, length);
|
|
2074
2037
|
// Array#includes uses SameValueZero equality algorithm
|
|
2075
2038
|
// eslint-disable-next-line no-self-compare -- NaN check
|
|
@@ -2098,12 +2061,7 @@ _export({
|
|
|
2098
2061
|
}
|
|
2099
2062
|
});
|
|
2100
2063
|
|
|
2101
|
-
var
|
|
2102
|
-
var Namespace = path[CONSTRUCTOR + "Prototype"], pureMethod = Namespace && Namespace[METHOD];
|
|
2103
|
-
if (pureMethod) return pureMethod;
|
|
2104
|
-
var NativeConstructor = globalThis$1[CONSTRUCTOR], NativePrototype = NativeConstructor && NativeConstructor.prototype;
|
|
2105
|
-
return NativePrototype && NativePrototype[METHOD];
|
|
2106
|
-
}, includes$4 = getBuiltInPrototypeMethod$2("Array", "includes"), isObject = isObject$5, classof$2 = classofRaw$2, MATCH$1 = wellKnownSymbol$5("match"), $TypeError = TypeError, test = {};
|
|
2064
|
+
var includes$4 = getBuiltInPrototypeMethod$2("Array", "includes"), isObject = isObject$5, classof$2 = classofRaw$2, MATCH$1 = wellKnownSymbol$5("match"), $TypeError = TypeError, test = {};
|
|
2107
2065
|
|
|
2108
2066
|
test[wellKnownSymbol$5("toStringTag")] = "z";
|
|
2109
2067
|
|
|
@@ -2159,148 +2117,6 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
2159
2117
|
/**
|
|
2160
2118
|
* Get GPU memory info if available (Chrome DevTools only)
|
|
2161
2119
|
*/
|
|
2162
|
-
/** Map an FPS value to a semantic color token string. */
|
|
2163
|
-
const getQualityColor = quality => {
|
|
2164
|
-
switch (quality) {
|
|
2165
|
-
case "high":
|
|
2166
|
-
return "var(--atomix-color-success, #4ade80)";
|
|
2167
|
-
|
|
2168
|
-
case "medium":
|
|
2169
|
-
return "var(--atomix-color-warning, #fbbf24)";
|
|
2170
|
-
|
|
2171
|
-
case "low":
|
|
2172
|
-
return "var(--atomix-color-danger, #ef4444)";
|
|
2173
|
-
|
|
2174
|
-
default:
|
|
2175
|
-
return "#9ca3af";
|
|
2176
|
-
}
|
|
2177
|
-
}, getFpsLabel = fps => fps >= 58 ? "Optimal" : fps >= 45 ? "Warning" : "Critical";
|
|
2178
|
-
|
|
2179
|
-
/** Map a quality level string to a semantic color token string. */
|
|
2180
|
-
// Inject keyframes once
|
|
2181
|
-
if ("undefined" != typeof document) {
|
|
2182
|
-
const styleId = "perf-dashboard-keyframes";
|
|
2183
|
-
if (!document.getElementById(styleId)) {
|
|
2184
|
-
const styleEl = document.createElement("style");
|
|
2185
|
-
styleEl.id = styleId, styleEl.textContent = "\n@keyframes perf-dashboard-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n}\n",
|
|
2186
|
-
document.head.appendChild(styleEl);
|
|
2187
|
-
}
|
|
2188
|
-
}
|
|
2189
|
-
|
|
2190
|
-
/**
|
|
2191
|
-
* PerformanceDashboard - Real-time performance monitoring overlay.
|
|
2192
|
-
*
|
|
2193
|
-
* Displays FPS, frame time, quality level, GPU memory, and auto-scaling status.
|
|
2194
|
-
* Rendered only when `debugPerformance={true}` on the parent `AtomixGlass`.
|
|
2195
|
-
*/ const PerformanceDashboard = memo((({metrics: metrics, isVisible: isVisible = !0, onClose: onClose}) => {
|
|
2196
|
-
if (!isVisible) return null;
|
|
2197
|
-
const fpsColor = (fps = metrics.fps) >= 58 ? "var(--atomix-color-success, #4ade80)" : fps >= 45 ? "var(--atomix-color-warning, #fbbf24)" : "var(--atomix-color-danger, #ef4444)";
|
|
2198
|
-
var fps;
|
|
2199
|
-
const isCritical = metrics.fps < 45;
|
|
2200
|
-
return jsxs("div", {
|
|
2201
|
-
className: "c-perf-dashboard u-position-fixed u-top-4 u-end-4 u-p-3 u-px-4 u-text-xs u-font-mono u-text-white u-rounded-md u-border u-border-white-alpha-10 u-shadow-lg",
|
|
2202
|
-
style: {
|
|
2203
|
-
zIndex: 9999,
|
|
2204
|
-
minWidth: "12.5rem",
|
|
2205
|
-
// 200px
|
|
2206
|
-
backgroundColor: "rgba(17, 24, 39, 0.95)",
|
|
2207
|
-
backdropFilter: "blur(8px)",
|
|
2208
|
-
transition: "opacity 0.3s ease"
|
|
2209
|
-
},
|
|
2210
|
-
children: [ jsxs("div", {
|
|
2211
|
-
className: "u-flex u-items-center u-justify-between u-mb-2 u-pb-2 u-border-b u-border-white-alpha-10",
|
|
2212
|
-
children: [ jsx("span", {
|
|
2213
|
-
className: "u-text-sm u-font-bold u-text-white",
|
|
2214
|
-
children: "Performance Monitor"
|
|
2215
|
-
}), onClose && jsx("button", {
|
|
2216
|
-
className: "u-bg-transparent u-border-none u-p-0 u-line-height-1 u-text-base u-text-gray-400 u-cursor-pointer hover:u-text-white",
|
|
2217
|
-
onClick: onClose,
|
|
2218
|
-
"aria-label": "Close performance dashboard",
|
|
2219
|
-
style: {
|
|
2220
|
-
transition: "color 0.2s ease"
|
|
2221
|
-
},
|
|
2222
|
-
children: "×"
|
|
2223
|
-
}) ]
|
|
2224
|
-
}), jsxs("div", {
|
|
2225
|
-
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
2226
|
-
children: [ jsx("span", {
|
|
2227
|
-
className: "u-text-gray-400 u-me-3",
|
|
2228
|
-
children: "FPS"
|
|
2229
|
-
}), jsx("span", {
|
|
2230
|
-
className: "u-font-bold",
|
|
2231
|
-
style: {
|
|
2232
|
-
color: fpsColor
|
|
2233
|
-
},
|
|
2234
|
-
children: Math.round(metrics.fps)
|
|
2235
|
-
}) ]
|
|
2236
|
-
}), jsxs("div", {
|
|
2237
|
-
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
2238
|
-
children: [ jsx("span", {
|
|
2239
|
-
className: "u-text-gray-400 u-me-3",
|
|
2240
|
-
children: "Frame Time"
|
|
2241
|
-
}), jsxs("span", {
|
|
2242
|
-
className: "u-font-bold",
|
|
2243
|
-
children: [ metrics.frameTime.toFixed(2), "ms" ]
|
|
2244
|
-
}) ]
|
|
2245
|
-
}), jsxs("div", {
|
|
2246
|
-
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
2247
|
-
children: [ jsx("span", {
|
|
2248
|
-
className: "u-text-gray-400 u-me-3",
|
|
2249
|
-
children: "Quality"
|
|
2250
|
-
}), jsx("span", {
|
|
2251
|
-
className: "u-font-bold u-text-uppercase",
|
|
2252
|
-
style: {
|
|
2253
|
-
fontSize: "0.6875rem",
|
|
2254
|
-
// 11px
|
|
2255
|
-
color: getQualityColor(metrics.qualityLevel)
|
|
2256
|
-
},
|
|
2257
|
-
children: metrics.qualityLevel
|
|
2258
|
-
}) ]
|
|
2259
|
-
}), metrics.gpuMemory && jsxs("div", {
|
|
2260
|
-
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
2261
|
-
children: [ jsx("span", {
|
|
2262
|
-
className: "u-text-gray-400 u-me-3",
|
|
2263
|
-
children: "GPU Memory"
|
|
2264
|
-
}), jsxs("span", {
|
|
2265
|
-
className: "u-font-bold",
|
|
2266
|
-
children: [ "~", Math.round(metrics.gpuMemory / 1024), "MB" ]
|
|
2267
|
-
}) ]
|
|
2268
|
-
}), metrics.isAutoScaling && jsx("div", {
|
|
2269
|
-
className: "u-mt-2 u-pt-2 u-border-t u-border-white-alpha-10 u-text-center",
|
|
2270
|
-
style: {
|
|
2271
|
-
fontSize: "0.625rem",
|
|
2272
|
-
// 10px
|
|
2273
|
-
color: "#6b7280"
|
|
2274
|
-
},
|
|
2275
|
-
children: "Auto-scaling active"
|
|
2276
|
-
}), jsxs("div", {
|
|
2277
|
-
className: "u-flex u-items-center u-gap-2 u-mt-2 u-pt-2 u-border-t u-border-white-alpha-10",
|
|
2278
|
-
children: [ jsx("div", {
|
|
2279
|
-
className: "u-rounded-full",
|
|
2280
|
-
style: {
|
|
2281
|
-
width: "0.5rem",
|
|
2282
|
-
height: "0.5rem",
|
|
2283
|
-
flexShrink: 0,
|
|
2284
|
-
backgroundColor: fpsColor,
|
|
2285
|
-
...isCritical && {
|
|
2286
|
-
animation: "perf-dashboard-pulse 1s infinite"
|
|
2287
|
-
}
|
|
2288
|
-
}
|
|
2289
|
-
}), jsx("span", {
|
|
2290
|
-
className: "u-text-xs",
|
|
2291
|
-
style: {
|
|
2292
|
-
fontSize: "0.625rem",
|
|
2293
|
-
// 10px
|
|
2294
|
-
color: fpsColor
|
|
2295
|
-
},
|
|
2296
|
-
children: getFpsLabel(metrics.fps)
|
|
2297
|
-
}) ]
|
|
2298
|
-
}) ]
|
|
2299
|
-
});
|
|
2300
|
-
}));
|
|
2301
|
-
|
|
2302
|
-
PerformanceDashboard.displayName = "PerformanceDashboard";
|
|
2303
|
-
|
|
2304
2120
|
/**
|
|
2305
2121
|
* Mobile optimization presets
|
|
2306
2122
|
*
|
|
@@ -2420,18 +2236,13 @@ const PERFORMANCE_PRESET = {
|
|
|
2420
2236
|
saturation: 70
|
|
2421
2237
|
}
|
|
2422
2238
|
}
|
|
2423
|
-
}, AtomixGlassInner = forwardRef((function({children: children, displacementScale: displacementScale = ATOMIX_GLASS.DEFAULTS.DISPLACEMENT_SCALE, blurAmount: blurAmount = ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT, saturation: saturation = ATOMIX_GLASS.DEFAULTS.SATURATION, aberrationIntensity: aberrationIntensity = ATOMIX_GLASS.DEFAULTS.ABERRATION_INTENSITY, elasticity: elasticity = ATOMIX_GLASS.DEFAULTS.ELASTICITY, borderRadius: borderRadius, globalMousePosition: externalGlobalMousePosition, mouseOffset: externalMouseOffset, mouseContainer: mouseContainer = null, className: className = "",
|
|
2424
|
-
const glassRef = useRef(null), contentRef = useRef(null), internalWrapperRef = useRef(null), mergedRef =
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
}));
|
|
2431
|
-
};
|
|
2432
|
-
}
|
|
2433
|
-
// Internal implementation with forwardRef
|
|
2434
|
-
(ref, internalWrapperRef)), [ ref ]), {zIndex: customZIndex, ...restStyle} = style, isFixedOrSticky = propsIsFixedOrSticky || "fixed" === restStyle.position || "sticky" === restStyle.position, {isHovered: isHovered, isActive: isActive, glassSize: glassSize, effectiveBorderRadius: effectiveBorderRadius, effectiveReducedMotion: effectiveReducedMotion, effectiveHighContrast: effectiveHighContrast, effectiveWithoutEffects: effectiveWithoutEffects, overLightConfig: overLightConfig, globalMousePosition: globalMousePosition, mouseOffset: mouseOffset, transformStyle: transformStyle, getShaderTime: getShaderTime, handleMouseEnter: handleMouseEnter, handleMouseLeave: handleMouseLeave, handleMouseDown: handleMouseDown, handleMouseUp: handleMouseUp, handleKeyDown: handleKeyDown} = useAtomixGlass({
|
|
2239
|
+
}, AtomixGlassInner = forwardRef((function({children: children, displacementScale: displacementScale = ATOMIX_GLASS.DEFAULTS.DISPLACEMENT_SCALE, blurAmount: blurAmount = ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT, saturation: saturation = ATOMIX_GLASS.DEFAULTS.SATURATION, aberrationIntensity: aberrationIntensity = ATOMIX_GLASS.DEFAULTS.ABERRATION_INTENSITY, elasticity: elasticity = ATOMIX_GLASS.DEFAULTS.ELASTICITY, borderRadius: borderRadius, globalMousePosition: externalGlobalMousePosition, mouseOffset: externalMouseOffset, mouseContainer: mouseContainer = null, className: className = "", overLight: overLight = ATOMIX_GLASS.DEFAULTS.OVER_LIGHT, style: style = {}, mode: mode = ATOMIX_GLASS.DEFAULTS.MODE, onClick: onClick, shaderVariant: shaderVariant = "liquidGlass", "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, role: role, tabIndex: tabIndex, reducedMotion: reducedMotion = !1, highContrast: highContrast = !1, withoutEffects: withoutEffects = !1, withLiquidBlur: withLiquidBlur = !1, border: border, withBorder: withBorder = !0, debugBorderRadius: debugBorderRadius = !1, withOverLightLayers: withOverLightLayers = ATOMIX_GLASS.DEFAULTS.ENABLE_OVER_LIGHT_LAYERS, debugPerformance: debugPerformance = !1, debugOverLight: debugOverLight = !1, height: height, width: width, withTimeAnimation: withTimeAnimation = !1, animationSpeed: animationSpeed = 1, withMultiLayerDistortion: withMultiLayerDistortion = !1, distortionOctaves: distortionOctaves = 3, distortionLacunarity: distortionLacunarity = 2, distortionGain: distortionGain = .5, distortionQuality: distortionQuality = "medium", devicePreset: devicePreset = "balanced", disableResponsiveBreakpoints: disableResponsiveBreakpoints = !1, isFixedOrSticky: propsIsFixedOrSticky, ...rest}, ref) {
|
|
2240
|
+
const glassRef = useRef(null), contentRef = useRef(null), internalWrapperRef = useRef(null), mergedRef = useForkRef(ref, internalWrapperRef), {zIndex: customZIndex, ...restStyle} = style, isFixedOrSticky = (explicit = propsIsFixedOrSticky,
|
|
2241
|
+
position = restStyle.position, Boolean(explicit || "fixed" === position || "sticky" === position));
|
|
2242
|
+
var explicit, position;
|
|
2243
|
+
/**
|
|
2244
|
+
* Extracts layout-related properties from a React `CSSProperties` object.
|
|
2245
|
+
*/ const {isHovered: isHovered, isActive: isActive, glassSize: glassSize, effectiveBorderRadius: effectiveBorderRadius, effectiveReducedMotion: effectiveReducedMotion, effectiveHighContrast: effectiveHighContrast, effectiveWithoutEffects: effectiveWithoutEffects, overLightConfig: overLightConfig, globalMousePosition: globalMousePosition, mouseOffset: mouseOffset, transformStyle: transformStyle, handleMouseEnter: handleMouseEnter, handleMouseLeave: handleMouseLeave, handleMouseDown: handleMouseDown, handleMouseUp: handleMouseUp, handleKeyDown: handleKeyDown, resolvedBorder: resolvedBorder} = useAtomixGlass({
|
|
2435
2246
|
glassRef: glassRef,
|
|
2436
2247
|
contentRef: contentRef,
|
|
2437
2248
|
wrapperRef: internalWrapperRef,
|
|
@@ -2451,20 +2262,13 @@ const PERFORMANCE_PRESET = {
|
|
|
2451
2262
|
blurAmount: blurAmount,
|
|
2452
2263
|
saturation: saturation,
|
|
2453
2264
|
withLiquidBlur: withLiquidBlur,
|
|
2454
|
-
|
|
2265
|
+
border: border,
|
|
2266
|
+
withBorder: withBorder,
|
|
2267
|
+
debugBorderRadius: debugBorderRadius,
|
|
2455
2268
|
style: style,
|
|
2456
|
-
isFixedOrSticky: isFixedOrSticky
|
|
2457
|
-
// Phase 1: Animation System props
|
|
2458
|
-
withTimeAnimation: withTimeAnimation,
|
|
2459
|
-
animationSpeed: animationSpeed,
|
|
2460
|
-
withMultiLayerDistortion: withMultiLayerDistortion,
|
|
2461
|
-
distortionOctaves: distortionOctaves,
|
|
2462
|
-
distortionLacunarity: distortionLacunarity,
|
|
2463
|
-
distortionGain: distortionGain,
|
|
2464
|
-
distortionQuality: distortionQuality
|
|
2269
|
+
isFixedOrSticky: isFixedOrSticky
|
|
2465
2270
|
});
|
|
2466
|
-
|
|
2467
|
-
!
|
|
2271
|
+
(
|
|
2468
2272
|
/**
|
|
2469
2273
|
* Responsive Glass Parameters Hook
|
|
2470
2274
|
*
|
|
@@ -2619,7 +2423,7 @@ const PERFORMANCE_PRESET = {
|
|
|
2619
2423
|
}), [ enabled ]), useCallback((() => {
|
|
2620
2424
|
calculateParams();
|
|
2621
2425
|
}), [ calculateParams ]);
|
|
2622
|
-
}({
|
|
2426
|
+
})({
|
|
2623
2427
|
baseParams: {
|
|
2624
2428
|
...useMemo((() =>
|
|
2625
2429
|
/**
|
|
@@ -2653,9 +2457,7 @@ const PERFORMANCE_PRESET = {
|
|
|
2653
2457
|
breakpoints: MOBILE_OPTIMIZED_BREAKPOINTS,
|
|
2654
2458
|
enabled: !disableResponsiveBreakpoints && "undefined" != typeof window,
|
|
2655
2459
|
debug: !1
|
|
2656
|
-
})
|
|
2657
|
-
// Performance monitoring - tracks FPS, frame time, memory usage
|
|
2658
|
-
const {metrics: performanceMetrics, toggleMonitoring: toggleMonitoring} =
|
|
2460
|
+
}),
|
|
2659
2461
|
/**
|
|
2660
2462
|
* Performance Monitor Hook
|
|
2661
2463
|
*
|
|
@@ -2690,7 +2492,13 @@ const PERFORMANCE_PRESET = {
|
|
|
2690
2492
|
timestamp: 0,
|
|
2691
2493
|
isAutoScaling: !0,
|
|
2692
2494
|
lowFpsCount: 0
|
|
2693
|
-
}), [manualOverride, setManualOverride] = useState(!1), [isEnabled, setIsEnabled] = useState(enabled)
|
|
2495
|
+
}), [manualOverride, setManualOverride] = useState(!1), [isEnabled, setIsEnabled] = useState(enabled);
|
|
2496
|
+
// Sync external `enabled` prop changes into internal state
|
|
2497
|
+
useEffect((() => {
|
|
2498
|
+
setIsEnabled(enabled ?? !0);
|
|
2499
|
+
}), [ enabled ]);
|
|
2500
|
+
// Refs for frame tracking
|
|
2501
|
+
const frameCountRef = useRef(0), lastFpsUpdateRef = useRef(0), lastFrameTimeRef = useRef(0), animationFrameRef = useRef(null), lowFpsCountRef = useRef(0), highFpsCountRef = useRef(0), qualityLevelRef = useRef("medium"), updateMetrics = useCallback((newMetrics => {
|
|
2694
2502
|
setMetrics((prev => ({
|
|
2695
2503
|
...prev,
|
|
2696
2504
|
...newMetrics,
|
|
@@ -2810,191 +2618,214 @@ const PERFORMANCE_PRESET = {
|
|
|
2810
2618
|
/**
|
|
2811
2619
|
* Reset to auto-scaling mode
|
|
2812
2620
|
*/ var fps, currentQuality;
|
|
2813
|
-
|
|
2814
|
-
metrics: metrics,
|
|
2815
|
-
recommendedQuality: (fps = metrics.fps, currentQuality = metrics.qualityLevel, fps >= 58 ? "high" : fps >= 45 ? "high" === currentQuality ? "high" : "medium" : "low"),
|
|
2816
|
-
isUnderperforming: metrics.fps < minFps,
|
|
2817
|
-
setQualityLevel: setQualityLevel,
|
|
2818
|
-
resetAutoScaling: resetAutoScaling,
|
|
2819
|
-
toggleMonitoring: toggleMonitoring
|
|
2820
|
-
};
|
|
2621
|
+
fps = metrics.fps, currentQuality = metrics.qualityLevel, metrics.fps;
|
|
2821
2622
|
}({
|
|
2822
2623
|
enabled: debugPerformance,
|
|
2823
|
-
// Enable when debugPerformance is true
|
|
2824
2624
|
debug: !1,
|
|
2825
2625
|
showOverlay: !1
|
|
2826
2626
|
});
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
}), [ debugPerformance ]);
|
|
2832
|
-
// Re-run when debugPerformance changes
|
|
2833
|
-
const isOverLight = useMemo((() => overLightConfig.isOverLight), [ overLightConfig.isOverLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, rootLayoutStyle = useMemo((() => {
|
|
2834
|
-
if (!isFixedOrSticky) return {};
|
|
2835
|
-
const {position: p, top: t, left: l, right: r, bottom: b} = restStyle;
|
|
2836
|
-
return {
|
|
2837
|
-
...p && {
|
|
2838
|
-
position: p
|
|
2839
|
-
},
|
|
2840
|
-
...void 0 !== t && {
|
|
2841
|
-
top: t
|
|
2842
|
-
},
|
|
2843
|
-
...void 0 !== l && {
|
|
2844
|
-
left: l
|
|
2845
|
-
},
|
|
2846
|
-
...void 0 !== r && {
|
|
2847
|
-
right: r
|
|
2848
|
-
},
|
|
2849
|
-
...void 0 !== b && {
|
|
2850
|
-
bottom: b
|
|
2851
|
-
}
|
|
2852
|
-
};
|
|
2853
|
-
}), [ isFixedOrSticky, restStyle ]);
|
|
2854
|
-
// Calculate base style with transforms
|
|
2855
|
-
// When layout is hoisted to the root, strip those props from the container
|
|
2856
|
-
useMemo((() => {
|
|
2857
|
-
if (isFixedOrSticky) {
|
|
2858
|
-
const {position: _p, top: _t, left: _l, right: _r, bottom: _b, ...visualStyle} = restStyle;
|
|
2859
|
-
return {
|
|
2860
|
-
...visualStyle
|
|
2861
|
-
};
|
|
2627
|
+
const isOverLight = useMemo((() => overLightConfig.isOverLight), [ overLightConfig.isOverLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, containerStyle = useMemo((() => ({
|
|
2628
|
+
...restStyle,
|
|
2629
|
+
...void 0 !== customZIndex && {
|
|
2630
|
+
zIndex: customZIndex
|
|
2862
2631
|
}
|
|
2632
|
+
})), [ restStyle, customZIndex ]), componentClassName = mergeClassNames(ATOMIX_GLASS.BASE_CLASS, effectiveReducedMotion && `${ATOMIX_GLASS.BASE_CLASS}--reduced-motion`, effectiveHighContrast && `${ATOMIX_GLASS.BASE_CLASS}--high-contrast`, effectiveWithoutEffects && `${ATOMIX_GLASS.BASE_CLASS}--disabled-effects`, className), positionStyles = useMemo((() =>
|
|
2633
|
+
/**
|
|
2634
|
+
* Returns the internal positioning context for effect layers relative to the root.
|
|
2635
|
+
*/
|
|
2636
|
+
function(isFixedOrSticky, restStyle) {
|
|
2863
2637
|
return {
|
|
2864
|
-
|
|
2638
|
+
position: isFixedOrSticky ? "absolute" : restStyle.position || "absolute",
|
|
2639
|
+
top: 0,
|
|
2640
|
+
left: 0,
|
|
2641
|
+
right: "auto",
|
|
2642
|
+
bottom: "auto"
|
|
2865
2643
|
};
|
|
2866
|
-
}
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
})), [ isFixedOrSticky, restStyle.position, restStyle.top, restStyle.left, restStyle.right, restStyle.bottom ]), adjustedSize = useMemo((() => {
|
|
2875
|
-
// Keep a reference to positionStyles to avoid unused-variable lint,
|
|
2876
|
-
// but sizing is driven by explicit width/height or measured size.
|
|
2877
|
-
positionStyles.position;
|
|
2878
|
-
const resolveLength = (value, measured) => void 0 !== value && isFixedOrSticky ? "number" == typeof value ? `${value}px` : value : measured > 0 && isFixedOrSticky ? `${measured}px` : "100%", effectiveWidth = width ?? restStyle.width, effectiveHeight = height ?? restStyle.height;
|
|
2644
|
+
}
|
|
2645
|
+
/**
|
|
2646
|
+
* Computes `--atomix-glass-width` and `--atomix-glass-height` values.
|
|
2647
|
+
*
|
|
2648
|
+
* Fixed/sticky elements prefer explicit dimensions or measured size; in-flow
|
|
2649
|
+
* elements default to `100%`.
|
|
2650
|
+
*/ (isFixedOrSticky, restStyle)), [ isFixedOrSticky, restStyle ]), adjustedSize = useMemo((() => function(options) {
|
|
2651
|
+
const {width: width, height: height, restStyle: restStyle, glassSize: glassSize, isFixedOrSticky: isFixedOrSticky} = options, resolveLength = (value, measured) => void 0 !== value && isFixedOrSticky ? "number" == typeof value ? `${value}px` : value : measured > 0 && isFixedOrSticky ? `${measured}px` : "100%", effectiveWidth = width ?? restStyle.width, effectiveHeight = height ?? restStyle.height;
|
|
2879
2652
|
return {
|
|
2880
2653
|
width: resolveLength(effectiveWidth, glassSize.width),
|
|
2881
2654
|
height: resolveLength(effectiveHeight, glassSize.height)
|
|
2882
2655
|
};
|
|
2883
|
-
}
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2656
|
+
}
|
|
2657
|
+
/**
|
|
2658
|
+
* Builds the CSS custom properties applied to the root `.c-atomix-glass` element.
|
|
2659
|
+
*
|
|
2660
|
+
* These variables drive layer geometry, transforms, and stacking offsets. They
|
|
2661
|
+
* must not include layout properties that would interfere with backdrop-filter.
|
|
2662
|
+
*/ ({
|
|
2663
|
+
width: width,
|
|
2664
|
+
height: height,
|
|
2665
|
+
restStyle: restStyle,
|
|
2666
|
+
glassSize: glassSize,
|
|
2667
|
+
isFixedOrSticky: isFixedOrSticky
|
|
2668
|
+
})), [ width, height, restStyle, glassSize, isFixedOrSticky ]), glassVars = useMemo((() => function(input) {
|
|
2669
|
+
const {effectiveBorderRadius: effectiveBorderRadius, transformStyle: transformStyle, adjustedSize: adjustedSize, isOverLight: isOverLight, customZIndex: customZIndex, isFixedOrSticky: isFixedOrSticky, positionStyles: positionStyles, restStyle: restStyle, borderWidth: borderWidth = ATOMIX_GLASS.BORDER.DEFAULT_WIDTH} = input, layerPosition =
|
|
2670
|
+
/**
|
|
2671
|
+
* Resolves the `--atomix-glass-position` value for decorative layers.
|
|
2672
|
+
*
|
|
2673
|
+
* Fixed/sticky layers use the same positioning mode as the container; in-flow
|
|
2674
|
+
* layers default to the internal absolute positioning context.
|
|
2675
|
+
*/
|
|
2676
|
+
function(isFixedOrSticky, positionStyles, restStyle) {
|
|
2677
|
+
return isFixedOrSticky ? `${function(style) {
|
|
2678
|
+
const {position: position, top: top, left: left, right: right, bottom: bottom, inset: inset} = style;
|
|
2679
|
+
return {
|
|
2680
|
+
...null != position && {
|
|
2681
|
+
position: position
|
|
2682
|
+
},
|
|
2683
|
+
...void 0 !== top && {
|
|
2684
|
+
top: top
|
|
2685
|
+
},
|
|
2686
|
+
...void 0 !== left && {
|
|
2687
|
+
left: left
|
|
2688
|
+
},
|
|
2689
|
+
...void 0 !== right && {
|
|
2690
|
+
right: right
|
|
2691
|
+
},
|
|
2692
|
+
...void 0 !== bottom && {
|
|
2693
|
+
bottom: bottom
|
|
2694
|
+
},
|
|
2695
|
+
...void 0 !== inset && {
|
|
2696
|
+
inset: inset
|
|
2697
|
+
}
|
|
2698
|
+
};
|
|
2699
|
+
}
|
|
2700
|
+
/**
|
|
2701
|
+
* Resolves inset custom properties for decorative layers (hover, borders, backgrounds).
|
|
2702
|
+
*
|
|
2703
|
+
* For fixed and sticky modes, insets mirror the container so sibling layers remain
|
|
2704
|
+
* aligned. In-flow modes, insets follow the consumer `style` when a non-default
|
|
2705
|
+
* `position` is provided.
|
|
2706
|
+
*/ (restStyle).position ?? restStyle.position ?? "fixed"}` : `${positionStyles.position}`;
|
|
2707
|
+
}(isFixedOrSticky, positionStyles, restStyle), layerInsets = function(isFixedOrSticky, restStyle) {
|
|
2708
|
+
if (isFixedOrSticky) return {
|
|
2709
|
+
top: formatGlassInsetValue(restStyle.top, 0),
|
|
2710
|
+
left: formatGlassInsetValue(restStyle.left, 0),
|
|
2711
|
+
right: formatGlassInsetValue(restStyle.right, "auto"),
|
|
2712
|
+
bottom: formatGlassInsetValue(restStyle.bottom, "auto")
|
|
2713
|
+
};
|
|
2714
|
+
const position = restStyle.position;
|
|
2715
|
+
return null != position && "static" !== position && "relative" !== position ? {
|
|
2716
|
+
top: formatGlassInsetValue(restStyle.top, 0),
|
|
2717
|
+
left: formatGlassInsetValue(restStyle.left, 0),
|
|
2718
|
+
right: formatGlassInsetValue(restStyle.right, "auto"),
|
|
2719
|
+
bottom: formatGlassInsetValue(restStyle.bottom, "auto")
|
|
2720
|
+
} : {
|
|
2721
|
+
top: "0px",
|
|
2722
|
+
left: "0px",
|
|
2723
|
+
right: "auto",
|
|
2724
|
+
bottom: "auto"
|
|
2725
|
+
};
|
|
2726
|
+
}(isFixedOrSticky, restStyle);
|
|
2921
2727
|
return {
|
|
2922
2728
|
...void 0 !== customZIndex && {
|
|
2923
2729
|
"--atomix-glass-base-z-index": customZIndex
|
|
2924
2730
|
},
|
|
2925
2731
|
"--atomix-glass-radius": `${effectiveBorderRadius}px`,
|
|
2926
2732
|
"--atomix-glass-transform": transformStyle || "none",
|
|
2927
|
-
"--atomix-glass-container-position":
|
|
2928
|
-
"--atomix-glass-position":
|
|
2929
|
-
"--atomix-glass-top":
|
|
2930
|
-
"--atomix-glass-left":
|
|
2931
|
-
"--atomix-glass-right":
|
|
2932
|
-
"--atomix-glass-bottom":
|
|
2733
|
+
"--atomix-glass-container-position": layerPosition,
|
|
2734
|
+
"--atomix-glass-position": layerPosition,
|
|
2735
|
+
"--atomix-glass-top": layerInsets.top,
|
|
2736
|
+
"--atomix-glass-left": layerInsets.left,
|
|
2737
|
+
"--atomix-glass-right": layerInsets.right,
|
|
2738
|
+
"--atomix-glass-bottom": layerInsets.bottom,
|
|
2933
2739
|
"--atomix-glass-width": adjustedSize.width,
|
|
2934
2740
|
"--atomix-glass-height": adjustedSize.height,
|
|
2935
|
-
|
|
2936
|
-
"--atomix-glass-
|
|
2937
|
-
"--atomix-glass-
|
|
2938
|
-
|
|
2939
|
-
"--atomix-glass-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2741
|
+
// Aliases maintained for backward compatibility and consumer overrides.
|
|
2742
|
+
"--atomix-glass-container-width": adjustedSize.width,
|
|
2743
|
+
"--atomix-glass-container-height": adjustedSize.height,
|
|
2744
|
+
[ATOMIX_GLASS.BORDER.WIDTH_CSS_VAR]: borderWidth,
|
|
2745
|
+
"--atomix-glass-blend-mode": isOverLight ? "multiply" : "overlay"
|
|
2746
|
+
};
|
|
2747
|
+
}
|
|
2748
|
+
/**
|
|
2749
|
+
* Applies mode-specific multipliers and accessibility overrides to container effects.
|
|
2750
|
+
*/ ({
|
|
2751
|
+
effectiveBorderRadius: effectiveBorderRadius,
|
|
2752
|
+
transformStyle: transformStyle,
|
|
2753
|
+
adjustedSize: adjustedSize,
|
|
2754
|
+
isOverLight: isOverLight,
|
|
2755
|
+
customZIndex: customZIndex,
|
|
2756
|
+
isFixedOrSticky: isFixedOrSticky,
|
|
2757
|
+
positionStyles: positionStyles,
|
|
2758
|
+
restStyle: restStyle,
|
|
2759
|
+
borderWidth: resolvedBorder.width
|
|
2760
|
+
})), [ effectiveBorderRadius, transformStyle, adjustedSize, isOverLight, customZIndex, isFixedOrSticky, positionStyles, restStyle, resolvedBorder.width ]), containerEffects = useMemo((() => function(options) {
|
|
2761
|
+
const {MULTIPLIERS: MULTIPLIERS, SATURATION: SATURATION} = ATOMIX_GLASS.CONSTANTS, zeroMouse = {
|
|
2762
|
+
x: 0,
|
|
2763
|
+
y: 0
|
|
2764
|
+
}, resolveSaturation = () => options.effectiveHighContrast ? SATURATION.HIGH_CONTRAST : options.isOverLight ? options.saturation * options.saturationBoost : options.saturation;
|
|
2765
|
+
if (options.effectiveWithoutEffects) return {
|
|
2766
|
+
displacementScale: 0,
|
|
2767
|
+
blurAmount: 0,
|
|
2768
|
+
saturation: resolveSaturation(),
|
|
2769
|
+
aberrationIntensity: 0,
|
|
2770
|
+
mouseOffset: zeroMouse,
|
|
2771
|
+
globalMousePosition: zeroMouse
|
|
2951
2772
|
};
|
|
2952
|
-
|
|
2953
|
-
|
|
2773
|
+
let resolvedDisplacement = options.displacementScale;
|
|
2774
|
+
"shader" === options.mode ? resolvedDisplacement *= MULTIPLIERS.SHADER_DISPLACEMENT : options.isOverLight && (resolvedDisplacement *= MULTIPLIERS.OVER_LIGHT_DISPLACEMENT);
|
|
2775
|
+
let resolvedAberration = options.aberrationIntensity;
|
|
2776
|
+
return "shader" === options.mode && (resolvedAberration *= MULTIPLIERS.SHADER_ABERRATION),
|
|
2777
|
+
{
|
|
2778
|
+
displacementScale: resolvedDisplacement,
|
|
2779
|
+
blurAmount: options.blurAmount,
|
|
2780
|
+
saturation: resolveSaturation(),
|
|
2781
|
+
aberrationIntensity: resolvedAberration,
|
|
2782
|
+
mouseOffset: options.mouseOffset,
|
|
2783
|
+
globalMousePosition: options.globalMousePosition
|
|
2784
|
+
};
|
|
2785
|
+
}({
|
|
2786
|
+
displacementScale: displacementScale,
|
|
2787
|
+
blurAmount: blurAmount,
|
|
2788
|
+
saturation: saturation,
|
|
2789
|
+
aberrationIntensity: aberrationIntensity,
|
|
2790
|
+
mode: mode,
|
|
2791
|
+
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
2792
|
+
effectiveHighContrast: effectiveHighContrast,
|
|
2793
|
+
isOverLight: isOverLight,
|
|
2794
|
+
saturationBoost: overLightConfig.saturationBoost,
|
|
2795
|
+
mouseOffset: mouseOffset,
|
|
2796
|
+
globalMousePosition: globalMousePosition
|
|
2797
|
+
})), [ displacementScale, blurAmount, saturation, aberrationIntensity, mode, effectiveWithoutEffects, effectiveHighContrast, isOverLight, overLightConfig.saturationBoost, mouseOffset, globalMousePosition ]), renderBackgroundLayer = layerType => jsx("div", {
|
|
2798
|
+
"aria-hidden": "true",
|
|
2799
|
+
className: mergeClassNames(ATOMIX_GLASS.BACKGROUND_LAYER_CLASS, "dark" === layerType ? ATOMIX_GLASS.BACKGROUND_LAYER_DARK_CLASS : ATOMIX_GLASS.BACKGROUND_LAYER_BLACK_CLASS, isOverLight ? ATOMIX_GLASS.BACKGROUND_LAYER_OVER_LIGHT_CLASS : ATOMIX_GLASS.BACKGROUND_LAYER_HIDDEN_CLASS)
|
|
2954
2800
|
});
|
|
2955
|
-
|
|
2956
|
-
// When root is fixed/sticky, internal layers use absolute (relative to root)
|
|
2957
|
-
return jsxs("div", {
|
|
2801
|
+
return jsxs("div", {
|
|
2958
2802
|
...rest,
|
|
2959
2803
|
ref: mergedRef,
|
|
2960
2804
|
className: componentClassName,
|
|
2961
|
-
style:
|
|
2962
|
-
...glassVars
|
|
2963
|
-
},
|
|
2805
|
+
style: glassVars,
|
|
2964
2806
|
role: role || (onClick ? "button" : void 0),
|
|
2965
2807
|
tabIndex: onClick ? tabIndex ?? 0 : tabIndex,
|
|
2966
2808
|
"aria-label": ariaLabel,
|
|
2967
2809
|
"aria-describedby": ariaDescribedBy,
|
|
2968
2810
|
"aria-disabled": !(!onClick || !effectiveWithoutEffects) || !onClick && void 0,
|
|
2969
|
-
"aria-pressed": onClick ? isActive : void 0,
|
|
2970
2811
|
onKeyDown: onClick ? handleKeyDown : void 0,
|
|
2971
2812
|
children: [ jsx(AtomixGlassContainer, {
|
|
2972
2813
|
ref: glassRef,
|
|
2973
2814
|
contentRef: contentRef,
|
|
2974
2815
|
className: className,
|
|
2975
|
-
style:
|
|
2976
|
-
...restStyle
|
|
2977
|
-
},
|
|
2816
|
+
style: containerStyle,
|
|
2978
2817
|
borderRadius: effectiveBorderRadius,
|
|
2979
|
-
displacementScale:
|
|
2980
|
-
blurAmount:
|
|
2981
|
-
saturation:
|
|
2982
|
-
aberrationIntensity:
|
|
2818
|
+
displacementScale: containerEffects.displacementScale,
|
|
2819
|
+
blurAmount: containerEffects.blurAmount,
|
|
2820
|
+
saturation: containerEffects.saturation,
|
|
2821
|
+
aberrationIntensity: containerEffects.aberrationIntensity,
|
|
2983
2822
|
glassSize: glassSize,
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
x: 0,
|
|
2987
|
-
y: 0
|
|
2988
|
-
} : mouseOffset,
|
|
2989
|
-
globalMousePosition: effectiveWithoutEffects ? {
|
|
2990
|
-
x: 0,
|
|
2991
|
-
y: 0
|
|
2992
|
-
} : globalMousePosition,
|
|
2823
|
+
mouseOffset: containerEffects.mouseOffset,
|
|
2824
|
+
globalMousePosition: containerEffects.globalMousePosition,
|
|
2993
2825
|
onMouseEnter: handleMouseEnter,
|
|
2994
2826
|
onMouseLeave: handleMouseLeave,
|
|
2995
2827
|
onMouseDown: handleMouseDown,
|
|
2996
2828
|
onMouseUp: handleMouseUp,
|
|
2997
|
-
isHovered: isHovered,
|
|
2998
2829
|
isActive: isActive,
|
|
2999
2830
|
overLight: isOverLight,
|
|
3000
2831
|
overLightConfig: {
|
|
@@ -3010,8 +2841,6 @@ const PERFORMANCE_PRESET = {
|
|
|
3010
2841
|
shaderVariant: shaderVariant,
|
|
3011
2842
|
withLiquidBlur: withLiquidBlur,
|
|
3012
2843
|
isFixedOrSticky: isFixedOrSticky,
|
|
3013
|
-
// Phase 1: Animation System props
|
|
3014
|
-
shaderTime: getShaderTime(),
|
|
3015
2844
|
withTimeAnimation: withTimeAnimation,
|
|
3016
2845
|
animationSpeed: animationSpeed,
|
|
3017
2846
|
withMultiLayerDistortion: withMultiLayerDistortion,
|
|
@@ -3022,32 +2851,39 @@ const PERFORMANCE_PRESET = {
|
|
|
3022
2851
|
children: children
|
|
3023
2852
|
}), Boolean(onClick) && jsxs(Fragment, {
|
|
3024
2853
|
children: [ jsx("div", {
|
|
2854
|
+
"aria-hidden": "true",
|
|
3025
2855
|
className: ATOMIX_GLASS.HOVER_1_CLASS
|
|
3026
2856
|
}), jsx("div", {
|
|
2857
|
+
"aria-hidden": "true",
|
|
3027
2858
|
className: ATOMIX_GLASS.HOVER_2_CLASS
|
|
3028
2859
|
}), jsx("div", {
|
|
2860
|
+
"aria-hidden": "true",
|
|
3029
2861
|
className: ATOMIX_GLASS.HOVER_3_CLASS
|
|
3030
2862
|
}) ]
|
|
3031
|
-
}),
|
|
2863
|
+
}), [ "dark", "black" ].map((layerType => jsx(React.Fragment, {
|
|
2864
|
+
children: renderBackgroundLayer(layerType)
|
|
2865
|
+
}, layerType))), shouldRenderOverLightLayers && jsxs(Fragment, {
|
|
3032
2866
|
children: [ jsx("div", {
|
|
2867
|
+
"aria-hidden": "true",
|
|
3033
2868
|
className: ATOMIX_GLASS.BASE_LAYER_CLASS
|
|
3034
2869
|
}), jsx("div", {
|
|
2870
|
+
"aria-hidden": "true",
|
|
3035
2871
|
className: ATOMIX_GLASS.OVERLAY_LAYER_CLASS
|
|
3036
2872
|
}), jsx("div", {
|
|
2873
|
+
"aria-hidden": "true",
|
|
3037
2874
|
className: ATOMIX_GLASS.OVERLAY_HIGHLIGHT_CLASS
|
|
3038
2875
|
}) ]
|
|
3039
|
-
}),
|
|
2876
|
+
}), resolvedBorder.enabled && jsxs(Fragment, {
|
|
3040
2877
|
children: [ jsx("span", {
|
|
2878
|
+
"aria-hidden": "true",
|
|
3041
2879
|
className: ATOMIX_GLASS.BORDER_BACKDROP_CLASS
|
|
3042
2880
|
}), jsx("span", {
|
|
2881
|
+
"aria-hidden": "true",
|
|
3043
2882
|
className: ATOMIX_GLASS.BORDER_1_CLASS
|
|
3044
2883
|
}), jsx("span", {
|
|
2884
|
+
"aria-hidden": "true",
|
|
3045
2885
|
className: ATOMIX_GLASS.BORDER_2_CLASS
|
|
3046
2886
|
}) ]
|
|
3047
|
-
}), debugPerformance && performanceMetrics && jsx(PerformanceDashboard, {
|
|
3048
|
-
metrics: performanceMetrics,
|
|
3049
|
-
isVisible: !0,
|
|
3050
|
-
onClose: () => {}
|
|
3051
2887
|
}) ]
|
|
3052
2888
|
});
|
|
3053
2889
|
}));
|
|
@@ -3057,44 +2893,16 @@ const PERFORMANCE_PRESET = {
|
|
|
3057
2893
|
* Default preset for most mobile devices
|
|
3058
2894
|
*/ AtomixGlassInner.displayName = "AtomixGlass";
|
|
3059
2895
|
|
|
3060
|
-
/**
|
|
3061
|
-
|
|
3062
|
-
* Ref is forwarded to the root `<div>` element.
|
|
3063
|
-
*/
|
|
3064
|
-
const AtomixGlass = memo(AtomixGlassInner), smoothStep = (a, b, t) => {
|
|
3065
|
-
// Add input validation
|
|
3066
|
-
if ("number" != typeof a || "number" != typeof b || "number" != typeof t) return 0;
|
|
3067
|
-
const clamped = Math.max(0, Math.min(1, (t - a) / (b - a)));
|
|
3068
|
-
return clamped * clamped * (3 - 2 * clamped);
|
|
3069
|
-
}, calculateLength = (x, y) => {
|
|
3070
|
-
// Add input validation and error handling
|
|
3071
|
-
if ("number" != typeof x || "number" != typeof y || isNaN(x) || isNaN(y)) return 0;
|
|
3072
|
-
// Prevent potential overflow
|
|
3073
|
-
const maxX = Math.max(Math.abs(x), Math.abs(y));
|
|
3074
|
-
if (0 === maxX) return 0;
|
|
3075
|
-
const scaledX = x / maxX, scaledY = y / maxX;
|
|
3076
|
-
return maxX * Math.sqrt(scaledX * scaledX + scaledY * scaledY);
|
|
3077
|
-
}, roundedRectSDF = (x, y, width, height, radius) => {
|
|
2896
|
+
/** Memoized public export. Ref targets the root `.c-atomix-glass` wrapper. */
|
|
2897
|
+
const AtomixGlass = memo(AtomixGlassInner), roundedRectSDF = (x, y, width, height, radius) => {
|
|
3078
2898
|
// Add input validation
|
|
3079
2899
|
if ("number" != typeof x || "number" != typeof y || "number" != typeof width || "number" != typeof height || "number" != typeof radius) return 0;
|
|
3080
2900
|
const qx = Math.abs(x) - width + radius, qy = Math.abs(y) - height + radius;
|
|
3081
|
-
return Math.min(Math.max(qx, qy), 0) +
|
|
2901
|
+
return Math.min(Math.max(qx, qy), 0) + vec2Length(Math.max(qx, 0), Math.max(qy, 0)) - radius;
|
|
3082
2902
|
}, createTexture = (x, y) => ({
|
|
3083
2903
|
x: "number" != typeof x || isNaN(x) ? .5 : Math.max(0, Math.min(1, x)),
|
|
3084
2904
|
y: "number" != typeof y || isNaN(y) ? .5 : Math.max(0, Math.min(1, y))
|
|
3085
|
-
}), validateVec2 = vec => vec && "number" == typeof vec.x && "number" == typeof vec.y && !isNaN(vec.x) && !isNaN(vec.y),
|
|
3086
|
-
// Add input validation
|
|
3087
|
-
"number" != typeof value || "number" != typeof min || "number" != typeof max || isNaN(value) ? min : isNaN(min) ? 0 : isNaN(max) ? 1 : Math.max(min, Math.min(max, value)), easeInOutCubic = t => {
|
|
3088
|
-
// Add input validation
|
|
3089
|
-
if ("number" != typeof t || isNaN(t)) return 0;
|
|
3090
|
-
const clampedT = Math.max(0, Math.min(1, t));
|
|
3091
|
-
return clampedT < .5 ? 4 * clampedT * clampedT * clampedT : 1 - Math.pow(-2 * clampedT + 2, 3) / 2;
|
|
3092
|
-
}, easeOutQuart = t => {
|
|
3093
|
-
// Add input validation
|
|
3094
|
-
if ("number" != typeof t || isNaN(t)) return 0;
|
|
3095
|
-
const clampedT = Math.max(0, Math.min(1, t));
|
|
3096
|
-
return 1 - Math.pow(1 - clampedT, 4);
|
|
3097
|
-
}, noise2D = (x, y) => {
|
|
2905
|
+
}), validateVec2 = vec => vec && "number" == typeof vec.x && "number" == typeof vec.y && !isNaN(vec.x) && !isNaN(vec.y), noise2D = (x, y) => {
|
|
3098
2906
|
// Add input validation
|
|
3099
2907
|
if ("number" != typeof x || "number" != typeof y || isNaN(x) || isNaN(y)) return 0;
|
|
3100
2908
|
const X = 255 & Math.floor(x), Y = 255 & Math.floor(y), xf = x - Math.floor(x), yf = y - Math.floor(y), u = easeInOutCubic(xf), v = easeInOutCubic(yf), hash = (i, j) => {
|
|
@@ -3133,13 +2941,13 @@ const AtomixGlass = memo(AtomixGlassInner), smoothStep = (a, b, t) => {
|
|
|
3133
2941
|
x: .5,
|
|
3134
2942
|
y: .5
|
|
3135
2943
|
};
|
|
3136
|
-
const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now(), mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance =
|
|
2944
|
+
const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now(), mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance = vec2Length(mouseX, mouseY), mouseFalloff = easeOutQuart(1 - Math.min(2 * mouseDistance, 1)), organicFlow = fbm(12 * (ix + .5 * mouseX) + time, 12 * (iy + .5 * mouseY) + .7 * time, 3) - .5, distanceToEdge = roundedRectSDF(ix, iy, .4, .3, .35), baseDisplacement = smoothstepEdge(.8, 0, distanceToEdge - .05), radialDist = ((x, y, strength) => {
|
|
3137
2945
|
// Add input validation
|
|
3138
2946
|
if ("number" != typeof x || "number" != typeof y || isNaN(x) || isNaN(y) || isNaN(strength)) return {
|
|
3139
2947
|
x: 0,
|
|
3140
2948
|
y: 0
|
|
3141
2949
|
};
|
|
3142
|
-
const distance =
|
|
2950
|
+
const distance = vec2Length(x, y), distortion = Math.pow(Math.min(distance, 10), 2) * strength;
|
|
3143
2951
|
// Limit distance to prevent extreme values
|
|
3144
2952
|
return {
|
|
3145
2953
|
x: x * (1 + distortion),
|
|
@@ -3151,7 +2959,7 @@ const AtomixGlass = memo(AtomixGlassInner), smoothStep = (a, b, t) => {
|
|
|
3151
2959
|
x: 0,
|
|
3152
2960
|
y: 0
|
|
3153
2961
|
};
|
|
3154
|
-
const distance =
|
|
2962
|
+
const distance = vec2Length(x, y);
|
|
3155
2963
|
// Prevent division by zero and extreme values
|
|
3156
2964
|
if (0 === distance) return {
|
|
3157
2965
|
x: 0,
|
|
@@ -3162,8 +2970,8 @@ const AtomixGlass = memo(AtomixGlassInner), smoothStep = (a, b, t) => {
|
|
|
3162
2970
|
x: Math.cos(angle) * distance * intensity,
|
|
3163
2971
|
y: Math.sin(angle) * distance * intensity
|
|
3164
2972
|
};
|
|
3165
|
-
})(ix, iy, .015 * baseDisplacement), scaled =
|
|
3166
|
-
return createTexture(
|
|
2973
|
+
})(ix, iy, .015 * baseDisplacement), scaled = smoothstepEdge(0, 1, 1.15 * baseDisplacement), finalX = ix + totalDistortionX + .5 * chromaticOffset.x, finalY = iy + totalDistortionY + .5 * chromaticOffset.y;
|
|
2974
|
+
return createTexture(clamp(finalX * scaled + .5, 0, 1), clamp(finalY * scaled + .5, 0, 1));
|
|
3167
2975
|
},
|
|
3168
2976
|
// Premium Apple-style fluid glass with enhanced organic flow
|
|
3169
2977
|
appleFluid: (uv, mousePosition) => {
|
|
@@ -3171,8 +2979,8 @@ const AtomixGlass = memo(AtomixGlassInner), smoothStep = (a, b, t) => {
|
|
|
3171
2979
|
x: .5,
|
|
3172
2980
|
y: .5
|
|
3173
2981
|
};
|
|
3174
|
-
const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * .6, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance =
|
|
3175
|
-
return createTexture(
|
|
2982
|
+
const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * .6, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance = vec2Length(mouseX, mouseY), mouseFalloff = easeOutQuart(1 - Math.min(1.5 * mouseDistance, 1)), organicX = fbm(10 * (ix + .3 * mouseX) + time, 10 * (iy + .3 * mouseY), 5) - .5, organicY = fbm(10 * (ix - .3 * mouseX), 10 * (iy - .3 * mouseY) + .8 * time, 5) - .5, distanceToEdge = roundedRectSDF(ix, iy, .42, .32, .38), mask = smoothstepEdge(.85, -.1, distanceToEdge), fluidVelocityX = Math.sin(6 * ix + 2 * time) * Math.cos(4 * iy - time) * .025, fluidVelocityY = Math.cos(4 * ix - time) * Math.sin(6 * iy + 2 * time) * .025, vortexAngle = Math.atan2(iy - mouseY, ix - mouseX), vortexStrength = mouseFalloff * mouseDistance * .08, vortexX = Math.cos(vortexAngle + time) * vortexStrength, totalY = iy + (.035 * organicY + fluidVelocityY + Math.sin(vortexAngle + time) * vortexStrength) * mask;
|
|
2983
|
+
return createTexture(clamp(ix + (.035 * organicX + fluidVelocityX + vortexX) * mask + .5, 0, 1), clamp(totalY + .5, 0, 1));
|
|
3176
2984
|
},
|
|
3177
2985
|
// High-end glass with advanced refraction and depth
|
|
3178
2986
|
premiumGlass: (uv, mousePosition) => {
|
|
@@ -3180,7 +2988,7 @@ const AtomixGlass = memo(AtomixGlassInner), smoothStep = (a, b, t) => {
|
|
|
3180
2988
|
x: .5,
|
|
3181
2989
|
y: .5
|
|
3182
2990
|
};
|
|
3183
|
-
const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * .4, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance =
|
|
2991
|
+
const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * .4, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance = vec2Length(mouseX, mouseY), centerDistance = vec2Length(ix, iy), refractionStrength = .3 * Math.pow(Math.min(centerDistance, 1), 1.5), refractionAngle = Math.atan2(iy, ix);
|
|
3184
2992
|
// Multi-layer depth effect
|
|
3185
2993
|
let depthX = 0, depthY = 0;
|
|
3186
2994
|
for (let layer = 0; layer < 3; layer++) {
|
|
@@ -3188,8 +2996,8 @@ const AtomixGlass = memo(AtomixGlassInner), smoothStep = (a, b, t) => {
|
|
|
3188
2996
|
depthX += Math.sin(ix * layerScale + layerTime) * layerStrength, depthY += Math.cos(iy * layerScale - layerTime) * layerStrength;
|
|
3189
2997
|
}
|
|
3190
2998
|
// Glass refraction with mouse influence
|
|
3191
|
-
const refractionX = Math.cos(refractionAngle) * refractionStrength * (1 + .5 * mouseDistance), refractionY = Math.sin(refractionAngle) * refractionStrength * (1 + .5 * mouseDistance), organicNoise = fbm(8 * ix + time, 8 * iy - time, 2) - .5, distanceToEdge = roundedRectSDF(ix, iy, .43, .33, .36), edgeMask =
|
|
3192
|
-
return createTexture(
|
|
2999
|
+
const refractionX = Math.cos(refractionAngle) * refractionStrength * (1 + .5 * mouseDistance), refractionY = Math.sin(refractionAngle) * refractionStrength * (1 + .5 * mouseDistance), organicNoise = fbm(8 * ix + time, 8 * iy - time, 2) - .5, distanceToEdge = roundedRectSDF(ix, iy, .43, .33, .36), edgeMask = smoothstepEdge(.9, -.05, distanceToEdge), finalY = iy + (refractionY + depthY + .015 * organicNoise) * edgeMask;
|
|
3000
|
+
return createTexture(clamp(ix + (refractionX + depthX + .015 * organicNoise) * edgeMask + .5, 0, 1), clamp(finalY + .5, 0, 1));
|
|
3193
3001
|
},
|
|
3194
3002
|
// Metallic liquid effect with shimmer
|
|
3195
3003
|
liquidMetal: (uv, mousePosition) => {
|
|
@@ -3197,8 +3005,8 @@ const AtomixGlass = memo(AtomixGlassInner), smoothStep = (a, b, t) => {
|
|
|
3197
3005
|
x: .5,
|
|
3198
3006
|
y: .5
|
|
3199
3007
|
};
|
|
3200
|
-
const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * 1.2, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, wave1 = Math.sin(20 * ix + 4 * time) * Math.cos(15 * iy - 3 * time) * .02, wave2 = Math.cos(15 * ix - 2 * time) * Math.sin(20 * iy + 5 * time) * .015, shimmer = .025 * fbm(25 * ix + 2 * time, 25 * iy - 2 * time, 4), flowAngle = Math.atan2(iy - mouseY, ix - mouseX), flowDistance =
|
|
3201
|
-
return createTexture(
|
|
3008
|
+
const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * 1.2, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, wave1 = Math.sin(20 * ix + 4 * time) * Math.cos(15 * iy - 3 * time) * .02, wave2 = Math.cos(15 * ix - 2 * time) * Math.sin(20 * iy + 5 * time) * .015, shimmer = .025 * fbm(25 * ix + 2 * time, 25 * iy - 2 * time, 4), flowAngle = Math.atan2(iy - mouseY, ix - mouseX), flowDistance = vec2Length(ix - mouseX, iy - mouseY), flowEffect = .02 * Math.sin(15 * flowDistance - 6 * time) * easeOutQuart(1 - Math.min(2 * flowDistance, 1)), distanceToEdge = roundedRectSDF(ix, iy, .41, .31, .37), mask = smoothstepEdge(.88, -.08, distanceToEdge), totalX = ix + (wave1 + shimmer + Math.cos(flowAngle) * flowEffect) * mask, totalY = iy + (wave2 + .8 * shimmer + Math.sin(flowAngle) * flowEffect) * mask;
|
|
3009
|
+
return createTexture(clamp(totalX + .5, 0, 1), clamp(totalY + .5, 0, 1));
|
|
3202
3010
|
},
|
|
3203
3011
|
// basiBasi - Expert Premium Glass Shader
|
|
3204
3012
|
// The most advanced shader with caustics, spectral dispersion, parallax depth, and volumetric effects
|
|
@@ -3207,7 +3015,7 @@ const AtomixGlass = memo(AtomixGlassInner), smoothStep = (a, b, t) => {
|
|
|
3207
3015
|
x: .5,
|
|
3208
3016
|
y: .5
|
|
3209
3017
|
};
|
|
3210
|
-
const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * .5, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance =
|
|
3018
|
+
const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * .5, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance = vec2Length(mouseX, mouseY), mouseFalloff = easeOutQuart(1 - Math.min(1.2 * mouseDistance, 1)), causticIntensity = ((x, y, time, intensity = 1) =>
|
|
3211
3019
|
// Add input validation
|
|
3212
3020
|
"number" != typeof x || "number" != typeof y || "number" != typeof time || "number" != typeof intensity || isNaN(x) || isNaN(y) || isNaN(time) || isNaN(intensity) ? .5 : .5 * (Math.sin(8 * x + 2 * time) * Math.cos(8 * y - 2 * time) * .5 + Math.sin(8 * (x + .5) * 1.3 - 2 * time * .8) * Math.cos(8 * (y - .3) * 1.3 + 2 * time * .8) * .3 + Math.sin(8 * (x - .3) * .7 + 2 * time * 1.2) * Math.cos(8 * (y + .4) * .7 - 2 * time * 1.2) * .2 + 1) * intensity)(ix, iy, time, .8), causticDistortion = .02 * (causticIntensity - .5), refractionAngle = Math.atan2(iy, ix), spectralDispersion = ((x, y, angle) => {
|
|
3213
3021
|
// Add input validation
|
|
@@ -3225,7 +3033,7 @@ const AtomixGlass = memo(AtomixGlassInner), smoothStep = (a, b, t) => {
|
|
|
3225
3033
|
y: 0
|
|
3226
3034
|
}
|
|
3227
3035
|
};
|
|
3228
|
-
const distance =
|
|
3036
|
+
const distance = vec2Length(x, y), dispersionStrength = Math.min(.025 * distance, 1), redOffset = .8 * dispersionStrength, greenOffset = 1 * dispersionStrength, blueOffset = 1.2 * dispersionStrength;
|
|
3229
3037
|
return {
|
|
3230
3038
|
r: {
|
|
3231
3039
|
x: Math.cos(angle) * redOffset,
|
|
@@ -3265,8 +3073,8 @@ const AtomixGlass = memo(AtomixGlassInner), smoothStep = (a, b, t) => {
|
|
|
3265
3073
|
return turbulence;
|
|
3266
3074
|
})(6 * ix, 6 * iy, time, 6), turbulenceX = .012 * Math.cos(turbulence * Math.PI * 2), turbulenceY = .012 * Math.sin(turbulence * Math.PI * 2), microSurface = ((x, y, time) =>
|
|
3267
3075
|
// Add input validation
|
|
3268
|
-
"number" != typeof x || "number" != typeof y || "number" != typeof time || isNaN(x) || isNaN(y) || isNaN(time) ? .5 : .5 * (.7 * fbm(40 * x + .3 * time, 40 * y - .3 * time, 6) + .3 * fbm(80 * x, 80 * y, 4)))(ix, iy, time), microDetailX = .008 * (microSurface - .5), microDetailY = .008 * (microSurface - .5), centerDistance =
|
|
3269
|
-
return createTexture(
|
|
3076
|
+
"number" != typeof x || "number" != typeof y || "number" != typeof time || isNaN(x) || isNaN(y) || isNaN(time) ? .5 : .5 * (.7 * fbm(40 * x + .3 * time, 40 * y - .3 * time, 6) + .3 * fbm(80 * x, 80 * y, 4)))(ix, iy, time), microDetailX = .008 * (microSurface - .5), microDetailY = .008 * (microSurface - .5), centerDistance = vec2Length(ix, iy), dynamicRefraction = .35 * Math.pow(Math.min(centerDistance, 1), 1.8) * (1 + mouseFalloff * mouseDistance * .8), refractionX = Math.cos(refractionAngle) * dynamicRefraction, refractionY = Math.sin(refractionAngle) * dynamicRefraction, vortexAngle = Math.atan2(iy - mouseY, ix - mouseX), vortexDistance = vec2Length(ix - mouseX, iy - mouseY), vortexStrength = mouseFalloff * Math.sin(10 * vortexDistance - 3 * time) * .025, vortexX = Math.cos(vortexAngle + 2 * time) * vortexStrength, vortexY = Math.sin(vortexAngle + 2 * time) * vortexStrength, fluidX = Math.sin(10 * ix + 5 * mouseX + 2.5 * time) * Math.cos(8 * iy - 2 * time) * .018, fluidY = Math.cos(8 * ix - 2 * time) * Math.sin(10 * iy + 5 * mouseY + 2.5 * time) * .018, rippleEffect = (.012 * Math.sin(15 * Math.min(centerDistance, 10) - 4 * time) + .008 * Math.cos(20 * Math.min(centerDistance, 10) + 3 * time)) * mouseFalloff, rippleX = Math.cos(refractionAngle) * rippleEffect, rippleY = Math.sin(refractionAngle) * rippleEffect, distanceToEdge = roundedRectSDF(ix, iy, .44, .34, .39), edgeMask = smoothstepEdge(.92, -.12, distanceToEdge), edgeSoftness = smoothstepEdge(.85, .1, distanceToEdge), finalY = iy + (1.2 * refractionY + .8 * spectralY + 1.5 * parallaxY + .9 * scatteringY + 1 * turbulenceY + .6 * microDetailY + 1.3 * vortexY + 1.1 * fluidY + .7 * rippleY + .8 * causticDistortion) * edgeMask * edgeSoftness * .85;
|
|
3077
|
+
return createTexture(clamp(ix + (1.2 * refractionX + .8 * spectralX + 1.5 * parallaxX + .9 * scatteringX + 1 * turbulenceX + .6 * microDetailX + 1.3 * vortexX + 1.1 * fluidX + .7 * rippleX + causticDistortion) * edgeMask * edgeSoftness * .85 + .5, 0, 1), clamp(finalY + .5, 0, 1));
|
|
3270
3078
|
},
|
|
3271
3079
|
// Aliases for compatibility
|
|
3272
3080
|
plasma: (uv, mousePosition) => fragmentShaders.premiumGlass(uv, mousePosition),
|
|
@@ -3308,8 +3116,8 @@ const AtomixGlass = memo(AtomixGlassInner), smoothStep = (a, b, t) => {
|
|
|
3308
3116
|
let dx = pos.x * w - x, dy = pos.y * h - y;
|
|
3309
3117
|
// Apply edge smoothing for Apple-like effect
|
|
3310
3118
|
const edgeX = 2 * Math.min(x / w, (w - x) / w), edgeY = 2 * Math.min(y / h, (h - y) / h), edgeFactor = Math.min(edgeX, edgeY);
|
|
3311
|
-
dx *=
|
|
3312
|
-
rawValues.push(dx, dy);
|
|
3119
|
+
dx *= smoothstepEdge(0, .2, edgeFactor), dy *= smoothstepEdge(0, .2, edgeFactor),
|
|
3120
|
+
maxScale = Math.max(maxScale, Math.abs(dx), Math.abs(dy)), rawValues.push(dx, dy);
|
|
3313
3121
|
}
|
|
3314
3122
|
// Improved normalization to prevent artifacts while maintaining intensity
|
|
3315
3123
|
maxScale = Math.max(maxScale, 1);
|
|
@@ -3319,9 +3127,9 @@ const AtomixGlass = memo(AtomixGlassInner), smoothStep = (a, b, t) => {
|
|
|
3319
3127
|
let rawIndex = 0;
|
|
3320
3128
|
for (let y = 0; y < h; y++) for (let x = 0; x < w; x++) {
|
|
3321
3129
|
const dx = rawValues[rawIndex++] || 0, dy = rawValues[rawIndex++] || 0, edgeDistance = Math.min(x, y, w - x - 1, h - y - 1), edgeFactor = Math.min(1, edgeDistance / 2), r = dx * edgeFactor / maxScale + .5, g = dy * edgeFactor / maxScale + .5, pixelIndex = 4 * (y * w + x);
|
|
3322
|
-
data[pixelIndex] =
|
|
3323
|
-
data[pixelIndex + 1] =
|
|
3324
|
-
data[pixelIndex + 2] =
|
|
3130
|
+
data[pixelIndex] = clamp(255 * r, 0, 255), // Red channel (X displacement)
|
|
3131
|
+
data[pixelIndex + 1] = clamp(255 * g, 0, 255), // Green channel (Y displacement)
|
|
3132
|
+
data[pixelIndex + 2] = clamp(255 * g, 0, 255), // Blue channel (Y displacement for SVG filter compatibility)
|
|
3325
3133
|
data[pixelIndex + 3] = 255;
|
|
3326
3134
|
}
|
|
3327
3135
|
return this.context.putImageData(imageData, 0, 0), this.canvas.toDataURL();
|
|
@@ -3349,34 +3157,10 @@ const AtomixGlass = memo(AtomixGlassInner), smoothStep = (a, b, t) => {
|
|
|
3349
3157
|
return this.canvasDPI;
|
|
3350
3158
|
}
|
|
3351
3159
|
},
|
|
3352
|
-
|
|
3353
|
-
fragmentShaders: fragmentShaders,
|
|
3354
|
-
liquidGlassWithTime: liquidGlassWithTime
|
|
3160
|
+
fragmentShaders: fragmentShaders
|
|
3355
3161
|
}, Symbol.toStringTag, {
|
|
3356
3162
|
value: "Module"
|
|
3357
|
-
}))
|
|
3358
|
-
|
|
3359
|
-
// Adapted from https://github.com/shuding/liquid-glass
|
|
3360
|
-
// Constants
|
|
3361
|
-
/**
|
|
3362
|
-
* Component Utilities
|
|
3363
|
-
*
|
|
3364
|
-
* Helper functions for component development with the new customization system
|
|
3365
|
-
*/
|
|
3366
|
-
/**
|
|
3367
|
-
* Check if a URL is a YouTube URL
|
|
3368
|
-
*/
|
|
3369
|
-
function isYouTubeUrl(url) {
|
|
3370
|
-
return /^(https?:\/\/)?(www\.)?(youtube\.com|youtu\.be)\/.+/.test(url);
|
|
3371
|
-
}
|
|
3372
|
-
|
|
3373
|
-
/**
|
|
3374
|
-
* Extract YouTube video ID from URL
|
|
3375
|
-
*/
|
|
3376
|
-
/**
|
|
3377
|
-
* Advanced Video Player Component
|
|
3378
|
-
*/
|
|
3379
|
-
const VideoPlayer = forwardRef((({src: src, type: type = "video", youtubeId: youtubeId, poster: poster, autoplay: autoplay = !1, loop: loop = !1, muted: muted = !1, controls: controls = !0, preload: preload = "metadata", width: width, height: height, aspectRatio: aspectRatio = "16:9", className: className = "", onPlay: onPlay, onPause: onPause, onEnded: onEnded, onTimeUpdate: onTimeUpdate, onVolumeChange: onVolumeChange, onFullscreenChange: onFullscreenChange, onError: onError, showDownload: showDownload = !1, showShare: showShare = !1, showSettings: showSettings = !0, playbackRates: playbackRates = [ .5, .75, 1, 1.25, 1.5, 2 ], subtitles: subtitles, quality: quality, ambientMode: ambientMode = !1, glass: glass = !1, glassOpacity: glassOpacity = 1, glassContent: glassContent, style: style, ...props}, ref) => {
|
|
3163
|
+
})), VideoPlayer = forwardRef((({src: src, type: type = "video", youtubeId: youtubeId, poster: poster, autoplay: autoplay = !1, loop: loop = !1, muted: muted = !1, controls: controls = !0, preload: preload = "metadata", width: width, height: height, aspectRatio: aspectRatio = "16:9", className: className = "", onPlay: onPlay, onPause: onPause, onEnded: onEnded, onTimeUpdate: onTimeUpdate, onVolumeChange: onVolumeChange, onFullscreenChange: onFullscreenChange, onError: onError, showDownload: showDownload = !1, showShare: showShare = !1, showSettings: showSettings = !0, playbackRates: playbackRates = [ .5, .75, 1, 1.25, 1.5, 2 ], subtitles: subtitles, quality: quality, ambientMode: ambientMode = !1, glass: glass = !1, glassOpacity: glassOpacity = 1, glassContent: glassContent, style: style, ...props}, ref) => {
|
|
3380
3164
|
const videoRef = useRef(null), containerRef = useRef(null), canvasRef = useRef(null), iframeRef = useRef(null), [containerBorderRadius, setContainerBorderRadius] = useState(8), isYouTube = "youtube" === type || youtubeId || src && isYouTubeUrl(src), videoId = youtubeId || (isYouTube && src ? function(url) {
|
|
3381
3165
|
if (!isYouTubeUrl(url)) return null;
|
|
3382
3166
|
const patterns = [ /(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/)([^&\n?#]+)/, /youtube\.com\/.*[?&]v=([^&\n?#]+)/ ];
|
|
@@ -3554,7 +3338,10 @@ const VideoPlayer = forwardRef((({src: src, type: type = "video", youtubeId: yo
|
|
|
3554
3338
|
getProgressPercentage: getProgressPercentage,
|
|
3555
3339
|
getBufferedPercentage: getBufferedPercentage
|
|
3556
3340
|
};
|
|
3557
|
-
}
|
|
3341
|
+
}
|
|
3342
|
+
/**
|
|
3343
|
+
* Advanced Video Player Component
|
|
3344
|
+
*/ ({
|
|
3558
3345
|
videoRef: videoRef,
|
|
3559
3346
|
containerRef: containerRef,
|
|
3560
3347
|
onPlay: onPlay,
|
|
@@ -4053,6 +3840,8 @@ const VideoPlayer = forwardRef((({src: src, type: type = "video", youtubeId: yo
|
|
|
4053
3840
|
});
|
|
4054
3841
|
}));
|
|
4055
3842
|
|
|
3843
|
+
// Adapted from https://github.com/shuding/liquid-glass
|
|
3844
|
+
// Constants
|
|
4056
3845
|
VideoPlayer.displayName = "VideoPlayer";
|
|
4057
3846
|
|
|
4058
3847
|
/**
|
|
@@ -4307,10 +4096,10 @@ const Badge = memo((({label: label, variant: variant = "primary", size: size =
|
|
|
4307
4096
|
if (glass) {
|
|
4308
4097
|
// Default glass settings for badges
|
|
4309
4098
|
const defaultGlassProps = {
|
|
4310
|
-
|
|
4311
|
-
borderRadius
|
|
4312
|
-
|
|
4313
|
-
|
|
4099
|
+
...GLASS_DEFAULTS_BADGE,
|
|
4100
|
+
// Override borderRadius dynamically if the ref is available
|
|
4101
|
+
borderRadius: ref.current?.getBoundingClientRect().width ? ref.current?.getBoundingClientRect().width / 2 : GLASS_DEFAULTS_BADGE.borderRadius,
|
|
4102
|
+
className: "c-badge--glass"
|
|
4314
4103
|
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
4315
4104
|
...defaultGlassProps,
|
|
4316
4105
|
...glass
|
|
@@ -4375,12 +4164,7 @@ const Spinner = memo( forwardRef((({size: size = "md", variant: variant = "prim
|
|
|
4375
4164
|
})
|
|
4376
4165
|
});
|
|
4377
4166
|
if (glass) {
|
|
4378
|
-
const defaultGlassProps = {
|
|
4379
|
-
displacementScale: 20,
|
|
4380
|
-
blurAmount: 1,
|
|
4381
|
-
borderRadius: 999,
|
|
4382
|
-
mode: "shader"
|
|
4383
|
-
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
4167
|
+
const defaultGlassProps = GLASS_DEFAULTS_SPINNER, glassProps = !0 === glass ? defaultGlassProps : {
|
|
4384
4168
|
...defaultGlassProps,
|
|
4385
4169
|
...glass
|
|
4386
4170
|
};
|
|
@@ -4660,11 +4444,7 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
|
|
|
4660
4444
|
// This is a safe fallback for disabled links.
|
|
4661
4445
|
if (glass) {
|
|
4662
4446
|
// Default glass props
|
|
4663
|
-
const defaultGlassProps = {
|
|
4664
|
-
displacementScale: 20,
|
|
4665
|
-
blurAmount: 0,
|
|
4666
|
-
saturation: 200
|
|
4667
|
-
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
4447
|
+
const defaultGlassProps = GLASS_DEFAULTS_BUTTON, glassProps = !0 === glass ? defaultGlassProps : {
|
|
4668
4448
|
...defaultGlassProps,
|
|
4669
4449
|
...glass
|
|
4670
4450
|
};
|