@scriptedpixels/liquid-glass-vue 0.0.1 → 0.0.2

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