@scriptedpixels/liquid-glass-vue 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,582 @@
1
+ (function(global, factory) {
2
+ typeof exports === "object" && typeof module !== "undefined" ? factory(require("vue")) : typeof define === "function" && define.amd ? define(["vue"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.Vue));
3
+ })(this, function(vue) {
4
+ "use strict";
5
+ const displacementMap = "data:image/jpeg;base64,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cUAUAkEkziomgGgkoxZGgxZFQFQlYnQHRdPfj/10KCSCKESCNiVkViPSLpD0h6I0Q0I0A2IoBWBIJIBKBIJoJIJ2R2J0JWBUJ0JUB0XTv479dFZDYiglYigkhEgjZFQjRFQjRFQjQigFYigHYigmgEgmglYlYnQlQlYlQHQlQnQ9P/kf1yVkNiNCNkNiVENiNiViNEViNkVCVgKCViViViSCViSCVgdCViVCViVCdgVCVCdD1D+U/XBWQ2I0I2Q2JUQ2I0JWQ0I2JUQ2JUI2JUI2J0JWJWJWA2R0BWJ0I2JUJ2BUJUJ0P//EABkQAQEBAQEBAAAAAAAAAAAAAAECABEDEP/aAAgBAQABAgB1atWrVq1atWrVq1atWrVq1atWrVq1atWrVq+OrVq1atWrVq1atWrVq1atWrVq1atWrVq1atXxVppppppdWrVq1atWrVq1NNNNNNNNNNNPVWmmmmms6tWrVq1atWpppppppppppppp6q0000uc51atWrVq1ammmmmmmmmmmmmt1Vpppc5znVq1atWrVqaaaaaaaaaaaaaeqtNLnOc51atWrVq1ammmmmmmmmmmmmnqrS5znOc6tWrVq16222mmmmmmlVppp6tKuc5znOrVq1a9TbbbbTTTTTSq000qtLnOc5zq1atWrW0222200000qqqtKqrnOc5zq1atTbbbbbbbbTTTSqqqqqq5znOc6tTTTbbbbbbbbTTTSqqqqrlVznOctNNNtttttttttNNNNKqqqrqznKqrTTTTbbbbbbbbbTTTSqqqqrqznOc5aaaabbbbbbbbbaaaaVVVVVdWc5znVq1NNttttttttttNNKqqqqudWc5znVq16tbbbbbbbbbbTTSqqqq5XVnOc6tWrVrb1tttttttttNNKqqqqrWrK5VWmmm2230bbbbbbaaaXOc5zlVa1KuVVppptttt9G22222mmlzlVznK6tWVVWmmmm2222222222mlznOc5znLWppVVWmmm22222229bTWrOc5znOcq1qaaVpWmm222222229erVqznOc5znKtatStK0rTbTTbbbberXr1as5znOc5aVpppppWlabaabbbb1ta9WrVnOc5znU0rTTTTTTTTTbTTbbbTWvVq1as5znOdTTStNNNNNNNNNtNNtttN6tWvVq1ZznOrU00rTTTTTTTTTTTTTbTWvVq1atWrOc6tTTTStNNNNNNNNNNtNNtNa9WrVq1Z1Z1NNNNNK1q1NNNNNNNNNNNtNatWrVq1atWrU00000rWrVq1atWrVq1alaaa1atWrVq1NNNammmmla1atWrVq1aterVq16tWrVnVqa1NK1qaaaVX/xAAWEAADAAAAAAAAAAAAAAAAAAAhgJD/2gAIAQEAAz8AaExf/8QAGhEBAQEBAQEBAAAAAAAAAAAAAQISEQADEP/aAAgBAgEBAgDx48ePHjx48ePHjx48ePHjx48ePHjx48ePHj86IiIiIiInjx48ePHjx48IiIiIj0oooooooooRERER73ve60UUUUUUVrWiiiiiihERERER73ve97ooooorRWiiiiihKERERER73ve973RRRRWtFFFFFFCIiIiIiPe973ve60UUVrRRRRRRQiIlCIiI973ve973pRRWiiiiiiiiiiiiiiihEe973ve973RRWtFFFFFFFFFFFFFFFFFFa13ve973WitaKKKKKKKKKKKKKKKKKK1rWtd1rutFa1oooooooooooosssooorWta1rWta1rRRRRRRRRRRZZZZZZZZZWta1rWta1rRRRRRRRRZZZZZZZZZZZZe9a1rWta1rWitaKLLLLLLLLLLLLLLLLL3rWta1rWtFbLLLLLLLLLLLLLLLLLLLL3vWta1rWita1ssssssss+hZZZZZZZZe961rWta0Vre97LLLLLLLLLLLPoWWWWWXrWta1oorWta3ssss+hZZZZ9Cyyyyyyyyiita1orWta1ve9llllllllllllllllFFa0VorWta1ve9llllllllllllllllllFFFaK1rWta1rWiyyyyyyyyyyyyiiiiiiitFFa1rWta1oosoosssssoooosoooorRRRWta1rWta0UUUUUWUUUUUUUUUUUVoooorWta1rWtaKKKKKKmiiiiiiiiiiiiiiitd73ve61oSiiipoqaKKKKKKKKKK0UUUVrve973vREREZoSihEooooorRRRRWtd73ve9EREREREoSiiiiitFllllla73ve9ERERERESiiiiiitH0PoWWWWVrXe96IiIiMoiJRRRRRRWjwlFFllllFFd6IiIiIlCUUUUUUUUUePHjx48ePCIiIiIiIiUUUUUUUUUUUePHjx48ePHjx48ePHjx48IiUUUUUUJRRRX//xAAWEQADAAAAAAAAAAAAAAAAAAABYJD/2gAIAQIBAz8AtEV7/8QAFxEBAQEBAAAAAAAAAAAAAAAAAAECEP/aAAgBAwEBAgCtNNNNNNNNNNNNNNNNNNNNNNNNNNNNNcrTTTTTTTTTTTTTTTTTTTTTTTTTTTTTXKrTTTTTTTU000000000000000000001FVpppppqampqaaaaaaaaaaaaaaaaaaaa5Vaaaaampqampqammmmmmmmmmmlaaaaaaiq0001NTU1NTU1NTTTTTTTTTTSqqtNNNcqtNNSyzU1LNTU1NTTTTTTTTTSqqq001ytNLLLLNTU1NTU1NTbbbTTTTTSqqq001ytNLLLLLNTU1NTU3NttttNNNNNKqq001KrSyyyyyzU1NTU3Nzc02220000qqqqrSqqyyyyyzU1NTU3Nzc3NttttNNNKqqqqqqssssss1NTU3Nzc3NzbbbbTTTSqqqqqqrLLLLLNTU1Nzc3Nzc22220000qqqqqqqqssss1NTU3Nzc3NzbbbbbTTSqqqqqqqqqqzU1NTc3Nzc3Nzbc22000qqqqqqqqqqqtTU3Nzc3Nzc3NtzbTTSqqqqrKqqqqqtNNzc23Nzc3Nzc3NTU1KqqqrKqqqqqtNNNNttzc3Nzc3NzU1NLLLLLKqqqqqqqq0022223Nzc3NzU1NSyyyyyyqqqqqqqrTTbbbbc3Nzc3NTU1LLLLLLKsqqqqqqrTTTTbbbc3Nzc1NTUsssssssqqqqqqrTTTTTbbbTc3NTU1NTUsssssqqqqqqqq0000222023NTU1NTUsssssqqqqqqqq000000003NTU1NTU1LLLLLNKrTSqqqqtNNNNNNtNNTU1NSzUssss00qq0qqqqrTTTTTTTTTU1NTUs1LLLNNNKrTTTSqqq00000000001NTU1LNTU0000qtNNNKqqqtNNNNNNNNTU1NTUs1NNNNNKss1NNNK00qtK0000001NNTU0s000000qq000001NKrStNNNNK1NNNNStNNNNNKqtNNNNNNNK0000000rU0000rTTTTTSq00000rTTTTTTTTTTTTTTTTStNNNNKr/xAAUEQEAAAAAAAAAAAAAAAAAAACg/9oACAEDAQM/AAAf/9k=";
6
+ const _hoisted_1 = ["id"];
7
+ const _hoisted_2 = ["offset"];
8
+ const _hoisted_3 = ["id"];
9
+ const _hoisted_4 = ["href"];
10
+ const _hoisted_5 = {
11
+ in: "EDGE_INTENSITY",
12
+ result: "EDGE_MASK"
13
+ };
14
+ const _hoisted_6 = ["tableValues"];
15
+ const _hoisted_7 = ["scale"];
16
+ const _hoisted_8 = ["scale"];
17
+ const _hoisted_9 = ["scale"];
18
+ const _hoisted_10 = ["stdDeviation"];
19
+ const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
20
+ __name: "GlassFilter",
21
+ props: {
22
+ id: {},
23
+ displacementScale: {},
24
+ aberrationIntensity: {},
25
+ width: {},
26
+ height: {}
27
+ },
28
+ setup(__props) {
29
+ const props = __props;
30
+ const edgeMaskOffset = vue.computed(() => {
31
+ return Math.max(30, 80 - props.aberrationIntensity * 2);
32
+ });
33
+ const redDisplacementScale = vue.computed(() => {
34
+ return props.displacementScale * -1;
35
+ });
36
+ const greenDisplacementScale = vue.computed(() => {
37
+ return props.displacementScale * (-1 - props.aberrationIntensity * 0.05);
38
+ });
39
+ const blueDisplacementScale = vue.computed(() => {
40
+ return props.displacementScale * (-1 - props.aberrationIntensity * 0.1);
41
+ });
42
+ const gaussianBlurStdDeviation = vue.computed(() => {
43
+ return Math.max(0.1, 0.5 - props.aberrationIntensity * 0.1);
44
+ });
45
+ const feFuncATableValues = vue.computed(() => {
46
+ return `0 ${props.aberrationIntensity * 0.05} 1`;
47
+ });
48
+ return (_ctx, _cache) => {
49
+ return vue.openBlock(), vue.createElementBlock("svg", {
50
+ style: vue.normalizeStyle({ position: "absolute", width: props.width + "px", height: props.height + "px" }),
51
+ "aria-hidden": "true"
52
+ }, [
53
+ vue.createElementVNode("defs", null, [
54
+ vue.createElementVNode("radialGradient", {
55
+ id: `${props.id}-edge-mask`,
56
+ cx: "50%",
57
+ cy: "50%",
58
+ r: "50%"
59
+ }, [
60
+ _cache[0] || (_cache[0] = vue.createElementVNode("stop", {
61
+ offset: "0%",
62
+ "stop-color": "black",
63
+ "stop-opacity": "0"
64
+ }, null, -1)),
65
+ vue.createElementVNode("stop", {
66
+ offset: `${edgeMaskOffset.value}%`,
67
+ "stop-color": "black",
68
+ "stop-opacity": "0"
69
+ }, null, 8, _hoisted_2),
70
+ _cache[1] || (_cache[1] = vue.createElementVNode("stop", {
71
+ offset: "100%",
72
+ "stop-color": "white",
73
+ "stop-opacity": "1"
74
+ }, null, -1))
75
+ ], 8, _hoisted_1),
76
+ vue.createElementVNode("filter", {
77
+ id: props.id,
78
+ x: "-35%",
79
+ y: "-35%",
80
+ width: "170%",
81
+ height: "170%",
82
+ "color-interpolation-filters": "sRGB"
83
+ }, [
84
+ vue.createElementVNode("feImage", {
85
+ id: "feimage",
86
+ x: "0",
87
+ y: "0",
88
+ width: "100%",
89
+ height: "100%",
90
+ result: "DISPLACEMENT_MAP",
91
+ href: vue.unref(displacementMap),
92
+ preserveAspectRatio: "xMidYMid slice"
93
+ }, null, 8, _hoisted_4),
94
+ _cache[2] || (_cache[2] = vue.createElementVNode("feColorMatrix", {
95
+ in: "DISPLACEMENT_MAP",
96
+ type: "matrix",
97
+ values: "0.3 0.3 0.3 0 0\n 0.3 0.3 0.3 0 0\n 0.3 0.3 0.3 0 0\n 0 0 0 1 0",
98
+ result: "EDGE_INTENSITY"
99
+ }, null, -1)),
100
+ vue.createElementVNode("feComponentTransfer", _hoisted_5, [
101
+ vue.createElementVNode("feFuncA", {
102
+ type: "discrete",
103
+ tableValues: feFuncATableValues.value
104
+ }, null, 8, _hoisted_6)
105
+ ]),
106
+ _cache[3] || (_cache[3] = vue.createElementVNode("feOffset", {
107
+ in: "SourceGraphic",
108
+ dx: "0",
109
+ dy: "0",
110
+ result: "CENTER_ORIGINAL"
111
+ }, null, -1)),
112
+ vue.createElementVNode("feDisplacementMap", {
113
+ in: "SourceGraphic",
114
+ in2: "DISPLACEMENT_MAP",
115
+ scale: redDisplacementScale.value,
116
+ xChannelSelector: "R",
117
+ yChannelSelector: "B",
118
+ result: "RED_DISPLACED"
119
+ }, null, 8, _hoisted_7),
120
+ _cache[4] || (_cache[4] = vue.createElementVNode("feColorMatrix", {
121
+ in: "RED_DISPLACED",
122
+ type: "matrix",
123
+ values: "1 0 0 0 0\n 0 0 0 0 0\n 0 0 0 0 0\n 0 0 0 1 0",
124
+ result: "RED_CHANNEL"
125
+ }, null, -1)),
126
+ vue.createElementVNode("feDisplacementMap", {
127
+ in: "SourceGraphic",
128
+ in2: "DISPLACEMENT_MAP",
129
+ scale: greenDisplacementScale.value,
130
+ xChannelSelector: "R",
131
+ yChannelSelector: "B",
132
+ result: "GREEN_DISPLACED"
133
+ }, null, 8, _hoisted_8),
134
+ _cache[5] || (_cache[5] = vue.createElementVNode("feColorMatrix", {
135
+ in: "GREEN_DISPLACED",
136
+ type: "matrix",
137
+ values: "0 0 0 0 0\n 0 1 0 0 0\n 0 0 0 0 0\n 0 0 0 1 0",
138
+ result: "GREEN_CHANNEL"
139
+ }, null, -1)),
140
+ vue.createElementVNode("feDisplacementMap", {
141
+ in: "SourceGraphic",
142
+ in2: "DISPLACEMENT_MAP",
143
+ scale: blueDisplacementScale.value,
144
+ xChannelSelector: "R",
145
+ yChannelSelector: "B",
146
+ result: "BLUE_DISPLACED"
147
+ }, null, 8, _hoisted_9),
148
+ _cache[6] || (_cache[6] = vue.createElementVNode("feColorMatrix", {
149
+ in: "BLUE_DISPLACED",
150
+ type: "matrix",
151
+ values: "0 0 0 0 0\n 0 0 0 0 0\n 0 0 1 0 0\n 0 0 0 1 0",
152
+ result: "BLUE_CHANNEL"
153
+ }, null, -1)),
154
+ _cache[7] || (_cache[7] = vue.createElementVNode("feBlend", {
155
+ in: "GREEN_CHANNEL",
156
+ in2: "BLUE_CHANNEL",
157
+ mode: "screen",
158
+ result: "GB_COMBINED"
159
+ }, null, -1)),
160
+ _cache[8] || (_cache[8] = vue.createElementVNode("feBlend", {
161
+ in: "RED_CHANNEL",
162
+ in2: "GB_COMBINED",
163
+ mode: "screen",
164
+ result: "RGB_COMBINED"
165
+ }, null, -1)),
166
+ vue.createElementVNode("feGaussianBlur", {
167
+ in: "RGB_COMBINED",
168
+ stdDeviation: gaussianBlurStdDeviation.value,
169
+ result: "ABERRATED_BLURRED"
170
+ }, null, 8, _hoisted_10),
171
+ _cache[9] || (_cache[9] = vue.createStaticVNode('<feComposite in="ABERRATED_BLURRED" in2="EDGE_MASK" operator="in" result="EDGE_ABERRATION"></feComposite><feComponentTransfer in="EDGE_MASK" result="INVERTED_MASK"><feFuncA type="table" tableValues="1 0"></feFuncA></feComponentTransfer><feComposite in="CENTER_ORIGINAL" in2="INVERTED_MASK" operator="in" result="CENTER_CLEAN"></feComposite><feComposite in="EDGE_ABERRATION" in2="CENTER_CLEAN" operator="over"></feComposite>', 4))
172
+ ], 8, _hoisted_3)
173
+ ])
174
+ ], 4);
175
+ };
176
+ }
177
+ });
178
+ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
179
+ __name: "GlassContainer",
180
+ props: {
181
+ className: { default: "" },
182
+ style: { default: () => ({}) },
183
+ displacementScale: { default: 25 },
184
+ blurAmount: { default: 12 },
185
+ saturation: { default: 180 },
186
+ aberrationIntensity: { default: 2 },
187
+ mouseOffset: { default: () => ({ x: 0, y: 0 }) },
188
+ active: { type: Boolean, default: false },
189
+ overLight: { type: Boolean, default: false },
190
+ cornerRadius: { default: 999 },
191
+ padding: { default: "24px 32px" },
192
+ glassSize: { default: () => ({ width: 270, height: 69 }) },
193
+ onClick: {}
194
+ },
195
+ emits: ["mouse-enter", "mouse-leave", "mouse-down", "mouse-up", "click"],
196
+ setup(__props, { expose: __expose, emit: __emit }) {
197
+ const props = __props;
198
+ const emit = __emit;
199
+ const filterId = `glass-filter-${Math.random().toString(36).substr(2, 9)}`;
200
+ const backdropStyle = vue.computed(() => ({
201
+ filter: `url(#${filterId})`,
202
+ backdropFilter: `blur(${(props.overLight ? 20 : 4) + props.blurAmount * 32}px) saturate(${props.saturation}%)`
203
+ }));
204
+ const glassContainerRef = vue.ref(null);
205
+ __expose({ glassContainerRef });
206
+ return (_ctx, _cache) => {
207
+ return vue.openBlock(), vue.createElementBlock("div", {
208
+ ref_key: "glassContainerRef",
209
+ ref: glassContainerRef,
210
+ class: vue.normalizeClass(`relative ${props.className} ${props.active ? "active" : ""} ${Boolean(props.onClick) ? "cursor-pointer" : ""}`),
211
+ style: vue.normalizeStyle(props.style),
212
+ onClick: _cache[4] || (_cache[4] = ($event) => props.onClick && props.onClick())
213
+ }, [
214
+ vue.createVNode(_sfc_main$3, {
215
+ id: filterId,
216
+ displacementScale: props.displacementScale,
217
+ aberrationIntensity: props.aberrationIntensity,
218
+ width: props.glassSize.width,
219
+ height: props.glassSize.height
220
+ }, null, 8, ["displacementScale", "aberrationIntensity", "width", "height"]),
221
+ vue.createElementVNode("div", {
222
+ class: "glass",
223
+ style: vue.normalizeStyle({
224
+ borderRadius: `${props.cornerRadius}px`,
225
+ position: "relative",
226
+ display: "inline-flex",
227
+ alignItems: "center",
228
+ gap: "24px",
229
+ padding: props.padding,
230
+ overflow: "hidden",
231
+ transition: "all 0.2s ease-in-out",
232
+ boxShadow: props.overLight ? "0px 16px 70px rgba(0, 0, 0, 0.75)" : "0px 12px 40px rgba(0, 0, 0, 0.25)"
233
+ }),
234
+ onMouseenter: _cache[0] || (_cache[0] = ($event) => emit("mouse-enter")),
235
+ onMouseleave: _cache[1] || (_cache[1] = ($event) => emit("mouse-leave")),
236
+ onMousedown: _cache[2] || (_cache[2] = ($event) => emit("mouse-down")),
237
+ onMouseup: _cache[3] || (_cache[3] = ($event) => emit("mouse-up"))
238
+ }, [
239
+ vue.createElementVNode("span", {
240
+ class: "glass__warp",
241
+ style: vue.normalizeStyle({
242
+ ...backdropStyle.value,
243
+ position: "absolute",
244
+ inset: "0"
245
+ })
246
+ }, null, 4),
247
+ vue.createElementVNode("div", {
248
+ class: "transition-all duration-150 ease-in-out text-white",
249
+ style: vue.normalizeStyle({
250
+ position: "relative",
251
+ zIndex: 1,
252
+ font: "500 20px/1 system-ui",
253
+ textShadow: props.overLight ? "0px 2px 12px rgba(0, 0, 0, 0)" : "0px 2px 12px rgba(0, 0, 0, 0.4)"
254
+ })
255
+ }, [
256
+ vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
257
+ ], 4)
258
+ ], 36)
259
+ ], 6);
260
+ };
261
+ }
262
+ });
263
+ const _export_sfc = (sfc, props) => {
264
+ const target = sfc.__vccOpts || sfc;
265
+ for (const [key, val] of props) {
266
+ target[key] = val;
267
+ }
268
+ return target;
269
+ };
270
+ const GlassContainer = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-689fee6a"]]);
271
+ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
272
+ __name: "LiquidGlass",
273
+ props: {
274
+ displacementScale: { default: 70 },
275
+ blurAmount: { default: 0.0625 },
276
+ saturation: { default: 140 },
277
+ aberrationIntensity: { default: 2 },
278
+ elasticity: { default: 0.15 },
279
+ cornerRadius: { default: 999 },
280
+ globalMousePos: { default: void 0 },
281
+ mouseOffset: { default: void 0 },
282
+ mouseContainer: { default: null },
283
+ className: { default: "" },
284
+ padding: { default: "24px 32px" },
285
+ style: {},
286
+ overLight: { type: Boolean, default: false },
287
+ onClick: { type: Function, default: () => ({}) }
288
+ },
289
+ setup(__props) {
290
+ const props = __props;
291
+ const glassRef = vue.ref(null);
292
+ const isHovered = vue.ref(false);
293
+ const isActive = vue.ref(false);
294
+ const glassSize = vue.ref({ width: 400, height: 400 });
295
+ const internalGlobalMousePos = vue.ref({ x: 0, y: 0 });
296
+ const internalMouseOffset = vue.ref({ x: 0, y: 0 });
297
+ const globalMousePos = vue.computed(() => props.globalMousePos || internalGlobalMousePos.value);
298
+ const mouseOffset = vue.computed(() => props.mouseOffset || internalMouseOffset.value);
299
+ const handleMouseMove = (e) => {
300
+ var _a;
301
+ const container = props.mouseContainer || ((_a = glassRef.value) == null ? void 0 : _a.glassContainerRef);
302
+ if (!container) return;
303
+ const rect = container.getBoundingClientRect();
304
+ const centerX = rect.left + rect.width / 2;
305
+ const centerY = rect.top + rect.height / 2;
306
+ internalMouseOffset.value = {
307
+ x: (e.clientX - centerX) / rect.width * 100,
308
+ y: (e.clientY - centerY) / rect.height * 100
309
+ };
310
+ internalGlobalMousePos.value = {
311
+ x: e.clientX,
312
+ y: e.clientY
313
+ };
314
+ };
315
+ vue.onMounted(() => {
316
+ const updateGlassSize = () => {
317
+ var _a;
318
+ if ((_a = glassRef.value) == null ? void 0 : _a.glassContainerRef) {
319
+ const rect = glassRef.value.glassContainerRef.getBoundingClientRect();
320
+ glassSize.value = { width: rect.width, height: rect.height };
321
+ }
322
+ };
323
+ updateGlassSize();
324
+ window.addEventListener("resize", updateGlassSize);
325
+ return () => window.removeEventListener("resize", updateGlassSize);
326
+ });
327
+ vue.watch([() => props.globalMousePos, () => props.mouseOffset, glassRef], ([newGlobalMousePos, newMouseOffset]) => {
328
+ var _a;
329
+ if (newGlobalMousePos && newMouseOffset) {
330
+ return;
331
+ }
332
+ const container = props.mouseContainer || ((_a = glassRef.value) == null ? void 0 : _a.glassContainerRef);
333
+ if (!container) return;
334
+ container.addEventListener("mousemove", handleMouseMove);
335
+ }, { immediate: true });
336
+ vue.onUnmounted(() => {
337
+ });
338
+ const calculateFadeInFactor = vue.computed(() => {
339
+ var _a;
340
+ if (!globalMousePos.value.x || !globalMousePos.value.y || !((_a = glassRef.value) == null ? void 0 : _a.glassContainerRef)) {
341
+ return 0;
342
+ }
343
+ const rect = glassRef.value.glassContainerRef.getBoundingClientRect();
344
+ const pillCenterX = rect.left + rect.width / 2;
345
+ const pillCenterY = rect.top + rect.height / 2;
346
+ const pillWidth = glassSize.value.width;
347
+ const pillHeight = glassSize.value.height;
348
+ const edgeDistanceX = Math.max(0, Math.abs(globalMousePos.value.x - pillCenterX) - pillWidth / 2);
349
+ const edgeDistanceY = Math.max(0, Math.abs(globalMousePos.value.y - pillCenterY) - pillHeight / 2);
350
+ const edgeDistance = Math.sqrt(edgeDistanceX * edgeDistanceX + edgeDistanceY * edgeDistanceY);
351
+ const activationZone = 200;
352
+ return edgeDistance > activationZone ? 0 : 1 - edgeDistance / activationZone;
353
+ });
354
+ const calculateElasticTranslation = vue.computed(() => {
355
+ var _a;
356
+ if (!((_a = glassRef.value) == null ? void 0 : _a.glassContainerRef)) {
357
+ return { x: 0, y: 0 };
358
+ }
359
+ const fadeInFactor = calculateFadeInFactor.value;
360
+ const rect = glassRef.value.glassContainerRef.getBoundingClientRect();
361
+ const pillCenterX = rect.left + rect.width / 2;
362
+ const pillCenterY = rect.top + rect.height / 2;
363
+ return {
364
+ x: (globalMousePos.value.x - pillCenterX) * props.elasticity * 0.1 * fadeInFactor,
365
+ y: (globalMousePos.value.y - pillCenterY) * props.elasticity * 0.1 * fadeInFactor
366
+ };
367
+ });
368
+ const calculateDirectionalScale = vue.computed(() => {
369
+ var _a;
370
+ if (!globalMousePos.value.x || !globalMousePos.value.y || !((_a = glassRef.value) == null ? void 0 : _a.glassContainerRef)) {
371
+ return "scale(1)";
372
+ }
373
+ const rect = glassRef.value.glassContainerRef.getBoundingClientRect();
374
+ const pillCenterX = rect.left + rect.width / 2;
375
+ const pillCenterY = rect.top + rect.height / 2;
376
+ const pillWidth = glassSize.value.width;
377
+ const pillHeight = glassSize.value.height;
378
+ const deltaX = globalMousePos.value.x - pillCenterX;
379
+ const deltaY = globalMousePos.value.y - pillCenterY;
380
+ const edgeDistanceX = Math.max(0, Math.abs(deltaX) - pillWidth / 2);
381
+ const edgeDistanceY = Math.max(0, Math.abs(deltaY) - pillHeight / 2);
382
+ const edgeDistance = Math.sqrt(edgeDistanceX * edgeDistanceX + edgeDistanceY * edgeDistanceY);
383
+ const activationZone = 200;
384
+ if (edgeDistance > activationZone) {
385
+ return "scale(1)";
386
+ }
387
+ const fadeInFactor = 1 - edgeDistance / activationZone;
388
+ const centerDistance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
389
+ if (centerDistance === 0) {
390
+ return "scale(1)";
391
+ }
392
+ const normalizedX = deltaX / centerDistance;
393
+ const normalizedY = deltaY / centerDistance;
394
+ const stretchIntensity = Math.min(centerDistance / 300, 1) * props.elasticity * fadeInFactor;
395
+ const scaleX = 1 + Math.abs(normalizedX) * stretchIntensity * 0.3 - Math.abs(normalizedY) * stretchIntensity * 0.15;
396
+ const scaleY = 1 + Math.abs(normalizedY) * stretchIntensity * 0.3 - Math.abs(normalizedX) * stretchIntensity * 0.15;
397
+ return `scaleX(${Math.max(0.8, scaleX)}) scaleY(${Math.max(0.8, scaleY)})`;
398
+ });
399
+ const transformStyle = vue.computed(() => {
400
+ return `translate(calc(-50% + ${calculateElasticTranslation.value.x}px), calc(-50% + ${calculateElasticTranslation.value.y}px)) ${isActive.value && Boolean(props.onClick) ? "scale(0.96)" : calculateDirectionalScale.value}`;
401
+ });
402
+ const baseStyle = vue.computed(() => ({
403
+ ...props.style,
404
+ transform: transformStyle.value,
405
+ transition: "all ease-out 0.2s"
406
+ }));
407
+ const positionStyles = vue.computed(() => {
408
+ var _a, _b, _c;
409
+ return {
410
+ position: ((_a = props.style) == null ? void 0 : _a.position) || "relative",
411
+ top: ((_b = props.style) == null ? void 0 : _b.top) || "50%",
412
+ left: ((_c = props.style) == null ? void 0 : _c.left) || "50%"
413
+ };
414
+ });
415
+ return (_ctx, _cache) => {
416
+ var _a, _b;
417
+ return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
418
+ vue.createVNode(_sfc_main$3, {
419
+ id: `liquid-glass-filter-${((_b = (_a = glassRef.value) == null ? void 0 : _a.glassContainerRef) == null ? void 0 : _b.id) || "default"}`,
420
+ displacementScale: props.overLight ? props.displacementScale * 0.5 : props.displacementScale,
421
+ aberrationIntensity: props.aberrationIntensity,
422
+ width: glassSize.value.width,
423
+ height: glassSize.value.height
424
+ }, null, 8, ["id", "displacementScale", "aberrationIntensity", "width", "height"]),
425
+ vue.createElementVNode("div", {
426
+ class: vue.normalizeClass(`bg-black transition-all duration-150 ease-in-out pointer-events-none ${props.overLight ? "opacity-20" : "opacity-0"}`),
427
+ style: vue.normalizeStyle({
428
+ ...positionStyles.value,
429
+ height: glassSize.value.height + "px",
430
+ width: glassSize.value.width + "px",
431
+ borderRadius: `${props.cornerRadius}px`,
432
+ transform: transformStyle.value,
433
+ transition: baseStyle.value.transition
434
+ })
435
+ }, null, 6),
436
+ vue.createElementVNode("div", {
437
+ class: vue.normalizeClass(`bg-black transition-all duration-150 ease-in-out pointer-events-none mix-blend-overlay ${props.overLight ? "opacity-100" : "opacity-0"}`),
438
+ style: vue.normalizeStyle({
439
+ ...positionStyles.value,
440
+ height: glassSize.value.height + "px",
441
+ width: glassSize.value.width + "px",
442
+ borderRadius: `${props.cornerRadius}px`,
443
+ transform: transformStyle.value,
444
+ transition: baseStyle.value.transition
445
+ })
446
+ }, null, 6),
447
+ vue.createVNode(GlassContainer, {
448
+ ref_key: "glassRef",
449
+ ref: glassRef,
450
+ class: vue.normalizeClass(props.className),
451
+ style: vue.normalizeStyle(baseStyle.value),
452
+ cornerRadius: props.cornerRadius,
453
+ displacementScale: props.overLight ? props.displacementScale * 0.5 : props.displacementScale,
454
+ blurAmount: props.blurAmount,
455
+ saturation: props.saturation,
456
+ aberrationIntensity: props.aberrationIntensity,
457
+ glassSize: glassSize.value,
458
+ padding: props.padding,
459
+ mouseOffset: mouseOffset.value,
460
+ onMouseEnter: _cache[0] || (_cache[0] = ($event) => isHovered.value = true),
461
+ onMouseLeave: _cache[1] || (_cache[1] = ($event) => isHovered.value = false),
462
+ onMouseDown: _cache[2] || (_cache[2] = ($event) => isActive.value = true),
463
+ onMouseUp: _cache[3] || (_cache[3] = ($event) => isActive.value = false),
464
+ active: isActive.value,
465
+ overLight: props.overLight,
466
+ onClick: _cache[4] || (_cache[4] = ($event) => props.onClick && props.onClick())
467
+ }, {
468
+ default: vue.withCtx(() => [
469
+ vue.renderSlot(_ctx.$slots, "default")
470
+ ]),
471
+ _: 3
472
+ }, 8, ["class", "style", "cornerRadius", "displacementScale", "blurAmount", "saturation", "aberrationIntensity", "glassSize", "padding", "mouseOffset", "active", "overLight"]),
473
+ vue.createElementVNode("span", {
474
+ style: vue.normalizeStyle({
475
+ ...positionStyles.value,
476
+ height: glassSize.value.height + "px",
477
+ width: glassSize.value.width + "px",
478
+ borderRadius: `${props.cornerRadius}px`,
479
+ transform: transformStyle.value,
480
+ transition: baseStyle.value.transition,
481
+ pointerEvents: "none",
482
+ mixBlendMode: "screen",
483
+ opacity: 0.2,
484
+ padding: "1.5px",
485
+ WebkitMask: "linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0)",
486
+ WebkitMaskComposite: "xor",
487
+ maskComposite: "exclude",
488
+ boxShadow: "0 0 0 0.5px rgba(255, 255, 255, 0.5) inset, 0 1px 3px rgba(255, 255, 255, 0.25) inset, 0 1px 4px rgba(0, 0, 0, 0.35)",
489
+ background: `linear-gradient(
490
+ ${135 + mouseOffset.value.x * 1.2}deg,
491
+ rgba(255, 255, 255, 0.0) 0%,
492
+ rgba(255, 255, 255, ${0.12 + Math.abs(mouseOffset.value.x) * 8e-3}) ${Math.max(10, 33 + mouseOffset.value.y * 0.3)}%,
493
+ rgba(255, 255, 255, ${0.4 + Math.abs(mouseOffset.value.x) * 0.012}) ${Math.min(90, 66 + mouseOffset.value.y * 0.4)}%,
494
+ rgba(255, 255, 255, 0.0) 100%
495
+ )`
496
+ })
497
+ }, null, 4),
498
+ vue.createElementVNode("span", {
499
+ style: vue.normalizeStyle({
500
+ ...positionStyles.value,
501
+ height: glassSize.value.height + "px",
502
+ width: glassSize.value.width + "px",
503
+ borderRadius: `${props.cornerRadius}px`,
504
+ transform: transformStyle.value,
505
+ transition: baseStyle.value.transition,
506
+ pointerEvents: "none",
507
+ mixBlendMode: "overlay",
508
+ padding: "1.5px",
509
+ WebkitMask: "linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0)",
510
+ WebkitMaskComposite: "xor",
511
+ maskComposite: "exclude",
512
+ boxShadow: "0 0 0 0.5px rgba(255, 255, 255, 0.5) inset, 0 1px 3px rgba(255, 255, 255, 0.25) inset, 0 1px 4px rgba(0, 0, 0, 0.35)",
513
+ background: `linear-gradient(
514
+ ${135 + mouseOffset.value.x * 1.2}deg,
515
+ rgba(255, 255, 255, 0.0) 0%,
516
+ rgba(255, 255, 255, ${0.32 + Math.abs(mouseOffset.value.x) * 8e-3}) ${Math.max(10, 33 + mouseOffset.value.y * 0.3)}%,
517
+ rgba(255, 255, 255, ${0.6 + Math.abs(mouseOffset.value.x) * 0.012}) ${Math.min(90, 66 + mouseOffset.value.y * 0.4)}%,
518
+ rgba(255, 255, 255, 0.0) 100%
519
+ )`
520
+ })
521
+ }, null, 4),
522
+ Boolean(props.onClick) ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [
523
+ vue.createElementVNode("div", {
524
+ style: vue.normalizeStyle({
525
+ ...positionStyles.value,
526
+ height: glassSize.value.height + "px",
527
+ width: glassSize.value.width + 1 + "px",
528
+ borderRadius: `${props.cornerRadius}px`,
529
+ transform: transformStyle.value,
530
+ pointerEvents: "none",
531
+ transition: "all 0.2s ease-out",
532
+ opacity: isHovered.value || isActive.value ? 0.5 : 0,
533
+ backgroundImage: "radial-gradient(circle at 50% 0%, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 50%)",
534
+ mixBlendMode: "overlay"
535
+ })
536
+ }, null, 4),
537
+ vue.createElementVNode("div", {
538
+ style: vue.normalizeStyle({
539
+ ...positionStyles.value,
540
+ height: glassSize.value.height + "px",
541
+ width: glassSize.value.width + 1 + "px",
542
+ borderRadius: `${props.cornerRadius}px`,
543
+ transform: transformStyle.value,
544
+ pointerEvents: "none",
545
+ transition: "all 0.2s ease-out",
546
+ opacity: isActive.value ? 0.5 : 0,
547
+ backgroundImage: "radial-gradient(circle at 50% 0%, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 80%)",
548
+ mixBlendMode: "overlay"
549
+ })
550
+ }, null, 4),
551
+ vue.createElementVNode("div", {
552
+ style: vue.normalizeStyle({
553
+ ...baseStyle.value,
554
+ height: glassSize.value.height + "px",
555
+ width: glassSize.value.width + 1 + "px",
556
+ borderRadius: `${props.cornerRadius}px`,
557
+ position: positionStyles.value.position,
558
+ top: positionStyles.value.top,
559
+ left: positionStyles.value.left,
560
+ pointerEvents: "none",
561
+ transition: "all 0.2s ease-out",
562
+ opacity: isHovered.value ? 0.4 : isActive.value ? 0.8 : 0,
563
+ backgroundImage: "radial-gradient(circle at 50% 0%, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%)",
564
+ mixBlendMode: "overlay"
565
+ })
566
+ }, null, 4)
567
+ ], 64)) : vue.createCommentVNode("", true)
568
+ ], 64);
569
+ };
570
+ }
571
+ });
572
+ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
573
+ __name: "App",
574
+ setup(__props) {
575
+ return (_ctx, _cache) => {
576
+ return vue.openBlock(), vue.createBlock(_sfc_main$1);
577
+ };
578
+ }
579
+ });
580
+ vue.createApp(_sfc_main).mount("#app");
581
+ });
582
+ //# sourceMappingURL=index.umd.js.map