@shohojdhara/atomix 0.6.1 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +510 -106
- package/dist/atomix.css +30 -24
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +6 -6
- package/dist/atomix.min.css.map +1 -1
- package/dist/atomix.umd.js +1 -1
- package/dist/atomix.umd.js.map +1 -1
- package/dist/atomix.umd.min.js +1 -1
- package/dist/charts.d.ts +11 -2
- package/dist/charts.js +294 -139
- package/dist/charts.js.map +1 -1
- package/dist/core.d.ts +14 -39
- package/dist/core.js +297 -145
- package/dist/core.js.map +1 -1
- package/dist/forms.d.ts +11 -1
- package/dist/forms.js +385 -185
- package/dist/forms.js.map +1 -1
- package/dist/heavy.d.ts +9 -0
- package/dist/heavy.js +297 -143
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +156 -164
- package/dist/index.esm.js +391 -203
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +391 -203
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/theme.d.ts +14 -6
- package/dist/theme.js +2 -9
- package/dist/theme.js.map +1 -1
- package/package.json +26 -26
- package/src/components/AtomixGlass/AtomixGlass.tsx +1 -1
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +8 -1
- package/src/components/AtomixGlass/deprecated/AtomixGlass.deprecated.tsx +390 -0
- package/src/components/AtomixGlass/glass-utils.ts +29 -0
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +32 -1
- package/src/components/Button/Button.stories.tsx +1 -1
- package/src/components/Button/Button.tsx +6 -5
- package/src/components/Card/Card.tsx +2 -2
- package/src/components/Dropdown/Dropdown.tsx +1 -0
- package/src/components/EdgePanel/EdgePanel.tsx +1 -3
- package/src/components/Form/Select.test.tsx +75 -0
- package/src/components/Form/Select.tsx +348 -252
- package/src/components/Form/SelectOption.tsx +16 -10
- package/src/components/index.ts +1 -1
- package/src/layouts/CssGrid/index.ts +1 -0
- package/src/lib/composables/shared-mouse-tracker.ts +62 -6
- package/src/lib/composables/useAtomixGlass.ts +241 -139
- package/src/lib/composables/useAtomixGlassStyles.ts +201 -149
- package/src/lib/constants/components.ts +54 -35
- package/src/lib/theme/config/configLoader.ts +1 -1
- package/src/lib/theme/test/testTheme.ts +2 -2
- package/src/lib/theme/utils/themeUtils.ts +98 -110
- package/src/lib/types/components.ts +29 -65
- package/src/styles/01-settings/_settings.spacing.scss +6 -1
- package/src/styles/03-generic/_generic.reset.scss +1 -1
- package/src/styles/06-components/_components.atomix-glass.scss +20 -29
- package/src/styles/06-components/_components.data-table.scss +5 -4
- package/src/styles/06-components/_components.dynamic-background.scss +9 -8
- package/src/styles/06-components/_components.footer.scss +8 -7
- package/src/styles/06-components/_components.hero.scss +2 -2
- package/src/styles/06-components/_components.messages.scss +16 -16
- package/src/styles/06-components/_components.navbar.scss +2 -0
- package/src/styles/06-components/_components.select.scss +15 -2
- package/src/styles/06-components/_components.upload.scss +3 -3
- package/CHANGELOG.md +0 -165
- package/src/lib/theme/devtools/DesignTokensCustomizer.stories.tsx +0 -215
package/dist/heavy.js
CHANGED
|
@@ -65,12 +65,23 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
65
65
|
},
|
|
66
66
|
DEFAULTS: {
|
|
67
67
|
DISPLACEMENT_SCALE: 70,
|
|
68
|
-
BLUR_AMOUNT
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
get BLUR_AMOUNT() {
|
|
69
|
+
return .15 * this.DISPLACEMENT_SCALE;
|
|
70
|
+
// Dynamically computed based on displacement
|
|
71
|
+
},
|
|
72
|
+
get SATURATION() {
|
|
73
|
+
return 100 + .5 * this.DISPLACEMENT_SCALE;
|
|
74
|
+
// Saturate relative to intensity
|
|
75
|
+
},
|
|
76
|
+
get ABERRATION_INTENSITY() {
|
|
77
|
+
return .03 * this.DISPLACEMENT_SCALE;
|
|
78
|
+
// Scale aberration with displacement
|
|
79
|
+
},
|
|
71
80
|
ELASTICITY: .15,
|
|
72
|
-
CORNER_RADIUS
|
|
73
|
-
|
|
81
|
+
get CORNER_RADIUS() {
|
|
82
|
+
return 16;
|
|
83
|
+
// Use 16 to match SCSS design system (was 20)
|
|
84
|
+
},
|
|
74
85
|
PADDING: "0",
|
|
75
86
|
MODE: "standard",
|
|
76
87
|
OVER_LIGHT: !1,
|
|
@@ -92,6 +103,15 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
92
103
|
MIN_BLUR: .1,
|
|
93
104
|
MOUSE_INFLUENCE_DIVISOR: 100,
|
|
94
105
|
EDGE_FADE_PIXELS: 2,
|
|
106
|
+
// Elasticity physics constants
|
|
107
|
+
ELASTICITY_TRANSLATION_FACTOR: .1,
|
|
108
|
+
ELASTICITY_DISTANCE_THRESHOLD: 200,
|
|
109
|
+
ELASTICITY_COMPRESSION_FACTOR: .3,
|
|
110
|
+
ELASTICITY_STIFFNESS: .1,
|
|
111
|
+
ELASTICITY_DAMPING: .76,
|
|
112
|
+
ELASTICITY_VELOCITY_FACTOR: .65,
|
|
113
|
+
ELASTICITY_STRETCH_RATIO: .45,
|
|
114
|
+
ELASTICITY_MAGNIFICATION_BASE: 1.02,
|
|
95
115
|
// Note: This default must match the SCSS variable --atomix-radius-md
|
|
96
116
|
// @see src/styles/01-settings/_settings.global.scss
|
|
97
117
|
DEFAULT_CORNER_RADIUS: 16,
|
|
@@ -108,84 +128,126 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
108
128
|
// Base angle for border gradients (degrees)
|
|
109
129
|
ANGLE_MULTIPLIER: 1.2,
|
|
110
130
|
// Multiplier for mouse influence on angle
|
|
131
|
+
VELOCITY_ANGLE_MULTIPLIER: 2.5,
|
|
132
|
+
// How much velocity affects gradient rotation
|
|
133
|
+
CHROMATIC_OFFSET: 1.5,
|
|
134
|
+
// Degree offset for chromatic rim layers
|
|
111
135
|
BORDER_STOP_1: {
|
|
112
136
|
MIN: 10,
|
|
113
137
|
// Minimum percentage for border stop 1
|
|
114
138
|
BASE: 33,
|
|
115
139
|
// Base percentage for border stop 1
|
|
116
|
-
MULTIPLIER
|
|
140
|
+
get MULTIPLIER() {
|
|
141
|
+
return .009 * this.BASE;
|
|
142
|
+
}
|
|
117
143
|
},
|
|
118
144
|
BORDER_STOP_2: {
|
|
119
145
|
MAX: 90,
|
|
120
146
|
// Maximum percentage for border stop 2
|
|
121
147
|
BASE: 66,
|
|
122
148
|
// Base percentage for border stop 2
|
|
123
|
-
MULTIPLIER
|
|
149
|
+
get MULTIPLIER() {
|
|
150
|
+
return .006 * this.BASE;
|
|
151
|
+
}
|
|
124
152
|
},
|
|
125
153
|
BORDER_OPACITY: {
|
|
126
154
|
BASE_1: .12,
|
|
127
155
|
// Base opacity for border gradient 1
|
|
128
|
-
BASE_2
|
|
156
|
+
get BASE_2() {
|
|
157
|
+
return 3.33 * this.BASE_1;
|
|
158
|
+
},
|
|
129
159
|
// Base opacity for border gradient 2
|
|
130
|
-
BASE_3
|
|
160
|
+
get BASE_3() {
|
|
161
|
+
return 2.66 * this.BASE_1;
|
|
162
|
+
},
|
|
131
163
|
// Base opacity for border gradient 3
|
|
132
|
-
BASE_4
|
|
164
|
+
get BASE_4() {
|
|
165
|
+
return 5 * this.BASE_1;
|
|
166
|
+
},
|
|
133
167
|
// Base opacity for border gradient 4
|
|
134
|
-
MULTIPLIER_LOW
|
|
168
|
+
get MULTIPLIER_LOW() {
|
|
169
|
+
return .066 * this.BASE_1;
|
|
170
|
+
},
|
|
135
171
|
// Low multiplier for mouse influence on opacity
|
|
136
|
-
MULTIPLIER_HIGH
|
|
172
|
+
get MULTIPLIER_HIGH() {
|
|
173
|
+
return .1 * this.BASE_1;
|
|
174
|
+
}
|
|
137
175
|
},
|
|
138
176
|
CENTER_POSITION: 50,
|
|
139
177
|
// Center position percentage (50%)
|
|
140
178
|
HOVER_POSITION: {
|
|
141
179
|
DIVISOR_1: 2,
|
|
142
180
|
// Divisor for hover 1 position calculation
|
|
143
|
-
DIVISOR_2
|
|
181
|
+
get DIVISOR_2() {
|
|
182
|
+
return .75 * this.DIVISOR_1;
|
|
183
|
+
},
|
|
144
184
|
// Divisor for hover 2 position calculation
|
|
145
|
-
MULTIPLIER_3
|
|
185
|
+
get MULTIPLIER_3() {
|
|
186
|
+
return .5 * this.DIVISOR_1;
|
|
187
|
+
}
|
|
146
188
|
},
|
|
147
|
-
BASE_LAYER_MULTIPLIER
|
|
189
|
+
get BASE_LAYER_MULTIPLIER() {
|
|
190
|
+
return .5;
|
|
191
|
+
}
|
|
148
192
|
},
|
|
149
193
|
// Gradient opacity values for hover effects
|
|
150
194
|
GRADIENT_OPACITY: {
|
|
151
195
|
HOVER_1: {
|
|
152
196
|
BLACK_START: .3,
|
|
153
197
|
// Start opacity for black hover 1
|
|
154
|
-
BLACK_MID
|
|
198
|
+
get BLACK_MID() {
|
|
199
|
+
return this.BLACK_START / 3;
|
|
200
|
+
},
|
|
155
201
|
// Mid opacity for black hover 1
|
|
156
202
|
BLACK_STOP: 30,
|
|
157
203
|
// Stop percentage for black hover 1
|
|
158
|
-
BLACK_END
|
|
204
|
+
get BLACK_END() {
|
|
205
|
+
return 2 * this.BLACK_STOP;
|
|
206
|
+
},
|
|
159
207
|
// End percentage for black hover 1
|
|
160
208
|
WHITE_START: .5,
|
|
161
209
|
// Start opacity for white hover 1
|
|
162
|
-
WHITE_STOP
|
|
210
|
+
get WHITE_STOP() {
|
|
211
|
+
return this.BLACK_END - 10;
|
|
212
|
+
}
|
|
163
213
|
},
|
|
164
214
|
HOVER_2: {
|
|
165
215
|
BLACK_START: .4,
|
|
166
216
|
// Start opacity for black hover 2
|
|
167
|
-
BLACK_MID
|
|
217
|
+
get BLACK_MID() {
|
|
218
|
+
return .375 * this.BLACK_START;
|
|
219
|
+
},
|
|
168
220
|
// Mid opacity for black hover 2
|
|
169
221
|
BLACK_STOP: 40,
|
|
170
222
|
// Stop percentage for black hover 2
|
|
171
|
-
BLACK_END
|
|
223
|
+
get BLACK_END() {
|
|
224
|
+
return 2 * this.BLACK_STOP;
|
|
225
|
+
},
|
|
172
226
|
// End percentage for black hover 2
|
|
173
227
|
WHITE_START: 1,
|
|
174
228
|
// Start opacity for white hover 2
|
|
175
|
-
WHITE_STOP
|
|
229
|
+
get WHITE_STOP() {
|
|
230
|
+
return this.BLACK_END;
|
|
231
|
+
}
|
|
176
232
|
},
|
|
177
233
|
HOVER_3: {
|
|
178
234
|
BLACK_START: .5,
|
|
179
235
|
// Start opacity for black hover 3
|
|
180
|
-
BLACK_MID
|
|
236
|
+
get BLACK_MID() {
|
|
237
|
+
return .4 * this.BLACK_START;
|
|
238
|
+
},
|
|
181
239
|
// Mid opacity for black hover 3
|
|
182
240
|
BLACK_STOP: 50,
|
|
183
241
|
// Stop percentage for black hover 3
|
|
184
|
-
BLACK_END
|
|
242
|
+
get BLACK_END() {
|
|
243
|
+
return 2 * this.BLACK_STOP;
|
|
244
|
+
},
|
|
185
245
|
// End percentage for black hover 3
|
|
186
246
|
WHITE_START: 1,
|
|
187
247
|
// Start opacity for white hover 3
|
|
188
|
-
WHITE_STOP
|
|
248
|
+
get WHITE_STOP() {
|
|
249
|
+
return this.BLACK_END;
|
|
250
|
+
}
|
|
189
251
|
}
|
|
190
252
|
},
|
|
191
253
|
// Base and overlay gradient constants
|
|
@@ -194,34 +256,54 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
194
256
|
// Gradient angle in degrees
|
|
195
257
|
BLACK_START_BASE: .15,
|
|
196
258
|
// Base start opacity for black
|
|
197
|
-
BLACK_START_MULTIPLIER
|
|
259
|
+
get BLACK_START_MULTIPLIER() {
|
|
260
|
+
return .02 * this.BLACK_START_BASE;
|
|
261
|
+
},
|
|
198
262
|
// Multiplier for mouse X influence on start
|
|
199
263
|
BLACK_MID_BASE: .1,
|
|
200
264
|
// Base mid opacity for black
|
|
201
|
-
BLACK_MID_MULTIPLIER
|
|
265
|
+
get BLACK_MID_MULTIPLIER() {
|
|
266
|
+
return .02 * this.BLACK_MID_BASE;
|
|
267
|
+
},
|
|
202
268
|
// Multiplier for mouse Y influence on mid
|
|
203
269
|
BLACK_MID_STOP: 50,
|
|
204
270
|
// Mid stop percentage
|
|
205
|
-
BLACK_END_BASE
|
|
271
|
+
get BLACK_END_BASE() {
|
|
272
|
+
return 1.2 * this.BLACK_START_BASE;
|
|
273
|
+
},
|
|
206
274
|
// Base end opacity for black
|
|
207
|
-
BLACK_END_MULTIPLIER
|
|
275
|
+
get BLACK_END_MULTIPLIER() {
|
|
276
|
+
return .022 * this.BLACK_END_BASE;
|
|
277
|
+
},
|
|
208
278
|
// Multiplier for mouse X influence on end
|
|
209
|
-
WHITE_OPACITY
|
|
279
|
+
get WHITE_OPACITY() {
|
|
280
|
+
return .666 * this.BLACK_START_BASE;
|
|
281
|
+
}
|
|
210
282
|
},
|
|
211
283
|
OVERLAY_GRADIENT: {
|
|
212
284
|
BLACK_START_BASE: .12,
|
|
213
285
|
// Base start opacity for black overlay
|
|
214
|
-
BLACK_START_MULTIPLIER
|
|
286
|
+
get BLACK_START_MULTIPLIER() {
|
|
287
|
+
return .025 * this.BLACK_START_BASE;
|
|
288
|
+
},
|
|
215
289
|
// Multiplier for mouse X influence on start
|
|
216
|
-
BLACK_MID
|
|
290
|
+
get BLACK_MID() {
|
|
291
|
+
return .5 * this.BLACK_START_BASE;
|
|
292
|
+
},
|
|
217
293
|
// Mid opacity for black overlay
|
|
218
294
|
BLACK_MID_STOP: 40,
|
|
219
295
|
// Mid stop percentage
|
|
220
|
-
BLACK_END_BASE
|
|
296
|
+
get BLACK_END_BASE() {
|
|
297
|
+
return 1.25 * this.BLACK_START_BASE;
|
|
298
|
+
},
|
|
221
299
|
// Base end opacity for black overlay
|
|
222
|
-
BLACK_END_MULTIPLIER
|
|
300
|
+
get BLACK_END_MULTIPLIER() {
|
|
301
|
+
return .02 * this.BLACK_END_BASE;
|
|
302
|
+
},
|
|
223
303
|
// Multiplier for mouse Y influence on end
|
|
224
|
-
WHITE_OPACITY
|
|
304
|
+
get WHITE_OPACITY() {
|
|
305
|
+
return .416 * this.BLACK_START_BASE;
|
|
306
|
+
}
|
|
225
307
|
},
|
|
226
308
|
// Overlay highlight constants
|
|
227
309
|
OVERLAY_HIGHLIGHT: {
|
|
@@ -231,9 +313,13 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
231
313
|
// Y position percentage
|
|
232
314
|
WHITE_OPACITY: .4,
|
|
233
315
|
// White opacity in gradient
|
|
234
|
-
STOP
|
|
316
|
+
get STOP() {
|
|
317
|
+
return 150 * this.WHITE_OPACITY;
|
|
318
|
+
},
|
|
235
319
|
// Stop percentage
|
|
236
|
-
OPACITY_MULTIPLIER
|
|
320
|
+
get OPACITY_MULTIPLIER() {
|
|
321
|
+
return 1.75 * this.WHITE_OPACITY;
|
|
322
|
+
}
|
|
237
323
|
},
|
|
238
324
|
// Displacement and aberration multipliers
|
|
239
325
|
MULTIPLIERS: {
|
|
@@ -286,11 +372,7 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
286
372
|
}
|
|
287
373
|
}
|
|
288
374
|
}
|
|
289
|
-
}, {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS,
|
|
290
|
-
if (!pos1 || !pos2 || "number" != typeof pos1.x || "number" != typeof pos1.y || "number" != typeof pos2.x || "number" != typeof pos2.y) return 0;
|
|
291
|
-
const deltaX = pos1.x - pos2.x, deltaY = pos1.y - pos2.y;
|
|
292
|
-
return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
293
|
-
}, calculateElementCenter = rect => rect ? {
|
|
375
|
+
}, {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateElementCenter = rect => rect ? {
|
|
294
376
|
x: rect.left + rect.width / 2,
|
|
295
377
|
y: rect.top + rect.height / 2
|
|
296
378
|
} : {
|
|
@@ -362,7 +444,16 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
362
444
|
// Silently handle errors
|
|
363
445
|
}
|
|
364
446
|
return CONSTANTS$2.DEFAULT_CORNER_RADIUS;
|
|
365
|
-
},
|
|
447
|
+
}, smoothstep = t => {
|
|
448
|
+
const clamped = Math.max(0, Math.min(1, t));
|
|
449
|
+
return clamped * clamped * (3 - 2 * clamped);
|
|
450
|
+
}, lerp$1 = (a, b, t) => a + (b - a) * t, softClamp = (value, max) => max <= 0 ? 0 : max * (1 - Math.exp(-value / max)), calculateSpring = (current, target, velocity, stiffness = .1, damping = .8) => {
|
|
451
|
+
const newVelocity = (velocity + (target - current) * stiffness) * damping;
|
|
452
|
+
return {
|
|
453
|
+
value: current + newVelocity,
|
|
454
|
+
velocity: newVelocity
|
|
455
|
+
};
|
|
456
|
+
}, getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
|
|
366
457
|
switch (mode) {
|
|
367
458
|
case "standard":
|
|
368
459
|
return displacementMap;
|
|
@@ -751,6 +842,9 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
751
842
|
}), jsx("div", {
|
|
752
843
|
ref: contentRef,
|
|
753
844
|
className: ATOMIX_GLASS.CONTENT_CLASS,
|
|
845
|
+
style: {
|
|
846
|
+
transform: "var(--atomix-glass-child-parallax, none)"
|
|
847
|
+
},
|
|
754
848
|
children: children
|
|
755
849
|
}) ]
|
|
756
850
|
})
|
|
@@ -785,9 +879,21 @@ class {
|
|
|
785
879
|
y: this.lastEvent.clientY
|
|
786
880
|
},
|
|
787
881
|
// Notify all subscribers
|
|
788
|
-
this.listeners.forEach((
|
|
882
|
+
this.listeners.forEach((listener => {
|
|
789
883
|
try {
|
|
790
|
-
|
|
884
|
+
// If the listener has an element, calculate distance-based attenuation
|
|
885
|
+
if (listener.element) {
|
|
886
|
+
const elementRect = listener.element.getBoundingClientRect(), elementCenter = {
|
|
887
|
+
x: elementRect.left + elementRect.width / 2,
|
|
888
|
+
y: elementRect.top + elementRect.height / 2
|
|
889
|
+
}, distance = this.calculateDistance(this.position, elementCenter), maxDistance = listener.maxDistance || 300, attenuation = Math.max(0, 1 - distance / maxDistance), attenuatedRelativePosition = {
|
|
890
|
+
x: (this.position.x - elementCenter.x) / elementRect.width * 100 * attenuation,
|
|
891
|
+
y: (this.position.y - elementCenter.y) / elementRect.height * 100 * attenuation
|
|
892
|
+
};
|
|
893
|
+
listener.callback(attenuatedRelativePosition);
|
|
894
|
+
} else
|
|
895
|
+
// Send original position for listeners without distance-based attenuation
|
|
896
|
+
listener.callback(this.position);
|
|
791
897
|
} catch (error) {
|
|
792
898
|
console.error("GlobalMouseTracker: Error in subscriber callback", error);
|
|
793
899
|
}
|
|
@@ -798,10 +904,17 @@ class {
|
|
|
798
904
|
/**
|
|
799
905
|
* Subscribe to mouse position updates
|
|
800
906
|
* @param callback Function to call when mouse position changes
|
|
907
|
+
* @param element Optional element for distance-based attenuation
|
|
908
|
+
* @param maxDistance Optional maximum distance for full effect
|
|
801
909
|
* @returns Unsubscribe function
|
|
802
|
-
*/ subscribe(callback) {
|
|
910
|
+
*/ subscribe(callback, element, maxDistance) {
|
|
911
|
+
const listener = {
|
|
912
|
+
callback: callback,
|
|
913
|
+
element: element,
|
|
914
|
+
maxDistance: maxDistance
|
|
915
|
+
};
|
|
803
916
|
// Return unsubscribe function
|
|
804
|
-
return this.listeners.add(
|
|
917
|
+
return this.listeners.add(listener),
|
|
805
918
|
// Start tracking if this is the first subscriber
|
|
806
919
|
1 === this.listeners.size && this.startTracking(),
|
|
807
920
|
// Immediately notify with current position
|
|
@@ -812,9 +925,13 @@ class {
|
|
|
812
925
|
/**
|
|
813
926
|
* Unsubscribe from mouse position updates
|
|
814
927
|
*/ unsubscribe(callback) {
|
|
815
|
-
|
|
928
|
+
// Find and remove the listener with the given callback
|
|
929
|
+
for (const listener of this.listeners) if (listener.callback === callback) {
|
|
930
|
+
this.listeners.delete(listener);
|
|
931
|
+
break;
|
|
932
|
+
}
|
|
816
933
|
// Stop tracking if no more subscribers
|
|
817
|
-
|
|
934
|
+
0 === this.listeners.size && this.stopTracking();
|
|
818
935
|
}
|
|
819
936
|
/**
|
|
820
937
|
* Start tracking mouse movement
|
|
@@ -833,6 +950,12 @@ class {
|
|
|
833
950
|
null !== this.rafId && (cancelAnimationFrame(this.rafId), this.rafId = null), this.lastEvent = null);
|
|
834
951
|
}
|
|
835
952
|
/**
|
|
953
|
+
* Calculate distance between two points
|
|
954
|
+
*/ calculateDistance(point1, point2) {
|
|
955
|
+
const dx = point1.x - point2.x, dy = point1.y - point2.y;
|
|
956
|
+
return Math.sqrt(dx * dx + dy * dy);
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
836
959
|
* Get current mouse position (synchronous)
|
|
837
960
|
*/ getPosition() {
|
|
838
961
|
return {
|
|
@@ -846,51 +969,26 @@ class {
|
|
|
846
969
|
}
|
|
847
970
|
}, updateAtomixGlassStyles = (wrapperElement, containerElement, params) => {
|
|
848
971
|
if (!wrapperElement && !containerElement) return;
|
|
849
|
-
|
|
972
|
+
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, padding: padding = ATOMIX_GLASS.DEFAULTS.PADDING, isFixedOrSticky: isFixedOrSticky = !1} = params, mouseInfluence = calculateMouseInfluence(mouseOffset), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1, overLightConfig = {
|
|
850
974
|
opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
|
|
851
975
|
contrast: Math.min(1.6, baseOverLightConfig.contrast + .1 * mouseInfluence),
|
|
852
976
|
brightness: Math.min(1.1, baseOverLightConfig.brightness + .05 * mouseInfluence),
|
|
853
977
|
shadowIntensity: Math.min(1.2, Math.max(.5, baseOverLightConfig.shadowIntensity + .2 * mouseInfluence)),
|
|
854
978
|
borderOpacity: Math.min(1, Math.max(.3, baseOverLightConfig.borderOpacity + .1 * mouseInfluence)),
|
|
855
979
|
saturationBoost: baseOverLightConfig.saturationBoost
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
|
|
980
|
+
}, scaleX = directionalScale.x * scaleBase, scaleY = directionalScale.y * scaleBase, transformStyle = effectiveWithoutEffects ? `scale(${scaleBase})` : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) scaleX(${scaleX}) scaleY(${scaleY})`, stretchMagnitude = ((pos1, pos2) => {
|
|
981
|
+
if (!pos1 || !pos2 || "number" != typeof pos1.x || "number" != typeof pos1.y || "number" != typeof pos2.x || "number" != typeof pos2.y) return 0;
|
|
982
|
+
const deltaX = pos1.x - pos2.x, deltaY = pos1.y - pos2.y;
|
|
983
|
+
return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
984
|
+
})({
|
|
859
985
|
x: 0,
|
|
860
986
|
y: 0
|
|
861
|
-
};
|
|
862
|
-
// Calculate
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
if (globalMousePosition.x && globalMousePosition.y && validateGlassSize(glassSize)) {
|
|
867
|
-
const deltaX = globalMousePosition.x - center.x, deltaY = globalMousePosition.y - center.y, edgeDistanceX = Math.max(0, Math.abs(deltaX) - glassSize.width / 2), edgeDistanceY = Math.max(0, Math.abs(deltaY) - glassSize.height / 2), edgeDistance = calculateDistance({
|
|
868
|
-
x: edgeDistanceX,
|
|
869
|
-
y: edgeDistanceY
|
|
870
|
-
}, {
|
|
871
|
-
x: 0,
|
|
872
|
-
y: 0
|
|
873
|
-
}), rawT = edgeDistance > ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE, fadeInFactor = (t => {
|
|
874
|
-
const clamped = Math.max(0, Math.min(1, t));
|
|
875
|
-
return clamped * clamped * (3 - 2 * clamped);
|
|
876
|
-
})(rawT);
|
|
877
|
-
// Directional scale
|
|
878
|
-
if (elasticTranslation = {
|
|
879
|
-
x: deltaX * elasticity * .1 * fadeInFactor,
|
|
880
|
-
y: deltaY * elasticity * .1 * fadeInFactor
|
|
881
|
-
}, !isOverLight && edgeDistance <= ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE) {
|
|
882
|
-
const centerDistance = calculateDistance(globalMousePosition, center);
|
|
883
|
-
if (centerDistance > 0) {
|
|
884
|
-
const normalizedX = deltaX / centerDistance, normalizedY = deltaY / centerDistance, stretchIntensity = Math.min(centerDistance / 300, 1) * elasticity * rawT, scaleX = 1 + Math.abs(normalizedX) * stretchIntensity * .3 - Math.abs(normalizedY) * stretchIntensity * .15, scaleY = 1 + Math.abs(normalizedY) * stretchIntensity * .3 - Math.abs(normalizedX) * stretchIntensity * .15, softScaleX = 1 - softClamp(Math.max(0, 1 - scaleX), .2), softScaleY = 1 - softClamp(Math.max(0, 1 - scaleY), .2);
|
|
885
|
-
computedDirectionalScale = `scaleX(${Math.max(.85, softScaleX)}) scaleY(${Math.max(.85, softScaleY)})`;
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
const transformStyle = effectiveWithoutEffects ? isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)" : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) ${isActive && Boolean(onClick) ? "scale(0.96)" : computedDirectionalScale}`;
|
|
891
|
-
// Update Wrapper Styles (glassVars)
|
|
892
|
-
if (wrapperElement) {
|
|
893
|
-
const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT, borderGradientAngle = GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER, borderStop1 = Math.max(GRADIENT.BORDER_STOP_1.MIN, GRADIENT.BORDER_STOP_1.BASE + my * GRADIENT.BORDER_STOP_1.MULTIPLIER), borderStop2 = Math.min(GRADIENT.BORDER_STOP_2.MAX, GRADIENT.BORDER_STOP_2.BASE + my * GRADIENT.BORDER_STOP_2.MULTIPLIER), borderOpacities = [ GRADIENT.BORDER_OPACITY.BASE_1 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW, GRADIENT.BORDER_OPACITY.BASE_2 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH, GRADIENT.BORDER_OPACITY.BASE_3 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW, GRADIENT.BORDER_OPACITY.BASE_4 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH ], configBorderOpacity = overLightConfig.borderOpacity, whiteColor = ATOMIX_GLASS.CONSTANTS.PALETTE.WHITE, blackColor = ATOMIX_GLASS.CONSTANTS.PALETTE.BLACK, hoverPositions = {
|
|
987
|
+
}, elasticTranslation), tensionFactor = smoothstep(stretchMagnitude / 80), lightingContrast = Math.min(1.8, overLightConfig.contrast + .2 * tensionFactor), lightingBrightness = Math.min(1.2, overLightConfig.brightness + .1 * tensionFactor);
|
|
988
|
+
// Calculate mouse influence
|
|
989
|
+
// Update Wrapper Styles (glassVars)
|
|
990
|
+
if (wrapperElement) {
|
|
991
|
+
const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT, velocityRotation = (mouseVelocity.x + elasticVelocity.x) * (GRADIENT.VELOCITY_ANGLE_MULTIPLIER || 2.5), borderGradientAngle = GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER + velocityRotation, chromaticOffset = GRADIENT.CHROMATIC_OFFSET || 1.5, angleR = borderGradientAngle - chromaticOffset, angleB = borderGradientAngle + chromaticOffset, borderStop1 = Math.max(GRADIENT.BORDER_STOP_1.MIN, GRADIENT.BORDER_STOP_1.BASE + my * GRADIENT.BORDER_STOP_1.MULTIPLIER), borderStop2 = Math.min(GRADIENT.BORDER_STOP_2.MAX, GRADIENT.BORDER_STOP_2.BASE + my * GRADIENT.BORDER_STOP_2.MULTIPLIER), tensionGlow = 1 + .5 * tensionFactor, borderOpacities = [ (GRADIENT.BORDER_OPACITY.BASE_1 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW) * tensionGlow, (GRADIENT.BORDER_OPACITY.BASE_2 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH) * tensionGlow, (GRADIENT.BORDER_OPACITY.BASE_3 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW) * tensionGlow, (GRADIENT.BORDER_OPACITY.BASE_4 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH) * tensionGlow ], configBorderOpacity = overLightConfig.borderOpacity, whiteColor = ATOMIX_GLASS.CONSTANTS.PALETTE.WHITE, blackColor = ATOMIX_GLASS.CONSTANTS.PALETTE.BLACK, hoverPositions = {
|
|
894
992
|
hover1: {
|
|
895
993
|
x: GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_1,
|
|
896
994
|
y: GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_1
|
|
@@ -913,10 +1011,16 @@ class {
|
|
|
913
1011
|
base: isOverLight ? overLightConfig.opacity : 0,
|
|
914
1012
|
over: isOverLight ? 1.1 * overLightConfig.opacity : 0
|
|
915
1013
|
}, style = wrapperElement.style;
|
|
916
|
-
style.setProperty("--atomix-glass-transform", transformStyle || "none")
|
|
917
|
-
//
|
|
918
|
-
|
|
919
|
-
style.setProperty("--atomix-glass-
|
|
1014
|
+
style.setProperty("--atomix-glass-transform", transformStyle || "none");
|
|
1015
|
+
// Parallax for content (liquid refraction feel)
|
|
1016
|
+
const parallaxFactor = .38 + .12 * tensionFactor;
|
|
1017
|
+
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()),
|
|
1019
|
+
// ── Chromatic Rim Lighting ──────────────────────────────────────
|
|
1020
|
+
// Layer 1: Core White/Blue highlight
|
|
1021
|
+
style.setProperty("--atomix-glass-border-gradient-1", `linear-gradient(${angleB}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[0] ?? 1) * configBorderOpacity}) ${borderStop1}%, rgba(${whiteColor}, ${(borderOpacities[1] ?? 1) * configBorderOpacity}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`),
|
|
1022
|
+
// Layer 2: Subtle Red/Warm highlight (offset angle)
|
|
1023
|
+
style.setProperty("--atomix-glass-border-gradient-2", `linear-gradient(${angleR}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[2] ?? 1) * configBorderOpacity}) ${borderStop1}%, rgba(${whiteColor}, ${(borderOpacities[3] ?? 1) * configBorderOpacity}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`),
|
|
920
1024
|
// Hover gradients
|
|
921
1025
|
style.setProperty("--atomix-glass-hover-1-gradient", isOverLight ? `radial-gradient(circle at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_START}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_STOP}%, rgba(${blackColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_END}%)` : `radial-gradient(circle at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_STOP}%)`),
|
|
922
1026
|
style.setProperty("--atomix-glass-hover-2-gradient", isOverLight ? `radial-gradient(circle at ${hoverPositions.hover2.x}% ${hoverPositions.hover2.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_START}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_STOP}%, rgba(${blackColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_END}%)` : `radial-gradient(circle at ${hoverPositions.hover2.x}% ${hoverPositions.hover2.y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_STOP}%)`),
|
|
@@ -944,7 +1048,7 @@ class {
|
|
|
944
1048
|
flowBlur: blurAmount * FLOW_BLUR_MULTIPLIER
|
|
945
1049
|
};
|
|
946
1050
|
if (withLiquidBlur && rect) {
|
|
947
|
-
const mouseInfluence = calculateMouseInfluence(mouseOffset), maxBlur = blurAmount * MAX_BLUR_RELATIVE, baseBlur =
|
|
1051
|
+
const mouseInfluence = calculateMouseInfluence(mouseOffset), maxBlur = blurAmount * MAX_BLUR_RELATIVE, baseBlur = softClamp(blurAmount + mouseInfluence * blurAmount * MOUSE_INFLUENCE_BLUR_FACTOR, maxBlur), edgeBlur = softClamp(baseBlur * (.8 + mouseInfluence * EDGE_INTENSITY_MOUSE_FACTOR * .4), maxBlur), centerBlur = softClamp(baseBlur * (.3 + mouseInfluence * CENTER_INTENSITY_MOUSE_FACTOR * .3), maxBlur), flowBlur = softClamp(baseBlur * FLOW_BLUR_MULTIPLIER, maxBlur);
|
|
948
1052
|
liquidBlur = {
|
|
949
1053
|
baseBlur: clampBlur(baseBlur),
|
|
950
1054
|
edgeBlur: clampBlur(edgeBlur),
|
|
@@ -953,9 +1057,10 @@ class {
|
|
|
953
1057
|
};
|
|
954
1058
|
}
|
|
955
1059
|
// Backdrop filter
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
1060
|
+
const dynamicSaturation = saturation + 40 * tensionFactor + 15 * (liquidBlur.baseBlur || 0);
|
|
1061
|
+
let backdropFilterString = "";
|
|
1062
|
+
const area = rect ? rect.width * rect.height : 0;
|
|
1063
|
+
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})`;
|
|
959
1064
|
// Container variables
|
|
960
1065
|
const style = containerElement.style;
|
|
961
1066
|
style.setProperty("--atomix-glass-container-padding", padding), style.setProperty("--atomix-glass-container-radius", `${effectiveBorderRadius}px`),
|
|
@@ -1117,7 +1222,8 @@ const {CONSTANTS: CONSTANTS} = ATOMIX_GLASS, backgroundDetectionCache = new Weak
|
|
|
1117
1222
|
* Composable hook for AtomixGlass component logic
|
|
1118
1223
|
* Manages all state, calculations, and event handlers
|
|
1119
1224
|
*/
|
|
1120
|
-
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 = .
|
|
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, padding: padding, withLiquidBlur: withLiquidBlur, isFixedOrSticky: isFixedOrSticky = !1, priority: priority = 1, withTimeAnimation:
|
|
1226
|
+
// Default priority
|
|
1121
1227
|
// Phase 1: Animation System Props
|
|
1122
1228
|
withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: animationSpeed = ATOMIX_GLASS.DEFAULTS.ANIMATION_SPEED, withMultiLayerDistortion: withMultiLayerDistortion = ATOMIX_GLASS.DEFAULTS.WITH_MULTI_LAYER_DISTORTION, distortionOctaves: distortionOctaves = ATOMIX_GLASS.DEFAULTS.DISTORTION_OCTAVES, distortionLacunarity: distortionLacunarity = ATOMIX_GLASS.DEFAULTS.DISTORTION_LACUNARITY, distortionGain: distortionGain = ATOMIX_GLASS.DEFAULTS.DISTORTION_GAIN, distortionQuality: distortionQuality = ATOMIX_GLASS.DEFAULTS.DISTORTION_QUALITY}) {
|
|
1123
1229
|
// State
|
|
@@ -1133,7 +1239,24 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1133
1239
|
}), targetGlobalMousePositionRef = useRef({
|
|
1134
1240
|
x: 0,
|
|
1135
1241
|
y: 0
|
|
1136
|
-
}), lerpRafRef = useRef(null), lerpActiveRef = useRef(!1), [dynamicBorderRadius, setDynamicCornerRadius] = useState(CONSTANTS.DEFAULT_CORNER_RADIUS),
|
|
1242
|
+
}), lerpRafRef = useRef(null), lerpActiveRef = useRef(!1), [dynamicBorderRadius, setDynamicCornerRadius] = useState(CONSTANTS.DEFAULT_CORNER_RADIUS), elasticTranslationRef = useRef({
|
|
1243
|
+
x: 0,
|
|
1244
|
+
y: 0
|
|
1245
|
+
}), elasticVelocityRef = useRef({
|
|
1246
|
+
x: 0,
|
|
1247
|
+
y: 0
|
|
1248
|
+
}), directionalScaleRef = useRef({
|
|
1249
|
+
x: 1,
|
|
1250
|
+
y: 1
|
|
1251
|
+
}), scaleVelocityRef = useRef({
|
|
1252
|
+
x: 0,
|
|
1253
|
+
y: 0
|
|
1254
|
+
});
|
|
1255
|
+
useRef(0);
|
|
1256
|
+
const mouseVelocityRef = useRef({
|
|
1257
|
+
x: 0,
|
|
1258
|
+
y: 0
|
|
1259
|
+
}), [userPrefersReducedMotion, setUserPrefersReducedMotion] = useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = useState(!1), [detectedOverLight, setDetectedOverLight] = useState(!1), animationFrameIdRef = useRef(null), animationStartTimeRef = useRef(0), elapsedTimeRef = useRef(0), shaderTimeRef = useRef(0), fbmConfig = useMemo((() => {
|
|
1137
1260
|
// If quality preset is provided, use it as base
|
|
1138
1261
|
const preset = (quality = distortionQuality, ATOMIX_GLASS.CONSTANTS.DISTORTION_QUALITY_PRESETS[quality]);
|
|
1139
1262
|
// Override with custom values if provided
|
|
@@ -1418,57 +1541,85 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1418
1541
|
return "undefined" == typeof process || process.env, finalConfig;
|
|
1419
1542
|
}
|
|
1420
1543
|
return "undefined" == typeof process || process.env, baseConfig;
|
|
1421
|
-
}), [ overLight, getEffectiveOverLight, isHovered, isActive, validateConfigValue, debugOverLight ]), transformStyle = useMemo((() => effectiveWithoutEffects || isActive && Boolean(onClick) ? "scale(0.
|
|
1544
|
+
}), [ overLight, getEffectiveOverLight, isHovered, isActive, validateConfigValue, debugOverLight ]), transformStyle = useMemo((() => effectiveWithoutEffects || isActive && Boolean(onClick) ? "scale(0.99)" : "scale(1)"), [ effectiveWithoutEffects, isActive, onClick ]), updateRectRef = useRef(null), stopLerpLoop = useCallback((() => {
|
|
1422
1545
|
lerpActiveRef.current = !1, null !== lerpRafRef.current && (cancelAnimationFrame(lerpRafRef.current),
|
|
1423
1546
|
lerpRafRef.current = null);
|
|
1424
1547
|
}), []), startLerpLoop = useCallback((() => {
|
|
1425
1548
|
if (lerpActiveRef.current) return;
|
|
1426
|
-
lerpActiveRef.current = !0;
|
|
1427
|
-
|
|
1549
|
+
lerpActiveRef.current = !0, CONSTANTS.LERP_FACTOR;
|
|
1550
|
+
// 0.08 – lower = more viscous
|
|
1551
|
+
const tick = () => {
|
|
1428
1552
|
if (!lerpActiveRef.current) return;
|
|
1429
1553
|
if (!glassRef.current) return void (lerpActiveRef.current = !1);
|
|
1430
|
-
const cur = internalMouseOffsetRef.current, tgt = targetMouseOffsetRef.current,
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
},
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
// Final update and stop
|
|
1438
|
-
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
1439
|
-
mouseOffset: internalMouseOffsetRef.current,
|
|
1440
|
-
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
1441
|
-
glassSize: glassSize,
|
|
1442
|
-
isHovered: isHovered,
|
|
1443
|
-
isActive: isActive,
|
|
1444
|
-
isOverLight: overLightConfig.isOverLight,
|
|
1445
|
-
baseOverLightConfig: overLightConfig,
|
|
1446
|
-
effectiveBorderRadius: effectiveBorderRadius,
|
|
1447
|
-
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
1448
|
-
effectiveReducedMotion: effectiveReducedMotion,
|
|
1449
|
-
elasticity: elasticity,
|
|
1450
|
-
directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
|
|
1451
|
-
onClick: onClick,
|
|
1452
|
-
withLiquidBlur: withLiquidBlur,
|
|
1453
|
-
blurAmount: blurAmount,
|
|
1454
|
-
saturation: saturation,
|
|
1455
|
-
padding: padding,
|
|
1456
|
-
isFixedOrSticky: isFixedOrSticky
|
|
1457
|
-
}), void stopLerpLoop();
|
|
1458
|
-
// Smooth step
|
|
1459
|
-
internalMouseOffsetRef.current = {
|
|
1460
|
-
x: lerp$1(cur.x, tgt.x, LERP_T),
|
|
1461
|
-
y: lerp$1(cur.y, tgt.y, LERP_T)
|
|
1554
|
+
const cur = internalMouseOffsetRef.current, tgt = targetMouseOffsetRef.current, springX = calculateSpring(cur.x, tgt.x, mouseVelocityRef.current.x, CONSTANTS.LERP_FACTOR, CONSTANTS.ELASTICITY_DAMPING), springY = calculateSpring(cur.y, tgt.y, mouseVelocityRef.current.y, CONSTANTS.LERP_FACTOR, CONSTANTS.ELASTICITY_DAMPING);
|
|
1555
|
+
internalMouseOffsetRef.current = {
|
|
1556
|
+
x: springX.value,
|
|
1557
|
+
y: springY.value
|
|
1558
|
+
}, mouseVelocityRef.current = {
|
|
1559
|
+
x: springX.velocity,
|
|
1560
|
+
y: springY.velocity
|
|
1462
1561
|
};
|
|
1463
1562
|
const curG = internalGlobalMousePositionRef.current, tgtG = targetGlobalMousePositionRef.current;
|
|
1464
1563
|
internalGlobalMousePositionRef.current = {
|
|
1465
|
-
x: lerp$1(curG.x, tgtG.x,
|
|
1466
|
-
y: lerp$1(curG.y, tgtG.y,
|
|
1564
|
+
x: lerp$1(curG.x, tgtG.x, CONSTANTS.LERP_FACTOR),
|
|
1565
|
+
y: lerp$1(curG.y, tgtG.y, CONSTANTS.LERP_FACTOR)
|
|
1566
|
+
};
|
|
1567
|
+
// ── Calculate Elastic Physics ─────────────────────────────────────
|
|
1568
|
+
let targetElasticTranslation = {
|
|
1569
|
+
x: 0,
|
|
1570
|
+
y: 0
|
|
1571
|
+
}, targetScale = {
|
|
1572
|
+
x: 1,
|
|
1573
|
+
y: 1
|
|
1574
|
+
};
|
|
1575
|
+
if (!effectiveWithoutEffects && glassRef.current) {
|
|
1576
|
+
const rect = cachedRectRef.current || glassRef.current.getBoundingClientRect(), center = calculateElementCenter(rect), globalPos = internalGlobalMousePositionRef.current;
|
|
1577
|
+
if (globalPos.x && globalPos.y) {
|
|
1578
|
+
const deltaX = globalPos.x - center.x, deltaY = globalPos.y - center.y, edgeDistanceX = Math.max(0, Math.abs(deltaX) - rect.width / 2), edgeDistanceY = Math.max(0, Math.abs(deltaY) - rect.height / 2), edgeDistance = Math.sqrt(edgeDistanceX * edgeDistanceX + edgeDistanceY * edgeDistanceY), activationZone = CONSTANTS.ACTIVATION_ZONE, rawT = edgeDistance > activationZone ? 0 : 1 - edgeDistance / activationZone, fadeInFactor = smoothstep(rawT);
|
|
1579
|
+
// Scale stretch logic (liquid surface tension)
|
|
1580
|
+
if (targetElasticTranslation = {
|
|
1581
|
+
x: deltaX * elasticity * CONSTANTS.ELASTICITY_TRANSLATION_FACTOR * fadeInFactor,
|
|
1582
|
+
y: deltaY * elasticity * CONSTANTS.ELASTICITY_TRANSLATION_FACTOR * fadeInFactor
|
|
1583
|
+
}, edgeDistance <= activationZone) {
|
|
1584
|
+
const centerDistance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
1585
|
+
if (centerDistance > 0) {
|
|
1586
|
+
const nx = deltaX / centerDistance, ny = deltaY / centerDistance, stretchIntensity = Math.min(centerDistance / 350, 1) * elasticity * rawT, mag = 1 + .06 * stretchIntensity;
|
|
1587
|
+
targetScale = {
|
|
1588
|
+
x: mag + Math.abs(nx) * stretchIntensity * CONSTANTS.ELASTICITY_STRETCH_RATIO,
|
|
1589
|
+
y: mag + Math.abs(ny) * stretchIntensity * CONSTANTS.ELASTICITY_STRETCH_RATIO
|
|
1590
|
+
},
|
|
1591
|
+
// Maintain liquid volume by compressing the perpendicular axis
|
|
1592
|
+
targetScale.x -= Math.abs(ny) * stretchIntensity * .15, targetScale.y -= Math.abs(nx) * stretchIntensity * .15;
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
// Integrate Elastic Translation Spring
|
|
1598
|
+
const springTX = calculateSpring(elasticTranslationRef.current.x, targetElasticTranslation.x, elasticVelocityRef.current.x, CONSTANTS.ELASTICITY_STIFFNESS, CONSTANTS.ELASTICITY_DAMPING), springTY = calculateSpring(elasticTranslationRef.current.y, targetElasticTranslation.y, elasticVelocityRef.current.y, CONSTANTS.ELASTICITY_STIFFNESS, CONSTANTS.ELASTICITY_DAMPING);
|
|
1599
|
+
elasticTranslationRef.current = {
|
|
1600
|
+
x: springTX.value,
|
|
1601
|
+
y: springTY.value
|
|
1602
|
+
}, elasticVelocityRef.current = {
|
|
1603
|
+
x: springTX.velocity,
|
|
1604
|
+
y: springTY.velocity
|
|
1605
|
+
};
|
|
1606
|
+
// Integrate Scale Spring
|
|
1607
|
+
const springSX = calculateSpring(directionalScaleRef.current.x, targetScale.x, scaleVelocityRef.current.x, CONSTANTS.ELASTICITY_STIFFNESS, CONSTANTS.ELASTICITY_DAMPING), springSY = calculateSpring(directionalScaleRef.current.y, targetScale.y, scaleVelocityRef.current.y, CONSTANTS.ELASTICITY_STIFFNESS, CONSTANTS.ELASTICITY_DAMPING);
|
|
1608
|
+
directionalScaleRef.current = {
|
|
1609
|
+
x: springSX.value,
|
|
1610
|
+
y: springSY.value
|
|
1611
|
+
}, scaleVelocityRef.current = {
|
|
1612
|
+
x: springSX.velocity,
|
|
1613
|
+
y: springSY.velocity
|
|
1467
1614
|
},
|
|
1468
1615
|
// Imperative style update
|
|
1469
1616
|
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
1470
1617
|
mouseOffset: internalMouseOffsetRef.current,
|
|
1471
1618
|
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
1619
|
+
elasticTranslation: elasticTranslationRef.current,
|
|
1620
|
+
elasticVelocity: elasticVelocityRef.current,
|
|
1621
|
+
mouseVelocity: mouseVelocityRef.current,
|
|
1622
|
+
directionalScale: directionalScaleRef.current,
|
|
1472
1623
|
glassSize: glassSize,
|
|
1473
1624
|
isHovered: isHovered,
|
|
1474
1625
|
isActive: isActive,
|
|
@@ -1478,17 +1629,16 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1478
1629
|
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
1479
1630
|
effectiveReducedMotion: effectiveReducedMotion,
|
|
1480
1631
|
elasticity: elasticity,
|
|
1481
|
-
|
|
1632
|
+
scaleBase: isActive && Boolean(onClick) ? .99 : 1,
|
|
1482
1633
|
onClick: onClick,
|
|
1483
1634
|
withLiquidBlur: withLiquidBlur,
|
|
1484
1635
|
blurAmount: blurAmount,
|
|
1485
1636
|
saturation: saturation,
|
|
1486
1637
|
padding: padding,
|
|
1487
1638
|
isFixedOrSticky: isFixedOrSticky
|
|
1488
|
-
}), lerpRafRef.current = requestAnimationFrame(tick);
|
|
1639
|
+
}), 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);
|
|
1489
1640
|
};
|
|
1490
|
-
|
|
1491
|
-
lerpRafRef.current = requestAnimationFrame(tick);
|
|
1641
|
+
lerpRafRef.current = requestAnimationFrame(tick);
|
|
1492
1642
|
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding, isFixedOrSticky, stopLerpLoop ]), handleGlobalMousePosition = useCallback((globalPos => {
|
|
1493
1643
|
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
1494
1644
|
if (effectiveWithoutEffects) return;
|
|
@@ -1514,7 +1664,8 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1514
1664
|
useEffect((() => {
|
|
1515
1665
|
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
1516
1666
|
if (effectiveWithoutEffects) return;
|
|
1517
|
-
const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition);
|
|
1667
|
+
const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition, glassRef.current || void 0, 300);
|
|
1668
|
+
// 300px max distance for full effect
|
|
1518
1669
|
// Initial start
|
|
1519
1670
|
startLerpLoop();
|
|
1520
1671
|
const container = mouseContainer?.current || glassRef.current;
|
|
@@ -1534,6 +1685,11 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1534
1685
|
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
1535
1686
|
mouseOffset: externalMouseOffset || internalMouseOffsetRef.current,
|
|
1536
1687
|
globalMousePosition: externalGlobalMousePosition || internalGlobalMousePositionRef.current,
|
|
1688
|
+
elasticTranslation: elasticTranslationRef.current,
|
|
1689
|
+
elasticVelocity: elasticVelocityRef.current,
|
|
1690
|
+
mouseVelocity: mouseVelocityRef.current,
|
|
1691
|
+
directionalScale: directionalScaleRef.current,
|
|
1692
|
+
scaleBase: isActive && Boolean(onClick) ? .96 : 1,
|
|
1537
1693
|
glassSize: glassSize,
|
|
1538
1694
|
isHovered: isHovered,
|
|
1539
1695
|
isActive: isActive,
|
|
@@ -1543,7 +1699,6 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1543
1699
|
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
1544
1700
|
effectiveReducedMotion: effectiveReducedMotion,
|
|
1545
1701
|
elasticity: elasticity,
|
|
1546
|
-
directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
|
|
1547
1702
|
onClick: onClick,
|
|
1548
1703
|
withLiquidBlur: withLiquidBlur,
|
|
1549
1704
|
blurAmount: blurAmount,
|
|
@@ -2811,7 +2966,7 @@ const PERFORMANCE_PRESET = {
|
|
|
2811
2966
|
"aria-label": ariaLabel,
|
|
2812
2967
|
"aria-describedby": ariaDescribedBy,
|
|
2813
2968
|
"aria-disabled": !(!onClick || !effectiveWithoutEffects) || !onClick && void 0,
|
|
2814
|
-
"aria-pressed": void 0,
|
|
2969
|
+
"aria-pressed": onClick ? isActive : void 0,
|
|
2815
2970
|
onKeyDown: onClick ? handleKeyDown : void 0,
|
|
2816
2971
|
children: [ jsx(AtomixGlassContainer, {
|
|
2817
2972
|
ref: glassRef,
|
|
@@ -4416,10 +4571,10 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
|
|
|
4416
4571
|
children: renderSlot(slots?.spinner, {
|
|
4417
4572
|
className: ThemeNaming.bemClass("btn", "spinner"),
|
|
4418
4573
|
size: spinnerSize,
|
|
4419
|
-
variant: "link" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "
|
|
4574
|
+
variant: "link" === variant || "ghost" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "danger" : variant
|
|
4420
4575
|
}, jsx(Spinner, {
|
|
4421
4576
|
size: spinnerSize,
|
|
4422
|
-
variant: "link" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "
|
|
4577
|
+
variant: "link" === variant || "ghost" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "danger" : variant
|
|
4423
4578
|
}))
|
|
4424
4579
|
}), iconElement && !loading && jsx("span", {
|
|
4425
4580
|
className: ThemeNaming.bemClass("btn", "icon"),
|
|
@@ -4508,8 +4663,7 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
|
|
|
4508
4663
|
const defaultGlassProps = {
|
|
4509
4664
|
displacementScale: 20,
|
|
4510
4665
|
blurAmount: 0,
|
|
4511
|
-
saturation: 200
|
|
4512
|
-
elasticity: 0
|
|
4666
|
+
saturation: 200
|
|
4513
4667
|
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
4514
4668
|
...defaultGlassProps,
|
|
4515
4669
|
...glass
|