ripppl 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Arman Luthra
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # ripyl
2
+
3
+ Ripple displacement over the **real DOM** (WebGL shader + screen capture). Works in the browser only.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install ripppl
9
+ ```
10
+
11
+ ## Use
12
+
13
+ ```ts
14
+ import { attachRipple } from "ripppl";
15
+
16
+ const handle = attachRipple("#my-button", {
17
+ scope: "#card",
18
+ amplitude: 3,
19
+ shimmer: "oklch(0.72 0.19 45)",
20
+ });
21
+
22
+ handle.update({ speed: 400 });
23
+ handle.trigger({ x: 0.5, y: 0.5 });
24
+ handle.destroy();
25
+ ```
26
+
27
+ - **`attachRipple(trigger, options?)`** — `trigger` is a selector, element, or list of elements that start a capture + ripple on click. Use **`scope`** to clip the effect to a container (e.g. a card); omit it for a full-page ripple.
28
+ - **`update(partial)`** — change tuning; see **`RippleTuning`** in the published types.
29
+ - **`trigger({ x?, y? })`** — fire a ripple at normalized **0–1** coordinates inside the scope (default center).
30
+ - **`destroy()`** — remove listeners and overlay.
31
+
32
+ Build before publish: `npm run build` (runs automatically via `prepublishOnly` on `npm publish`).
33
+
34
+ ## License
35
+
36
+ MIT
@@ -0,0 +1,29 @@
1
+ export type RippleTuning = {
2
+ amplitude?: number;
3
+ frequency?: number;
4
+ speed?: number;
5
+ damping?: number;
6
+ decay?: number;
7
+ duration?: number;
8
+ chromatic?: boolean;
9
+ chromaticIntensity?: number;
10
+ shimmer?: string | false;
11
+ shimmerWidth?: number;
12
+ shimmerDuration?: number;
13
+ shimmerGlowColor?: string;
14
+ };
15
+ export type RippleOptions = RippleTuning & {
16
+ scope?: string | HTMLElement;
17
+ };
18
+ export type RippleHandle = {
19
+ destroy: () => void;
20
+ update: (opts: Partial<RippleTuning>) => void;
21
+ trigger: (opts?: {
22
+ x?: number;
23
+ y?: number;
24
+ }) => void;
25
+ };
26
+ type TriggerInput = string | HTMLElement | NodeListOf<HTMLElement> | HTMLElement[];
27
+ export declare function attachRipple(trigger: TriggerInput, options?: RippleOptions): RippleHandle;
28
+ export {};
29
+ //# sourceMappingURL=ripyl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ripyl.d.ts","sourceRoot":"","sources":["../src/ripyl.ts"],"names":[],"mappings":"AAwFA,MAAM,MAAM,YAAY,GAAG;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG;IACzC,KAAK,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;CAC9B,CAAC;AAgBF,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;IAC9C,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACtD,CAAC;AAEF,KAAK,YAAY,GACb,MAAM,GACN,WAAW,GACX,UAAU,CAAC,WAAW,CAAC,GACvB,WAAW,EAAE,CAAC;AA0JlB,wBAAgB,YAAY,CAC1B,OAAO,EAAE,YAAY,EACrB,OAAO,GAAE,aAAkB,GAC1B,YAAY,CAuWd"}
package/dist/ripyl.js ADDED
@@ -0,0 +1,847 @@
1
+ function Ce(d) {
2
+ return d && d.__esModule && Object.prototype.hasOwnProperty.call(d, "default") ? d.default : d;
3
+ }
4
+ var de = { exports: {} };
5
+ /*! dom-to-image-more 23-10-2025 */
6
+ var Ae = de.exports, Te;
7
+ function Pe() {
8
+ return Te || (Te = 1, (function(d, f) {
9
+ ((b) => {
10
+ let r = /* @__PURE__ */ (() => {
11
+ let i = 0;
12
+ return { escape: function(e) {
13
+ return e.replace(/([.*+?^${}()|[\]/\\])/g, "\\$1");
14
+ }, isDataUrl: function(e) {
15
+ return e.search(/^(data:)/) !== -1;
16
+ }, canvasToBlob: function(e) {
17
+ return e.toBlob ? new Promise(function(a) {
18
+ e.toBlob(a);
19
+ }) : ((a) => new Promise(function(m) {
20
+ var l = Q(a.toDataURL().split(",")[1]), g = l.length, C = new Uint8Array(g);
21
+ for (let H = 0; H < g; H++) C[H] = l.charCodeAt(H);
22
+ m(new Blob([C], { type: "image/png" }));
23
+ }))(e);
24
+ }, resolveUrl: function(e, a) {
25
+ var m = document.implementation.createHTMLDocument(), l = m.createElement("base"), g = (m.head.appendChild(l), m.createElement("a"));
26
+ return m.body.appendChild(g), l.href = a, g.href = e, g.href;
27
+ }, getAndEncode: function(e) {
28
+ let a = w.impl.urlCache.find(function(m) {
29
+ return m.url === e;
30
+ });
31
+ return a || (a = { url: e, promise: null }, w.impl.urlCache.push(a)), a.promise === null && (w.impl.options.cacheBust && (e += (/\?/.test(e) ? "&" : "?") + (/* @__PURE__ */ new Date()).getTime()), a.promise = new Promise(function(m) {
32
+ let l = new XMLHttpRequest();
33
+ function g(p) {
34
+ console.error(p), m("");
35
+ }
36
+ function C() {
37
+ var p = w.impl.options.imagePlaceholder;
38
+ p ? m(p) : g("Status:" + l.status + " while fetching resource: " + e);
39
+ }
40
+ if (l.timeout = w.impl.options.httpTimeout, l.onerror = C, l.ontimeout = C, l.onloadend = function() {
41
+ if (l.readyState === XMLHttpRequest.DONE) {
42
+ var p = l.status;
43
+ if (p === 0 && e.toLowerCase().startsWith("file://") || 200 <= p && p <= 300 && l.response !== null) {
44
+ p = l.response, p instanceof Blob || g("Expected response to be a Blob, but got: " + typeof p);
45
+ let A = new FileReader();
46
+ A.onloadend = function() {
47
+ var y = A.result;
48
+ m(y);
49
+ };
50
+ try {
51
+ A.readAsDataURL(p);
52
+ } catch (y) {
53
+ g("Failed to read the response as Data URL: " + y.toString());
54
+ }
55
+ } else C();
56
+ }
57
+ }, 0 < w.impl.options.useCredentialsFilters.length && (w.impl.options.useCredentials = 0 < w.impl.options.useCredentialsFilters.filter((p) => 0 <= e.search(p)).length), w.impl.options.useCredentials && (l.withCredentials = !0), w.impl.options.corsImg && e.indexOf("http") === 0 && e.indexOf(window.location.origin) === -1) {
58
+ var H = (w.impl.options.corsImg.method || "GET").toUpperCase() === "POST" ? "POST" : "GET";
59
+ l.open(H, (w.impl.options.corsImg.url || "").replace("#{cors}", e), !0);
60
+ let p = !1, A = w.impl.options.corsImg.headers || {}, y = (Object.keys(A).forEach(function(c) {
61
+ A[c].indexOf("application/json") !== -1 && (p = !0), l.setRequestHeader(c, A[c]);
62
+ }), ((c) => {
63
+ try {
64
+ return JSON.parse(JSON.stringify(c));
65
+ } catch (S) {
66
+ g("corsImg.data is missing or invalid:" + S.toString());
67
+ }
68
+ })(w.impl.options.corsImg.data || ""));
69
+ Object.keys(y).forEach(function(c) {
70
+ typeof y[c] == "string" && (y[c] = y[c].replace("#{cors}", e));
71
+ }), l.responseType = "blob", l.send(p ? JSON.stringify(y) : y);
72
+ } else l.open("GET", e, !0), l.responseType = "blob", l.send();
73
+ })), a.promise;
74
+ }, uid: function() {
75
+ return "u" + ("0000" + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4) + i++;
76
+ }, asArray: function(e) {
77
+ var a = [], m = e.length;
78
+ for (let l = 0; l < m; l++) a.push(e[l]);
79
+ return a;
80
+ }, escapeXhtml: function(e) {
81
+ return e.replace(/%/g, "%25").replace(/#/g, "%23").replace(/\n/g, "%0A");
82
+ }, makeImage: function(e) {
83
+ return e !== "data:," ? new Promise(function(a, m) {
84
+ let l = document.createElementNS("http://www.w3.org/2000/svg", "svg"), g = new Image();
85
+ w.impl.options.useCredentials && (g.crossOrigin = "use-credentials"), g.onload = function() {
86
+ document.body.removeChild(l), window && window.requestAnimationFrame ? window.requestAnimationFrame(function() {
87
+ a(g);
88
+ }) : a(g);
89
+ }, g.onerror = (C) => {
90
+ document.body.removeChild(l), m(C);
91
+ }, l.appendChild(g), g.src = e, document.body.appendChild(l);
92
+ }) : Promise.resolve();
93
+ }, width: function(e) {
94
+ var a = u(e, "width");
95
+ if (!isNaN(a)) return a;
96
+ var a = u(e, "border-left-width"), m = u(e, "border-right-width");
97
+ return e.scrollWidth + a + m;
98
+ }, height: function(e) {
99
+ var a = u(e, "height");
100
+ if (!isNaN(a)) return a;
101
+ var a = u(e, "border-top-width"), m = u(e, "border-bottom-width");
102
+ return e.scrollHeight + a + m;
103
+ }, getWindow: t, isElement: E, isElementHostForOpenShadowRoot: function(e) {
104
+ return E(e) && e.shadowRoot !== null;
105
+ }, isShadowRoot: h, isInShadowRoot: s, isHTMLElement: function(e) {
106
+ return e instanceof t(e).HTMLElement;
107
+ }, isHTMLCanvasElement: function(e) {
108
+ return e instanceof t(e).HTMLCanvasElement;
109
+ }, isHTMLInputElement: function(e) {
110
+ return e instanceof t(e).HTMLInputElement;
111
+ }, isHTMLImageElement: function(e) {
112
+ return e instanceof t(e).HTMLImageElement;
113
+ }, isHTMLLinkElement: function(e) {
114
+ return e instanceof t(e).HTMLLinkElement;
115
+ }, isHTMLScriptElement: function(e) {
116
+ return e instanceof t(e).HTMLScriptElement;
117
+ }, isHTMLStyleElement: function(e) {
118
+ return e instanceof t(e).HTMLStyleElement;
119
+ }, isHTMLTextAreaElement: function(e) {
120
+ return e instanceof t(e).HTMLTextAreaElement;
121
+ }, isShadowSlotElement: function(e) {
122
+ return s(e) && e instanceof t(e).HTMLSlotElement;
123
+ }, isSVGElement: function(e) {
124
+ return e instanceof t(e).SVGElement;
125
+ }, isSVGRectElement: function(e) {
126
+ return e instanceof t(e).SVGRectElement;
127
+ }, isDimensionMissing: function(e) {
128
+ return isNaN(e) || e <= 0;
129
+ } };
130
+ function t(e) {
131
+ return e = e ? e.ownerDocument : void 0, (e ? e.defaultView : void 0) || window || b;
132
+ }
133
+ function h(e) {
134
+ return e instanceof t(e).ShadowRoot;
135
+ }
136
+ function s(e) {
137
+ return e != null && e.getRootNode !== void 0 && h(e.getRootNode());
138
+ }
139
+ function E(e) {
140
+ return e instanceof t(e).Element;
141
+ }
142
+ function u(e, a) {
143
+ if (e.nodeType === te) {
144
+ let m = K(e).getPropertyValue(a);
145
+ if (m.slice(-2) === "px") return m = m.slice(0, -2), parseFloat(m);
146
+ }
147
+ return NaN;
148
+ }
149
+ })(), T = /* @__PURE__ */ (() => {
150
+ let i = /url\(\s*(["']?)((?:\\.|[^\\)])+)\1\s*\)/gm;
151
+ return { inlineAll: function(u, e, a) {
152
+ return t(u) ? Promise.resolve(u).then(h).then(function(m) {
153
+ let l = Promise.resolve(u);
154
+ return m.forEach(function(g) {
155
+ l = l.then(function(C) {
156
+ return E(C, g, e, a);
157
+ });
158
+ }), l;
159
+ }) : Promise.resolve(u);
160
+ }, shouldProcess: t, impl: { readUrls: h, inline: E, urlAsRegex: s } };
161
+ function t(u) {
162
+ return u.search(i) !== -1;
163
+ }
164
+ function h(u) {
165
+ for (var e, a = []; (e = i.exec(u)) !== null; ) a.push(e[2]);
166
+ return a.filter(function(m) {
167
+ return !r.isDataUrl(m);
168
+ });
169
+ }
170
+ function s(u) {
171
+ return new RegExp(`url\\((["']?)(${r.escape(u)})\\1\\)`, "gm");
172
+ }
173
+ function E(u, e, a, m) {
174
+ return Promise.resolve(e).then(function(l) {
175
+ return a ? r.resolveUrl(l, a) : l;
176
+ }).then(m || r.getAndEncode).then(function(l) {
177
+ var g = s(e);
178
+ return u.replace(g, `url($1${l}$1)`);
179
+ });
180
+ }
181
+ })(), L = { resolveAll: function() {
182
+ return B().then(function(i) {
183
+ return Promise.all(i.map(function(t) {
184
+ return t.resolve();
185
+ }));
186
+ }).then(function(i) {
187
+ return i.join(`
188
+ `);
189
+ });
190
+ }, impl: { readAll: B } };
191
+ function B() {
192
+ return Promise.resolve(r.asArray(document.styleSheets)).then(function(t) {
193
+ let h = [];
194
+ return t.forEach(function(s) {
195
+ var E = Object.getPrototypeOf(s);
196
+ if (Object.prototype.hasOwnProperty.call(E, "cssRules")) try {
197
+ r.asArray(s.cssRules || []).forEach(h.push.bind(h));
198
+ } catch (u) {
199
+ console.error("domtoimage: Error while reading CSS rules from: " + s.href, u.toString());
200
+ }
201
+ }), h;
202
+ }).then(function(t) {
203
+ return t.filter(function(h) {
204
+ return h.type === CSSRule.FONT_FACE_RULE;
205
+ }).filter(function(h) {
206
+ return T.shouldProcess(h.style.getPropertyValue("src"));
207
+ });
208
+ }).then(function(t) {
209
+ return t.map(i);
210
+ });
211
+ function i(t) {
212
+ return { resolve: function() {
213
+ var h = (t.parentStyleSheet || {}).href;
214
+ return T.inlineAll(t.cssText, h);
215
+ }, src: function() {
216
+ return t.style.getPropertyValue("src");
217
+ } };
218
+ }
219
+ }
220
+ let G = { inlineAll: function i(t) {
221
+ if (!r.isElement(t)) return Promise.resolve(t);
222
+ return h(t).then(function() {
223
+ return r.isHTMLImageElement(t) ? oe(t).inline() : Promise.all(r.asArray(t.childNodes).map(function(s) {
224
+ return i(s);
225
+ }));
226
+ });
227
+ function h(s) {
228
+ let E = ["background", "background-image"], u = E.map(function(e) {
229
+ let a = s.style.getPropertyValue(e), m = s.style.getPropertyPriority(e);
230
+ return a ? T.inlineAll(a).then(function(l) {
231
+ s.style.setProperty(e, l, m);
232
+ }) : Promise.resolve();
233
+ });
234
+ return Promise.all(u).then(function() {
235
+ return s;
236
+ });
237
+ }
238
+ }, impl: { newImage: oe } };
239
+ function oe(i) {
240
+ return { inline: function(t) {
241
+ return r.isDataUrl(i.src) ? Promise.resolve() : Promise.resolve(i.src).then(t || r.getAndEncode).then(function(h) {
242
+ return new Promise(function(s) {
243
+ i.onload = s, i.onerror = s, i.src = h;
244
+ });
245
+ });
246
+ } };
247
+ }
248
+ let k = { copyDefaultStyles: !0, imagePlaceholder: void 0, cacheBust: !1, useCredentials: !1, useCredentialsFilters: [], httpTimeout: 3e4, styleCaching: "strict", corsImg: void 0 }, w = { toSvg: Z, toPng: function(i, t) {
249
+ return q(i, t).then(function(h) {
250
+ return h.toDataURL();
251
+ });
252
+ }, toJpeg: function(i, t) {
253
+ return q(i, t).then(function(h) {
254
+ return h.toDataURL("image/jpeg", (t ? t.quality : void 0) || 1);
255
+ });
256
+ }, toBlob: function(i, t) {
257
+ return q(i, t).then(r.canvasToBlob);
258
+ }, toPixelData: function(i, t) {
259
+ return q(i, t).then(function(h) {
260
+ return h.getContext("2d").getImageData(0, 0, r.width(i), r.height(i)).data;
261
+ });
262
+ }, toCanvas: q, impl: { fontFaces: L, images: G, util: r, inliner: T, urlCache: [], options: {}, copyOptions: function(i) {
263
+ i.copyDefaultStyles === void 0 ? w.impl.options.copyDefaultStyles = k.copyDefaultStyles : w.impl.options.copyDefaultStyles = i.copyDefaultStyles, w.impl.options.imagePlaceholder = (i.imagePlaceholder === void 0 ? k : i).imagePlaceholder, w.impl.options.cacheBust = (i.cacheBust === void 0 ? k : i).cacheBust, w.impl.options.corsImg = (i.corsImg === void 0 ? k : i).corsImg, w.impl.options.useCredentials = (i.useCredentials === void 0 ? k : i).useCredentials, w.impl.options.useCredentialsFilters = (i.useCredentialsFilters === void 0 ? k : i).useCredentialsFilters, w.impl.options.httpTimeout = (i.httpTimeout === void 0 ? k : i).httpTimeout, w.impl.options.styleCaching = (i.styleCaching === void 0 ? k : i).styleCaching;
264
+ } } }, te = (d.exports = w, (Node === void 0 ? void 0 : Node.ELEMENT_NODE) || 1), K = (b === void 0 ? void 0 : b.getComputedStyle) || (window === void 0 ? void 0 : window.getComputedStyle) || globalThis.getComputedStyle, Q = (b === void 0 ? void 0 : b.atob) || (window === void 0 ? void 0 : window.atob) || globalThis.atob;
265
+ function Z(i, t) {
266
+ w.impl.util.getWindow(i);
267
+ let h = (t = t || {}, w.impl.copyOptions(t), []);
268
+ return Promise.resolve(i).then(function(s) {
269
+ if (s.nodeType === te) return s;
270
+ var E = s, u = document.createElement("span");
271
+ return E.replaceWith(u), u.append(s), h.push({ child: E, wrapper: u }), u;
272
+ }).then(function(s) {
273
+ return (function E(u, e, a, m) {
274
+ let l = e.filter;
275
+ if (u === O || r.isHTMLScriptElement(u) || r.isHTMLStyleElement(u) || r.isHTMLLinkElement(u) || a !== null && l && !l(u)) return Promise.resolve();
276
+ return Promise.resolve(u).then(g).then(C).then(function(c) {
277
+ return A(c, p(u));
278
+ }).then(H).then(function(c) {
279
+ return y(c, u);
280
+ });
281
+ function g(c) {
282
+ return r.isHTMLCanvasElement(c) ? r.makeImage(c.toDataURL()) : c.cloneNode(!1);
283
+ }
284
+ function C(c) {
285
+ return e.adjustClonedNode && e.adjustClonedNode(u, c, !1), Promise.resolve(c);
286
+ }
287
+ function H(c) {
288
+ return e.adjustClonedNode && e.adjustClonedNode(u, c, !0), Promise.resolve(c);
289
+ }
290
+ function p(c) {
291
+ return r.isElementHostForOpenShadowRoot(c) ? c.shadowRoot : c;
292
+ }
293
+ function A(c, S) {
294
+ let j = $(S), X = Promise.resolve();
295
+ if (j.length !== 0) {
296
+ let R = K(z(S));
297
+ r.asArray(j).forEach(function(I) {
298
+ X = X.then(function() {
299
+ return E(I, e, R).then(function(P) {
300
+ P && c.appendChild(P);
301
+ });
302
+ });
303
+ });
304
+ }
305
+ return X.then(function() {
306
+ return c;
307
+ });
308
+ function z(R) {
309
+ return r.isShadowRoot(R) ? R.host : R;
310
+ }
311
+ function $(R) {
312
+ if (r.isShadowSlotElement(R)) {
313
+ let I = R.assignedNodes();
314
+ if (I && 0 < I.length) return I;
315
+ }
316
+ return R.childNodes;
317
+ }
318
+ }
319
+ function y(c, S) {
320
+ return !r.isElement(c) || r.isShadowSlotElement(S) ? Promise.resolve(c) : Promise.resolve().then(X).then(z).then($).then(R).then(j).then(function() {
321
+ return c;
322
+ });
323
+ function j() {
324
+ r.isHTMLImageElement(c) && (c.removeAttribute("loading"), S.srcset || S.sizes) && (c.removeAttribute("srcset"), c.removeAttribute("sizes"), c.src = S.currentSrc || S.src);
325
+ }
326
+ function X() {
327
+ function I(x, v) {
328
+ v.font = x.font, v.fontFamily = x.fontFamily, v.fontFeatureSettings = x.fontFeatureSettings, v.fontKerning = x.fontKerning, v.fontSize = x.fontSize, v.fontStretch = x.fontStretch, v.fontStyle = x.fontStyle, v.fontVariant = x.fontVariant, v.fontVariantCaps = x.fontVariantCaps, v.fontVariantEastAsian = x.fontVariantEastAsian, v.fontVariantLigatures = x.fontVariantLigatures, v.fontVariantNumeric = x.fontVariantNumeric, v.fontVariationSettings = x.fontVariationSettings, v.fontWeight = x.fontWeight;
329
+ }
330
+ function P(x, v) {
331
+ let N = K(x);
332
+ N.cssText ? (v.style.cssText = N.cssText, I(N, v.style)) : (U(e, x, N, a, v), a === null && (["inset-block", "inset-block-start", "inset-block-end"].forEach((V) => v.style.removeProperty(V)), ["left", "right", "top", "bottom"].forEach((V) => {
333
+ v.style.getPropertyValue(V) && v.style.setProperty(V, "0px");
334
+ })));
335
+ }
336
+ P(S, c);
337
+ }
338
+ function z() {
339
+ let I = r.uid();
340
+ function P(x) {
341
+ let v = K(S, x), N = v.getPropertyValue("content");
342
+ if (N !== "" && N !== "none") {
343
+ let le = function() {
344
+ let se = `.${I}:` + x, he = (v.cssText ? ne : ce)();
345
+ return document.createTextNode(se + `{${he}}`);
346
+ function ne() {
347
+ return `${v.cssText} content: ${N};`;
348
+ }
349
+ function ce() {
350
+ return r.asArray(v).map(o).join("; ") + ";";
351
+ function o(_) {
352
+ let D = v.getPropertyValue(_), W = v.getPropertyPriority(_) ? " !important" : "";
353
+ return _ + ": " + D + W;
354
+ }
355
+ }
356
+ }, V = c.getAttribute("class") || "", Y = (c.setAttribute("class", V + " " + I), document.createElement("style"));
357
+ Y.appendChild(le()), c.appendChild(Y);
358
+ }
359
+ }
360
+ [":before", ":after"].forEach(function(x) {
361
+ P(x);
362
+ });
363
+ }
364
+ function $() {
365
+ r.isHTMLTextAreaElement(S) && (c.innerHTML = S.value), r.isHTMLInputElement(S) && c.setAttribute("value", S.value);
366
+ }
367
+ function R() {
368
+ r.isSVGElement(c) && (c.setAttribute("xmlns", "http://www.w3.org/2000/svg"), r.isSVGRectElement(c)) && ["width", "height"].forEach(function(I) {
369
+ let P = c.getAttribute(I);
370
+ P && c.style.setProperty(I, P);
371
+ });
372
+ }
373
+ }
374
+ })(s, t, null);
375
+ }).then(t.disableEmbedFonts ? Promise.resolve(i) : re).then(t.disableInlineImages ? Promise.resolve(i) : ie).then(function(s) {
376
+ t.bgcolor && (s.style.backgroundColor = t.bgcolor), t.width && (s.style.width = t.width + "px"), t.height && (s.style.height = t.height + "px"), t.style && Object.keys(t.style).forEach(function(u) {
377
+ s.style[u] = t.style[u];
378
+ });
379
+ let E = null;
380
+ return typeof t.onclone == "function" && (E = t.onclone(s)), Promise.resolve(E).then(function() {
381
+ return s;
382
+ });
383
+ }).then(function(s) {
384
+ let E = t.width || r.width(i), u = t.height || r.height(i);
385
+ return Promise.resolve(s).then(function(e) {
386
+ return e.setAttribute("xmlns", "http://www.w3.org/1999/xhtml"), new XMLSerializer().serializeToString(e);
387
+ }).then(r.escapeXhtml).then(function(e) {
388
+ var a = (r.isDimensionMissing(E) ? ' width="100%"' : ` width="${E}"`) + (r.isDimensionMissing(u) ? ' height="100%"' : ` height="${u}"`);
389
+ return `<svg xmlns="http://www.w3.org/2000/svg"${(r.isDimensionMissing(E) ? "" : ` width="${E}"`) + (r.isDimensionMissing(u) ? "" : ` height="${u}"`)}><foreignObject${a}>${e}</foreignObject></svg>`;
390
+ }).then(function(e) {
391
+ return "data:image/svg+xml;charset=utf-8," + e;
392
+ });
393
+ }).then(function(s) {
394
+ for (; 0 < h.length; ) {
395
+ var E = h.pop();
396
+ E.wrapper.replaceWith(E.child);
397
+ }
398
+ return s;
399
+ }).then(function(s) {
400
+ return w.impl.urlCache = [], O && (document.body.removeChild(O), O = null), M && clearTimeout(M), M = setTimeout(() => {
401
+ M = null, n = {};
402
+ }, 2e4), s;
403
+ });
404
+ }
405
+ function q(i, t) {
406
+ return Z(i, t = t || {}).then(r.makeImage).then(function(h) {
407
+ var s = typeof t.scale != "number" ? 1 : t.scale, E = ((e, a) => {
408
+ let m = t.width || r.width(e), l = t.height || r.height(e);
409
+ return r.isDimensionMissing(m) && (m = r.isDimensionMissing(l) ? 300 : 2 * l), r.isDimensionMissing(l) && (l = m / 2), (e = document.createElement("canvas")).width = m * a, e.height = l * a, t.bgcolor && ((a = e.getContext("2d")).fillStyle = t.bgcolor, a.fillRect(0, 0, e.width, e.height)), e;
410
+ })(i, s), u = E.getContext("2d");
411
+ return u.msImageSmoothingEnabled = !1, u.imageSmoothingEnabled = !1, h && (u.scale(s, s), u.drawImage(h, 0, 0)), E;
412
+ });
413
+ }
414
+ let O = null;
415
+ function re(i) {
416
+ return L.resolveAll().then(function(t) {
417
+ var h;
418
+ return t !== "" && (h = document.createElement("style"), i.appendChild(h), h.appendChild(document.createTextNode(t))), i;
419
+ });
420
+ }
421
+ function ie(i) {
422
+ return G.inlineAll(i).then(function() {
423
+ return i;
424
+ });
425
+ }
426
+ function U(i, t, h, s, E) {
427
+ let u = w.impl.options.copyDefaultStyles ? ((a, m) => {
428
+ var l, g = ((p) => (a.styleCaching !== "relaxed" ? p : p.filter((A, y, c) => y === 0 || y === c.length - 1)).join(">"))(m = ((p) => {
429
+ var A = [];
430
+ do
431
+ if (p.nodeType === te) {
432
+ var y = p.tagName;
433
+ if (A.push(y), ae.includes(y)) break;
434
+ }
435
+ while (p = p.parentNode);
436
+ return A;
437
+ })(m));
438
+ {
439
+ if (n[g]) return n[g];
440
+ m = ((p, A) => {
441
+ let y = p.body;
442
+ do {
443
+ var c = A.pop(), c = p.createElement(c);
444
+ y.appendChild(c), y = c;
445
+ } while (0 < A.length);
446
+ return y.textContent = "​", y;
447
+ })((l = (() => {
448
+ if (O) return O.contentWindow;
449
+ A = document.characterSet || "UTF-8", p = (p = document.doctype) ? (`<!DOCTYPE ${z(p.name)} ${z(p.publicId)} ` + z(p.systemId)).trim() + ">" : "", (O = document.createElement("iframe")).id = "domtoimage-sandbox-" + r.uid(), O.style.top = "-9999px", O.style.visibility = "hidden", O.style.position = "fixed", document.body.appendChild(O);
450
+ var p, A, y = O, c = "domtoimage-sandbox";
451
+ try {
452
+ return y.contentWindow.document.write(p + `<html><head><meta charset='${A}'><title>${c}</title></head><body></body></html>`), y.contentWindow;
453
+ } catch {
454
+ }
455
+ var S = document.createElement("meta");
456
+ S.setAttribute("charset", A);
457
+ try {
458
+ var j = document.implementation.createHTMLDocument(c), X = (j.head.appendChild(S), p + j.documentElement.outerHTML);
459
+ return y.setAttribute("srcdoc", X), y.contentWindow;
460
+ } catch {
461
+ }
462
+ return y.contentDocument.head.appendChild(S), y.contentDocument.title = c, y.contentWindow;
463
+ function z($) {
464
+ var R;
465
+ return $ ? ((R = document.createElement("div")).innerText = $, R.innerHTML) : "";
466
+ }
467
+ })()).document, m), l = ((p, A) => {
468
+ let y = {}, c = p.getComputedStyle(A);
469
+ return r.asArray(c).forEach(function(S) {
470
+ y[S] = S === "width" || S === "height" ? "auto" : c.getPropertyValue(S);
471
+ }), y;
472
+ })(l, m);
473
+ var C = m;
474
+ do {
475
+ var H = C.parentElement;
476
+ H !== null && H.removeChild(C), C = H;
477
+ } while (C && C.tagName !== "BODY");
478
+ return n[g] = l;
479
+ }
480
+ })(i, t) : {}, e = E.style;
481
+ r.asArray(h).forEach(function(a) {
482
+ var m, l, g, C;
483
+ i.filterStyles && !i.filterStyles(t, a) || (l = h.getPropertyValue(a), g = u[a], m = s ? s.getPropertyValue(a) : void 0, e.getPropertyValue(a)) || (l !== g || s && l !== m) && (g = h.getPropertyPriority(a), m = e, l = l, g = g, C = 0 <= ["background-clip"].indexOf(a = a), g ? (m.setProperty(a, l, g), C && m.setProperty("-webkit-" + a, l, g)) : (m.setProperty(a, l), C && m.setProperty("-webkit-" + a, l)));
484
+ });
485
+ }
486
+ let M = null, n = {}, ae = ["ADDRESS", "ARTICLE", "ASIDE", "BLOCKQUOTE", "DETAILS", "DIALOG", "DD", "DIV", "DL", "DT", "FIELDSET", "FIGCAPTION", "FIGURE", "FOOTER", "FORM", "H1", "H2", "H3", "H4", "H5", "H6", "HEADER", "HGROUP", "HR", "LI", "MAIN", "NAV", "OL", "P", "PRE", "SECTION", "SVG", "TABLE", "UL", "math", "svg", "BODY", "HEAD", "HTML"];
487
+ })(Ae);
488
+ })(de)), de.exports;
489
+ }
490
+ var Me = Pe();
491
+ const De = /* @__PURE__ */ Ce(Me);
492
+ function J(d) {
493
+ return Math.min(1, Math.max(0, d));
494
+ }
495
+ function Se(d, f, b) {
496
+ const r = 1 - b;
497
+ return [r * d[0] + b * f[0], r * d[1] + b * f[1], r * d[2] + b * f[2]];
498
+ }
499
+ function _e(d, f) {
500
+ const b = 0.2126 * d[0] + 0.7152 * d[1] + 0.0722 * d[2];
501
+ return [
502
+ J(d[0] + (d[0] - b) * f),
503
+ J(d[1] + (d[1] - b) * f),
504
+ J(d[2] + (d[2] - b) * f)
505
+ ];
506
+ }
507
+ function Re(d) {
508
+ const f = d.trim().toLowerCase();
509
+ return f.endsWith("deg") ? parseFloat(f.slice(0, -3)) : f.endsWith("rad") ? parseFloat(f.slice(0, -3)) * 180 / Math.PI : f.endsWith("turn") ? parseFloat(f.slice(0, -4)) * 360 : f.endsWith("grad") ? parseFloat(f.slice(0, -4)) * 360 / 400 : parseFloat(f);
510
+ }
511
+ function Le(d) {
512
+ const f = d.trim();
513
+ if (!/^oklch\s*\(/i.test(f)) return null;
514
+ const T = f.slice(f.indexOf("(") + 1, f.lastIndexOf(")")).split(/\s*\/\s*/)[0].trim().split(/\s+/).filter(Boolean);
515
+ if (T.length < 3) return null;
516
+ let L;
517
+ T[0].endsWith("%") ? L = Math.min(1, Math.max(0, parseFloat(T[0]) / 100)) : L = Math.min(1, Math.max(0, parseFloat(T[0])));
518
+ let B;
519
+ T[1].endsWith("%") ? B = Math.max(0, parseFloat(T[1]) * 0.4 / 100) : B = Math.max(0, parseFloat(T[1]));
520
+ const G = Re(T[2]);
521
+ return !Number.isFinite(L) || !Number.isFinite(B) || !Number.isFinite(G) ? null : { l: L, c: B, h: G };
522
+ }
523
+ function Ie(d, f, b) {
524
+ const r = Math.pow(d + 0.3963377773761749 * f + 0.2158037573099136 * b, 3), T = Math.pow(d - 0.1055613458156586 * f - 0.0638541728258133 * b, 3), L = Math.pow(d - 0.0894841775298119 * f - 1.2914855480194092 * b, 3);
525
+ return [
526
+ 4.076741636075957 * r - 3.3077115392580616 * T + 0.2309699031821044 * L,
527
+ -1.2684379732850317 * r + 2.6097573492876887 * T - 0.3413193760026573 * L,
528
+ -0.0041960761386756 * r - 0.7034186179359362 * T + 1.7076146940746117 * L
529
+ ];
530
+ }
531
+ function ye(d) {
532
+ const f = Math.abs(d);
533
+ return f > 31308e-7 ? (Math.sign(d) || 1) * (1.055 * Math.pow(f, 1 / 2.4) - 0.055) : d * 12.92;
534
+ }
535
+ function ve(d) {
536
+ const f = Le(d);
537
+ if (!f) return [1, 1, 1];
538
+ const b = f.h / 180 * Math.PI, r = f.c ? f.c * Math.cos(b) : 0, T = f.c ? f.c * Math.sin(b) : 0, [L, B, G] = Ie(f.l, r, T);
539
+ return [
540
+ J(ye(L)),
541
+ J(ye(B)),
542
+ J(ye(G))
543
+ ];
544
+ }
545
+ function Oe(d) {
546
+ return typeof d == "string" ? Array.from(document.querySelectorAll(d)) : d instanceof HTMLElement ? [d] : Array.from(d);
547
+ }
548
+ function Fe(d) {
549
+ return d ? typeof d == "string" ? document.querySelector(d) ?? document.body : d : document.body;
550
+ }
551
+ const He = `attribute vec2 a_pos;
552
+ void main(){ gl_Position = vec4(a_pos, 0.0, 1.0); }`, Ne = `precision highp float;
553
+ uniform sampler2D u_tex;
554
+ uniform vec2 u_res;
555
+ uniform vec2 u_css;
556
+ uniform float u_time;
557
+ uniform int u_count;
558
+ uniform vec3 u_rip[16];
559
+ uniform float u_freq, u_speed, u_amp, u_damp, u_decay;
560
+ uniform float u_chroma;
561
+ uniform vec3 u_shimColor;
562
+ uniform float u_shimStr;
563
+ uniform float u_shimWidth;
564
+ uniform float u_shimIntScale;
565
+ uniform float u_shimDur;
566
+ uniform vec3 u_glowDodge;
567
+ uniform vec3 u_glowScreen;
568
+ uniform vec3 u_glowMix;
569
+
570
+ void main(){
571
+ vec2 uv = gl_FragCoord.xy / u_res;
572
+ uv.y = 1.0 - uv.y;
573
+ vec2 d = vec2(0.0);
574
+ float maxShim = 0.0;
575
+ float maxDodge = 0.0;
576
+ float maxScreen = 0.0;
577
+ float maxOuter = 0.0;
578
+ for(int i = 0; i < 16; i++){
579
+ if(i >= u_count) break;
580
+ vec2 c = u_rip[i].xy;
581
+ float t = u_time - u_rip[i].z;
582
+ vec2 diff = (uv - c) * u_css;
583
+ float dist = length(diff);
584
+ if(dist < 0.5) continue;
585
+
586
+ float front = t * u_speed;
587
+ float behind = front - dist;
588
+ float mask = smoothstep(0.0, 2.0, behind);
589
+ float ringDecay = exp(-behind * u_damp);
590
+ float temporal = exp(-t * u_decay);
591
+ float phase = dist * u_freq - t * u_speed * u_freq;
592
+ float wave = sin(phase) * mask * ringDecay * temporal;
593
+ float center = smoothstep(0.0, 10.0, dist);
594
+
595
+ d -= normalize(diff) * wave * u_amp * center;
596
+
597
+ float b = max(0.0, behind);
598
+ float delayT = clamp((t - 0.05) / 0.32, 0.0, 1.0);
599
+ float delay = (1.0 - pow(1.0 - delayT, 3.0)) * step(0.05, t);
600
+ float growT = clamp(t / 3.9, 0.0, 1.0);
601
+ float easeOut = 1.0 - pow(1.0 - growT, 3.0);
602
+ float radialScale = clamp(1.0 + front * 0.0032 + front * front * 8.0e-7, 1.0, 5.0);
603
+ float sigma = mix(32.0, 142.0, easeOut) * radialScale * u_shimWidth;
604
+ float peak = mix(18.0, 72.0, easeOut) * radialScale * u_shimWidth;
605
+ float x = (b - peak) / max(sigma, 1.0);
606
+ float x2 = x * x;
607
+ float shimBell =
608
+ exp(-x2) * 0.68 + exp(-x2 * 0.52) * 0.32;
609
+ float tailW = mix(0.12, 0.075, easeOut) / (1.0 + t * 1.15 + front * 0.0012);
610
+ float shimTail = exp(-b * tailW);
611
+ float enterW = mix(10.0, 36.0, easeOut) * radialScale * u_shimWidth;
612
+ float shimEnter = smoothstep(0.0, enterW, b);
613
+ float fadeT = clamp(t / max(u_shimDur, 0.001), 0.0, 1.0);
614
+ float opacityEase = 1.0 - pow(fadeT, 2.35);
615
+ float opacityFade = opacityEase * delay * exp(-t * 0.72);
616
+ float shimEdge =
617
+ shimEnter * shimBell * shimTail * opacityFade * center * u_shimIntScale;
618
+ maxShim = max(maxShim, shimEdge);
619
+ float gBase = shimEnter * shimTail * opacityFade * center;
620
+ float su = max(sigma, 1.0);
621
+ float u = (b - peak) / su;
622
+ float ao = (u + 0.78) / 0.48;
623
+ float gOut = exp(-(ao * ao));
624
+ float am = (u + 0.22) / 0.26;
625
+ float gMid = exp(-(am * am));
626
+ float ac = u / 0.1;
627
+ float gHot = exp(-(ac * ac));
628
+ float mOuter =
629
+ max(0.0, gOut - gMid * 0.75 - gHot * 0.15) * gBase * u_shimIntScale;
630
+ float mScreen =
631
+ max(0.0, gMid - gHot * 0.82 - gOut * 0.35) * gBase * u_shimIntScale;
632
+ float mDodge = max(0.0, gHot - gMid * 0.45) * gBase * u_shimIntScale;
633
+ maxDodge = max(maxDodge, mDodge);
634
+ maxScreen = max(maxScreen, mScreen);
635
+ maxOuter = max(maxOuter, mOuter);
636
+ }
637
+ d /= u_css;
638
+
639
+ vec3 col;
640
+ if(u_chroma > 0.0){
641
+ vec2 spread = d * u_chroma;
642
+ vec2 perp = vec2(-spread.y, spread.x) * 0.5;
643
+
644
+ float r = 0.0, g = 0.0, b = 0.0;
645
+ float tw = 0.0;
646
+ for(int s = -3; s <= 3; s++){
647
+ float f = float(s) / 3.0;
648
+ float w = exp(-2.0 * f * f);
649
+ tw += w;
650
+ vec2 rOff = spread * (f - 1.0) + perp * f;
651
+ vec2 gOff = perp * f * 0.3;
652
+ vec2 bOff = spread * (f + 1.0) - perp * f;
653
+ r += texture2D(u_tex, uv + d + rOff).r * w;
654
+ g += texture2D(u_tex, uv + d + gOff).g * w;
655
+ b += texture2D(u_tex, uv + d + bOff).b * w;
656
+ }
657
+ col = vec3(r, g, b) / tw;
658
+ } else {
659
+ col = texture2D(u_tex, uv + d).rgb;
660
+ }
661
+ if(u_shimStr > 0.0){
662
+ float di = fract(sin(dot(floor(gl_FragCoord.xy), vec2(12.9898, 78.233))) * 43758.5453);
663
+ float n = (di - 0.5) * 0.012;
664
+ float coreAmt = clamp(maxShim * u_shimStr + n, 0.0, 1.0);
665
+ float edge = 1.0 - coreAmt * 0.18;
666
+ float o = clamp(maxOuter * u_shimStr + n, 0.0, 1.0) * edge;
667
+ float s = clamp(maxScreen * u_shimStr + n, 0.0, 1.0) * edge;
668
+ col = mix(col, u_glowMix, o * 0.92);
669
+ vec3 scr = u_glowScreen * s * 1.02;
670
+ scr = min(scr, vec3(0.97));
671
+ col = vec3(1.0) - (vec3(1.0) - col) * (vec3(1.0) - scr);
672
+ col = min(col, vec3(1.0));
673
+ col = mix(col, u_shimColor, coreAmt);
674
+ float dg = clamp(maxDodge * u_shimStr + n, 0.0, 1.0);
675
+ float hot = dg * (0.62 + 0.38 * (1.0 - coreAmt));
676
+ vec3 cs = u_glowDodge * hot * 2.05;
677
+ cs = clamp(cs, vec3(0.0), vec3(0.995));
678
+ vec3 denom = vec3(1.0) - cs;
679
+ denom = max(denom, vec3(0.001));
680
+ col = min(col / denom, vec3(1.0));
681
+ }
682
+ gl_FragColor = vec4(col, 1.0);
683
+ }`;
684
+ function Be(d, f = {}) {
685
+ const b = Oe(d), r = Fe(f.scope), T = r === document.body;
686
+ let L = f.amplitude ?? 3, B = f.frequency ?? 0.018, G = f.speed ?? 300, oe = f.damping ?? 0.025, k = f.decay ?? 1.2, w = (f.duration ?? 3500) / 1e3, te = f.chromatic ?? !1, K = f.chromaticIntensity ?? 0.4, Q = f.shimmer ? ve(f.shimmer) : [1, 1, 1], Z = f.shimmer ? 1 : 0, q = f.shimmerWidth ?? 1, O = (f.shimmerDuration ?? 2600) / 1e3, re = f.shimmerGlowColor;
687
+ const ie = () => {
688
+ if (!Z)
689
+ return {
690
+ dodge: [1, 1, 1],
691
+ screen: [1, 1, 1],
692
+ mix: [1, 1, 1]
693
+ };
694
+ const o = re ? ve(re) : Q;
695
+ return {
696
+ dodge: Se(o, [1, 1, 1], 0.94),
697
+ screen: _e(o, 1.72),
698
+ mix: Se(_e(o, 0.45), [1, 1, 1], 0.4)
699
+ };
700
+ };
701
+ let U = ie();
702
+ const M = document.createElement("canvas");
703
+ if (M.setAttribute("data-ripyl-overlay", ""), T)
704
+ M.style.cssText = "position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:2147483647;";
705
+ else {
706
+ getComputedStyle(r).position === "static" && (r.style.position = "relative");
707
+ const _ = getComputedStyle(r);
708
+ M.style.cssText = "position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:2147483647;", M.style.borderRadius = _.borderRadius, M.style.overflow = "hidden";
709
+ }
710
+ (T ? document.body : r).appendChild(M);
711
+ const n = M.getContext("webgl", {
712
+ premultipliedAlpha: !0,
713
+ alpha: !0
714
+ });
715
+ if (!n)
716
+ return M.remove(), {
717
+ destroy() {
718
+ },
719
+ update() {
720
+ },
721
+ trigger() {
722
+ }
723
+ };
724
+ const ae = (o, _) => {
725
+ const D = n.createShader(o);
726
+ return n.shaderSource(D, _), n.compileShader(D), D;
727
+ }, i = n.createProgram();
728
+ n.attachShader(i, ae(n.VERTEX_SHADER, He)), n.attachShader(i, ae(n.FRAGMENT_SHADER, Ne)), n.linkProgram(i), n.useProgram(i);
729
+ const t = n.createBuffer();
730
+ n.bindBuffer(n.ARRAY_BUFFER, t), n.bufferData(
731
+ n.ARRAY_BUFFER,
732
+ new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),
733
+ n.STATIC_DRAW
734
+ );
735
+ const h = n.getAttribLocation(i, "a_pos");
736
+ n.enableVertexAttribArray(h), n.vertexAttribPointer(h, 2, n.FLOAT, !1, 0, 0);
737
+ const s = (o) => n.getUniformLocation(i, o), E = s("u_res"), u = s("u_css"), e = s("u_time"), a = s("u_count"), m = s("u_freq"), l = s("u_speed"), g = s("u_amp"), C = s("u_damp"), H = s("u_decay"), p = s("u_chroma"), A = s("u_shimColor"), y = s("u_shimStr"), c = s("u_shimWidth"), S = s("u_shimIntScale"), j = s("u_shimDur"), X = s("u_glowDodge"), z = s("u_glowScreen"), $ = s("u_glowMix"), R = [];
738
+ for (let o = 0; o < 16; o++) R.push(s(`u_rip[${o}]`));
739
+ const I = n.createTexture();
740
+ n.bindTexture(n.TEXTURE_2D, I), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_WRAP_S, n.CLAMP_TO_EDGE), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_WRAP_T, n.CLAMP_TO_EDGE), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_MIN_FILTER, n.LINEAR), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_MAG_FILTER, n.LINEAR);
741
+ const P = [];
742
+ let x = 0, v = !1, N = !1, V = !1, Y = !1;
743
+ const le = () => {
744
+ const o = devicePixelRatio || 1, _ = T ? innerWidth : r.clientWidth, D = T ? innerHeight : r.clientHeight, W = _ * o, F = D * o;
745
+ (M.width !== W || M.height !== F) && (M.width = W, M.height = F, n.viewport(0, 0, W, F));
746
+ }, se = () => {
747
+ n.clearColor(0, 0, 0, 0), n.clear(n.COLOR_BUFFER_BIT);
748
+ }, he = async () => {
749
+ if (!(V || Y)) {
750
+ V = !0, se();
751
+ try {
752
+ const o = devicePixelRatio || 1, _ = innerWidth, D = innerHeight, W = (ee) => !(ee instanceof Element && ee.hasAttribute("data-ripyl-overlay")), F = Math.round(_ * o), we = Math.round(D * o), be = await De.toPng(document.documentElement, {
753
+ width: F,
754
+ height: we,
755
+ style: {
756
+ transform: `scale(${o})`,
757
+ transformOrigin: "top left",
758
+ width: _ + "px",
759
+ height: D + "px"
760
+ },
761
+ filter: W
762
+ });
763
+ if (Y) return;
764
+ const ge = new Image();
765
+ if (ge.src = be, await ge.decode(), Y) return;
766
+ let Ee = 0, xe = 0, ue = F, me = we;
767
+ if (!T) {
768
+ const ee = r.getBoundingClientRect();
769
+ Ee = Math.round(ee.left * o), xe = Math.round(ee.top * o), ue = Math.round(ee.width * o), me = Math.round(ee.height * o);
770
+ }
771
+ const fe = document.createElement("canvas");
772
+ fe.width = ue, fe.height = me, fe.getContext("2d").drawImage(ge, Ee, xe, ue, me, 0, 0, ue, me), n.bindTexture(n.TEXTURE_2D, I), n.texImage2D(
773
+ n.TEXTURE_2D,
774
+ 0,
775
+ n.RGBA,
776
+ n.RGBA,
777
+ n.UNSIGNED_BYTE,
778
+ fe
779
+ ), N = !0, le();
780
+ } catch {
781
+ }
782
+ V = !1, N && P.length > 0 && !v && (v = !0, cancelAnimationFrame(x), x = requestAnimationFrame(ne));
783
+ }
784
+ }, ne = () => {
785
+ const o = performance.now() / 1e3;
786
+ let _ = 0;
787
+ for (; _ < P.length; )
788
+ o - P[_].t0 > w ? P.splice(_, 1) : _++;
789
+ if (P.length === 0) {
790
+ se(), v = !1, N = !1;
791
+ return;
792
+ }
793
+ if (!N) {
794
+ x = requestAnimationFrame(ne);
795
+ return;
796
+ }
797
+ le(), n.clearColor(0, 0, 0, 0), n.clear(n.COLOR_BUFFER_BIT);
798
+ const D = T ? innerWidth : r.clientWidth, W = T ? innerHeight : r.clientHeight;
799
+ n.uniform2f(E, M.width, M.height), n.uniform2f(u, D, W), n.uniform1f(e, o), n.uniform1i(a, P.length), n.uniform1f(m, B), n.uniform1f(l, G), n.uniform1f(g, L), n.uniform1f(C, oe), n.uniform1f(H, k), n.uniform1f(p, te ? K : 0), n.uniform3f(A, Q[0], Q[1], Q[2]), n.uniform1f(y, Z), n.uniform1f(c, q), n.uniform1f(
800
+ S,
801
+ 1 / Math.sqrt(Math.max(0.2, q))
802
+ ), n.uniform1f(j, O), n.uniform3f(
803
+ X,
804
+ U.dodge[0],
805
+ U.dodge[1],
806
+ U.dodge[2]
807
+ ), n.uniform3f(
808
+ z,
809
+ U.screen[0],
810
+ U.screen[1],
811
+ U.screen[2]
812
+ ), n.uniform3f(
813
+ $,
814
+ U.mix[0],
815
+ U.mix[1],
816
+ U.mix[2]
817
+ );
818
+ for (let F = 0; F < Math.min(P.length, 16); F++)
819
+ n.uniform3f(R[F], P[F].cx, P[F].cy, P[F].t0);
820
+ n.drawArrays(n.TRIANGLE_STRIP, 0, 4), x = requestAnimationFrame(ne);
821
+ }, ce = async (o, _) => {
822
+ if (Y) return;
823
+ const D = J(o), W = J(_);
824
+ !v && !V && await he();
825
+ const F = performance.now() / 1e3;
826
+ P.push({ cx: D, cy: W, t0: F }), P.length > 16 && P.shift(), N && !v && (v = !0, cancelAnimationFrame(x), x = requestAnimationFrame(ne));
827
+ }, pe = async (o) => {
828
+ if (!(o instanceof MouseEvent) || o.button !== 0) return;
829
+ const _ = T ? { left: 0, top: 0, width: innerWidth, height: innerHeight } : r.getBoundingClientRect(), D = (o.clientX - _.left) / _.width, W = (o.clientY - _.top) / _.height;
830
+ await ce(D, W);
831
+ };
832
+ return b.forEach((o) => o.addEventListener("click", pe, !0)), {
833
+ destroy() {
834
+ Y = !0, cancelAnimationFrame(x), b.forEach((o) => o.removeEventListener("click", pe, !0)), M.remove();
835
+ },
836
+ trigger(o) {
837
+ const _ = (o == null ? void 0 : o.x) ?? 0.5, D = (o == null ? void 0 : o.y) ?? 0.5;
838
+ ce(_, D);
839
+ },
840
+ update(o) {
841
+ o.amplitude !== void 0 && (L = o.amplitude), o.frequency !== void 0 && (B = o.frequency), o.speed !== void 0 && (G = o.speed), o.damping !== void 0 && (oe = o.damping), o.decay !== void 0 && (k = o.decay), o.duration !== void 0 && (w = o.duration / 1e3), o.chromatic !== void 0 && (te = o.chromatic), o.chromaticIntensity !== void 0 && (K = o.chromaticIntensity), o.shimmer !== void 0 && (o.shimmer ? (Q = ve(o.shimmer), Z = 1) : Z = 0), o.shimmerWidth !== void 0 && (q = o.shimmerWidth), o.shimmerDuration !== void 0 && (O = o.shimmerDuration / 1e3), o.shimmerGlowColor !== void 0 && (re = o.shimmerGlowColor), (o.shimmer !== void 0 || o.shimmerGlowColor !== void 0) && (U = ie());
842
+ }
843
+ };
844
+ }
845
+ export {
846
+ Be as attachRipple
847
+ };
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "ripppl",
3
+ "version": "0.1.0",
4
+ "description": "Ripple displacement effect over the real DOM (WebGL + screen capture)",
5
+ "keywords": [
6
+ "ripple",
7
+ "webgl",
8
+ "dom",
9
+ "effect",
10
+ "animation",
11
+ "canvas"
12
+ ],
13
+ "license": "MIT",
14
+ "author": "Arman Luthra",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/Arman-Luthra/ripyl.git"
18
+ },
19
+ "bugs": {
20
+ "url": "https://github.com/Arman-Luthra/ripyl/issues"
21
+ },
22
+ "homepage": "https://github.com/Arman-Luthra/ripyl#readme",
23
+ "type": "module",
24
+ "main": "./dist/ripyl.js",
25
+ "module": "./dist/ripyl.js",
26
+ "types": "./dist/ripyl.d.ts",
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/ripyl.d.ts",
30
+ "import": "./dist/ripyl.js",
31
+ "default": "./dist/ripyl.js"
32
+ }
33
+ },
34
+ "files": [
35
+ "dist",
36
+ "README.md",
37
+ "LICENSE"
38
+ ],
39
+ "sideEffects": false,
40
+ "scripts": {
41
+ "dev": "vite",
42
+ "build": "vite build --config vite.lib.config.ts && tsc -p tsconfig.build.json",
43
+ "prepublishOnly": "npm run build",
44
+ "preview": "vite preview"
45
+ },
46
+ "devDependencies": {
47
+ "culori": "^4.0.2",
48
+ "typescript": "^5.7.2",
49
+ "vite": "^6.0.3"
50
+ },
51
+ "dependencies": {
52
+ "dom-to-image-more": "^3.7.2"
53
+ }
54
+ }