@shohojdhara/atomix 0.4.7 → 0.4.9
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/atomix.config.ts +58 -1
- package/dist/atomix.css +172 -157
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +4 -4
- package/dist/atomix.min.css.map +1 -1
- package/dist/charts.d.ts +33 -0
- package/dist/charts.js +1274 -164
- package/dist/charts.js.map +1 -1
- package/dist/core.d.ts +33 -10
- package/dist/core.js +1099 -83
- package/dist/core.js.map +1 -1
- package/dist/forms.d.ts +33 -0
- package/dist/forms.js +2106 -1050
- package/dist/forms.js.map +1 -1
- package/dist/heavy.d.ts +42 -1
- package/dist/heavy.js +1663 -638
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +442 -270
- package/dist/index.esm.js +1947 -680
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1982 -712
- 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 +6 -3
- package/scripts/atomix-cli.js +136 -1827
- package/scripts/cli/__tests__/basic.test.js +3 -2
- package/scripts/cli/__tests__/clean.test.js +278 -0
- package/scripts/cli/__tests__/component-validator.test.js +433 -0
- package/scripts/cli/__tests__/generator.test.js +613 -0
- package/scripts/cli/__tests__/glass-motion.test.js +256 -0
- package/scripts/cli/__tests__/integration.test.js +719 -108
- package/scripts/cli/__tests__/migrate.test.js +74 -0
- package/scripts/cli/__tests__/security.test.js +206 -0
- package/scripts/cli/__tests__/test-setup.js +3 -1
- package/scripts/cli/__tests__/theme-bridge.test.js +507 -0
- package/scripts/cli/__tests__/token-provider.test.js +361 -0
- package/scripts/cli/__tests__/utils.test.js +5 -5
- package/scripts/cli/commands/benchmark.js +105 -0
- package/scripts/cli/commands/build-theme.js +115 -0
- package/scripts/cli/commands/clean.js +109 -0
- package/scripts/cli/commands/doctor.js +88 -0
- package/scripts/cli/commands/generate.js +218 -0
- package/scripts/cli/commands/init.js +73 -0
- package/scripts/cli/commands/migrate.js +106 -0
- package/scripts/cli/commands/sync-tokens.js +206 -0
- package/scripts/cli/commands/theme-bridge.js +248 -0
- package/scripts/cli/commands/tokens.js +157 -0
- package/scripts/cli/commands/validate.js +194 -0
- package/scripts/cli/internal/ai-engine.js +156 -0
- package/scripts/cli/internal/compiler.js +114 -0
- package/scripts/cli/internal/component-validator.js +443 -0
- package/scripts/cli/internal/config-loader.js +162 -0
- package/scripts/cli/internal/filesystem.js +158 -0
- package/scripts/cli/internal/generator.js +430 -0
- package/scripts/cli/internal/glass-generator.js +398 -0
- package/scripts/cli/internal/hook-generator.js +369 -0
- package/scripts/cli/internal/hooks.js +61 -0
- package/scripts/cli/internal/itcss-generator.js +565 -0
- package/scripts/cli/internal/motion-generator.js +679 -0
- package/scripts/cli/internal/template-engine.js +301 -0
- package/scripts/cli/internal/theme-bridge.js +664 -0
- package/scripts/cli/internal/tokens/engine.js +122 -0
- package/scripts/cli/internal/tokens/provider.js +34 -0
- package/scripts/cli/internal/tokens/providers/figma.js +50 -0
- package/scripts/cli/internal/tokens/providers/style-dictionary.js +48 -0
- package/scripts/cli/internal/tokens/providers/w3c.js +48 -0
- package/scripts/cli/internal/tokens/token-provider.js +443 -0
- package/scripts/cli/internal/tokens/token-validator.js +513 -0
- package/scripts/cli/internal/validator.js +276 -0
- package/scripts/cli/internal/wizard.js +115 -0
- package/scripts/cli/mappings.js +23 -0
- package/scripts/cli/migration-tools.js +164 -94
- package/scripts/cli/plugins/style-dictionary.js +46 -0
- package/scripts/cli/templates/README.md +525 -95
- package/scripts/cli/templates/common-templates.js +40 -14
- package/scripts/cli/templates/components/react-component.ts +282 -0
- package/scripts/cli/templates/config/project-config.ts +112 -0
- package/scripts/cli/templates/hooks/use-component.ts +477 -0
- package/scripts/cli/templates/index.js +19 -4
- package/scripts/cli/templates/index.ts +171 -0
- package/scripts/cli/templates/next-templates.js +72 -0
- package/scripts/cli/templates/react-templates.js +70 -126
- package/scripts/cli/templates/scss-templates.js +35 -35
- package/scripts/cli/templates/stories/storybook-story.ts +241 -0
- package/scripts/cli/templates/styles/scss-component.ts +255 -0
- package/scripts/cli/templates/tests/vitest-test.ts +229 -0
- package/scripts/cli/templates/token-templates.js +337 -1
- package/scripts/cli/templates/tokens/token-generators.ts +1088 -0
- package/scripts/cli/templates/types/component-types.ts +145 -0
- package/scripts/cli/templates/utils/testing-utils.ts +144 -0
- package/scripts/cli/templates/vanilla-templates.js +39 -0
- package/scripts/cli/token-manager.js +8 -2
- package/scripts/cli/utils/cache-manager.js +240 -0
- package/scripts/cli/utils/detector.js +46 -0
- package/scripts/cli/utils/diagnostics.js +289 -0
- package/scripts/cli/utils/error.js +89 -0
- package/scripts/cli/utils/helpers.js +67 -0
- package/scripts/cli/utils/logger.js +75 -0
- package/scripts/cli/utils/security.js +302 -0
- package/scripts/cli/utils/telemetry.js +115 -0
- package/scripts/cli/utils/validation.js +37 -0
- package/scripts/cli/utils.js +28 -341
- package/src/components/Accordion/Accordion.stories.tsx +0 -18
- package/src/components/Accordion/Accordion.test.tsx +0 -17
- package/src/components/Accordion/Accordion.tsx +0 -4
- package/src/components/AtomixGlass/AtomixGlass.test.tsx +37 -3
- package/src/components/AtomixGlass/AtomixGlass.tsx +143 -31
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +129 -31
- package/src/components/AtomixGlass/PerformanceDashboard.tsx +219 -0
- package/src/components/AtomixGlass/README.md +25 -10
- package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +216 -0
- package/src/components/AtomixGlass/animation-system.ts +578 -0
- package/src/components/AtomixGlass/shader-utils.ts +4 -1
- package/src/components/AtomixGlass/stories/Overview.stories.tsx +157 -6
- package/src/components/AtomixGlass/stories/Phase1-Animation.stories.tsx +653 -0
- package/src/components/AtomixGlass/stories/Phase1-Test.stories.tsx +95 -0
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +51 -51
- package/src/components/AtomixGlass/stories/shared-components.tsx +6 -0
- package/src/components/Avatar/Avatar.tsx +1 -1
- package/src/components/Button/Button.stories.disabled-link.tsx +10 -0
- package/src/components/Button/Button.stories.tsx +10 -0
- package/src/components/Button/Button.test.tsx +16 -11
- package/src/components/Button/Button.tsx +4 -4
- package/src/components/Card/Card.tsx +1 -1
- package/src/components/Dropdown/Dropdown.tsx +12 -12
- package/src/components/Form/Select.tsx +62 -3
- package/src/components/Modal/Modal.tsx +14 -3
- package/src/components/Navigation/Navbar/Navbar.tsx +44 -0
- package/src/components/Slider/Slider.stories.tsx +3 -3
- package/src/components/Slider/Slider.tsx +38 -0
- package/src/components/Steps/Steps.tsx +3 -3
- package/src/components/Tabs/Tabs.tsx +77 -8
- package/src/components/Testimonial/Testimonial.tsx +1 -1
- package/src/components/TypedButton/TypedButton.stories.tsx +59 -0
- package/src/components/TypedButton/TypedButton.tsx +39 -0
- package/src/components/TypedButton/index.ts +2 -0
- package/src/components/VideoPlayer/VideoPlayer.tsx +11 -4
- package/src/lib/composables/index.ts +4 -7
- package/src/lib/composables/types.ts +45 -0
- package/src/lib/composables/useAccordion.ts +0 -7
- package/src/lib/composables/useAtomixGlass.ts +148 -6
- package/src/lib/composables/useAtomixGlassStyles.ts +9 -7
- package/src/lib/composables/useChartExport.ts +3 -13
- package/src/lib/composables/useDropdown.ts +66 -0
- package/src/lib/composables/useFocusTrap.ts +80 -0
- package/src/lib/composables/usePerformanceMonitor.ts +448 -0
- package/src/lib/composables/useResponsiveGlass.presets.ts +192 -0
- package/src/lib/composables/useResponsiveGlass.ts +441 -0
- package/src/lib/composables/useTooltip.ts +16 -0
- package/src/lib/composables/useTypedButton.ts +66 -0
- package/src/lib/config/index.ts +62 -5
- package/src/lib/constants/components.ts +62 -7
- package/src/lib/theme/devtools/__tests__/useHistory.test.tsx +150 -0
- package/src/lib/theme/tokens/centralized-tokens.ts +120 -0
- package/src/lib/theme/utils/__tests__/domUtils.test.ts +101 -0
- package/src/lib/types/components.ts +37 -11
- package/src/lib/types/glass.ts +35 -0
- package/src/lib/types/index.ts +1 -0
- package/src/lib/utils/displacement-generator.ts +1 -1
- package/src/styles/01-settings/_settings.testtypecheck.scss +53 -0
- package/src/styles/01-settings/_settings.typedbutton.scss +53 -0
- package/src/styles/06-components/_components.atomix-glass.scss +17 -21
- package/src/styles/06-components/_components.edge-panel.scss +1 -5
- package/src/styles/06-components/_components.modal.scss +1 -4
- package/src/styles/06-components/_components.navbar.scss +1 -1
- package/src/styles/06-components/_components.testbutton.scss +212 -0
- package/src/styles/06-components/_components.testtypecheck.scss +212 -0
- package/src/styles/06-components/_components.tooltip.scss +9 -5
- package/src/styles/06-components/_components.typedbutton.scss +212 -0
- package/src/styles/99-utilities/_index.scss +1 -0
- package/src/styles/99-utilities/_utilities.text.scss +1 -1
- package/src/styles/99-utilities/_utilities.touch-target.scss +36 -0
- package/scripts/cli/component-generator.js +0 -564
- package/scripts/cli/interactive-init.js +0 -357
- package/src/styles/06-components/old.chart.styles.scss +0 -2788
package/dist/charts.js
CHANGED
|
@@ -12,13 +12,13 @@ function getDefaultExportFromCjs(x) {
|
|
|
12
12
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x.default : x;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
var fails$
|
|
15
|
+
var fails$9 = function(exec) {
|
|
16
16
|
try {
|
|
17
17
|
return !!exec();
|
|
18
18
|
} catch (error) {
|
|
19
19
|
return !0;
|
|
20
20
|
}
|
|
21
|
-
}, functionBindNative = !fails$
|
|
21
|
+
}, functionBindNative = !fails$9((function() {
|
|
22
22
|
// eslint-disable-next-line es/no-function-prototype-bind -- safe
|
|
23
23
|
var test = function() {/* empty */}.bind();
|
|
24
24
|
// eslint-disable-next-line no-prototype-builtins -- safe
|
|
@@ -39,18 +39,18 @@ function() {
|
|
|
39
39
|
return this;
|
|
40
40
|
}() || 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() {
|
|
41
41
|
return call$4.apply(apply$1, arguments);
|
|
42
|
-
}), uncurryThis$
|
|
43
|
-
return stringSlice(toString$
|
|
44
|
-
}, classofRaw = classofRaw$
|
|
42
|
+
}), uncurryThis$7 = functionUncurryThis, toString$3 = uncurryThis$7({}.toString), stringSlice = uncurryThis$7("".slice), classofRaw$2 = function(it) {
|
|
43
|
+
return stringSlice(toString$3(it), 8, -1);
|
|
44
|
+
}, classofRaw$1 = classofRaw$2, uncurryThis$6 = functionUncurryThis, functionUncurryThisClause = function(fn) {
|
|
45
45
|
// Nashorn bug:
|
|
46
46
|
// https://github.com/zloirock/core-js/issues/1128
|
|
47
47
|
// https://github.com/zloirock/core-js/issues/1130
|
|
48
|
-
if ("Function" === classofRaw(fn)) return uncurryThis$
|
|
49
|
-
}, documentAll = "object" == typeof document && document.all, isCallable$
|
|
48
|
+
if ("Function" === classofRaw$1(fn)) return uncurryThis$6(fn);
|
|
49
|
+
}, documentAll = "object" == typeof document && document.all, isCallable$8 = void 0 === documentAll && void 0 !== documentAll ? function(argument) {
|
|
50
50
|
return "function" == typeof argument || argument === documentAll;
|
|
51
51
|
} : function(argument) {
|
|
52
52
|
return "function" == typeof argument;
|
|
53
|
-
}, objectGetOwnPropertyDescriptor = {}, descriptors = !fails$
|
|
53
|
+
}, objectGetOwnPropertyDescriptor = {}, descriptors = !fails$9((function() {
|
|
54
54
|
// eslint-disable-next-line es/no-object-defineproperty -- required for testing
|
|
55
55
|
return 7 !== Object.defineProperty({}, 1, {
|
|
56
56
|
get: function() {
|
|
@@ -77,22 +77,24 @@ var match, version, createPropertyDescriptor$2 = function(bitmap, value) {
|
|
|
77
77
|
writable: !(4 & bitmap),
|
|
78
78
|
value: value
|
|
79
79
|
};
|
|
80
|
-
}, fails$
|
|
80
|
+
}, fails$6 = fails$9, classof$4 = classofRaw$2, $Object$3 = Object, split = functionUncurryThis("".split), indexedObject = fails$6((function() {
|
|
81
81
|
// throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
|
|
82
82
|
// eslint-disable-next-line no-prototype-builtins -- safe
|
|
83
|
-
return !$Object$
|
|
83
|
+
return !$Object$3("z").propertyIsEnumerable(0);
|
|
84
84
|
})) ? function(it) {
|
|
85
|
-
return "String" === classof$
|
|
86
|
-
} : $Object$
|
|
85
|
+
return "String" === classof$4(it) ? split(it, "") : $Object$3(it);
|
|
86
|
+
} : $Object$3, isNullOrUndefined$2 = function(it) {
|
|
87
87
|
return null == it;
|
|
88
|
-
}, isNullOrUndefined$1 = isNullOrUndefined$2, $TypeError$
|
|
89
|
-
if (isNullOrUndefined$1(it)) throw new $TypeError$
|
|
88
|
+
}, isNullOrUndefined$1 = isNullOrUndefined$2, $TypeError$7 = TypeError, requireObjectCoercible$3 = function(it) {
|
|
89
|
+
if (isNullOrUndefined$1(it)) throw new $TypeError$7("Can't call method on " + it);
|
|
90
90
|
return it;
|
|
91
|
-
}, IndexedObject$1 = indexedObject, requireObjectCoercible$
|
|
92
|
-
return
|
|
93
|
-
},
|
|
94
|
-
return
|
|
95
|
-
},
|
|
91
|
+
}, IndexedObject$1 = indexedObject, requireObjectCoercible$2 = requireObjectCoercible$3, toIndexedObject$2 = function(it) {
|
|
92
|
+
return IndexedObject$1(requireObjectCoercible$2(it));
|
|
93
|
+
}, isCallable$7 = isCallable$8, isObject$5 = function(it) {
|
|
94
|
+
return "object" == typeof it ? null !== it : isCallable$7(it);
|
|
95
|
+
}, path$3 = {}, path$2 = path$3, globalThis$b = globalThis_1, isCallable$6 = isCallable$8, aFunction = function(variable) {
|
|
96
|
+
return isCallable$6(variable) ? variable : void 0;
|
|
97
|
+
}, navigator$1 = globalThis_1.navigator, userAgent$2 = navigator$1 && navigator$1.userAgent, environmentUserAgent = userAgent$2 ? String(userAgent$2) : "", globalThis$9 = globalThis_1, userAgent$1 = environmentUserAgent, process$1 = globalThis$9.process, Deno$1 = globalThis$9.Deno, versions = process$1 && process$1.versions || Deno$1 && Deno$1.version, v8 = versions && versions.v8;
|
|
96
98
|
|
|
97
99
|
v8 && (
|
|
98
100
|
// in old Chrome, versions of V8 isn't V8 = Chrome / 10
|
|
@@ -102,32 +104,32 @@ version = (match = v8.split("."))[0] > 0 && match[0] < 4 ? 1 : +(match[0] + matc
|
|
|
102
104
|
// so check `userAgent` even if `.v8` exists, but 0
|
|
103
105
|
!version && userAgent$1 && (!(match = userAgent$1.match(/Edge\/(\d+)/)) || match[1] >= 74) && (match = userAgent$1.match(/Chrome\/(\d+)/)) && (version = +match[1]);
|
|
104
106
|
|
|
105
|
-
var environmentV8Version = version, V8_VERSION = environmentV8Version, fails$
|
|
107
|
+
var environmentV8Version = version, V8_VERSION = environmentV8Version, fails$5 = fails$9, $String$3 = globalThis_1.String, symbolConstructorDetection = !!Object.getOwnPropertySymbols && !fails$5((function() {
|
|
106
108
|
var symbol = Symbol("symbol detection");
|
|
107
109
|
// Chrome 38 Symbol has incorrect toString conversion
|
|
108
110
|
// `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances
|
|
109
111
|
// nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will,
|
|
110
112
|
// of course, fail.
|
|
111
|
-
return !$String$
|
|
113
|
+
return !$String$3(symbol) || !(Object(symbol) instanceof Symbol) ||
|
|
112
114
|
// Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances
|
|
113
115
|
!Symbol.sham && V8_VERSION && V8_VERSION < 41;
|
|
114
|
-
})), useSymbolAsUid = symbolConstructorDetection && !Symbol.sham && "symbol" == typeof Symbol.iterator, isCallable$
|
|
116
|
+
})), useSymbolAsUid = symbolConstructorDetection && !Symbol.sham && "symbol" == typeof Symbol.iterator, isCallable$5 = isCallable$8, isPrototypeOf$2 = objectIsPrototypeOf, $Object$2 = Object, isSymbol$2 = useSymbolAsUid ? function(it) {
|
|
115
117
|
return "symbol" == typeof it;
|
|
116
118
|
} : function(it) {
|
|
117
119
|
var $Symbol = function(namespace, method) {
|
|
118
120
|
return arguments.length < 2 ? aFunction(path$2[namespace]) || aFunction(globalThis$b[namespace]) : path$2[namespace] && path$2[namespace][method] || globalThis$b[namespace] && globalThis$b[namespace][method];
|
|
119
121
|
}("Symbol");
|
|
120
|
-
return isCallable$
|
|
121
|
-
}, $String$
|
|
122
|
-
if (isCallable$
|
|
123
|
-
throw new $TypeError$
|
|
122
|
+
return isCallable$5($Symbol) && isPrototypeOf$2($Symbol.prototype, $Object$2(it));
|
|
123
|
+
}, $String$2 = String, isCallable$4 = isCallable$8, $TypeError$6 = TypeError, aCallable$3 = function(argument) {
|
|
124
|
+
if (isCallable$4(argument)) return argument;
|
|
125
|
+
throw new $TypeError$6(function(argument) {
|
|
124
126
|
try {
|
|
125
|
-
return $String$
|
|
127
|
+
return $String$2(argument);
|
|
126
128
|
} catch (error) {
|
|
127
129
|
return "Object";
|
|
128
130
|
}
|
|
129
131
|
}(argument) + " is not a function");
|
|
130
|
-
}, aCallable$2 = aCallable$3, isNullOrUndefined = isNullOrUndefined$2, call$2 = functionCall, isCallable$
|
|
132
|
+
}, aCallable$2 = aCallable$3, isNullOrUndefined = isNullOrUndefined$2, call$2 = functionCall, isCallable$3 = isCallable$8, isObject$4 = isObject$5, $TypeError$5 = TypeError, sharedStore = {
|
|
131
133
|
exports: {}
|
|
132
134
|
}, globalThis$7 = globalThis_1, defineProperty = Object.defineProperty, globalThis$6 = globalThis_1, store$1 = sharedStore.exports = globalThis$6["__core-js_shared__"] || function(key, value) {
|
|
133
135
|
try {
|
|
@@ -150,32 +152,34 @@ var environmentV8Version = version, V8_VERSION = environmentV8Version, fails$4 =
|
|
|
150
152
|
source: "https://github.com/zloirock/core-js"
|
|
151
153
|
});
|
|
152
154
|
|
|
153
|
-
var
|
|
154
|
-
return $Object(requireObjectCoercible(argument));
|
|
155
|
+
var key, value, store = sharedStore.exports, requireObjectCoercible$1 = requireObjectCoercible$3, $Object$1 = Object, toObject$2 = function(argument) {
|
|
156
|
+
return $Object$1(requireObjectCoercible$1(argument));
|
|
155
157
|
}, toObject$1 = toObject$2, hasOwnProperty = functionUncurryThis({}.hasOwnProperty), hasOwnProperty_1 = Object.hasOwn || function(it, key) {
|
|
156
158
|
return hasOwnProperty(toObject$1(it), key);
|
|
157
|
-
}, uncurryThis$
|
|
158
|
-
return "Symbol(" + (void 0 === key ? "" : key) + ")_" + toString(++id + postfix, 36);
|
|
159
|
-
},
|
|
160
|
-
WellKnownSymbolsStore[name]
|
|
161
|
-
|
|
159
|
+
}, 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) {
|
|
160
|
+
return "Symbol(" + (void 0 === key ? "" : key) + ")_" + toString$2(++id + postfix, 36);
|
|
161
|
+
}, wellKnownSymbol$5 = function(name) {
|
|
162
|
+
return hasOwn$2(WellKnownSymbolsStore, name) || (WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn$2(Symbol$1, name) ? Symbol$1[name] : createWellKnownSymbol("Symbol." + name)),
|
|
163
|
+
WellKnownSymbolsStore[name];
|
|
164
|
+
}, call$1 = functionCall, isObject$3 = isObject$5, isSymbol$1 = isSymbol$2, $TypeError$4 = TypeError, TO_PRIMITIVE = wellKnownSymbol$5("toPrimitive"), toPrimitive = function(input, pref) {
|
|
165
|
+
if (!isObject$3(input) || isSymbol$1(input)) return input;
|
|
162
166
|
var result, func, exoticToPrim = (func = input[TO_PRIMITIVE], isNullOrUndefined(func) ? void 0 : aCallable$2(func));
|
|
163
167
|
if (exoticToPrim) {
|
|
164
168
|
if (void 0 === pref && (pref = "default"), result = call$1(exoticToPrim, input, pref),
|
|
165
|
-
!isObject$
|
|
166
|
-
throw new $TypeError$
|
|
169
|
+
!isObject$3(result) || isSymbol$1(result)) return result;
|
|
170
|
+
throw new $TypeError$4("Can't convert object to primitive value");
|
|
167
171
|
}
|
|
168
172
|
return void 0 === pref && (pref = "number"), function(input, pref) {
|
|
169
173
|
var fn, val;
|
|
170
|
-
if ("string" === pref && isCallable$
|
|
171
|
-
if (isCallable$
|
|
172
|
-
if ("string" !== pref && isCallable$
|
|
173
|
-
throw new $TypeError$
|
|
174
|
+
if ("string" === pref && isCallable$3(fn = input.toString) && !isObject$4(val = call$2(fn, input))) return val;
|
|
175
|
+
if (isCallable$3(fn = input.valueOf) && !isObject$4(val = call$2(fn, input))) return val;
|
|
176
|
+
if ("string" !== pref && isCallable$3(fn = input.toString) && !isObject$4(val = call$2(fn, input))) return val;
|
|
177
|
+
throw new $TypeError$5("Can't convert object to primitive value");
|
|
174
178
|
}(input, pref);
|
|
175
179
|
}, isSymbol = isSymbol$2, toPropertyKey$2 = function(argument) {
|
|
176
180
|
var key = toPrimitive(argument, "string");
|
|
177
181
|
return isSymbol(key) ? key : key + "";
|
|
178
|
-
}, isObject$
|
|
182
|
+
}, isObject$2 = isObject$5, document$1 = globalThis_1.document, EXISTS = isObject$2(document$1) && isObject$2(document$1.createElement), ie8DomDefine = !descriptors && !fails$9((function() {
|
|
179
183
|
// eslint-disable-next-line es/no-object-defineproperty -- required for testing
|
|
180
184
|
return 7 !== Object.defineProperty((it = "div", EXISTS ? document$1.createElement(it) : {}), "a", {
|
|
181
185
|
get: function() {
|
|
@@ -183,32 +187,32 @@ WellKnownSymbolsStore[name]), toPrimitive = function(input, pref) {
|
|
|
183
187
|
}
|
|
184
188
|
}).a;
|
|
185
189
|
var it;
|
|
186
|
-
})), DESCRIPTORS$3 = descriptors, call = functionCall, propertyIsEnumerableModule = objectPropertyIsEnumerable, createPropertyDescriptor$1 = createPropertyDescriptor$2, toPropertyKey$1 = toPropertyKey$2, hasOwn$1 = hasOwnProperty_1, IE8_DOM_DEFINE$1 = ie8DomDefine, $getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor;
|
|
190
|
+
})), 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;
|
|
187
191
|
|
|
188
192
|
// `Object.getOwnPropertyDescriptor` method
|
|
189
193
|
// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
|
|
190
194
|
objectGetOwnPropertyDescriptor.f = DESCRIPTORS$3 ? $getOwnPropertyDescriptor$1 : function(O, P) {
|
|
191
|
-
if (O =
|
|
195
|
+
if (O = toIndexedObject$1(O), P = toPropertyKey$1(P), IE8_DOM_DEFINE$1) try {
|
|
192
196
|
return $getOwnPropertyDescriptor$1(O, P);
|
|
193
197
|
} catch (error) {/* empty */}
|
|
194
198
|
if (hasOwn$1(O, P)) return createPropertyDescriptor$1(!call(propertyIsEnumerableModule.f, O, P), O[P]);
|
|
195
199
|
};
|
|
196
200
|
|
|
197
|
-
var fails$
|
|
201
|
+
var fails$3 = fails$9, isCallable$2 = isCallable$8, replacement = /#|\.prototype\./, isForced$1 = function(feature, detection) {
|
|
198
202
|
var value = data[normalize(feature)];
|
|
199
|
-
return value === POLYFILL || value !== NATIVE && (isCallable$
|
|
203
|
+
return value === POLYFILL || value !== NATIVE && (isCallable$2(detection) ? fails$3(detection) : !!detection);
|
|
200
204
|
}, normalize = isForced$1.normalize = function(string) {
|
|
201
205
|
return String(string).replace(replacement, ".").toLowerCase();
|
|
202
|
-
}, data = isForced$1.data = {}, NATIVE = isForced$1.NATIVE = "N", POLYFILL = isForced$1.POLYFILL = "P", isForced_1 = isForced$1, aCallable$1 = aCallable$3, NATIVE_BIND = functionBindNative, bind$1 = functionUncurryThisClause(functionUncurryThisClause.bind), objectDefineProperty = {}, v8PrototypeDefineBug = descriptors && fails$
|
|
206
|
+
}, data = isForced$1.data = {}, NATIVE = isForced$1.NATIVE = "N", POLYFILL = isForced$1.POLYFILL = "P", isForced_1 = isForced$1, aCallable$1 = aCallable$3, NATIVE_BIND = functionBindNative, bind$1 = functionUncurryThisClause(functionUncurryThisClause.bind), objectDefineProperty = {}, v8PrototypeDefineBug = descriptors && fails$9((function() {
|
|
203
207
|
// eslint-disable-next-line es/no-object-defineproperty -- required for testing
|
|
204
208
|
return 42 !== Object.defineProperty((function() {/* empty */}), "prototype", {
|
|
205
209
|
value: 42,
|
|
206
210
|
writable: !1
|
|
207
211
|
}).prototype;
|
|
208
|
-
})), isObject = isObject$
|
|
209
|
-
if (isObject(argument)) return argument;
|
|
210
|
-
throw new $TypeError$
|
|
211
|
-
}, toPropertyKey = toPropertyKey$2, $TypeError$
|
|
212
|
+
})), isObject$1 = isObject$5, $String$1 = String, $TypeError$3 = TypeError, DESCRIPTORS$1 = descriptors, IE8_DOM_DEFINE = ie8DomDefine, V8_PROTOTYPE_DEFINE_BUG = v8PrototypeDefineBug, anObject = function(argument) {
|
|
213
|
+
if (isObject$1(argument)) return argument;
|
|
214
|
+
throw new $TypeError$3($String$1(argument) + " is not an object");
|
|
215
|
+
}, toPropertyKey = toPropertyKey$2, $TypeError$2 = TypeError, $defineProperty = Object.defineProperty, $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
|
|
212
216
|
|
|
213
217
|
// `Object.defineProperty` method
|
|
214
218
|
// https://tc39.es/ecma262/#sec-object.defineproperty
|
|
@@ -226,7 +230,7 @@ objectDefineProperty.f = DESCRIPTORS$1 ? V8_PROTOTYPE_DEFINE_BUG ? function(O, P
|
|
|
226
230
|
if (anObject(O), P = toPropertyKey(P), anObject(Attributes), IE8_DOM_DEFINE) try {
|
|
227
231
|
return $defineProperty(O, P, Attributes);
|
|
228
232
|
} catch (error) {/* empty */}
|
|
229
|
-
if ("get" in Attributes || "set" in Attributes) throw new $TypeError$
|
|
233
|
+
if ("get" in Attributes || "set" in Attributes) throw new $TypeError$2("Accessors not supported");
|
|
230
234
|
return "value" in Attributes && (O[P] = Attributes.value), O;
|
|
231
235
|
};
|
|
232
236
|
|
|
@@ -234,7 +238,7 @@ var definePropertyModule = objectDefineProperty, createPropertyDescriptor = crea
|
|
|
234
238
|
return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));
|
|
235
239
|
} : function(object, key, value) {
|
|
236
240
|
return object[key] = value, object;
|
|
237
|
-
}, globalThis$3 = globalThis_1, apply = functionApply, uncurryThis = functionUncurryThisClause, isCallable = isCallable$
|
|
241
|
+
}, globalThis$3 = 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) {
|
|
238
242
|
return aCallable$1(fn), void 0 === that ? fn : NATIVE_BIND ? bind$1(fn, that) : function() {
|
|
239
243
|
return fn.apply(that, arguments);
|
|
240
244
|
};
|
|
@@ -256,28 +260,44 @@ var definePropertyModule = objectDefineProperty, createPropertyDescriptor = crea
|
|
|
256
260
|
return apply(NativeConstructor, this, arguments);
|
|
257
261
|
};
|
|
258
262
|
return Wrapper.prototype = NativeConstructor.prototype, Wrapper;
|
|
263
|
+
}, _export = function(options, source) {
|
|
264
|
+
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$3 : STATIC ? globalThis$3[TARGET] : globalThis$3[TARGET] && globalThis$3[TARGET].prototype, target = GLOBAL ? path$1 : path$1[TARGET] || createNonEnumerableProperty(path$1, TARGET, {})[TARGET], targetPrototype = target.prototype;
|
|
265
|
+
for (key in source)
|
|
266
|
+
// contains in native
|
|
267
|
+
USE_NATIVE = !(FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? "." : "#") + key, options.forced)) && nativeSource && hasOwn(nativeSource, key),
|
|
268
|
+
targetProperty = target[key], USE_NATIVE && (nativeProperty = options.dontCallGetSet ? (descriptor = getOwnPropertyDescriptor(nativeSource, key)) && descriptor.value : nativeSource[key]),
|
|
269
|
+
// export native or implementation
|
|
270
|
+
sourceProperty = USE_NATIVE && nativeProperty ? nativeProperty : source[key], (FORCED || PROTO || typeof targetProperty != typeof sourceProperty) && (
|
|
271
|
+
// bind methods to global for calling from export context
|
|
272
|
+
resultProperty = options.bind && USE_NATIVE ? bind(sourceProperty, globalThis$3) : options.wrap && USE_NATIVE ? wrapConstructor(sourceProperty) : PROTO && isCallable$1(sourceProperty) ? uncurryThis$1(sourceProperty) : sourceProperty,
|
|
273
|
+
// add a flag to not completely full polyfills
|
|
274
|
+
(options.sham || sourceProperty && sourceProperty.sham || targetProperty && targetProperty.sham) && createNonEnumerableProperty(resultProperty, "sham", !0),
|
|
275
|
+
createNonEnumerableProperty(target, key, resultProperty), PROTO && (hasOwn(path$1, VIRTUAL_PROTOTYPE = TARGET + "Prototype") || createNonEnumerableProperty(path$1, VIRTUAL_PROTOTYPE, {}),
|
|
276
|
+
// export virtual prototype methods
|
|
277
|
+
createNonEnumerableProperty(path$1[VIRTUAL_PROTOTYPE], key, sourceProperty),
|
|
278
|
+
// export real prototype methods
|
|
279
|
+
options.real && targetPrototype && (FORCED || !targetPrototype[key]) && createNonEnumerableProperty(targetPrototype, key, sourceProperty)));
|
|
259
280
|
}, ceil = Math.ceil, floor = Math.floor, trunc = Math.trunc || function(x) {
|
|
260
281
|
var n = +x;
|
|
261
282
|
return (n > 0 ? floor : ceil)(n);
|
|
262
|
-
},
|
|
263
|
-
var
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
}, aCallable = aCallable$3, toObject = toObject$2, IndexedObject = indexedObject, $TypeError = TypeError, REDUCE_EMPTY = "Reduce of empty array with no initial value", createMethod = function(IS_RIGHT) {
|
|
283
|
+
}, toIntegerOrInfinity$2 = function(argument) {
|
|
284
|
+
var number = +argument;
|
|
285
|
+
// eslint-disable-next-line no-self-compare -- NaN check
|
|
286
|
+
return number != number || 0 === number ? 0 : trunc(number);
|
|
287
|
+
}, toIntegerOrInfinity$1 = toIntegerOrInfinity$2, min$1 = Math.min, lengthOfArrayLike$2 = function(obj) {
|
|
288
|
+
return argument = obj.length, (len = toIntegerOrInfinity$1(argument)) > 0 ? min$1(len, 9007199254740991) : 0;
|
|
289
|
+
var argument, len;
|
|
290
|
+
}, aCallable = aCallable$3, toObject = toObject$2, IndexedObject = indexedObject, lengthOfArrayLike$1 = lengthOfArrayLike$2, $TypeError$1 = TypeError, REDUCE_EMPTY = "Reduce of empty array with no initial value", createMethod$1 = function(IS_RIGHT) {
|
|
271
291
|
return function(that, callbackfn, argumentsLength, memo) {
|
|
272
|
-
var O = toObject(that), self = IndexedObject(O), length =
|
|
273
|
-
if (aCallable(callbackfn), 0 === length && argumentsLength < 2) throw new $TypeError(REDUCE_EMPTY);
|
|
292
|
+
var O = toObject(that), self = IndexedObject(O), length = lengthOfArrayLike$1(O);
|
|
293
|
+
if (aCallable(callbackfn), 0 === length && argumentsLength < 2) throw new $TypeError$1(REDUCE_EMPTY);
|
|
274
294
|
var index = IS_RIGHT ? length - 1 : 0, i = IS_RIGHT ? -1 : 1;
|
|
275
295
|
if (argumentsLength < 2) for (;;) {
|
|
276
296
|
if (index in self) {
|
|
277
297
|
memo = self[index], index += i;
|
|
278
298
|
break;
|
|
279
299
|
}
|
|
280
|
-
if (index += i, IS_RIGHT ? index < 0 : length <= index) throw new $TypeError(REDUCE_EMPTY);
|
|
300
|
+
if (index += i, IS_RIGHT ? index < 0 : length <= index) throw new $TypeError$1(REDUCE_EMPTY);
|
|
281
301
|
}
|
|
282
302
|
for (;IS_RIGHT ? index >= 0 : length > index; index += i) index in self && (memo = callbackfn(memo, self[index], index, O));
|
|
283
303
|
return memo;
|
|
@@ -285,39 +305,22 @@ var definePropertyModule = objectDefineProperty, createPropertyDescriptor = crea
|
|
|
285
305
|
}, arrayReduce = {
|
|
286
306
|
// `Array.prototype.reduce` method
|
|
287
307
|
// https://tc39.es/ecma262/#sec-array.prototype.reduce
|
|
288
|
-
left: createMethod(!1),
|
|
308
|
+
left: createMethod$1(!1),
|
|
289
309
|
// `Array.prototype.reduceRight` method
|
|
290
310
|
// https://tc39.es/ecma262/#sec-array.prototype.reduceright
|
|
291
|
-
right: createMethod(!0)
|
|
292
|
-
}, fails = fails$
|
|
311
|
+
right: createMethod$1(!0)
|
|
312
|
+
}, fails$1 = fails$9, globalThis$2 = globalThis_1, userAgent = environmentUserAgent, classof$3 = classofRaw$2, userAgentStartsWith = function(string) {
|
|
293
313
|
return userAgent.slice(0, string.length) === string;
|
|
294
|
-
}, environment = userAgentStartsWith("Bun/") ? "BUN" : userAgentStartsWith("Cloudflare-Workers") ? "CLOUDFLARE" : userAgentStartsWith("Deno/") ? "DENO" : userAgentStartsWith("Node.js/") ? "NODE" : globalThis$2.Bun && "string" == typeof Bun.version ? "BUN" : globalThis$2.Deno && "object" == typeof Deno.version ? "DENO" : "process" === classof(globalThis$2.process) ? "NODE" : globalThis$2.window && globalThis$2.document ? "BROWSER" : "REST", $reduce = arrayReduce.left;
|
|
314
|
+
}, environment = userAgentStartsWith("Bun/") ? "BUN" : userAgentStartsWith("Cloudflare-Workers") ? "CLOUDFLARE" : userAgentStartsWith("Deno/") ? "DENO" : userAgentStartsWith("Node.js/") ? "NODE" : globalThis$2.Bun && "string" == typeof Bun.version ? "BUN" : globalThis$2.Deno && "object" == typeof Deno.version ? "DENO" : "process" === classof$3(globalThis$2.process) ? "NODE" : globalThis$2.window && globalThis$2.document ? "BROWSER" : "REST", $reduce = arrayReduce.left;
|
|
295
315
|
|
|
296
316
|
// `Array.prototype.reduce` method
|
|
297
317
|
// https://tc39.es/ecma262/#sec-array.prototype.reduce
|
|
298
|
-
|
|
299
|
-
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$3 : STATIC ? globalThis$3[TARGET] : globalThis$3[TARGET] && globalThis$3[TARGET].prototype, target = GLOBAL ? path$1 : path$1[TARGET] || createNonEnumerableProperty(path$1, TARGET, {})[TARGET], targetPrototype = target.prototype;
|
|
300
|
-
for (key in source)
|
|
301
|
-
// contains in native
|
|
302
|
-
USE_NATIVE = !(FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? "." : "#") + key, options.forced)) && nativeSource && hasOwn(nativeSource, key),
|
|
303
|
-
targetProperty = target[key], USE_NATIVE && (nativeProperty = options.dontCallGetSet ? (descriptor = getOwnPropertyDescriptor(nativeSource, key)) && descriptor.value : nativeSource[key]),
|
|
304
|
-
// export native or implementation
|
|
305
|
-
sourceProperty = USE_NATIVE && nativeProperty ? nativeProperty : source[key], (FORCED || PROTO || typeof targetProperty != typeof sourceProperty) && (
|
|
306
|
-
// bind methods to global for calling from export context
|
|
307
|
-
resultProperty = options.bind && USE_NATIVE ? bind(sourceProperty, globalThis$3) : options.wrap && USE_NATIVE ? wrapConstructor(sourceProperty) : PROTO && isCallable(sourceProperty) ? uncurryThis(sourceProperty) : sourceProperty,
|
|
308
|
-
// add a flag to not completely full polyfills
|
|
309
|
-
(options.sham || sourceProperty && sourceProperty.sham || targetProperty && targetProperty.sham) && createNonEnumerableProperty(resultProperty, "sham", !0),
|
|
310
|
-
createNonEnumerableProperty(target, key, resultProperty), PROTO && (hasOwn(path$1, VIRTUAL_PROTOTYPE = TARGET + "Prototype") || createNonEnumerableProperty(path$1, VIRTUAL_PROTOTYPE, {}),
|
|
311
|
-
// export virtual prototype methods
|
|
312
|
-
createNonEnumerableProperty(path$1[VIRTUAL_PROTOTYPE], key, sourceProperty),
|
|
313
|
-
// export real prototype methods
|
|
314
|
-
options.real && targetPrototype && (FORCED || !targetPrototype[key]) && createNonEnumerableProperty(targetPrototype, key, sourceProperty)));
|
|
315
|
-
}({
|
|
318
|
+
_export({
|
|
316
319
|
target: "Array",
|
|
317
320
|
proto: !0,
|
|
318
321
|
forced: !("NODE" === environment) && environmentV8Version > 79 && environmentV8Version < 83 || !function(METHOD_NAME, argument) {
|
|
319
322
|
var method = [][METHOD_NAME];
|
|
320
|
-
return !!method && fails((function() {
|
|
323
|
+
return !!method && fails$1((function() {
|
|
321
324
|
// eslint-disable-next-line no-useless-call -- required for testing
|
|
322
325
|
method.call(null, argument || function() {
|
|
323
326
|
return 1;
|
|
@@ -331,16 +334,16 @@ var definePropertyModule = objectDefineProperty, createPropertyDescriptor = crea
|
|
|
331
334
|
}
|
|
332
335
|
});
|
|
333
336
|
|
|
334
|
-
var globalThis$1 = globalThis_1, path = path$3,
|
|
335
|
-
var Namespace = path
|
|
337
|
+
var globalThis$1 = globalThis_1, path = path$3, getBuiltInPrototypeMethod$3 = function(CONSTRUCTOR, METHOD) {
|
|
338
|
+
var Namespace = path[CONSTRUCTOR + "Prototype"], pureMethod = Namespace && Namespace[METHOD];
|
|
336
339
|
if (pureMethod) return pureMethod;
|
|
337
|
-
var NativeConstructor = globalThis$1
|
|
338
|
-
return NativePrototype && NativePrototype
|
|
339
|
-
}(), isPrototypeOf = objectIsPrototypeOf, method = reduce$3, ArrayPrototype = Array.prototype;
|
|
340
|
+
var NativeConstructor = globalThis$1[CONSTRUCTOR], NativePrototype = NativeConstructor && NativeConstructor.prototype;
|
|
341
|
+
return NativePrototype && NativePrototype[METHOD];
|
|
342
|
+
}, reduce$3 = getBuiltInPrototypeMethod$3("Array", "reduce"), isPrototypeOf$1 = objectIsPrototypeOf, method = reduce$3, ArrayPrototype$1 = Array.prototype;
|
|
340
343
|
|
|
341
344
|
const _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
342
345
|
var own = it.reduce;
|
|
343
|
-
return it === ArrayPrototype || isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.reduce ? method : own;
|
|
346
|
+
return it === ArrayPrototype$1 || isPrototypeOf$1(ArrayPrototype$1, it) && own === ArrayPrototype$1.reduce ? method : own;
|
|
344
347
|
})), CHART = {
|
|
345
348
|
BASE_CLASS: "c-chart",
|
|
346
349
|
ROOT_CLASS: "c-chart",
|
|
@@ -497,20 +500,29 @@ const _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
497
500
|
SHADER: "c-atomix-glass--shader"
|
|
498
501
|
},
|
|
499
502
|
DEFAULTS: {
|
|
500
|
-
DISPLACEMENT_SCALE:
|
|
501
|
-
BLUR_AMOUNT:
|
|
503
|
+
DISPLACEMENT_SCALE: 70,
|
|
504
|
+
BLUR_AMOUNT: 0,
|
|
502
505
|
SATURATION: 140,
|
|
503
|
-
ABERRATION_INTENSITY: 2
|
|
504
|
-
ELASTICITY: .
|
|
505
|
-
CORNER_RADIUS:
|
|
506
|
+
ABERRATION_INTENSITY: 2,
|
|
507
|
+
ELASTICITY: .15,
|
|
508
|
+
CORNER_RADIUS: 20,
|
|
506
509
|
// Default border-radius matching design system
|
|
507
|
-
PADDING: "0
|
|
510
|
+
PADDING: "0",
|
|
508
511
|
MODE: "standard",
|
|
509
512
|
OVER_LIGHT: !1,
|
|
510
|
-
ENABLE_OVER_LIGHT_LAYERS: !0
|
|
513
|
+
ENABLE_OVER_LIGHT_LAYERS: !0,
|
|
514
|
+
// Phase 1: Time-Based Animation System defaults
|
|
515
|
+
WITH_TIME_ANIMATION: !0,
|
|
516
|
+
ANIMATION_SPEED: 1,
|
|
517
|
+
// Phase 1: Multi-Layer Distortion System defaults
|
|
518
|
+
WITH_MULTI_LAYER_DISTORTION: !1,
|
|
519
|
+
DISTORTION_OCTAVES: 5,
|
|
520
|
+
DISTORTION_LACUNARITY: 2,
|
|
521
|
+
DISTORTION_GAIN: .5,
|
|
522
|
+
DISTORTION_QUALITY: "high"
|
|
511
523
|
},
|
|
512
524
|
CONSTANTS: {
|
|
513
|
-
ACTIVATION_ZONE:
|
|
525
|
+
ACTIVATION_ZONE: 200,
|
|
514
526
|
LERP_FACTOR: .08,
|
|
515
527
|
SMOOTHSTEP_POWER: 2.5,
|
|
516
528
|
MIN_BLUR: .1,
|
|
@@ -670,6 +682,44 @@ const _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
670
682
|
// Saturation constants
|
|
671
683
|
SATURATION: {
|
|
672
684
|
HIGH_CONTRAST: 200
|
|
685
|
+
},
|
|
686
|
+
// Phase 1: Animation System Constants
|
|
687
|
+
ANIMATION: {
|
|
688
|
+
// Breathing effect timing (in milliseconds)
|
|
689
|
+
BREATHING_CYCLE: 2e3,
|
|
690
|
+
// 2-second breathing cycle
|
|
691
|
+
// Flow animation speed
|
|
692
|
+
FLOW_SPEED_X: .1,
|
|
693
|
+
// Horizontal flow speed
|
|
694
|
+
FLOW_SPEED_Y: .15,
|
|
695
|
+
// Vertical flow speed
|
|
696
|
+
// Wave propagation
|
|
697
|
+
WAVE_SPEED: .05,
|
|
698
|
+
// Radial wave speed
|
|
699
|
+
WAVE_AMPLITUDE: .02
|
|
700
|
+
},
|
|
701
|
+
// Phase 1: Multi-Layer Distortion Quality Presets
|
|
702
|
+
DISTORTION_QUALITY_PRESETS: {
|
|
703
|
+
low: {
|
|
704
|
+
octaves: 2,
|
|
705
|
+
lacunarity: 2,
|
|
706
|
+
gain: .5
|
|
707
|
+
},
|
|
708
|
+
medium: {
|
|
709
|
+
octaves: 4,
|
|
710
|
+
lacunarity: 2,
|
|
711
|
+
gain: .5
|
|
712
|
+
},
|
|
713
|
+
high: {
|
|
714
|
+
octaves: 5,
|
|
715
|
+
lacunarity: 2,
|
|
716
|
+
gain: .5
|
|
717
|
+
},
|
|
718
|
+
ultra: {
|
|
719
|
+
octaves: 7,
|
|
720
|
+
lacunarity: 2,
|
|
721
|
+
gain: .5
|
|
722
|
+
}
|
|
673
723
|
}
|
|
674
724
|
}
|
|
675
725
|
};
|
|
@@ -1602,7 +1652,7 @@ const {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
|
|
|
1602
1652
|
// Silently handle errors
|
|
1603
1653
|
}
|
|
1604
1654
|
return CONSTANTS$2.DEFAULT_CORNER_RADIUS;
|
|
1605
|
-
}, lerp = (a, b, t) => a + (b - a) * t, softClamp = (value, max) => max <= 0 ? 0 : max * (1 - Math.exp(-value / max)), getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
|
|
1655
|
+
}, lerp$1 = (a, b, t) => a + (b - a) * t, softClamp = (value, max) => max <= 0 ? 0 : max * (1 - Math.exp(-value / max)), getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
|
|
1606
1656
|
switch (mode) {
|
|
1607
1657
|
case "standard":
|
|
1608
1658
|
return displacementMap;
|
|
@@ -1769,20 +1819,19 @@ let idCounter = 0;
|
|
|
1769
1819
|
const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({children: children, className: className = "", style: style, displacementScale: displacementScale = 25, blurAmount: blurAmount = .0625, saturation: saturation = 180, aberrationIntensity: aberrationIntensity = 2, mouseOffset: mouseOffset = {
|
|
1770
1820
|
x: 0,
|
|
1771
1821
|
y: 0
|
|
1772
|
-
},
|
|
1773
|
-
x: 0,
|
|
1774
|
-
y: 0
|
|
1775
|
-
}, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, isHovered: isHovered = !1, isActive: isActive = !1, overLight: overLight = !1, overLightConfig: overLightConfig = {}, borderRadius: borderRadius = 0, padding: padding = "0 0", glassSize: glassSize = {
|
|
1822
|
+
}, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, isActive: isActive = !1, overLight: overLight = !1, overLightConfig: overLightConfig = {}, borderRadius: borderRadius = 0, padding: padding = "0 0", glassSize: glassSize = {
|
|
1776
1823
|
width: 0,
|
|
1777
1824
|
height: 0
|
|
1778
|
-
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1,
|
|
1825
|
+
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1,
|
|
1826
|
+
// Phase 1: Animation System props
|
|
1827
|
+
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) => {
|
|
1779
1828
|
// Generate a stable, deterministic ID for SSR compatibility
|
|
1780
1829
|
// Use a module-level counter that's consistent across server and client
|
|
1781
|
-
const filterId = useMemo((() => "atomix-glass-filter-" + ++idCounter), []), [shaderMapUrl, setShaderMapUrl] = useState(""), shaderGeneratorRef = useRef(null), shaderUtilsRef = useRef(null), shaderDebounceTimeoutRef = useRef(null);
|
|
1830
|
+
const filterId = useMemo((() => "atomix-glass-filter-" + ++idCounter), []), [shaderMapUrl, setShaderMapUrl] = useState(""), shaderGeneratorRef = useRef(null), shaderUtilsRef = useRef(null), shaderDebounceTimeoutRef = useRef(null), shaderUpdateTimeoutRef = useRef(null), animationFrameRef = useRef(null);
|
|
1782
1831
|
// Lazy load shader utilities only when shader mode is needed
|
|
1783
1832
|
useEffect((() => {
|
|
1784
1833
|
"shader" === mode ?
|
|
1785
|
-
// Dynamic import shader utilities
|
|
1834
|
+
// Dynamic import shader utilities with animation support
|
|
1786
1835
|
Promise.resolve().then((() => shaderUtils)).then((shaderUtils => {
|
|
1787
1836
|
shaderUtilsRef.current = {
|
|
1788
1837
|
ShaderDisplacementGenerator: shaderUtils.ShaderDisplacementGenerator,
|
|
@@ -1797,7 +1846,7 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
|
|
|
1797
1846
|
// Generate shader map with debouncing and caching
|
|
1798
1847
|
useEffect((() => {
|
|
1799
1848
|
// Enhanced validation for shader mode
|
|
1800
|
-
if ("shader" === mode && glassSize && validateGlassSize(glassSize)
|
|
1849
|
+
if ("shader" === mode && glassSize && validateGlassSize(glassSize)) {
|
|
1801
1850
|
// Create cache key from size and variant
|
|
1802
1851
|
const cacheKey = `${glassSize.width}x${glassSize.height}-${shaderVariant}`, cachedUrl = (key => {
|
|
1803
1852
|
const entry = sharedShaderCache.get(key);
|
|
@@ -1819,11 +1868,9 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
|
|
|
1819
1868
|
width: glassSize.width,
|
|
1820
1869
|
height: glassSize.height,
|
|
1821
1870
|
fragment: selectedShader
|
|
1822
|
-
}),
|
|
1823
|
-
// Defer shader generation with longer delay to avoid blocking
|
|
1824
|
-
setTimeout((() => {
|
|
1871
|
+
}), shaderUpdateTimeoutRef.current = setTimeout((() => {
|
|
1825
1872
|
const url = shaderGeneratorRef.current?.updateShader() || "";
|
|
1826
|
-
((key, url) => {
|
|
1873
|
+
url && ((key, url) => {
|
|
1827
1874
|
// Evict oldest entries if at capacity
|
|
1828
1875
|
if (sharedShaderCache.size >= 15) {
|
|
1829
1876
|
const entries = Array.from(sharedShaderCache.entries());
|
|
@@ -1855,7 +1902,8 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
|
|
|
1855
1902
|
// Cleanup function with error handling
|
|
1856
1903
|
return () => {
|
|
1857
1904
|
shaderDebounceTimeoutRef.current && (clearTimeout(shaderDebounceTimeoutRef.current),
|
|
1858
|
-
shaderDebounceTimeoutRef.current = null)
|
|
1905
|
+
shaderDebounceTimeoutRef.current = null), shaderUpdateTimeoutRef.current && (clearTimeout(shaderUpdateTimeoutRef.current),
|
|
1906
|
+
shaderUpdateTimeoutRef.current = null);
|
|
1859
1907
|
try {
|
|
1860
1908
|
shaderGeneratorRef.current?.destroy();
|
|
1861
1909
|
} catch (error) {
|
|
@@ -1864,7 +1912,37 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
|
|
|
1864
1912
|
shaderGeneratorRef.current = null;
|
|
1865
1913
|
}
|
|
1866
1914
|
};
|
|
1867
|
-
}), [ mode, glassSize, shaderVariant ])
|
|
1915
|
+
}), [ mode, glassSize, shaderVariant ]),
|
|
1916
|
+
// Phase 1: Time-Based Animation Loop - Continuous shader regeneration
|
|
1917
|
+
useEffect((() => {
|
|
1918
|
+
// Only run animations in shader mode with time animation enabled
|
|
1919
|
+
if ("shader" !== mode || !withTimeAnimation || effectiveReducedMotion || effectiveWithoutEffects)
|
|
1920
|
+
// Cancel any existing animation frame
|
|
1921
|
+
return void (null !== animationFrameRef.current && (cancelAnimationFrame(animationFrameRef.current),
|
|
1922
|
+
animationFrameRef.current = null));
|
|
1923
|
+
const baseFps = "ultra" === distortionQuality ? 60 : "high" === distortionQuality ? 30 : "medium" === distortionQuality ? 24 : 20, effectiveSpeed = Math.max(.5, Math.min(2, animationSpeed || 1)), complexity = withMultiLayerDistortion ? Math.max(1, (distortionOctaves || 3) / 3 + .25 * Math.max(0, (distortionLacunarity || 2) - 2) + Math.max(0, (distortionGain || .5) - .5)) : 1, frameInterval = 1e3 / Math.max(12, Math.min(60, Math.round(baseFps * effectiveSpeed / complexity)));
|
|
1924
|
+
let lastUpdate = 0, isCancelled = !1;
|
|
1925
|
+
const animate = currentTime => {
|
|
1926
|
+
if (!isCancelled) {
|
|
1927
|
+
if (currentTime - lastUpdate >= frameInterval && shaderGeneratorRef.current) {
|
|
1928
|
+
lastUpdate = currentTime;
|
|
1929
|
+
try {
|
|
1930
|
+
const animatedShaderUrl = shaderGeneratorRef.current.updateShader();
|
|
1931
|
+
animatedShaderUrl && setShaderMapUrl(animatedShaderUrl);
|
|
1932
|
+
} catch (error) {
|
|
1933
|
+
console.warn("AtomixGlassContainer: Error in animation loop", error);
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
animationFrameRef.current = requestAnimationFrame(animate);
|
|
1937
|
+
}
|
|
1938
|
+
};
|
|
1939
|
+
// Start animation loop
|
|
1940
|
+
// Cleanup animation on unmount or dependency change
|
|
1941
|
+
return animationFrameRef.current = requestAnimationFrame(animate), () => {
|
|
1942
|
+
isCancelled = !0, null !== animationFrameRef.current && (cancelAnimationFrame(animationFrameRef.current),
|
|
1943
|
+
animationFrameRef.current = null);
|
|
1944
|
+
};
|
|
1945
|
+
}), [ mode, withTimeAnimation, animationSpeed, displacementScale, withMultiLayerDistortion, distortionOctaves, distortionLacunarity, distortionGain, distortionQuality, effectiveReducedMotion, effectiveWithoutEffects, glassSize ]);
|
|
1868
1946
|
// Removed forced reflow to avoid layout thrash and potential feedback sizing loops
|
|
1869
1947
|
const [rectCache, setRectCache] = useState(null);
|
|
1870
1948
|
useEffect((() => {
|
|
@@ -1916,21 +1994,18 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
|
|
|
1916
1994
|
backdropFilter: `blur(${blurAmount}px) saturate(${saturation}%) contrast(1.05) brightness(1.05)`
|
|
1917
1995
|
};
|
|
1918
1996
|
}
|
|
1919
|
-
}), [ liquidBlur, saturation, blurAmount, rectCache, effectiveReducedMotion, effectiveWithoutEffects, withLiquidBlur ]), containerVars = useMemo((() => {
|
|
1997
|
+
}), [ liquidBlur, saturation, blurAmount, rectCache, effectiveReducedMotion, effectiveWithoutEffects, withLiquidBlur, overLightConfig ]), containerVars = useMemo((() => {
|
|
1920
1998
|
try {
|
|
1921
1999
|
// Safe extraction of mouse offset values
|
|
1922
2000
|
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;
|
|
1923
2001
|
return {
|
|
1924
|
-
"--atomix-glass-container-width": `${glassSize?.width}`,
|
|
1925
|
-
"--atomix-glass-container-height": `${glassSize?.height}`,
|
|
1926
|
-
"--atomix-glass-container-padding": padding || "0 0",
|
|
1927
2002
|
"--atomix-glass-container-radius": `${"number" != typeof borderRadius || isNaN(borderRadius) ? 0 : borderRadius}px`,
|
|
1928
2003
|
"--atomix-glass-container-backdrop": backdropStyle?.backdropFilter || "none",
|
|
1929
2004
|
"--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",
|
|
1930
2005
|
"--atomix-glass-container-shadow-opacity": effectiveWithoutEffects ? 0 : 1,
|
|
1931
2006
|
// Background and shadow values use design token-aligned RGB values
|
|
1932
2007
|
"--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",
|
|
1933
|
-
"--atomix-glass-container-text-shadow": overLight ? "0px 2px
|
|
2008
|
+
"--atomix-glass-container-text-shadow": overLight ? "0px 1px 2px rgba(255, 255, 255, 0.15)" : "0px 2px 12px rgba(0, 0, 0, 0.4)",
|
|
1934
2009
|
"--atomix-glass-container-box-shadow": overLight ? "0px 16px 70px rgba(0, 0, 0, 0.75)" : "0px 12px 40px rgba(0, 0, 0, 0.25)"
|
|
1935
2010
|
};
|
|
1936
2011
|
} catch (error) {
|
|
@@ -1945,7 +2020,7 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
|
|
|
1945
2020
|
"--atomix-glass-container-text-shadow": "none"
|
|
1946
2021
|
};
|
|
1947
2022
|
}
|
|
1948
|
-
}), [
|
|
2023
|
+
}), [ borderRadius, backdropStyle, mouseOffset, overLight, effectiveWithoutEffects, overLightConfig ]);
|
|
1949
2024
|
return jsx("div", {
|
|
1950
2025
|
ref: el => {
|
|
1951
2026
|
// Apply force no-transition
|
|
@@ -1974,10 +2049,6 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
|
|
|
1974
2049
|
aberrationIntensity: "number" != typeof aberrationIntensity || isNaN(aberrationIntensity) ? 0 : aberrationIntensity,
|
|
1975
2050
|
shaderMapUrl: shaderMapUrl
|
|
1976
2051
|
}), jsx("div", {
|
|
1977
|
-
ref: el => {
|
|
1978
|
-
el && (el.style.setProperty("transition-duration", "0s", "important"), el.style.setProperty("animation-duration", "0s", "important"),
|
|
1979
|
-
el.style.setProperty("transition-delay", "0s", "important"));
|
|
1980
|
-
},
|
|
1981
2052
|
className: ATOMIX_GLASS.FILTER_OVERLAY_CLASS,
|
|
1982
2053
|
style: {
|
|
1983
2054
|
filter: `url(#${filterId})`
|
|
@@ -2082,7 +2153,7 @@ class {
|
|
|
2082
2153
|
}
|
|
2083
2154
|
}, updateAtomixGlassStyles = (wrapperElement, containerElement, params) => {
|
|
2084
2155
|
if (!wrapperElement && !containerElement) return;
|
|
2085
|
-
const {mouseOffset: mouseOffset, globalMousePosition: globalMousePosition, glassSize: glassSize, isHovered: isHovered, isActive: isActive, isOverLight: isOverLight, baseOverLightConfig: baseOverLightConfig, effectiveBorderRadius: effectiveBorderRadius, effectiveWithoutEffects: effectiveWithoutEffects, effectiveReducedMotion: effectiveReducedMotion, elasticity: elasticity, directionalScale: directionalScale, onClick: onClick, withLiquidBlur: withLiquidBlur, blurAmount: blurAmount = ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT, saturation: saturation = ATOMIX_GLASS.DEFAULTS.SATURATION, padding: padding = ATOMIX_GLASS.DEFAULTS.PADDING} = params, mouseInfluence = calculateMouseInfluence(mouseOffset), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1, overLightConfig = {
|
|
2156
|
+
const {mouseOffset: mouseOffset, globalMousePosition: globalMousePosition, glassSize: glassSize, isHovered: isHovered, isActive: isActive, isOverLight: isOverLight, baseOverLightConfig: baseOverLightConfig, effectiveBorderRadius: effectiveBorderRadius, effectiveWithoutEffects: effectiveWithoutEffects, effectiveReducedMotion: effectiveReducedMotion, elasticity: elasticity, directionalScale: directionalScale, 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 = {
|
|
2086
2157
|
opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
|
|
2087
2158
|
contrast: Math.min(1.6, baseOverLightConfig.contrast + .1 * mouseInfluence),
|
|
2088
2159
|
brightness: Math.min(1.1, baseOverLightConfig.brightness + .05 * mouseInfluence),
|
|
@@ -2172,7 +2243,7 @@ class {
|
|
|
2172
2243
|
}
|
|
2173
2244
|
// Update Container Styles (containerVars)
|
|
2174
2245
|
if (containerElement) {
|
|
2175
|
-
const mx = mouseOffset.x, my = mouseOffset.y, EDGE_BLUR_MULTIPLIER =
|
|
2246
|
+
const mx = mouseOffset.x, my = mouseOffset.y, EDGE_BLUR_MULTIPLIER = .5, CENTER_BLUR_MULTIPLIER = .2, FLOW_BLUR_MULTIPLIER = .3, MOUSE_INFLUENCE_BLUR_FACTOR = .4, EDGE_INTENSITY_MOUSE_FACTOR = .15, CENTER_INTENSITY_MOUSE_FACTOR = .1, MAX_BLUR_RELATIVE = 2, rect = containerElement.getBoundingClientRect();
|
|
2176
2247
|
let liquidBlur = {
|
|
2177
2248
|
baseBlur: blurAmount,
|
|
2178
2249
|
edgeBlur: blurAmount * EDGE_BLUR_MULTIPLIER,
|
|
@@ -2194,22 +2265,155 @@ class {
|
|
|
2194
2265
|
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, 200)}%) contrast(${overLightConfig.contrast}) brightness(${overLightConfig.brightness})` : `blur(${clampBlur(.4 * liquidBlur.baseBlur + .25 * liquidBlur.edgeBlur + .15 * liquidBlur.centerBlur + .2 * liquidBlur.flowBlur)}px) saturate(${Math.min(dynamicSaturation, 200)}%) contrast(${overLightConfig.contrast}) brightness(${overLightConfig.brightness})`;
|
|
2195
2266
|
// Container variables
|
|
2196
2267
|
const style = containerElement.style;
|
|
2197
|
-
style.setProperty("--atomix-glass-container-width", `${glassSize.width}`
|
|
2268
|
+
style.setProperty("--atomix-glass-container-width", isFixedOrSticky ? `${glassSize.width}` : "100%"),
|
|
2269
|
+
style.setProperty("--atomix-glass-container-height", isFixedOrSticky ? `${glassSize.height}` : "100%"),
|
|
2198
2270
|
style.setProperty("--atomix-glass-container-padding", padding), style.setProperty("--atomix-glass-container-radius", `${effectiveBorderRadius}px`),
|
|
2199
2271
|
style.setProperty("--atomix-glass-container-backdrop", backdropFilterString),
|
|
2200
2272
|
// Shadows
|
|
2201
2273
|
style.setProperty("--atomix-glass-container-shadow", isOverLight ? [ `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"),
|
|
2202
2274
|
style.setProperty("--atomix-glass-container-shadow-opacity", effectiveWithoutEffects ? "0" : "1"),
|
|
2203
2275
|
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"),
|
|
2204
|
-
style.setProperty("--atomix-glass-container-text-shadow", isOverLight ? "0px 2px
|
|
2276
|
+
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)"),
|
|
2205
2277
|
style.setProperty("--atomix-glass-container-box-shadow", isOverLight ? "0px 16px 70px rgba(0, 0, 0, 0.75)" : "0px 12px 40px rgba(0, 0, 0, 0.25)");
|
|
2206
2278
|
}
|
|
2207
|
-
}
|
|
2279
|
+
};
|
|
2208
2280
|
|
|
2209
2281
|
/**
|
|
2210
2282
|
* Updates the styles of the AtomixGlass wrapper and container elements imperatively
|
|
2211
2283
|
* to avoid React re-renders on mouse movement.
|
|
2212
|
-
*/
|
|
2284
|
+
*/
|
|
2285
|
+
/**
|
|
2286
|
+
* Animation System for AtomixGlass Component
|
|
2287
|
+
*
|
|
2288
|
+
* Implements Phase 1 features from the AtomixGlass Feature Implementation Roadmap:
|
|
2289
|
+
* - Feature 1.1: Time-Based Animation System
|
|
2290
|
+
* - Feature 1.2: Multi-Layer Distortion System (FBM)
|
|
2291
|
+
*
|
|
2292
|
+
* @packageDocumentation
|
|
2293
|
+
*/
|
|
2294
|
+
// ============================================================================
|
|
2295
|
+
// Noise Functions for FBM (Feature 1.2)
|
|
2296
|
+
// ============================================================================
|
|
2297
|
+
/**
|
|
2298
|
+
* Perlin noise implementation for smooth gradient noise
|
|
2299
|
+
*
|
|
2300
|
+
* @param x - X coordinate
|
|
2301
|
+
* @param y - Y coordinate
|
|
2302
|
+
* @returns Noise value in range [0, 1]
|
|
2303
|
+
*/
|
|
2304
|
+
function perlinNoise(x, y) {
|
|
2305
|
+
// Simplified Perlin noise using pseudo-random gradients
|
|
2306
|
+
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);
|
|
2307
|
+
// Scale to [0, 1] range
|
|
2308
|
+
return (lerp(lerpX1, lerpX2, v) + 1) / 2;
|
|
2309
|
+
}
|
|
2310
|
+
|
|
2311
|
+
// ============================================================================
|
|
2312
|
+
// Fractal Brownian Motion (FBM) Engine (Feature 1.2)
|
|
2313
|
+
// ============================================================================
|
|
2314
|
+
/**
|
|
2315
|
+
* Creates an FBM engine with configurable parameters
|
|
2316
|
+
*
|
|
2317
|
+
* @param config - FBM configuration (octaves, lacunarity, gain)
|
|
2318
|
+
* @returns Object with fbm function
|
|
2319
|
+
*
|
|
2320
|
+
* @example
|
|
2321
|
+
* ```typescript
|
|
2322
|
+
* const fbmEngine = createFBMEngine({ octaves: 5, lacunarity: 2, gain: 0.5 });
|
|
2323
|
+
*
|
|
2324
|
+
* // Generate noise at position (0.5, 0.5) with time animation
|
|
2325
|
+
* const noiseValue = fbmEngine.fbm(0.5, 0.5, Date.now());
|
|
2326
|
+
* ```
|
|
2327
|
+
*/ function createFBMEngine(config) {
|
|
2328
|
+
/**
|
|
2329
|
+
* Fractal Brownian Motion function
|
|
2330
|
+
* Combines multiple octaves of noise for complex, natural patterns
|
|
2331
|
+
*
|
|
2332
|
+
* @param x - X coordinate
|
|
2333
|
+
* @param y - Y coordinate
|
|
2334
|
+
* @param time - Optional time value for animation
|
|
2335
|
+
* @returns FBM noise value in range [0, 1]
|
|
2336
|
+
*/
|
|
2337
|
+
const fbm = (x, y, time = 0) => {
|
|
2338
|
+
let value = 0, amplitude = .5, frequency = 1, phase = .001 * time;
|
|
2339
|
+
// Convert to seconds for reasonable animation speed
|
|
2340
|
+
for (let i = 0; i < config.octaves; i++)
|
|
2341
|
+
// Apply time-based phase shift to all octaves
|
|
2342
|
+
value += perlinNoise(x * frequency + phase, y * frequency + phase) * amplitude,
|
|
2343
|
+
frequency *= config.lacunarity, // Increase frequency
|
|
2344
|
+
amplitude *= config.gain;
|
|
2345
|
+
return value;
|
|
2346
|
+
};
|
|
2347
|
+
/**
|
|
2348
|
+
* Get FBM with simple time factor
|
|
2349
|
+
*/ return {
|
|
2350
|
+
fbm: fbm,
|
|
2351
|
+
fbmWithTime: (x, y, time) => fbm(x, y, time)
|
|
2352
|
+
};
|
|
2353
|
+
}
|
|
2354
|
+
|
|
2355
|
+
/**
|
|
2356
|
+
* Gets optimal FBM config based on quality preset
|
|
2357
|
+
*
|
|
2358
|
+
* @param quality - Quality preset level
|
|
2359
|
+
* @returns FBM configuration for the quality level
|
|
2360
|
+
*/ const fbmEngineCache = new Map;
|
|
2361
|
+
|
|
2362
|
+
// ============================================================================
|
|
2363
|
+
// Shader Utility Functions for Time-Based Effects
|
|
2364
|
+
// ============================================================================
|
|
2365
|
+
/**
|
|
2366
|
+
* Liquid glass distortion with time-based animation
|
|
2367
|
+
* Uses FBM to create organic, flowing liquid effects
|
|
2368
|
+
*
|
|
2369
|
+
* @param uv - UV coordinates (normalized 0-1)
|
|
2370
|
+
* @param time - Elapsed time in milliseconds
|
|
2371
|
+
* @param config - FBM configuration
|
|
2372
|
+
* @returns Distorted UV coordinates
|
|
2373
|
+
*/ function liquidGlassWithTime(uv, time, config) {
|
|
2374
|
+
const configKey = `${config.octaves}-${config.lacunarity}-${config.gain}`;
|
|
2375
|
+
let fbmEngine = fbmEngineCache.get(configKey);
|
|
2376
|
+
fbmEngine || (fbmEngine = createFBMEngine(config), fbmEngineCache.set(configKey, fbmEngine));
|
|
2377
|
+
// Animate noise with time
|
|
2378
|
+
const animatedNoise = fbmEngine.fbmWithTime(2 * uv.x + 1e-4 * time, 2 * uv.y + 15e-5 * time, time);
|
|
2379
|
+
return {
|
|
2380
|
+
x: uv.x + .04 * (animatedNoise - .5),
|
|
2381
|
+
y: uv.y + .04 * (animatedNoise - .5)
|
|
2382
|
+
};
|
|
2383
|
+
}
|
|
2384
|
+
|
|
2385
|
+
// ============================================================================
|
|
2386
|
+
// Helper Functions
|
|
2387
|
+
// ============================================================================
|
|
2388
|
+
/**
|
|
2389
|
+
* Fade curve for smooth interpolation (Perlin's fade function)
|
|
2390
|
+
*/ function fade(t) {
|
|
2391
|
+
return t * t * t * (t * (6 * t - 15) + 10);
|
|
2392
|
+
}
|
|
2393
|
+
|
|
2394
|
+
/**
|
|
2395
|
+
* Linear interpolation
|
|
2396
|
+
*/ function lerp(a, b, t) {
|
|
2397
|
+
return a + t * (b - a);
|
|
2398
|
+
}
|
|
2399
|
+
|
|
2400
|
+
/**
|
|
2401
|
+
* Gradient calculation for Perlin noise
|
|
2402
|
+
*/ function grad(hash, x, y) {
|
|
2403
|
+
const h = 15 & hash, u = h < 8 ? x : y, v = h < 4 ? y : 12 === h || 14 === h ? x : 0;
|
|
2404
|
+
return (1 & h ? -u : u) + (2 & h ? -v : v);
|
|
2405
|
+
}
|
|
2406
|
+
|
|
2407
|
+
/**
|
|
2408
|
+
* Permutation table for Perlin noise
|
|
2409
|
+
*/ const p = (() => {
|
|
2410
|
+
const permutation = [];
|
|
2411
|
+
for (let i = 0; i < 256; i++) permutation[i] = Math.floor(256 * Math.random());
|
|
2412
|
+
// Duplicate for overflow handling
|
|
2413
|
+
return [ ...permutation, ...permutation ];
|
|
2414
|
+
})(), {CONSTANTS: CONSTANTS$1} = ATOMIX_GLASS;
|
|
2415
|
+
|
|
2416
|
+
const {CONSTANTS: CONSTANTS} = ATOMIX_GLASS, backgroundDetectionCache = new WeakMap, setCachedBackgroundDetection = (parentElement, overLightConfig, result, threshold) => {
|
|
2213
2417
|
parentElement && backgroundDetectionCache.set(parentElement, {
|
|
2214
2418
|
result: result,
|
|
2215
2419
|
timestamp: Date.now(),
|
|
@@ -2222,7 +2426,9 @@ class {
|
|
|
2222
2426
|
* Composable hook for AtomixGlass component logic
|
|
2223
2427
|
* Manages all state, calculations, and event handlers
|
|
2224
2428
|
*/
|
|
2225
|
-
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 = .05, onClick: onClick, debugBorderRadius: debugBorderRadius = !1, debugOverLight: debugOverLight = !1,
|
|
2429
|
+
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 = .05, onClick: onClick, debugBorderRadius: debugBorderRadius = !1, debugOverLight: debugOverLight = !1, children: children, blurAmount: blurAmount, saturation: saturation, padding: padding, withLiquidBlur: withLiquidBlur, isFixedOrSticky: isFixedOrSticky = !1, withTimeAnimation:
|
|
2430
|
+
// Phase 1: Animation System Props
|
|
2431
|
+
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}) {
|
|
2226
2432
|
// State
|
|
2227
2433
|
const [isHovered, setIsHovered] = useState(!1), [isActive, setIsActive] = useState(!1), cachedRectRef = useRef(null), internalGlobalMousePositionRef = useRef({
|
|
2228
2434
|
x: 0,
|
|
@@ -2236,7 +2442,47 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2236
2442
|
}), targetGlobalMousePositionRef = useRef({
|
|
2237
2443
|
x: 0,
|
|
2238
2444
|
y: 0
|
|
2239
|
-
}), lerpRafRef = useRef(null), lerpActiveRef = useRef(!1), [dynamicBorderRadius, setDynamicCornerRadius] = useState(CONSTANTS.DEFAULT_CORNER_RADIUS), [userPrefersReducedMotion, setUserPrefersReducedMotion] = useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = useState(!1), [detectedOverLight, setDetectedOverLight] = useState(!1),
|
|
2445
|
+
}), lerpRafRef = useRef(null), lerpActiveRef = useRef(!1), [dynamicBorderRadius, setDynamicCornerRadius] = useState(CONSTANTS.DEFAULT_CORNER_RADIUS), [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((() => {
|
|
2446
|
+
// If quality preset is provided, use it as base
|
|
2447
|
+
const preset = (quality = distortionQuality, ATOMIX_GLASS.CONSTANTS.DISTORTION_QUALITY_PRESETS[quality]);
|
|
2448
|
+
// Override with custom values if provided
|
|
2449
|
+
var quality;
|
|
2450
|
+
return {
|
|
2451
|
+
octaves: distortionOctaves ?? preset.octaves,
|
|
2452
|
+
lacunarity: distortionLacunarity ?? preset.lacunarity,
|
|
2453
|
+
gain: distortionGain ?? preset.gain
|
|
2454
|
+
};
|
|
2455
|
+
}), [ distortionQuality, distortionOctaves, distortionLacunarity, distortionGain ]), fbmEngine = useMemo((() => withMultiLayerDistortion ? createFBMEngine(fbmConfig) : null), [ withMultiLayerDistortion, fbmConfig ]), effectiveReducedMotion = useMemo((() => reducedMotion || userPrefersReducedMotion), [ reducedMotion, userPrefersReducedMotion ]), effectiveWithTimeAnimation = useMemo((() => withTimeAnimation && !effectiveReducedMotion), [ withTimeAnimation, effectiveReducedMotion ]);
|
|
2456
|
+
/**
|
|
2457
|
+
* Animation loop for time-based effects
|
|
2458
|
+
*/
|
|
2459
|
+
useEffect((() => {
|
|
2460
|
+
if (!effectiveWithTimeAnimation || "undefined" == typeof window) return;
|
|
2461
|
+
let lastFrameTime = performance.now();
|
|
2462
|
+
/**
|
|
2463
|
+
* Animation frame handler
|
|
2464
|
+
*/ const animate = currentTime => {
|
|
2465
|
+
// Calculate delta time
|
|
2466
|
+
const deltaTime = currentTime - lastFrameTime;
|
|
2467
|
+
lastFrameTime = currentTime;
|
|
2468
|
+
// Apply animation speed multiplier
|
|
2469
|
+
const scaledDelta = deltaTime * animationSpeed;
|
|
2470
|
+
elapsedTimeRef.current += scaledDelta, shaderTimeRef.current = elapsedTimeRef.current,
|
|
2471
|
+
// Continue animation loop
|
|
2472
|
+
animationFrameIdRef.current = requestAnimationFrame(animate);
|
|
2473
|
+
};
|
|
2474
|
+
// Start animation
|
|
2475
|
+
// Cleanup
|
|
2476
|
+
return animationStartTimeRef.current = performance.now(), animationFrameIdRef.current = requestAnimationFrame(animate),
|
|
2477
|
+
() => {
|
|
2478
|
+
null !== animationFrameIdRef.current && (cancelAnimationFrame(animationFrameIdRef.current),
|
|
2479
|
+
animationFrameIdRef.current = null);
|
|
2480
|
+
};
|
|
2481
|
+
}), [ effectiveWithTimeAnimation, animationSpeed ]);
|
|
2482
|
+
/**
|
|
2483
|
+
* Get current shader time for animations
|
|
2484
|
+
*/
|
|
2485
|
+
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}) {
|
|
2240
2486
|
const [glassSize, setGlassSize] = useState({
|
|
2241
2487
|
width: 270,
|
|
2242
2488
|
height: 69
|
|
@@ -2295,7 +2541,10 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2295
2541
|
glassRef: glassRef,
|
|
2296
2542
|
effectiveBorderRadius: effectiveBorderRadius,
|
|
2297
2543
|
cachedRectRef: cachedRectRef
|
|
2298
|
-
}),
|
|
2544
|
+
}), effectiveHighContrast = useMemo((() => highContrast || userPrefersHighContrast), [ highContrast, userPrefersHighContrast ]), effectiveWithoutEffects = useMemo((() => withoutEffects || effectiveReducedMotion), [ withoutEffects, effectiveReducedMotion ]), globalMousePosition = externalGlobalMousePosition || internalGlobalMousePositionRef.current, mouseOffset = externalMouseOffset || internalMouseOffsetRef.current;
|
|
2545
|
+
/**
|
|
2546
|
+
* Apply time-based distortion to UV coordinates
|
|
2547
|
+
*/
|
|
2299
2548
|
// Extract border-radius from children
|
|
2300
2549
|
useEffect((() => {
|
|
2301
2550
|
const extractRadius = () => {
|
|
@@ -2498,6 +2747,8 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2498
2747
|
lerpActiveRef.current = !0;
|
|
2499
2748
|
const LERP_T = CONSTANTS.LERP_FACTOR, tick = () => {
|
|
2500
2749
|
if (!lerpActiveRef.current) return;
|
|
2750
|
+
// Add ref validity check to prevent memory leaks
|
|
2751
|
+
if (!glassRef.current || !wrapperRef?.current) return void (lerpActiveRef.current = !1);
|
|
2501
2752
|
const cur = internalMouseOffsetRef.current, tgt = targetMouseOffsetRef.current, dx = tgt.x - cur.x, dy = tgt.y - cur.y;
|
|
2502
2753
|
// If we're close enough, snap and park
|
|
2503
2754
|
if (Math.abs(dx) < .05 && Math.abs(dy) < .05) internalMouseOffsetRef.current = {
|
|
@@ -2506,17 +2757,17 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2506
2757
|
...targetGlobalMousePositionRef.current
|
|
2507
2758
|
}; else {
|
|
2508
2759
|
internalMouseOffsetRef.current = {
|
|
2509
|
-
x: lerp(cur.x, tgt.x, LERP_T),
|
|
2510
|
-
y: lerp(cur.y, tgt.y, LERP_T)
|
|
2760
|
+
x: lerp$1(cur.x, tgt.x, LERP_T),
|
|
2761
|
+
y: lerp$1(cur.y, tgt.y, LERP_T)
|
|
2511
2762
|
};
|
|
2512
2763
|
const curG = internalGlobalMousePositionRef.current, tgtG = targetGlobalMousePositionRef.current;
|
|
2513
2764
|
internalGlobalMousePositionRef.current = {
|
|
2514
|
-
x: lerp(curG.x, tgtG.x, LERP_T),
|
|
2515
|
-
y: lerp(curG.y, tgtG.y, LERP_T)
|
|
2765
|
+
x: lerp$1(curG.x, tgtG.x, LERP_T),
|
|
2766
|
+
y: lerp$1(curG.y, tgtG.y, LERP_T)
|
|
2516
2767
|
};
|
|
2517
2768
|
}
|
|
2518
2769
|
// Imperative style update with the smoothed values
|
|
2519
|
-
updateAtomixGlassStyles(wrapperRef
|
|
2770
|
+
updateAtomixGlassStyles(wrapperRef.current, glassRef.current, {
|
|
2520
2771
|
mouseOffset: internalMouseOffsetRef.current,
|
|
2521
2772
|
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
2522
2773
|
glassSize: glassSize,
|
|
@@ -2533,12 +2784,13 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2533
2784
|
withLiquidBlur: withLiquidBlur,
|
|
2534
2785
|
blurAmount: blurAmount,
|
|
2535
2786
|
saturation: saturation,
|
|
2536
|
-
padding: padding
|
|
2787
|
+
padding: padding,
|
|
2788
|
+
isFixedOrSticky: isFixedOrSticky
|
|
2537
2789
|
}), lerpRafRef.current = requestAnimationFrame(tick);
|
|
2538
2790
|
};
|
|
2539
2791
|
// 0.08 – lower = more viscous
|
|
2540
2792
|
lerpRafRef.current = requestAnimationFrame(tick);
|
|
2541
|
-
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding ]), stopLerpLoop = useCallback((() => {
|
|
2793
|
+
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding, isFixedOrSticky ]), stopLerpLoop = useCallback((() => {
|
|
2542
2794
|
lerpActiveRef.current = !1, null !== lerpRafRef.current && (cancelAnimationFrame(lerpRafRef.current),
|
|
2543
2795
|
lerpRafRef.current = null);
|
|
2544
2796
|
}), []);
|
|
@@ -2606,6 +2858,8 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2606
2858
|
// This is now static (refs or props) unless prop changes
|
|
2607
2859
|
overLightConfig: overLightConfig,
|
|
2608
2860
|
transformStyle: transformStyle,
|
|
2861
|
+
getShaderTime: getShaderTime,
|
|
2862
|
+
applyTimeBasedDistortion: applyTimeBasedDistortion,
|
|
2609
2863
|
handleMouseEnter: handleMouseEnter,
|
|
2610
2864
|
handleMouseLeave: handleMouseLeave,
|
|
2611
2865
|
handleMouseDown: handleMouseDown,
|
|
@@ -2614,6 +2868,448 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2614
2868
|
};
|
|
2615
2869
|
}
|
|
2616
2870
|
|
|
2871
|
+
/**
|
|
2872
|
+
* Default responsive breakpoints configuration
|
|
2873
|
+
*
|
|
2874
|
+
* These breakpoints are optimized for glass effect performance across device classes:
|
|
2875
|
+
* - Mobile: Reduced complexity for 60 FPS target
|
|
2876
|
+
* - Tablet: Balanced quality and performance
|
|
2877
|
+
* - Desktop: Full fidelity effects
|
|
2878
|
+
*/ const DEFAULT_BREAKPOINTS = {
|
|
2879
|
+
mobile: {
|
|
2880
|
+
maxWidth: 640,
|
|
2881
|
+
params: {
|
|
2882
|
+
distortionOctaves: 3,
|
|
2883
|
+
displacementScale: .7,
|
|
2884
|
+
blurAmount: .8,
|
|
2885
|
+
animationSpeed: .8,
|
|
2886
|
+
chromaticIntensity: .5
|
|
2887
|
+
}
|
|
2888
|
+
},
|
|
2889
|
+
tablet: {
|
|
2890
|
+
minWidth: 641,
|
|
2891
|
+
maxWidth: 1024,
|
|
2892
|
+
params: {
|
|
2893
|
+
distortionOctaves: 4,
|
|
2894
|
+
displacementScale: .85,
|
|
2895
|
+
blurAmount: .9,
|
|
2896
|
+
animationSpeed: .9,
|
|
2897
|
+
chromaticIntensity: .75
|
|
2898
|
+
}
|
|
2899
|
+
},
|
|
2900
|
+
desktop: {
|
|
2901
|
+
minWidth: 1025,
|
|
2902
|
+
params: {
|
|
2903
|
+
distortionOctaves: 5,
|
|
2904
|
+
displacementScale: 1,
|
|
2905
|
+
blurAmount: 1,
|
|
2906
|
+
animationSpeed: 1,
|
|
2907
|
+
chromaticIntensity: 1
|
|
2908
|
+
}
|
|
2909
|
+
}
|
|
2910
|
+
};
|
|
2911
|
+
|
|
2912
|
+
/**
|
|
2913
|
+
* Device performance tier detection
|
|
2914
|
+
*
|
|
2915
|
+
* Uses Device Memory API and Hardware Concurrency API to classify devices
|
|
2916
|
+
* into performance tiers for automatic quality adjustment.
|
|
2917
|
+
*
|
|
2918
|
+
* @returns Performance tier classification
|
|
2919
|
+
*/ var toIntegerOrInfinity = toIntegerOrInfinity$2, max = Math.max, min = Math.min, toIndexedObject = toIndexedObject$2, lengthOfArrayLike = lengthOfArrayLike$2, createMethod = function(IS_INCLUDES) {
|
|
2920
|
+
return function($this, el, fromIndex) {
|
|
2921
|
+
var O = toIndexedObject($this), length = lengthOfArrayLike(O);
|
|
2922
|
+
if (0 === length) return !IS_INCLUDES && -1;
|
|
2923
|
+
var value, index = function(index, length) {
|
|
2924
|
+
var integer = toIntegerOrInfinity(index);
|
|
2925
|
+
return integer < 0 ? max(integer + length, 0) : min(integer, length);
|
|
2926
|
+
}(fromIndex, length);
|
|
2927
|
+
// Array#includes uses SameValueZero equality algorithm
|
|
2928
|
+
// eslint-disable-next-line no-self-compare -- NaN check
|
|
2929
|
+
if (IS_INCLUDES && el != el) {
|
|
2930
|
+
for (;length > index; )
|
|
2931
|
+
// eslint-disable-next-line no-self-compare -- NaN check
|
|
2932
|
+
if ((value = O[index++]) != value) return !0;
|
|
2933
|
+
// Array#indexOf ignores holes, Array#includes - not
|
|
2934
|
+
} else for (;length > index; index++) if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;
|
|
2935
|
+
return !IS_INCLUDES && -1;
|
|
2936
|
+
};
|
|
2937
|
+
}, $includes = [ createMethod(!0), createMethod(!1) ][0];
|
|
2938
|
+
|
|
2939
|
+
// `Array.prototype.includes` method
|
|
2940
|
+
// https://tc39.es/ecma262/#sec-array.prototype.includes
|
|
2941
|
+
_export({
|
|
2942
|
+
target: "Array",
|
|
2943
|
+
proto: !0,
|
|
2944
|
+
forced: fails$9((function() {
|
|
2945
|
+
// eslint-disable-next-line es/no-array-prototype-includes -- detection
|
|
2946
|
+
return !Array(1).includes();
|
|
2947
|
+
}))
|
|
2948
|
+
}, {
|
|
2949
|
+
includes: function(el /* , fromIndex = 0 */) {
|
|
2950
|
+
return $includes(this, el, arguments.length > 1 ? arguments[1] : void 0);
|
|
2951
|
+
}
|
|
2952
|
+
});
|
|
2953
|
+
|
|
2954
|
+
var includes$4 = getBuiltInPrototypeMethod$3("Array", "includes"), isObject = isObject$5, classof$2 = classofRaw$2, MATCH$1 = wellKnownSymbol$5("match"), $TypeError = TypeError, test = {};
|
|
2955
|
+
|
|
2956
|
+
test[wellKnownSymbol$5("toStringTag")] = "z";
|
|
2957
|
+
|
|
2958
|
+
var TO_STRING_TAG_SUPPORT = "[object z]" === String(test), isCallable = isCallable$8, classofRaw = classofRaw$2, TO_STRING_TAG = wellKnownSymbol$5("toStringTag"), $Object = Object, CORRECT_ARGUMENTS = "Arguments" === classofRaw(function() {
|
|
2959
|
+
return arguments;
|
|
2960
|
+
}()), classof = TO_STRING_TAG_SUPPORT ? classofRaw : function(it) {
|
|
2961
|
+
var O, tag, result;
|
|
2962
|
+
return void 0 === it ? "Undefined" : null === it ? "Null" : "string" == typeof (tag = function(it, key) {
|
|
2963
|
+
try {
|
|
2964
|
+
return it[key];
|
|
2965
|
+
} catch (error) {/* empty */}
|
|
2966
|
+
}(O = $Object(it), TO_STRING_TAG)) ? tag : CORRECT_ARGUMENTS ? classofRaw(O) : "Object" === (result = classofRaw(O)) && isCallable(O.callee) ? "Arguments" : result;
|
|
2967
|
+
}, $String = String, MATCH = wellKnownSymbol$5("match"), $ = _export, notARegExp = function(it) {
|
|
2968
|
+
if (function(it) {
|
|
2969
|
+
var isRegExp;
|
|
2970
|
+
return isObject(it) && (void 0 !== (isRegExp = it[MATCH$1]) ? !!isRegExp : "RegExp" === classof$2(it));
|
|
2971
|
+
}(it)) throw new $TypeError("The method doesn't accept regular expressions");
|
|
2972
|
+
return it;
|
|
2973
|
+
}, requireObjectCoercible = requireObjectCoercible$3, toString = function(argument) {
|
|
2974
|
+
if ("Symbol" === classof(argument)) throw new TypeError("Cannot convert a Symbol value to a string");
|
|
2975
|
+
return $String(argument);
|
|
2976
|
+
}, stringIndexOf = functionUncurryThis("".indexOf);
|
|
2977
|
+
|
|
2978
|
+
// `String.prototype.includes` method
|
|
2979
|
+
// https://tc39.es/ecma262/#sec-string.prototype.includes
|
|
2980
|
+
$({
|
|
2981
|
+
target: "String",
|
|
2982
|
+
proto: !0,
|
|
2983
|
+
forced: !function(METHOD_NAME) {
|
|
2984
|
+
var regexp = /./;
|
|
2985
|
+
try {
|
|
2986
|
+
"/./"[METHOD_NAME](regexp);
|
|
2987
|
+
} catch (error1) {
|
|
2988
|
+
try {
|
|
2989
|
+
return regexp[MATCH] = !1, "/./"[METHOD_NAME](regexp);
|
|
2990
|
+
} catch (error2) {/* empty */}
|
|
2991
|
+
}
|
|
2992
|
+
return !1;
|
|
2993
|
+
}("includes")
|
|
2994
|
+
}, {
|
|
2995
|
+
includes: function(searchString /* , position = 0 */) {
|
|
2996
|
+
return !!~stringIndexOf(toString(requireObjectCoercible(this)), toString(notARegExp(searchString)), arguments.length > 1 ? arguments[1] : void 0);
|
|
2997
|
+
}
|
|
2998
|
+
});
|
|
2999
|
+
|
|
3000
|
+
var includes$3 = getBuiltInPrototypeMethod$3("String", "includes"), isPrototypeOf = objectIsPrototypeOf, arrayMethod = includes$4, stringMethod = includes$3, ArrayPrototype = Array.prototype, StringPrototype = String.prototype;
|
|
3001
|
+
|
|
3002
|
+
const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
3003
|
+
var own = it.includes;
|
|
3004
|
+
return it === ArrayPrototype || isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.includes ? arrayMethod : "string" == typeof it || it === StringPrototype || isPrototypeOf(StringPrototype, it) && own === StringPrototype.includes ? stringMethod : own;
|
|
3005
|
+
}));
|
|
3006
|
+
|
|
3007
|
+
/**
|
|
3008
|
+
* Get GPU memory info if available (Chrome DevTools only)
|
|
3009
|
+
*/
|
|
3010
|
+
/**
|
|
3011
|
+
* PerformanceDashboard - Real-time performance monitoring overlay
|
|
3012
|
+
*
|
|
3013
|
+
* Displays:
|
|
3014
|
+
* - Current FPS with color coding
|
|
3015
|
+
* - Frame time statistics
|
|
3016
|
+
* - Quality level indicator
|
|
3017
|
+
* - GPU memory usage (if available)
|
|
3018
|
+
* - Auto-scaling status
|
|
3019
|
+
*/
|
|
3020
|
+
const PerformanceDashboard = ({metrics: metrics, isVisible: isVisible = !0, onClose: onClose}) => {
|
|
3021
|
+
// Get color for FPS display
|
|
3022
|
+
const getFpsColor = fps => fps >= 58 ? "#4ade80" : // Green - good
|
|
3023
|
+
fps >= 45 ? "#fbbf24" : "#ef4444" // Red - critical
|
|
3024
|
+
, dashboardStyle = useMemo((() => ({
|
|
3025
|
+
position: "fixed",
|
|
3026
|
+
top: "16px",
|
|
3027
|
+
right: "16px",
|
|
3028
|
+
padding: "12px 16px",
|
|
3029
|
+
backgroundColor: "rgba(17, 24, 39, 0.95)",
|
|
3030
|
+
borderRadius: "8px",
|
|
3031
|
+
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
|
|
3032
|
+
fontFamily: "monospace",
|
|
3033
|
+
fontSize: "12px",
|
|
3034
|
+
color: "#fff",
|
|
3035
|
+
zIndex: 9999,
|
|
3036
|
+
minWidth: "200px",
|
|
3037
|
+
backdropFilter: "blur(8px)",
|
|
3038
|
+
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
3039
|
+
transition: "opacity 0.3s ease",
|
|
3040
|
+
opacity: isVisible ? 1 : 0,
|
|
3041
|
+
pointerEvents: isVisible ? "auto" : "none"
|
|
3042
|
+
})), [ isVisible ]), headerStyle = useMemo((() => ({
|
|
3043
|
+
display: "flex",
|
|
3044
|
+
justifyContent: "space-between",
|
|
3045
|
+
alignItems: "center",
|
|
3046
|
+
marginBottom: "8px",
|
|
3047
|
+
paddingBottom: "8px",
|
|
3048
|
+
borderBottom: "1px solid rgba(255, 255, 255, 0.1)"
|
|
3049
|
+
})), []), titleStyle = useMemo((() => ({
|
|
3050
|
+
fontWeight: "bold",
|
|
3051
|
+
fontSize: "13px",
|
|
3052
|
+
color: "#fff"
|
|
3053
|
+
})), []), closeButtonStyle = useMemo((() => ({
|
|
3054
|
+
background: "transparent",
|
|
3055
|
+
border: "none",
|
|
3056
|
+
color: "#9ca3af",
|
|
3057
|
+
cursor: "pointer",
|
|
3058
|
+
fontSize: "16px",
|
|
3059
|
+
padding: "0",
|
|
3060
|
+
lineHeight: "1"
|
|
3061
|
+
})), []), metricRowStyle = useMemo((() => ({
|
|
3062
|
+
display: "flex",
|
|
3063
|
+
justifyContent: "space-between",
|
|
3064
|
+
alignItems: "center",
|
|
3065
|
+
marginBottom: "6px"
|
|
3066
|
+
})), []), labelStyle = useMemo((() => ({
|
|
3067
|
+
color: "#9ca3af",
|
|
3068
|
+
marginRight: "12px"
|
|
3069
|
+
})), []), valueStyle = useMemo((() => ({
|
|
3070
|
+
fontWeight: "bold"
|
|
3071
|
+
})), []);
|
|
3072
|
+
// Get quality level badge color
|
|
3073
|
+
return isVisible ? jsxs("div", {
|
|
3074
|
+
style: dashboardStyle,
|
|
3075
|
+
children: [ jsxs("div", {
|
|
3076
|
+
style: headerStyle,
|
|
3077
|
+
children: [ jsx("span", {
|
|
3078
|
+
style: titleStyle,
|
|
3079
|
+
children: "Performance Monitor"
|
|
3080
|
+
}), onClose && jsx("button", {
|
|
3081
|
+
style: closeButtonStyle,
|
|
3082
|
+
onClick: onClose,
|
|
3083
|
+
"aria-label": "Close performance dashboard",
|
|
3084
|
+
children: "×"
|
|
3085
|
+
}) ]
|
|
3086
|
+
}), jsxs("div", {
|
|
3087
|
+
style: metricRowStyle,
|
|
3088
|
+
children: [ jsx("span", {
|
|
3089
|
+
style: labelStyle,
|
|
3090
|
+
children: "FPS"
|
|
3091
|
+
}), jsx("span", {
|
|
3092
|
+
style: {
|
|
3093
|
+
...valueStyle,
|
|
3094
|
+
color: getFpsColor(metrics.fps)
|
|
3095
|
+
},
|
|
3096
|
+
children: Math.round(metrics.fps)
|
|
3097
|
+
}) ]
|
|
3098
|
+
}), jsxs("div", {
|
|
3099
|
+
style: metricRowStyle,
|
|
3100
|
+
children: [ jsx("span", {
|
|
3101
|
+
style: labelStyle,
|
|
3102
|
+
children: "Frame Time"
|
|
3103
|
+
}), jsxs("span", {
|
|
3104
|
+
style: valueStyle,
|
|
3105
|
+
children: [ metrics.frameTime.toFixed(2), "ms" ]
|
|
3106
|
+
}) ]
|
|
3107
|
+
}), jsxs("div", {
|
|
3108
|
+
style: metricRowStyle,
|
|
3109
|
+
children: [ jsx("span", {
|
|
3110
|
+
style: labelStyle,
|
|
3111
|
+
children: "Quality"
|
|
3112
|
+
}), jsx("span", {
|
|
3113
|
+
style: {
|
|
3114
|
+
...valueStyle,
|
|
3115
|
+
color: (quality => {
|
|
3116
|
+
switch (quality) {
|
|
3117
|
+
case "high":
|
|
3118
|
+
return "#4ade80";
|
|
3119
|
+
|
|
3120
|
+
case "medium":
|
|
3121
|
+
return "#fbbf24";
|
|
3122
|
+
|
|
3123
|
+
case "low":
|
|
3124
|
+
return "#ef4444";
|
|
3125
|
+
|
|
3126
|
+
default:
|
|
3127
|
+
return "#9ca3af";
|
|
3128
|
+
}
|
|
3129
|
+
})(metrics.qualityLevel),
|
|
3130
|
+
textTransform: "uppercase",
|
|
3131
|
+
fontSize: "11px"
|
|
3132
|
+
},
|
|
3133
|
+
children: metrics.qualityLevel
|
|
3134
|
+
}) ]
|
|
3135
|
+
}), metrics.gpuMemory && jsxs("div", {
|
|
3136
|
+
style: metricRowStyle,
|
|
3137
|
+
children: [ jsx("span", {
|
|
3138
|
+
style: labelStyle,
|
|
3139
|
+
children: "GPU Memory"
|
|
3140
|
+
}), jsxs("span", {
|
|
3141
|
+
style: valueStyle,
|
|
3142
|
+
children: [ "~", Math.round(metrics.gpuMemory / 1024), "MB" ]
|
|
3143
|
+
}) ]
|
|
3144
|
+
}), metrics.isAutoScaling && jsx("div", {
|
|
3145
|
+
style: {
|
|
3146
|
+
marginTop: "8px",
|
|
3147
|
+
paddingTop: "8px",
|
|
3148
|
+
borderTop: "1px solid rgba(255, 255, 255, 0.1)",
|
|
3149
|
+
fontSize: "10px",
|
|
3150
|
+
color: "#6b7280",
|
|
3151
|
+
textAlign: "center"
|
|
3152
|
+
},
|
|
3153
|
+
children: "Auto-scaling active"
|
|
3154
|
+
}), jsxs("div", {
|
|
3155
|
+
style: {
|
|
3156
|
+
marginTop: "8px",
|
|
3157
|
+
paddingTop: "8px",
|
|
3158
|
+
borderTop: "1px solid rgba(255, 255, 255, 0.1)",
|
|
3159
|
+
display: "flex",
|
|
3160
|
+
alignItems: "center",
|
|
3161
|
+
gap: "6px"
|
|
3162
|
+
},
|
|
3163
|
+
children: [ jsx("div", {
|
|
3164
|
+
style: {
|
|
3165
|
+
width: "8px",
|
|
3166
|
+
height: "8px",
|
|
3167
|
+
borderRadius: "50%",
|
|
3168
|
+
backgroundColor: getFpsColor(metrics.fps),
|
|
3169
|
+
animation: metrics.fps < 45 ? "pulse 1s infinite" : "none"
|
|
3170
|
+
}
|
|
3171
|
+
}), jsx("span", {
|
|
3172
|
+
style: {
|
|
3173
|
+
fontSize: "10px",
|
|
3174
|
+
color: metrics.fps >= 58 ? "#4ade80" : metrics.fps >= 45 ? "#fbbf24" : "#ef4444"
|
|
3175
|
+
},
|
|
3176
|
+
children: metrics.fps >= 58 ? "Optimal" : metrics.fps >= 45 ? "Warning" : "Critical"
|
|
3177
|
+
}) ]
|
|
3178
|
+
}) ]
|
|
3179
|
+
}) : null;
|
|
3180
|
+
};
|
|
3181
|
+
|
|
3182
|
+
// Add pulse animation for critical FPS
|
|
3183
|
+
if ("undefined" != typeof document) {
|
|
3184
|
+
const styleSheet = document.createElement("style");
|
|
3185
|
+
styleSheet.textContent = "\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n ",
|
|
3186
|
+
document.head.appendChild(styleSheet);
|
|
3187
|
+
}
|
|
3188
|
+
|
|
3189
|
+
/**
|
|
3190
|
+
* Mobile optimization presets
|
|
3191
|
+
*
|
|
3192
|
+
* These presets adjust glass effect parameters based on device performance tier
|
|
3193
|
+
* to ensure smooth animations and responsive interactions.
|
|
3194
|
+
*/
|
|
3195
|
+
/**
|
|
3196
|
+
* Performance preset - Maximum FPS, reduced quality
|
|
3197
|
+
* Best for low-end devices or when battery saving is priority
|
|
3198
|
+
*/ const PERFORMANCE_PRESET = {
|
|
3199
|
+
distortionOctaves: 2,
|
|
3200
|
+
// Minimal FBM layers
|
|
3201
|
+
displacementScale: 50,
|
|
3202
|
+
// Subtle displacement
|
|
3203
|
+
blurAmount: 5,
|
|
3204
|
+
// Light blur
|
|
3205
|
+
saturation: 80,
|
|
3206
|
+
// Reduced saturation
|
|
3207
|
+
aberrationIntensity: .3,
|
|
3208
|
+
// Minimal chromatic aberration
|
|
3209
|
+
animationSpeed: .8,
|
|
3210
|
+
// Slightly slower for performance
|
|
3211
|
+
chromaticIntensity: .3,
|
|
3212
|
+
// Low chromatic effect
|
|
3213
|
+
distortionLacunarity: 1.5,
|
|
3214
|
+
// Simpler noise pattern
|
|
3215
|
+
distortionGain: .3
|
|
3216
|
+
}, BALANCED_PRESET = {
|
|
3217
|
+
distortionOctaves: 3,
|
|
3218
|
+
// Moderate FBM layers
|
|
3219
|
+
displacementScale: 75,
|
|
3220
|
+
// Medium displacement
|
|
3221
|
+
blurAmount: 8,
|
|
3222
|
+
// Moderate blur
|
|
3223
|
+
saturation: 90,
|
|
3224
|
+
// Near-full saturation
|
|
3225
|
+
aberrationIntensity: .5,
|
|
3226
|
+
// Moderate chromatic aberration
|
|
3227
|
+
animationSpeed: 1,
|
|
3228
|
+
// Normal speed
|
|
3229
|
+
chromaticIntensity: .5,
|
|
3230
|
+
// Moderate chromatic effect
|
|
3231
|
+
distortionLacunarity: 2,
|
|
3232
|
+
// Standard noise pattern
|
|
3233
|
+
distortionGain: .4
|
|
3234
|
+
}, QUALITY_PRESET = {
|
|
3235
|
+
distortionOctaves: 4,
|
|
3236
|
+
// More FBM layers for detail
|
|
3237
|
+
displacementScale: 100,
|
|
3238
|
+
// Stronger displacement
|
|
3239
|
+
blurAmount: 12,
|
|
3240
|
+
// Smoother blur
|
|
3241
|
+
saturation: 100,
|
|
3242
|
+
// Full saturation
|
|
3243
|
+
aberrationIntensity: .7,
|
|
3244
|
+
// Pronounced chromatic aberration
|
|
3245
|
+
animationSpeed: 1.2,
|
|
3246
|
+
// Slightly faster for drama
|
|
3247
|
+
chromaticIntensity: .7,
|
|
3248
|
+
// Strong chromatic effect
|
|
3249
|
+
distortionLacunarity: 2.2,
|
|
3250
|
+
// Richer noise pattern
|
|
3251
|
+
distortionGain: .5
|
|
3252
|
+
}, MOBILE_OPTIMIZED_BREAKPOINTS = {
|
|
3253
|
+
/** Desktop - Full quality */
|
|
3254
|
+
desktop: {
|
|
3255
|
+
minWidth: 1024,
|
|
3256
|
+
params: {
|
|
3257
|
+
distortionOctaves: 6,
|
|
3258
|
+
displacementScale: 150,
|
|
3259
|
+
blurAmount: 15,
|
|
3260
|
+
saturation: 100,
|
|
3261
|
+
aberrationIntensity: 1,
|
|
3262
|
+
animationSpeed: 1,
|
|
3263
|
+
chromaticIntensity: 1,
|
|
3264
|
+
distortionLacunarity: 2.5,
|
|
3265
|
+
distortionGain: .6
|
|
3266
|
+
}
|
|
3267
|
+
},
|
|
3268
|
+
/** Laptop - High quality */
|
|
3269
|
+
laptop: {
|
|
3270
|
+
minWidth: 768,
|
|
3271
|
+
params: {
|
|
3272
|
+
...QUALITY_PRESET,
|
|
3273
|
+
distortionOctaves: 5,
|
|
3274
|
+
displacementScale: 120
|
|
3275
|
+
}
|
|
3276
|
+
},
|
|
3277
|
+
/** Tablet - Balanced quality */
|
|
3278
|
+
tablet: {
|
|
3279
|
+
minWidth: 640,
|
|
3280
|
+
params: {
|
|
3281
|
+
...BALANCED_PRESET,
|
|
3282
|
+
distortionOctaves: 4,
|
|
3283
|
+
displacementScale: 90
|
|
3284
|
+
}
|
|
3285
|
+
},
|
|
3286
|
+
/** Mobile - Performance optimized */
|
|
3287
|
+
mobile: {
|
|
3288
|
+
maxWidth: 639,
|
|
3289
|
+
params: {
|
|
3290
|
+
...PERFORMANCE_PRESET,
|
|
3291
|
+
distortionOctaves: 3,
|
|
3292
|
+
displacementScale: 75,
|
|
3293
|
+
blurAmount: 6
|
|
3294
|
+
}
|
|
3295
|
+
},
|
|
3296
|
+
/** Small mobile - Maximum performance */
|
|
3297
|
+
mobileSmall: {
|
|
3298
|
+
maxWidth: 375,
|
|
3299
|
+
params: {
|
|
3300
|
+
...PERFORMANCE_PRESET,
|
|
3301
|
+
distortionOctaves: 2,
|
|
3302
|
+
displacementScale: 50,
|
|
3303
|
+
blurAmount: 4,
|
|
3304
|
+
saturation: 70
|
|
3305
|
+
}
|
|
3306
|
+
}
|
|
3307
|
+
};
|
|
3308
|
+
|
|
3309
|
+
/**
|
|
3310
|
+
* Balanced preset - Good quality with reasonable performance
|
|
3311
|
+
* Default preset for most mobile devices
|
|
3312
|
+
*/
|
|
2617
3313
|
/**
|
|
2618
3314
|
* AtomixGlass - A high-performance glass morphism component with liquid distortion effects
|
|
2619
3315
|
*
|
|
@@ -2628,6 +3324,8 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2628
3324
|
* - Focus ring support for keyboard navigation
|
|
2629
3325
|
* - Responsive breakpoints for mobile optimization
|
|
2630
3326
|
* - Enhanced ARIA attributes for screen readers
|
|
3327
|
+
* - Time-based animation system with FBM distortion
|
|
3328
|
+
* - Device preset optimization for performance/quality balance
|
|
2631
3329
|
*
|
|
2632
3330
|
* Design System Compliance:
|
|
2633
3331
|
* - Uses design tokens for opacity, spacing, and colors
|
|
@@ -2684,8 +3382,15 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2684
3382
|
* <AtomixGlass overLight="auto" debugOverLight={true}>
|
|
2685
3383
|
* <div>Content with debug logging enabled</div>
|
|
2686
3384
|
* </AtomixGlass>
|
|
2687
|
-
|
|
2688
|
-
|
|
3385
|
+
*
|
|
3386
|
+
* @example
|
|
3387
|
+
* // Performance-optimized for mobile devices
|
|
3388
|
+
* <AtomixGlass devicePreset="performance" disableResponsiveBreakpoints={false}>
|
|
3389
|
+
* <div>Mobile-optimized glass effect</div>
|
|
3390
|
+
* </AtomixGlass>
|
|
3391
|
+
*/
|
|
3392
|
+
function AtomixGlass({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 = "", padding: padding = ATOMIX_GLASS.DEFAULTS.PADDING, 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, withBorder: withBorder = !0, 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, ...rest}) {
|
|
3393
|
+
const glassRef = useRef(null), contentRef = useRef(null), {zIndex: customZIndex, ...restStyle} = style, isFixedOrSticky = "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, applyTimeBasedDistortion: applyTimeBasedDistortion, handleMouseEnter: handleMouseEnter, handleMouseLeave: handleMouseLeave, handleMouseDown: handleMouseDown, handleMouseUp: handleMouseUp, handleKeyDown: handleKeyDown} = useAtomixGlass({
|
|
2689
3394
|
glassRef: glassRef,
|
|
2690
3395
|
contentRef: contentRef,
|
|
2691
3396
|
borderRadius: borderRadius,
|
|
@@ -2698,7 +3403,6 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2698
3403
|
withoutEffects: withoutEffects,
|
|
2699
3404
|
elasticity: elasticity,
|
|
2700
3405
|
onClick: onClick,
|
|
2701
|
-
debugBorderRadius: debugBorderRadius,
|
|
2702
3406
|
debugOverLight: debugOverLight,
|
|
2703
3407
|
debugPerformance: debugPerformance,
|
|
2704
3408
|
children: children,
|
|
@@ -2706,8 +3410,387 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2706
3410
|
saturation: saturation,
|
|
2707
3411
|
withLiquidBlur: withLiquidBlur,
|
|
2708
3412
|
padding: padding,
|
|
2709
|
-
style: style
|
|
2710
|
-
|
|
3413
|
+
style: style,
|
|
3414
|
+
isFixedOrSticky: isFixedOrSticky,
|
|
3415
|
+
// Phase 1: Animation System props
|
|
3416
|
+
withTimeAnimation: withTimeAnimation,
|
|
3417
|
+
animationSpeed: animationSpeed,
|
|
3418
|
+
withMultiLayerDistortion: withMultiLayerDistortion,
|
|
3419
|
+
distortionOctaves: distortionOctaves,
|
|
3420
|
+
distortionLacunarity: distortionLacunarity,
|
|
3421
|
+
distortionGain: distortionGain,
|
|
3422
|
+
distortionQuality: distortionQuality
|
|
3423
|
+
});
|
|
3424
|
+
// Re-calculate only when devicePreset changes
|
|
3425
|
+
// Responsive breakpoint system - automatically adjusts parameters based on viewport
|
|
3426
|
+
!
|
|
3427
|
+
/**
|
|
3428
|
+
* Responsive Glass Parameters Hook
|
|
3429
|
+
*
|
|
3430
|
+
* Automatically adjusts glass effect parameters based on:
|
|
3431
|
+
* 1. Screen size (mobile/tablet/desktop breakpoints)
|
|
3432
|
+
* 2. Device performance (RAM and CPU detection)
|
|
3433
|
+
* 3. Custom breakpoint configuration
|
|
3434
|
+
*
|
|
3435
|
+
* Features:
|
|
3436
|
+
* - Debounced resize handling
|
|
3437
|
+
* - Performance-based quality adjustment
|
|
3438
|
+
* - Smooth parameter transitions
|
|
3439
|
+
* - Debug mode for development
|
|
3440
|
+
*
|
|
3441
|
+
* @example
|
|
3442
|
+
* ```typescript
|
|
3443
|
+
* const { responsiveParams, currentBreakpoint } = useResponsiveGlass({
|
|
3444
|
+
* baseParams: {
|
|
3445
|
+
* distortionOctaves: 5,
|
|
3446
|
+
* displacementScale: 20,
|
|
3447
|
+
* blurAmount: 10,
|
|
3448
|
+
* },
|
|
3449
|
+
* debug: true,
|
|
3450
|
+
* });
|
|
3451
|
+
* ```
|
|
3452
|
+
*
|
|
3453
|
+
* @param options Hook configuration options
|
|
3454
|
+
* @returns Responsive parameters and metadata
|
|
3455
|
+
*/
|
|
3456
|
+
function({baseParams: baseParams, breakpoints: breakpoints = DEFAULT_BREAKPOINTS, enabled: enabled = !0, enablePerformanceAdjustment: enablePerformanceAdjustment = !0, debug: debug = !1}) {
|
|
3457
|
+
const [responsiveParams, setResponsiveParams] = useState(baseParams), [currentBreakpoint, setCurrentBreakpoint] = useState("desktop"), [performanceTier, setPerformanceTier] = useState("high"), [isActive, setIsActive] = useState(enabled), baseParamsRef = useRef(baseParams), breakpointsRef = useRef(breakpoints);
|
|
3458
|
+
// Update refs when props change
|
|
3459
|
+
baseParamsRef.current = baseParams, breakpointsRef.current = breakpoints;
|
|
3460
|
+
/**
|
|
3461
|
+
* Calculate and apply responsive parameters
|
|
3462
|
+
*/
|
|
3463
|
+
const calculateParams = useCallback((() => {
|
|
3464
|
+
if (!enabled || "undefined" == typeof window) return setIsActive(!1), setResponsiveParams(baseParamsRef.current),
|
|
3465
|
+
void setCurrentBreakpoint("disabled");
|
|
3466
|
+
setIsActive(!0);
|
|
3467
|
+
// Get current screen width
|
|
3468
|
+
const width = window.innerWidth, {name: name, params: breakpointParams} = ((width, breakpoints) => {
|
|
3469
|
+
// Convert breakpoints to array and sort by minWidth descending
|
|
3470
|
+
const sortedBreakpoints = Object.entries(breakpoints).filter((([_, bp]) => void 0 !== bp.minWidth)).sort(((a, b) => (b[1].minWidth || 0) - (a[1].minWidth || 0)));
|
|
3471
|
+
// Find first breakpoint where width >= minWidth
|
|
3472
|
+
for (const [name, bp] of sortedBreakpoints) if (width >= (bp.minWidth || 0)) return {
|
|
3473
|
+
name: name,
|
|
3474
|
+
params: bp.params
|
|
3475
|
+
};
|
|
3476
|
+
// If no minWidth matched, check maxWidth breakpoints
|
|
3477
|
+
const maxWidthBreakpoints = Object.entries(breakpoints).filter((([_, bp]) => void 0 !== bp.maxWidth)).sort(((a, b) => (a[1].maxWidth || 1 / 0) - (b[1].maxWidth || 1 / 0)));
|
|
3478
|
+
for (const [name, bp] of maxWidthBreakpoints) if (width <= (bp.maxWidth || 1 / 0)) return {
|
|
3479
|
+
name: name,
|
|
3480
|
+
params: bp.params
|
|
3481
|
+
};
|
|
3482
|
+
// Fallback to first available breakpoint
|
|
3483
|
+
const entries = Object.entries(breakpoints);
|
|
3484
|
+
if (0 === entries.length)
|
|
3485
|
+
// Ultimate fallback - return sensible defaults
|
|
3486
|
+
return {
|
|
3487
|
+
name: "desktop",
|
|
3488
|
+
params: {
|
|
3489
|
+
distortionOctaves: 5,
|
|
3490
|
+
displacementScale: 1,
|
|
3491
|
+
blurAmount: 1
|
|
3492
|
+
}
|
|
3493
|
+
};
|
|
3494
|
+
const firstEntry = entries[0];
|
|
3495
|
+
if (!firstEntry) return {
|
|
3496
|
+
name: "desktop",
|
|
3497
|
+
params: {
|
|
3498
|
+
distortionOctaves: 5,
|
|
3499
|
+
displacementScale: 1,
|
|
3500
|
+
blurAmount: 1
|
|
3501
|
+
}
|
|
3502
|
+
};
|
|
3503
|
+
const [fallbackName, fallbackBreakpoint] = firstEntry;
|
|
3504
|
+
return {
|
|
3505
|
+
name: fallbackName,
|
|
3506
|
+
params: fallbackBreakpoint.params
|
|
3507
|
+
};
|
|
3508
|
+
})(width, breakpointsRef.current);
|
|
3509
|
+
// Determine current breakpoint
|
|
3510
|
+
setCurrentBreakpoint(name);
|
|
3511
|
+
// Merge base params with breakpoint params
|
|
3512
|
+
let mergedParams = ((baseParams, breakpointParams) => {
|
|
3513
|
+
const result = {
|
|
3514
|
+
...baseParams
|
|
3515
|
+
}, scaleProperties = [ "displacementScale", "blurAmount", "saturation", "aberrationIntensity", "animationSpeed", "chromaticIntensity" ];
|
|
3516
|
+
// Apply scaling for specific properties
|
|
3517
|
+
for (const prop of scaleProperties) void 0 !== breakpointParams[prop] && void 0 !== baseParams[prop] && (result[prop] = baseParams[prop] * breakpointParams[prop]);
|
|
3518
|
+
// Override properties that should be set directly (not scaled)
|
|
3519
|
+
const overrideProperties = [ "distortionOctaves", "distortionLacunarity", "distortionGain" ];
|
|
3520
|
+
for (const prop of overrideProperties) void 0 !== breakpointParams[prop] && (result[prop] = breakpointParams[prop]);
|
|
3521
|
+
return result;
|
|
3522
|
+
})(baseParamsRef.current, breakpointParams);
|
|
3523
|
+
// Apply performance adjustments if enabled
|
|
3524
|
+
if (enablePerformanceAdjustment) {
|
|
3525
|
+
const tier = (() => {
|
|
3526
|
+
// Check if we're in a browser environment
|
|
3527
|
+
if ("undefined" == typeof window || "undefined" == typeof navigator) return "high"; // Default to high for SSR
|
|
3528
|
+
// Device Memory API (Chrome, Edge, Opera)
|
|
3529
|
+
// Returns RAM in GB: 0.25, 0.5, 1, 2, 4, 8
|
|
3530
|
+
const deviceMemory = navigator.deviceMemory || 4, hardwareConcurrency = navigator.hardwareConcurrency || 4;
|
|
3531
|
+
// Hardware Concurrency API (logical CPU cores)
|
|
3532
|
+
// Low-end: ≤2GB RAM OR ≤2 CPU cores
|
|
3533
|
+
return deviceMemory <= 2 || hardwareConcurrency <= 2 ? "low" :
|
|
3534
|
+
// High-end: ≥4GB RAM AND ≥4 CPU cores
|
|
3535
|
+
deviceMemory >= 4 && hardwareConcurrency >= 4 ? "high" : "medium";
|
|
3536
|
+
})();
|
|
3537
|
+
setPerformanceTier(tier), mergedParams = ((baseParams, performanceTier) => {
|
|
3538
|
+
if ("high" === performanceTier) return baseParams;
|
|
3539
|
+
// No adjustment needed
|
|
3540
|
+
const multiplier = "low" === performanceTier ? .7 : .85;
|
|
3541
|
+
return {
|
|
3542
|
+
...baseParams,
|
|
3543
|
+
distortionOctaves: Math.max(2, Math.round((baseParams.distortionOctaves || 5) * multiplier)),
|
|
3544
|
+
displacementScale: (baseParams.displacementScale || 1) * multiplier,
|
|
3545
|
+
blurAmount: (baseParams.blurAmount || 1) * multiplier,
|
|
3546
|
+
animationSpeed: (baseParams.animationSpeed || 1) * multiplier,
|
|
3547
|
+
chromaticIntensity: (baseParams.chromaticIntensity || 1) * multiplier
|
|
3548
|
+
};
|
|
3549
|
+
})(mergedParams, tier);
|
|
3550
|
+
}
|
|
3551
|
+
setResponsiveParams(mergedParams);
|
|
3552
|
+
}), [ enabled, enablePerformanceAdjustment, debug ]), debouncedCalculate = (func => {
|
|
3553
|
+
const timeoutRef = useRef(null);
|
|
3554
|
+
return useEffect((() => () => {
|
|
3555
|
+
timeoutRef.current && clearTimeout(timeoutRef.current);
|
|
3556
|
+
}), []), useCallback(((...args) => {
|
|
3557
|
+
timeoutRef.current && clearTimeout(timeoutRef.current), timeoutRef.current = setTimeout((() => {
|
|
3558
|
+
func(...args);
|
|
3559
|
+
}), 200);
|
|
3560
|
+
}), [ func, 200 ]);
|
|
3561
|
+
})(calculateParams);
|
|
3562
|
+
/**
|
|
3563
|
+
* Debounced parameter calculation for resize events
|
|
3564
|
+
*/
|
|
3565
|
+
/**
|
|
3566
|
+
* Handle window resize
|
|
3567
|
+
*/
|
|
3568
|
+
useEffect((() => {
|
|
3569
|
+
if (enabled)
|
|
3570
|
+
// Cleanup
|
|
3571
|
+
// Initial calculation
|
|
3572
|
+
return calculateParams(),
|
|
3573
|
+
// Listen for resize events
|
|
3574
|
+
window.addEventListener("resize", debouncedCalculate), () => {
|
|
3575
|
+
window.removeEventListener("resize", debouncedCalculate);
|
|
3576
|
+
};
|
|
3577
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3578
|
+
}), [ enabled ]), useCallback((() => {
|
|
3579
|
+
calculateParams();
|
|
3580
|
+
}), [ calculateParams ]);
|
|
3581
|
+
}({
|
|
3582
|
+
baseParams: {
|
|
3583
|
+
...useMemo((() =>
|
|
3584
|
+
/**
|
|
3585
|
+
* Get preset by name
|
|
3586
|
+
*/
|
|
3587
|
+
function(presetName) {
|
|
3588
|
+
switch (presetName) {
|
|
3589
|
+
case "performance":
|
|
3590
|
+
return PERFORMANCE_PRESET;
|
|
3591
|
+
|
|
3592
|
+
case "balanced":
|
|
3593
|
+
default:
|
|
3594
|
+
return BALANCED_PRESET;
|
|
3595
|
+
|
|
3596
|
+
case "quality":
|
|
3597
|
+
return QUALITY_PRESET;
|
|
3598
|
+
}
|
|
3599
|
+
}
|
|
3600
|
+
/**
|
|
3601
|
+
* Mobile-optimized responsive breakpoints
|
|
3602
|
+
* Automatically applies appropriate presets based on viewport size
|
|
3603
|
+
*/ (devicePreset)), [ devicePreset ]),
|
|
3604
|
+
distortionOctaves: Math.round((displacementScale || ATOMIX_GLASS.DEFAULTS.DISPLACEMENT_SCALE) / 25),
|
|
3605
|
+
displacementScale: displacementScale || ATOMIX_GLASS.DEFAULTS.DISPLACEMENT_SCALE,
|
|
3606
|
+
blurAmount: blurAmount || ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT,
|
|
3607
|
+
saturation: saturation || ATOMIX_GLASS.DEFAULTS.SATURATION,
|
|
3608
|
+
aberrationIntensity: aberrationIntensity || ATOMIX_GLASS.DEFAULTS.ABERRATION_INTENSITY,
|
|
3609
|
+
animationSpeed: 1,
|
|
3610
|
+
chromaticIntensity: aberrationIntensity || ATOMIX_GLASS.DEFAULTS.ABERRATION_INTENSITY
|
|
3611
|
+
},
|
|
3612
|
+
breakpoints: MOBILE_OPTIMIZED_BREAKPOINTS,
|
|
3613
|
+
enabled: !disableResponsiveBreakpoints && "undefined" != typeof window,
|
|
3614
|
+
// Enable unless disabled
|
|
3615
|
+
debug: !1
|
|
3616
|
+
});
|
|
3617
|
+
// Performance monitoring - tracks FPS, frame time, memory usage
|
|
3618
|
+
const {metrics: performanceMetrics, recommendedQuality: recommendedQuality, isUnderperforming: isUnderperforming, setQualityLevel: setQualityLevel, toggleMonitoring: toggleMonitoring} =
|
|
3619
|
+
/**
|
|
3620
|
+
* Performance Monitor Hook
|
|
3621
|
+
*
|
|
3622
|
+
* Real-time performance tracking with automatic quality scaling.
|
|
3623
|
+
* Monitors FPS, frame time, and GPU memory to optimize glass effects.
|
|
3624
|
+
*
|
|
3625
|
+
* Features:
|
|
3626
|
+
* - Real-time FPS measurement
|
|
3627
|
+
* - Frame timing analysis
|
|
3628
|
+
* - Automatic quality scaling
|
|
3629
|
+
* - Debug overlay option
|
|
3630
|
+
* - Manual override capability
|
|
3631
|
+
*
|
|
3632
|
+
* @example
|
|
3633
|
+
* ```typescript
|
|
3634
|
+
* const { metrics, recommendedQuality, setQualityLevel } = usePerformanceMonitor({
|
|
3635
|
+
* targetFps: 60,
|
|
3636
|
+
* minFps: 45,
|
|
3637
|
+
* debug: true,
|
|
3638
|
+
* });
|
|
3639
|
+
* ```
|
|
3640
|
+
*
|
|
3641
|
+
* @param config Monitor configuration
|
|
3642
|
+
* @returns Performance metrics and controls
|
|
3643
|
+
*/
|
|
3644
|
+
function(config = {}) {
|
|
3645
|
+
const {enabled: enabled = !0, targetFps: targetFps = 60, minFps: minFps = 45, scaleUpThreshold: scaleUpThreshold = 58, lowFpsFrames: lowFpsFrames = 3, highFpsFrames: highFpsFrames = 10, debug: debug = !1, showOverlay: showOverlay = !1} = config, [metrics, setMetrics] = useState({
|
|
3646
|
+
fps: 0,
|
|
3647
|
+
frameTime: 0,
|
|
3648
|
+
gpuMemory: null,
|
|
3649
|
+
qualityLevel: "medium",
|
|
3650
|
+
timestamp: 0,
|
|
3651
|
+
isAutoScaling: !0,
|
|
3652
|
+
lowFpsCount: 0
|
|
3653
|
+
}), [manualOverride, setManualOverride] = useState(!1), [isEnabled, setIsEnabled] = useState(enabled), frameCountRef = useRef(0), lastFpsUpdateRef = useRef(0), lastFrameTimeRef = useRef(0), animationFrameRef = useRef(null), lowFpsCountRef = useRef(0), highFpsCountRef = useRef(0), qualityLevelRef = useRef("medium"), updateMetrics = useCallback((newMetrics => {
|
|
3654
|
+
setMetrics((prev => ({
|
|
3655
|
+
...prev,
|
|
3656
|
+
...newMetrics,
|
|
3657
|
+
timestamp: performance.now()
|
|
3658
|
+
})));
|
|
3659
|
+
}), []), applyAutoScaling = useCallback((currentFps => {
|
|
3660
|
+
if (manualOverride) return;
|
|
3661
|
+
const currentQuality = qualityLevelRef.current;
|
|
3662
|
+
// Check for low FPS
|
|
3663
|
+
if (currentFps < minFps) lowFpsCountRef.current++, highFpsCountRef.current = 0,
|
|
3664
|
+
// Scale down after N consecutive low-FPS frames
|
|
3665
|
+
lowFpsCountRef.current >= lowFpsFrames && "low" !== currentQuality && (qualityLevelRef.current = "low",
|
|
3666
|
+
updateMetrics({
|
|
3667
|
+
qualityLevel: "low",
|
|
3668
|
+
lowFpsCount: lowFpsCountRef.current
|
|
3669
|
+
})); else if (currentFps >= scaleUpThreshold) {
|
|
3670
|
+
// Scale up after N consecutive high-FPS frames
|
|
3671
|
+
if (highFpsCountRef.current++, lowFpsCountRef.current = 0, highFpsCountRef.current >= highFpsFrames) {
|
|
3672
|
+
const newQuality = "low" === currentQuality ? "medium" : "high";
|
|
3673
|
+
qualityLevelRef.current = newQuality, updateMetrics({
|
|
3674
|
+
qualityLevel: newQuality,
|
|
3675
|
+
lowFpsCount: 0
|
|
3676
|
+
}), highFpsCountRef.current = 0;
|
|
3677
|
+
}
|
|
3678
|
+
} else
|
|
3679
|
+
// FPS in normal range, reset counters
|
|
3680
|
+
lowFpsCountRef.current = 0, highFpsCountRef.current = 0;
|
|
3681
|
+
}), [ manualOverride, minFps, scaleUpThreshold, lowFpsFrames, highFpsFrames, debug, updateMetrics ]), measureFrame = useCallback((currentTime => {
|
|
3682
|
+
if (!isEnabled) return;
|
|
3683
|
+
frameCountRef.current++;
|
|
3684
|
+
// Calculate frame time
|
|
3685
|
+
const frameTime = currentTime - lastFrameTimeRef.current;
|
|
3686
|
+
// Update FPS every 100ms for responsiveness
|
|
3687
|
+
if (lastFrameTimeRef.current = currentTime, currentTime - lastFpsUpdateRef.current >= 100) {
|
|
3688
|
+
const elapsed = currentTime - lastFpsUpdateRef.current, fps = Math.round(1e3 * frameCountRef.current / elapsed);
|
|
3689
|
+
// Apply auto-scaling
|
|
3690
|
+
applyAutoScaling(fps), updateMetrics({
|
|
3691
|
+
fps: fps,
|
|
3692
|
+
frameTime: frameTime,
|
|
3693
|
+
qualityLevel: qualityLevelRef.current,
|
|
3694
|
+
lowFpsCount: lowFpsCountRef.current
|
|
3695
|
+
}),
|
|
3696
|
+
// Reset for next measurement period
|
|
3697
|
+
frameCountRef.current = 0, lastFpsUpdateRef.current = currentTime;
|
|
3698
|
+
}
|
|
3699
|
+
// Continue measurement loop
|
|
3700
|
+
animationFrameRef.current = requestAnimationFrame(measureFrame);
|
|
3701
|
+
}), [ isEnabled, applyAutoScaling, updateMetrics ]);
|
|
3702
|
+
/**
|
|
3703
|
+
* Initialize GPU memory tracking
|
|
3704
|
+
*/
|
|
3705
|
+
useEffect((() => {
|
|
3706
|
+
if (!isEnabled || "undefined" == typeof window) return;
|
|
3707
|
+
let mounted = !0;
|
|
3708
|
+
return (async () => {
|
|
3709
|
+
const memory = await new Promise((resolve => {
|
|
3710
|
+
// Check for WebGL debug renderer info
|
|
3711
|
+
if ("undefined" != typeof window && "undefined" != typeof document) try {
|
|
3712
|
+
const canvas = document.createElement("canvas"), gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
|
|
3713
|
+
if (gl) {
|
|
3714
|
+
const debugInfo = gl.getExtension("WEBGL_debug_renderer_info");
|
|
3715
|
+
if (debugInfo) {
|
|
3716
|
+
var _context, _context2, _context3;
|
|
3717
|
+
// Note: Actual memory info is not directly available via WebGL
|
|
3718
|
+
// We estimate based on renderer
|
|
3719
|
+
const renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
|
|
3720
|
+
// Rough estimation based on renderer type
|
|
3721
|
+
return void ((null == (_context = renderer) ? void 0 : Function.call.bind(_includesInstanceProperty(_context), _context))?.("Integrated") ? resolve(256) : (null == (_context2 = renderer) ? void 0 : Function.call.bind(_includesInstanceProperty(_context2), _context2))?.("AMD") || (null == (_context3 = renderer) ? void 0 : Function.call.bind(_includesInstanceProperty(_context3), _context3))?.("NVIDIA") ? resolve(512) : resolve(null));
|
|
3722
|
+
}
|
|
3723
|
+
}
|
|
3724
|
+
} catch (e) {
|
|
3725
|
+
// WebGL not available or error occurred
|
|
3726
|
+
}
|
|
3727
|
+
resolve(null);
|
|
3728
|
+
}));
|
|
3729
|
+
mounted && updateMetrics({
|
|
3730
|
+
gpuMemory: memory
|
|
3731
|
+
});
|
|
3732
|
+
})(), () => {
|
|
3733
|
+
mounted = !1;
|
|
3734
|
+
};
|
|
3735
|
+
}), [ isEnabled, updateMetrics ]),
|
|
3736
|
+
/**
|
|
3737
|
+
* Start/stop monitoring based on enabled state
|
|
3738
|
+
*/
|
|
3739
|
+
useEffect((() => {
|
|
3740
|
+
if (isEnabled)
|
|
3741
|
+
// Cleanup
|
|
3742
|
+
// Initialize
|
|
3743
|
+
return lastFpsUpdateRef.current = performance.now(), lastFrameTimeRef.current = performance.now(),
|
|
3744
|
+
animationFrameRef.current = requestAnimationFrame(measureFrame), () => {
|
|
3745
|
+
null !== animationFrameRef.current && (cancelAnimationFrame(animationFrameRef.current),
|
|
3746
|
+
animationFrameRef.current = null);
|
|
3747
|
+
};
|
|
3748
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3749
|
+
null !== animationFrameRef.current && (cancelAnimationFrame(animationFrameRef.current),
|
|
3750
|
+
animationFrameRef.current = null);
|
|
3751
|
+
}), [ isEnabled ]);
|
|
3752
|
+
// measureFrame is stable via useCallback, avoid re-creating RAF loop
|
|
3753
|
+
/**
|
|
3754
|
+
* Manually set quality level (disables auto-scaling)
|
|
3755
|
+
*/
|
|
3756
|
+
const setQualityLevel = useCallback((level => {
|
|
3757
|
+
setManualOverride(!0), qualityLevelRef.current = level, updateMetrics({
|
|
3758
|
+
qualityLevel: level,
|
|
3759
|
+
isAutoScaling: !1
|
|
3760
|
+
});
|
|
3761
|
+
}), [ updateMetrics, debug ]), resetAutoScaling = useCallback((() => {
|
|
3762
|
+
setManualOverride(!1), lowFpsCountRef.current = 0, highFpsCountRef.current = 0,
|
|
3763
|
+
updateMetrics({
|
|
3764
|
+
isAutoScaling: !0,
|
|
3765
|
+
lowFpsCount: 0
|
|
3766
|
+
});
|
|
3767
|
+
}), [ updateMetrics, debug ]), toggleMonitoring = useCallback((() => {
|
|
3768
|
+
setIsEnabled((prev => !prev));
|
|
3769
|
+
}), []);
|
|
3770
|
+
/**
|
|
3771
|
+
* Reset to auto-scaling mode
|
|
3772
|
+
*/ var fps, currentQuality;
|
|
3773
|
+
return {
|
|
3774
|
+
metrics: metrics,
|
|
3775
|
+
recommendedQuality: (fps = metrics.fps, currentQuality = metrics.qualityLevel, fps >= 58 ? "high" : fps >= 45 ? "high" === currentQuality ? "high" : "medium" : "low"),
|
|
3776
|
+
isUnderperforming: metrics.fps < minFps,
|
|
3777
|
+
setQualityLevel: setQualityLevel,
|
|
3778
|
+
resetAutoScaling: resetAutoScaling,
|
|
3779
|
+
toggleMonitoring: toggleMonitoring
|
|
3780
|
+
};
|
|
3781
|
+
}({
|
|
3782
|
+
enabled: !1,
|
|
3783
|
+
// We'll toggle manually based on prop
|
|
3784
|
+
debug: !1,
|
|
3785
|
+
showOverlay: !1
|
|
3786
|
+
});
|
|
3787
|
+
// Auto-start performance monitoring if enabled (only in development)
|
|
3788
|
+
React.useEffect((() => {
|
|
3789
|
+
"development" === process.env.NODE_ENV && window?.enablePerformanceMonitoring && toggleMonitoring();
|
|
3790
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3791
|
+
}), []);
|
|
3792
|
+
// Only run once on mount
|
|
3793
|
+
const isOverLight = useMemo((() => overLightConfig.isOverLight), [ overLightConfig.isOverLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, rootLayoutStyle = useMemo((() => {
|
|
2711
3794
|
if (!isFixedOrSticky) return {};
|
|
2712
3795
|
const {position: p, top: t, left: l, right: r, bottom: b} = restStyle;
|
|
2713
3796
|
return {
|
|
@@ -2727,7 +3810,10 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2727
3810
|
bottom: b
|
|
2728
3811
|
}
|
|
2729
3812
|
};
|
|
2730
|
-
}), [ isFixedOrSticky, restStyle ])
|
|
3813
|
+
}), [ isFixedOrSticky, restStyle ]);
|
|
3814
|
+
// Calculate base style with transforms
|
|
3815
|
+
// When layout is hoisted to the root, strip those props from the container
|
|
3816
|
+
useMemo((() => {
|
|
2731
3817
|
if (isFixedOrSticky) {
|
|
2732
3818
|
const {position: _p, top: _t, left: _l, right: _r, bottom: _b, ...visualStyle} = restStyle;
|
|
2733
3819
|
return {
|
|
@@ -2743,18 +3829,20 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2743
3829
|
transform: transformStyle
|
|
2744
3830
|
}
|
|
2745
3831
|
};
|
|
2746
|
-
}), [ isFixedOrSticky, restStyle, effectiveWithoutEffects, transformStyle ])
|
|
3832
|
+
}), [ isFixedOrSticky, restStyle, effectiveWithoutEffects, transformStyle ]);
|
|
3833
|
+
// Build className with state modifiers
|
|
3834
|
+
const componentClassName = [ 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 ].filter(Boolean).join(" "), positionStyles = useMemo((() => ({
|
|
2747
3835
|
position: isFixedOrSticky ? "absolute" : restStyle.position || "absolute",
|
|
2748
3836
|
top: isFixedOrSticky ? 0 : restStyle.top || 0,
|
|
2749
3837
|
left: isFixedOrSticky ? 0 : restStyle.left || 0
|
|
2750
3838
|
})), [ isFixedOrSticky, restStyle.position, restStyle.top, restStyle.left ]), adjustedSize = useMemo((() => {
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
};
|
|
3839
|
+
// Keep a reference to positionStyles to avoid unused-variable lint,
|
|
3840
|
+
// but sizing is driven by explicit width/height or measured size.
|
|
3841
|
+
positionStyles.position;
|
|
3842
|
+
const resolveLength = (value, measured) => void 0 !== value ? "number" == typeof value ? `${value}px` : value : measured > 0 ? `${measured}px` : "100%", effectiveWidth = width ?? restStyle.width, effectiveHeight = height ?? restStyle.height;
|
|
2755
3843
|
return {
|
|
2756
|
-
width:
|
|
2757
|
-
height:
|
|
3844
|
+
width: resolveLength(effectiveWidth, glassSize.width),
|
|
3845
|
+
height: resolveLength(effectiveHeight, glassSize.height)
|
|
2758
3846
|
};
|
|
2759
3847
|
}), [ width, height, restStyle.width, restStyle.height, positionStyles.position, glassSize.width, glassSize.height ]), gradientValues = useMemo((() => {
|
|
2760
3848
|
const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT;
|
|
@@ -2803,9 +3891,10 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2803
3891
|
},
|
|
2804
3892
|
"--atomix-glass-radius": `${effectiveBorderRadius}px`,
|
|
2805
3893
|
"--atomix-glass-transform": transformStyle || "none",
|
|
2806
|
-
|
|
2807
|
-
"--atomix-glass-
|
|
2808
|
-
"--atomix-glass-
|
|
3894
|
+
// Internal decorative layers are positioned relative to the root;
|
|
3895
|
+
"--atomix-glass-position": rootLayoutStyle.position,
|
|
3896
|
+
"--atomix-glass-top": `${isFixedOrSticky ? rootLayoutStyle.top : 0}px`,
|
|
3897
|
+
"--atomix-glass-left": `${isFixedOrSticky ? rootLayoutStyle.left : 0}px`,
|
|
2809
3898
|
"--atomix-glass-width": adjustedSize.width,
|
|
2810
3899
|
"--atomix-glass-height": adjustedSize.height,
|
|
2811
3900
|
"--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.09375rem)",
|
|
@@ -2825,10 +3914,12 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2825
3914
|
"--atomix-glass-overlay-highlight-opacity": opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER,
|
|
2826
3915
|
"--atomix-glass-overlay-highlight-bg": `radial-gradient(circle at ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.POSITION_X}% ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.POSITION_Y}%, rgba(255, 255, 255, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.WHITE_OPACITY}) 0%, transparent ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.STOP}%)`
|
|
2827
3916
|
};
|
|
2828
|
-
}), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle,
|
|
3917
|
+
}), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, adjustedSize, isOverLight, overLightConfig.borderOpacity, customZIndex, rootLayoutStyle, isFixedOrSticky ]), renderBackgroundLayer = layerType => jsx("div", {
|
|
2829
3918
|
className: [ 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 ].filter(Boolean).join(" ")
|
|
2830
3919
|
});
|
|
2831
|
-
|
|
3920
|
+
// Calculate position and size styles for internal layers
|
|
3921
|
+
// When root is fixed/sticky, internal layers use absolute (relative to root)
|
|
3922
|
+
return jsxs("div", {
|
|
2832
3923
|
...rest,
|
|
2833
3924
|
className: componentClassName,
|
|
2834
3925
|
style: {
|
|
@@ -2845,7 +3936,12 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2845
3936
|
ref: glassRef,
|
|
2846
3937
|
contentRef: contentRef,
|
|
2847
3938
|
className: className,
|
|
2848
|
-
style:
|
|
3939
|
+
style: {
|
|
3940
|
+
...restStyle,
|
|
3941
|
+
...!isFixedOrSticky && {
|
|
3942
|
+
position: "relative"
|
|
3943
|
+
}
|
|
3944
|
+
},
|
|
2849
3945
|
borderRadius: effectiveBorderRadius,
|
|
2850
3946
|
displacementScale: effectiveWithoutEffects ? 0 : "shader" === mode ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_DISPLACEMENT : isOverLight ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.OVER_LIGHT_DISPLACEMENT : displacementScale,
|
|
2851
3947
|
blurAmount: effectiveWithoutEffects ? 0 : blurAmount,
|
|
@@ -2876,11 +3972,19 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2876
3972
|
},
|
|
2877
3973
|
onClick: onClick,
|
|
2878
3974
|
mode: mode,
|
|
2879
|
-
transform: baseStyle.transform,
|
|
2880
3975
|
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
2881
3976
|
effectiveReducedMotion: effectiveReducedMotion,
|
|
2882
3977
|
shaderVariant: shaderVariant,
|
|
2883
3978
|
withLiquidBlur: withLiquidBlur,
|
|
3979
|
+
// Phase 1: Animation System props
|
|
3980
|
+
shaderTime: getShaderTime(),
|
|
3981
|
+
withTimeAnimation: withTimeAnimation,
|
|
3982
|
+
animationSpeed: animationSpeed,
|
|
3983
|
+
withMultiLayerDistortion: withMultiLayerDistortion,
|
|
3984
|
+
distortionOctaves: distortionOctaves,
|
|
3985
|
+
distortionLacunarity: distortionLacunarity,
|
|
3986
|
+
distortionGain: distortionGain,
|
|
3987
|
+
distortionQuality: distortionQuality,
|
|
2884
3988
|
children: children
|
|
2885
3989
|
}), Boolean(onClick) && jsxs(Fragment, {
|
|
2886
3990
|
children: [ jsx("div", {
|
|
@@ -2904,6 +4008,10 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2904
4008
|
}), jsx("span", {
|
|
2905
4009
|
className: ATOMIX_GLASS.BORDER_2_CLASS
|
|
2906
4010
|
}) ]
|
|
4011
|
+
}), debugPerformance && performanceMetrics && jsx(PerformanceDashboard, {
|
|
4012
|
+
metrics: performanceMetrics,
|
|
4013
|
+
isVisible: !0,
|
|
4014
|
+
onClose: () => {}
|
|
2907
4015
|
}) ]
|
|
2908
4016
|
});
|
|
2909
4017
|
}
|
|
@@ -6511,7 +7619,9 @@ const smoothStep = (a, b, t) => {
|
|
|
6511
7619
|
return this.canvasDPI;
|
|
6512
7620
|
}
|
|
6513
7621
|
},
|
|
6514
|
-
|
|
7622
|
+
createFBMEngine: createFBMEngine,
|
|
7623
|
+
fragmentShaders: fragmentShaders,
|
|
7624
|
+
liquidGlassWithTime: liquidGlassWithTime
|
|
6515
7625
|
}, Symbol.toStringTag, {
|
|
6516
7626
|
value: "Module"
|
|
6517
7627
|
}));
|