@supermousejs/labs 2.4.4-beta.3 → 2.4.4-beta.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # @supermousejs/labs
2
2
 
3
+ ## 2.4.4-beta.4
4
+
5
+ ### Patch Changes
6
+
7
+ - cb9bf9a: Beta.4
8
+
9
+ **Added**
10
+ - `state.authoredCursor` — the cursor value the page intends at the element under the pointer, resolved as if Supermouse's suppression were not active. Populated on every pointerTarget change, in all cursor modes. Read this to know what the page wants (`canvas { cursor: crosshair }`, `.drag-handle { cursor: grab }`, `[disabled] { cursor: not-allowed }`) rather than just whether the OS cursor should be shown (`state.isNative`).
11
+ - `state.pointerTarget` — the raw element under the pointer, regardless of hover selectors. Distinct from `state.hoverTarget`, which reports the nearest ancestor matching a hover selector.
12
+
13
+ **Fixed**
14
+ - Cursor detection in `auto` mode no longer reads its own suppression output. The previous implementation called `getComputedStyle(target).cursor` while the scope's hide class was active, so it always saw `"none"` and never triggered native fallback for authored exotic cursors. A probe attribute (`data-sm-probe`) is now excluded from every generated suppression rule, so the read sees the page's intended value.
15
+
16
+ **Changed**
17
+ - `@supermousejs/labs`: `SmartIcon` now reads `state.pointerTarget` and `state.authoredCursor` instead of relying on a broad hover-selector sweep. Hovering a `<p>` no longer sets `state.isHover` on the primary scope.
18
+ - `@supermousejs/labs`: `SmartIconOptions.useSemanticTags` renamed to `useSemanticDetection`. The old name referred to a `registerHoverTarget` sweep that no longer runs.
19
+
20
+ **Internal**
21
+ - Size budget raised to 6.5 kB gzip / 5.75 kB brotli to accommodate the beta.4 surface. Will be re-tightened once the shape settles.
22
+
23
+ - Updated dependencies [cb9bf9a]
24
+ - @supermousejs/core@2.5.0-beta.4
25
+ - @supermousejs/utils@2.4.4-beta.4
26
+
3
27
  ## 2.4.4-beta.3
4
28
 
5
29
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -14,7 +14,14 @@ export declare interface SmartIconOptions {
14
14
  isEnabled?: boolean;
15
15
  icons: SmartIconMap;
16
16
  defaultState?: string;
17
- useSemanticTags?: boolean;
17
+ /**
18
+ * If true (default), resolve icon state from the semantic meaning of the
19
+ * pointer target — text inputs become "text", links become "pointer",
20
+ * authored cursors feed the "text"/"grab" icons. If false, only
21
+ * `data-supermouse-icon` attributes drive state, with `defaultState`
22
+ * as the fallback.
23
+ */
24
+ useSemanticDetection?: boolean;
18
25
  transitionDuration?: number;
19
26
  /** Minimum ms a state must be requested before committing. Default 80. */
20
27
  switchDelay?: number;
package/dist/index.mjs CHANGED
@@ -1,48 +1,41 @@
1
- import { normalizeAll as X, definePlugin as N, css as x, math as M, createActor as j, Layers as U, injectStyles as tt, damp as V, effects as et, lerpAngle as rt, setTransform as D, createCircle as _, normalize as nt, circlePath as st, circumference as ot, createSVGElement as G, path as it, text as at, textPath as lt } from "@supermousejs/utils";
2
- function ct(t, e) {
3
- const f = t.tagName.toLowerCase();
4
- if (f === "input" || f === "textarea" || t.isContentEditable) {
5
- const a = t.type;
6
- if (["button", "submit", "checkbox", "radio", "range", "color"].includes(a)) {
7
- if (e.pointer)
1
+ import { normalizeAll as X, definePlugin as N, css as x, math as M, createActor as H, Layers as U, injectStyles as tt, damp as j, effects as et, lerpAngle as nt, setTransform as I, createCircle as _, normalize as st, circlePath as ot, circumference as rt, createSVGElement as G, path as it, text as at, textPath as lt } from "@supermousejs/utils";
2
+ function ct(t, n, u) {
3
+ const a = t.tagName.toLowerCase(), r = t.isContentEditable || t.closest(
4
+ '[contenteditable=""], [contenteditable="true"], [contenteditable="plaintext-only"]'
5
+ ) !== null;
6
+ if (a === "input" || a === "textarea" || r) {
7
+ const g = t.type;
8
+ if (["button", "submit", "checkbox", "radio", "range", "color"].includes(g)) {
9
+ if (n.pointer)
8
10
  return "pointer";
9
- } else if (e.text) return "text";
10
- } else if ((f === "a" || f === "button" || t.closest("a") || t.closest("button")) && e.pointer)
11
+ } else if (n.text) return "text";
12
+ } else if ((a === "a" || a === "button" || t.closest("a") || t.closest("button")) && n.pointer)
11
13
  return "pointer";
12
- if (e.text && ["p", "span", "h1", "h2", "h3", "h4", "h5", "h6", "li", "blockquote", "code", "pre"].includes(
13
- f
14
- ))
15
- return "text";
16
- if (e.text || e.grab) {
17
- const a = window.getComputedStyle(t).cursor;
18
- if (e.text && a === "text") return "text";
19
- if (e.grab && a === "grab") return "grab";
20
- }
21
- return null;
14
+ return n.text && t.closest("p, span, h1, h2, h3, h4, h5, h6, li, blockquote, code, pre") || n.text && u === "text" ? "text" : n.grab && u === "grab" ? "grab" : null;
22
15
  }
23
16
  const xt = (t) => {
24
- let e, f = t.defaultState ?? "default", a = null, i, g = "idle", c = 0, C = f, u = null, n = 0, o = 0, z = 0;
17
+ let n, u = t.defaultState ?? "default", a = null, r, g = "idle", c = 0, C = u, f = null, s = 0, i = 0, z = 0;
25
18
  const d = X(t, {
26
19
  size: 24,
27
20
  color: "",
28
21
  followStrategy: "smooth",
29
22
  anchor: "center",
30
23
  rotateWithVelocity: !1
31
- }), p = t.useSemanticTags ?? !0, m = t.transitionDuration ?? 200, r = t.switchDelay ?? 80, h = t.offset?.[0] ?? 0, y = t.offset?.[1] ?? 0, A = t.defaultState ?? "default", b = m / 2;
32
- function v(s) {
33
- x(e, { transform: `scale(${s})` });
24
+ }), S = t.useSemanticDetection ?? !0, m = t.transitionDuration ?? 200, e = t.switchDelay ?? 80, h = t.offset?.[0] ?? 0, y = t.offset?.[1] ?? 0, w = t.defaultState ?? "default", b = m / 2;
25
+ function v(o) {
26
+ x(n, { transform: `scale(${o})` });
34
27
  }
35
- function S(s) {
36
- f = s, e.innerHTML = t.icons[s] ?? "";
28
+ function p(o) {
29
+ u = o, n.innerHTML = t.icons[o] ?? "";
37
30
  }
38
31
  let l;
39
32
  return N(
40
33
  {
41
34
  name: t.name ?? "smart-icon",
42
35
  selector: "[data-supermouse-icon]",
43
- create: (s) => {
44
- const w = j("div");
45
- return x(w, { zIndex: U.CURSOR }), p && s.registerHoverTarget("p, span, h1, h2, h3, h4, h5, h6, li, blockquote, code, pre"), e = j("div"), x(e, {
36
+ create: (o) => {
37
+ const A = H("div");
38
+ return x(A, { zIndex: U.CURSOR }), n = H("div"), x(n, {
46
39
  width: "100%",
47
40
  height: "100%",
48
41
  display: "flex",
@@ -51,7 +44,7 @@ const xt = (t) => {
51
44
  transformOrigin: "center center",
52
45
  transform: "scale(1)",
53
46
  transition: `transform ${b}ms cubic-bezier(0.16, 1, 0.3, 1)`
54
- }), e.innerHTML = t.icons[f] ?? "", tt(
47
+ }), n.innerHTML = t.icons[u] ?? "", tt(
55
48
  "supermouse-smart-icon-styles",
56
49
  `
57
50
  @keyframes sm {
@@ -62,27 +55,27 @@ const xt = (t) => {
62
55
  animation: sm 1s linear infinite;
63
56
  }
64
57
  `
65
- ), l = s.state.cursorMode, s.setCursor("custom"), w.appendChild(e), w;
58
+ ), l = o.state.cursorMode, o.setCursor("custom"), A.appendChild(n), A;
66
59
  },
67
- update: (s, w, $) => {
68
- const T = performance.now(), F = $ / 1e3, O = t.icons, k = s.state.hoverTarget, H = !!k, I = H && k !== a;
69
- let R = A;
70
- if (H) {
71
- I && (a = k, i = p ? ct(k, O) : null);
72
- const L = s.state.interaction?.icon;
73
- L && O[L] ? R = L : i && (R = i);
60
+ update: (o, A, $) => {
61
+ const R = performance.now(), F = $ / 1e3, D = t.icons, E = o.state.pointerTarget, V = !!E, O = V && E !== a;
62
+ let T = w;
63
+ if (V) {
64
+ O && (a = E, r = S ? ct(E, D, o.state.authoredCursor) : null);
65
+ const k = o.state.interaction?.icon;
66
+ k && D[k] ? T = k : r && (T = r);
74
67
  } else
75
- a && (a = null, i = null);
76
- R !== f && g === "idle" ? !!O[R] || R === A ? I ? (S(R), v(1), u = null, n = 0) : R !== u ? (u = R, n = 0) : (n += $, n >= r && (C = R, g = "out", c = T, v(0), u = null, n = 0)) : (u = null, n = 0) : R === f && (u = null, n = 0), g === "out" && T - c >= b && (S(C), g = "in", c = T, v(0)), g === "in" && T - c >= b && (g = "idle", v(1));
77
- const E = d.size(s.state), J = d.color(s.state);
78
- x(w, {
79
- width: `${E}px`,
80
- height: `${E}px`,
68
+ a && (a = null, r = null);
69
+ T !== u && g === "idle" ? !!D[T] || T === w ? O ? (p(T), v(1), f = null, s = 0) : T !== f ? (f = T, s = 0) : (s += $, s >= e && (C = T, g = "out", c = R, v(0), f = null, s = 0)) : (f = null, s = 0) : T === u && (f = null, s = 0), g === "out" && R - c >= b && (p(C), g = "in", c = R, v(0)), g === "in" && R - c >= b && (g = "idle", v(1));
70
+ const L = d.size(o.state), J = d.color(o.state);
71
+ x(A, {
72
+ width: `${L}px`,
73
+ height: `${L}px`,
81
74
  color: J || "inherit"
82
75
  });
83
76
  let P = 0, W = 0;
84
- const Y = E / 2;
85
- switch (d.anchor(s.state)) {
77
+ const Y = L / 2;
78
+ switch (d.anchor(o.state)) {
86
79
  case "center":
87
80
  P = -Y, W = -Y;
88
81
  break;
@@ -90,123 +83,123 @@ const xt = (t) => {
90
83
  P = 0, W = 0;
91
84
  break;
92
85
  case "top-right":
93
- P = -E, W = 0;
86
+ P = -L, W = 0;
94
87
  break;
95
88
  case "bottom-left":
96
- P = 0, W = -E;
89
+ P = 0, W = -L;
97
90
  break;
98
91
  case "bottom-right":
99
- P = -E, W = -E;
92
+ P = -L, W = -L;
100
93
  break;
101
94
  }
102
- const K = f === "pointer" || f === "text";
103
- if (d.rotateWithVelocity(s.state) && !K && !s.state.reducedMotion) {
104
- const { x: L, y: B } = s.state.velocity;
105
- M.dist(L, B) > 1 && (z = M.angle(L, B));
95
+ const K = u === "pointer" || u === "text";
96
+ if (d.rotateWithVelocity(o.state) && !K && !o.state.reducedMotion) {
97
+ const { x: k, y: B } = o.state.velocity;
98
+ M.dist(k, B) > 1 && (z = M.angle(k, B));
106
99
  const Z = 1 - Math.exp(-20 * F);
107
- o = M.lerpAngle(o, z, Z);
100
+ i = M.lerpAngle(i, z, Z);
108
101
  } else {
109
- const L = 1 - Math.exp(-20 * F);
110
- o = M.lerpAngle(o, 0, L);
102
+ const k = 1 - Math.exp(-20 * F);
103
+ i = M.lerpAngle(i, 0, k);
111
104
  }
112
- const q = d.followStrategy(s.state) === "raw" ? s.state.pointer : s.state.smooth, Q = `translate3d(${q.x + h + P}px, ${q.y + y + W}px, 0) rotate(${o}deg)`;
113
- w.style.transform = Q;
105
+ const q = d.followStrategy(o.state) === "raw" ? o.state.pointer : o.state.smooth, Q = `translate3d(${q.x + h + P}px, ${q.y + y + W}px, 0) rotate(${i}deg)`;
106
+ A.style.transform = Q;
114
107
  },
115
- cleanup(s) {
116
- s.setCursor(l);
108
+ cleanup(o) {
109
+ o.setCursor(l);
117
110
  }
118
111
  },
119
112
  t
120
113
  );
121
114
  }, gt = (t = {}) => {
122
- const e = X(t, {
115
+ const n = X(t, {
123
116
  size: 20,
124
117
  hoverSize: 40,
125
118
  color: "#ffffff",
126
119
  fill: "transparent",
127
120
  borderWidth: 2
128
121
  });
129
- let f = 20, a = 20, i = 0, g = 1, c = 1;
122
+ let u = 20, a = 20, r = 0, g = 1, c = 1;
130
123
  const C = 150;
131
- let u = null;
124
+ let f = null;
132
125
  return N(
133
126
  {
134
127
  name: t.name ?? "smart-ring",
135
128
  selector: "[data-supermouse-color]",
136
- create: (n) => {
137
- const o = _(e.size(n.state), e.fill(n.state));
138
- return x(o, {
129
+ create: (s) => {
130
+ const i = _(n.size(s.state), n.fill(s.state));
131
+ return x(i, {
139
132
  zIndex: U.FOLLOWER,
140
133
  mixBlendMode: t.mixBlendMode ?? "difference",
141
134
  transition: "border-radius 0.2s ease",
142
135
  borderStyle: "solid",
143
136
  opacity: "0"
144
- }), o;
137
+ }), i;
145
138
  },
146
- onEnable(n, o) {
147
- const z = e.size(n.state);
148
- f = z * 0.5, a = z * 0.5, i = 0, g = 1, c = 1, clearTimeout(u ?? void 0), o.style.display = "block", o.style.opacity = "1", o.style.transition = "border-radius 0.2s ease";
139
+ onEnable(s, i) {
140
+ const z = n.size(s.state);
141
+ u = z * 0.5, a = z * 0.5, r = 0, g = 1, c = 1, clearTimeout(f ?? void 0), i.style.display = "block", i.style.opacity = "1", i.style.transition = "border-radius 0.2s ease";
149
142
  },
150
- beforeDisable(n, o) {
151
- const { x: z, y: d } = n.state.smooth;
152
- return o.style.transition = `opacity ${C}ms ease, transform ${C}ms ease`, o.style.opacity = "0", D(o, z, d, 0, 0.2, 0.2), new Promise((p) => {
153
- u = setTimeout(() => {
154
- o.style.transition = "border-radius 0.2s ease", p();
143
+ beforeDisable(s, i) {
144
+ const { x: z, y: d } = s.state.smooth;
145
+ return i.style.transition = `opacity ${C}ms ease, transform ${C}ms ease`, i.style.opacity = "0", I(i, z, d, 0, 0.2, 0.2), new Promise((S) => {
146
+ f = setTimeout(() => {
147
+ i.style.transition = "border-radius 0.2s ease", S();
155
148
  }, C);
156
149
  });
157
150
  },
158
- update: (n, o, z) => {
159
- if (o.style.display === "none") return;
160
- const d = z / 1e3, p = e.size(n.state), m = n.state.shape;
161
- let r = p, h = p, y = "50%", A = e.color(n.state);
162
- m ? (r = m.width, h = m.height, y = `${m.borderRadius}px`) : (n.state.isHover && (r = e.hoverSize(n.state), h = e.hoverSize(n.state)), n.state.isDown && (r *= 0.9, h *= 0.9)), n.state.interaction.color && (A = n.state.interaction.color), f = V(f, r, 20, d), a = V(a, h, 20, d), x(o, {
163
- width: `${f}px`,
151
+ update: (s, i, z) => {
152
+ if (i.style.display === "none") return;
153
+ const d = z / 1e3, S = n.size(s.state), m = s.state.shape;
154
+ let e = S, h = S, y = "50%", w = n.color(s.state);
155
+ m ? (e = m.width, h = m.height, y = `${m.borderRadius}px`) : (s.state.isHover && (e = n.hoverSize(s.state), h = n.hoverSize(s.state)), s.state.isDown && (e *= 0.9, h *= 0.9)), s.state.interaction.color && (w = s.state.interaction.color), u = j(u, e, 20, d), a = j(a, h, 20, d), x(i, {
156
+ width: `${u}px`,
164
157
  height: `${a}px`,
165
158
  borderRadius: y,
166
- borderColor: A,
167
- backgroundColor: e.fill(n.state),
168
- borderWidth: `${e.borderWidth(n.state)}px`,
159
+ borderColor: w,
160
+ backgroundColor: n.fill(s.state),
161
+ borderWidth: `${n.borderWidth(s.state)}px`,
169
162
  opacity: "1"
170
163
  });
171
- let b = 0, v = 1, S = 1;
172
- if (!m && t.enableSkew && !n.state.reducedMotion) {
173
- const { displacement: w } = n.state, $ = et.getVelocityDistortion(w.x, w.y);
174
- b = $.rotation, v = $.scaleX, S = $.scaleY;
175
- const T = 1 - Math.exp(-20 * d);
176
- i = rt(i, b, T);
164
+ let b = 0, v = 1, p = 1;
165
+ if (!m && t.enableSkew && !s.state.reducedMotion) {
166
+ const { displacement: A } = s.state, $ = et.getVelocityDistortion(A.x, A.y);
167
+ b = $.rotation, v = $.scaleX, p = $.scaleY;
168
+ const R = 1 - Math.exp(-20 * d);
169
+ r = nt(r, b, R);
177
170
  } else
178
- i = 0;
179
- g = V(g, v, 20, d), c = V(c, S, 20, d);
180
- const { x: l, y: s } = n.state.smooth;
181
- D(o, l, s, i, g, c);
171
+ r = 0;
172
+ g = j(g, v, 20, d), c = j(c, p, 20, d);
173
+ const { x: l, y: o } = s.state.smooth;
174
+ I(i, l, o, r, g, c);
182
175
  }
183
176
  },
184
177
  t
185
178
  );
186
179
  }, yt = (t = {}) => {
187
- const e = t.count ?? 30, f = t.decay ?? 2.5, a = t.frequency ?? 10, i = t.scatter ?? 5, g = nt(t.color, "#ff00ff"), c = [];
188
- let C = 0, u = 0, n = !1, o = 0;
189
- const z = (d, p, m) => {
190
- const r = c.find((b) => !b.isActive);
191
- if (!r) return;
192
- r.isActive = !0, r.life = 1, r.x = d + M.random(-i, i), r.y = p + M.random(-i, i);
180
+ const n = t.count ?? 30, u = t.decay ?? 2.5, a = t.frequency ?? 10, r = t.scatter ?? 5, g = st(t.color, "#ff00ff"), c = [];
181
+ let C = 0, f = 0, s = !1, i = 0;
182
+ const z = (d, S, m) => {
183
+ const e = c.find((b) => !b.isActive);
184
+ if (!e) return;
185
+ e.isActive = !0, e.life = 1, e.x = d + M.random(-r, r), e.y = S + M.random(-r, r);
193
186
  const h = M.random(0, Math.PI * 2), y = M.random(0.5, 1.5);
194
- r.vx = Math.cos(h) * y, r.vy = Math.sin(h) * y, r.scale = M.random(0.5, 1.2), r.color = m;
195
- const A = M.random(2, 5);
196
- x(r.el, {
197
- width: `${A}px`,
198
- height: `${A}px`,
187
+ e.vx = Math.cos(h) * y, e.vy = Math.sin(h) * y, e.scale = M.random(0.5, 1.2), e.color = m;
188
+ const w = M.random(2, 5);
189
+ x(e.el, {
190
+ width: `${w}px`,
191
+ height: `${w}px`,
199
192
  backgroundColor: m,
200
193
  opacity: "1"
201
- }), D(r.el, r.x, r.y, 0, r.scale, r.scale);
194
+ }), I(e.el, e.x, e.y, 0, e.scale, e.scale);
202
195
  };
203
196
  return N(
204
197
  {
205
198
  name: t.name ?? "sparkles",
206
199
  create: () => {
207
- const d = j("div");
200
+ const d = H("div");
208
201
  x(d, { zIndex: U.TRACE });
209
- for (let p = 0; p < e; p++) {
202
+ for (let S = 0; S < n; S++) {
210
203
  const m = _(0, "transparent");
211
204
  x(m, {
212
205
  opacity: "0",
@@ -225,27 +218,27 @@ const xt = (t) => {
225
218
  }
226
219
  return d;
227
220
  },
228
- update: (d, p, m) => {
229
- const r = m / 1e3, { x: h, y } = d.state.pointer;
230
- n || (C = h, u = y, n = !0);
231
- const A = h - C, b = y - u, v = Math.hypot(A, b);
232
- if (o += v, o > a) {
233
- const S = g(d.state), l = Math.floor(o / a);
234
- for (let s = 0; s < l; s++) {
235
- const w = s / l;
236
- z(C + A * w, u + b * w, S);
221
+ update: (d, S, m) => {
222
+ const e = m / 1e3, { x: h, y } = d.state.pointer;
223
+ s || (C = h, f = y, s = !0);
224
+ const w = h - C, b = y - f, v = Math.hypot(w, b);
225
+ if (i += v, i > a) {
226
+ const p = g(d.state), l = Math.floor(i / a);
227
+ for (let o = 0; o < l; o++) {
228
+ const A = o / l;
229
+ z(C + w * A, f + b * A, p);
237
230
  }
238
- o = o % a;
231
+ i = i % a;
239
232
  }
240
- C = h, u = y;
241
- for (let S = 0; S < e; S++) {
242
- const l = c[S];
233
+ C = h, f = y;
234
+ for (let p = 0; p < n; p++) {
235
+ const l = c[p];
243
236
  if (l.isActive)
244
- if (l.x += l.vx * r * 60, l.y += l.vy * r * 60, l.life -= f * r, l.life <= 0)
237
+ if (l.x += l.vx * e * 60, l.y += l.vy * e * 60, l.life -= u * e, l.life <= 0)
245
238
  l.isActive = !1, x(l.el, { opacity: "0" });
246
239
  else {
247
- const s = l.scale * l.life;
248
- x(l.el, { opacity: String(l.life) }), D(l.el, l.x, l.y, 0, s, s);
240
+ const o = l.scale * l.life;
241
+ x(l.el, { opacity: String(l.life) }), I(l.el, l.x, l.y, 0, o, o);
249
242
  }
250
243
  }
251
244
  },
@@ -256,27 +249,27 @@ const xt = (t) => {
256
249
  t
257
250
  );
258
251
  };
259
- function dt(t, e) {
260
- return e ? t + " " : t;
252
+ function dt(t, n) {
253
+ return n ? t + " " : t;
261
254
  }
262
255
  let ft = 0;
263
256
  const pt = (t = {}) => {
264
- let e, f, a, i, g, c;
265
- const C = `supermouse-text-ring-path-${ft++}`, u = X(t, {
257
+ let n, u, a, r, g, c;
258
+ const C = `supermouse-text-ring-path-${ft++}`, f = X(t, {
266
259
  text: "SUPERMOUSE • SUPERMOUSE • ",
267
260
  radius: 60,
268
261
  fontSize: 12,
269
262
  speed: 30,
270
263
  opacity: 1,
271
264
  color: "currentColor"
272
- }), n = t.className ?? "", o = t.spread ?? !0;
273
- let z = 0, d = "", p = 0, m = 0;
265
+ }), s = t.className ?? "", i = t.spread ?? !0;
266
+ let z = 0, d = "", S = 0, m = 0;
274
267
  return N(
275
268
  {
276
269
  name: t.name ?? "text-ring",
277
270
  selector: "[data-supermouse-text-ring]",
278
- create: (r) => {
279
- const h = j("div");
271
+ create: (e) => {
272
+ const h = H("div");
280
273
  x(h, {
281
274
  zIndex: U.FOLLOWER,
282
275
  transition: "opacity 0.2s ease",
@@ -287,53 +280,53 @@ const pt = (t = {}) => {
287
280
  display: "flex",
288
281
  alignItems: "center",
289
282
  justifyContent: "center"
290
- }), n && h.classList.add(...n.split(" ").filter(Boolean)), e = G("svg"), x(e, {
283
+ }), s && h.classList.add(...s.split(" ").filter(Boolean)), n = G("svg"), x(n, {
291
284
  overflow: "visible",
292
285
  position: "absolute",
293
286
  left: "0",
294
287
  top: "0"
295
- }), f = it(void 0, { id: C, fill: "none" });
296
- const y = u.fontSize(r.state);
297
- return m = y, i = at({ "font-size": `${y}px`, fill: "currentColor" }), x(i, {
288
+ }), u = it(void 0, { id: C, fill: "none" });
289
+ const y = f.fontSize(e.state);
290
+ return m = y, r = at({ "font-size": `${y}px`, fill: "currentColor" }), x(r, {
298
291
  textTransform: "uppercase",
299
292
  letterSpacing: "2px"
300
- }), a = lt(`#${C}`, { startOffset: "0%" }), g = document.createTextNode(""), a.appendChild(g), i.appendChild(a), e.appendChild(f), e.appendChild(i), c = G("text"), x(c, {
293
+ }), a = lt(`#${C}`, { startOffset: "0%" }), g = document.createTextNode(""), a.appendChild(g), r.appendChild(a), n.appendChild(u), n.appendChild(r), c = G("text"), x(c, {
301
294
  visibility: "hidden",
302
295
  position: "absolute",
303
296
  pointerEvents: "none",
304
297
  whiteSpace: "nowrap"
305
- }), c.setAttribute("font-size", `${y}px`), c.setAttribute("font-family", getComputedStyle(i).fontFamily || "sans-serif"), c.setAttribute("font-weight", getComputedStyle(i).fontWeight || "normal"), c.setAttribute("font-style", getComputedStyle(i).fontStyle || "normal"), e.appendChild(c), h.appendChild(e), h;
298
+ }), c.setAttribute("font-size", `${y}px`), c.setAttribute("font-family", getComputedStyle(r).fontFamily || "sans-serif"), c.setAttribute("font-weight", getComputedStyle(r).fontWeight || "normal"), c.setAttribute("font-style", getComputedStyle(r).fontStyle || "normal"), n.appendChild(c), h.appendChild(n), h;
306
299
  },
307
- update: (r, h, y) => {
308
- const A = y / 1e3;
309
- let b = u.text(r.state);
310
- const v = u.radius(r.state), S = u.fontSize(r.state), l = u.speed(r.state), s = u.opacity(r.state), w = u.color(r.state);
311
- x(h, { color: w, opacity: String(s) });
312
- const $ = r.state.interaction;
313
- if ($.textRing && typeof $.textRing == "string" ? b = $.textRing : $.text && typeof $.text == "string" && (b = $.text), v !== p) {
314
- f.setAttribute("d", st(v));
315
- const k = v * 2;
316
- x(e, {
317
- width: `${k}px`,
318
- height: `${k}px`
319
- }), p = v;
300
+ update: (e, h, y) => {
301
+ const w = y / 1e3;
302
+ let b = f.text(e.state);
303
+ const v = f.radius(e.state), p = f.fontSize(e.state), l = f.speed(e.state), o = f.opacity(e.state), A = f.color(e.state);
304
+ x(h, { color: A, opacity: String(o) });
305
+ const $ = e.state.interaction;
306
+ if ($.textRing && typeof $.textRing == "string" ? b = $.textRing : $.text && typeof $.text == "string" && (b = $.text), v !== S) {
307
+ u.setAttribute("d", ot(v));
308
+ const E = v * 2;
309
+ x(n, {
310
+ width: `${E}px`,
311
+ height: `${E}px`
312
+ }), S = v;
320
313
  }
321
- const T = dt(b, o);
322
- if (S !== m && (i.setAttribute("font-size", `${S}px`), c.setAttribute("font-size", `${S}px`), m = S), T !== d && (g.textContent = T, d = T), o) {
323
- const k = ot(v);
324
- c.textContent = T;
325
- const H = c.getComputedTextLength(), I = T.length;
326
- if (I > 1) {
327
- const E = (k - H) / (I - 1);
328
- x(i, { letterSpacing: `${E}px` });
314
+ const R = dt(b, i);
315
+ if (p !== m && (r.setAttribute("font-size", `${p}px`), c.setAttribute("font-size", `${p}px`), m = p), R !== d && (g.textContent = R, d = R), i) {
316
+ const E = rt(v);
317
+ c.textContent = R;
318
+ const V = c.getComputedTextLength(), O = R.length;
319
+ if (O > 1) {
320
+ const L = (E - V) / (O - 1);
321
+ x(r, { letterSpacing: `${L}px` });
329
322
  } else
330
- x(i, { letterSpacing: "0px" });
331
- i.removeAttribute("textLength"), a.removeAttribute("textLength"), a.removeAttribute("lengthAdjust");
323
+ x(r, { letterSpacing: "0px" });
324
+ r.removeAttribute("textLength"), a.removeAttribute("textLength"), a.removeAttribute("lengthAdjust");
332
325
  } else
333
- x(i, { letterSpacing: "2px" }), i.removeAttribute("textLength"), a.removeAttribute("textLength"), a.removeAttribute("lengthAdjust");
334
- z += l * A;
335
- const { x: F, y: O } = r.state.smooth;
336
- D(h, F, O, z);
326
+ x(r, { letterSpacing: "2px" }), r.removeAttribute("textLength"), a.removeAttribute("textLength"), a.removeAttribute("lengthAdjust");
327
+ z += l * w;
328
+ const { x: F, y: D } = e.state.smooth;
329
+ I(h, F, D, z);
337
330
  }
338
331
  },
339
332
  t
package/dist/index.umd.js CHANGED
@@ -1,4 +1,4 @@
1
- (function(L,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("@supermousejs/utils")):typeof define=="function"&&define.amd?define(["exports","@supermousejs/utils"],e):(L=typeof globalThis<"u"?globalThis:L||self,e(L.SupermouseLabs={},L.SupermouseUtils))})(this,(function(L,e){"use strict";function U(t,r){const m=t.tagName.toLowerCase();if(m==="input"||m==="textarea"||t.isContentEditable){const i=t.type;if(["button","submit","checkbox","radio","range","color"].includes(i)){if(r.pointer)return"pointer"}else if(r.text)return"text"}else if((m==="a"||m==="button"||t.closest("a")||t.closest("button"))&&r.pointer)return"pointer";if(r.text&&["p","span","h1","h2","h3","h4","h5","h6","li","blockquote","code","pre"].includes(m))return"text";if(r.text||r.grab){const i=window.getComputedStyle(t).cursor;if(r.text&&i==="text")return"text";if(r.grab&&i==="grab")return"grab"}return null}const q=t=>{let r,m=t.defaultState??"default",i=null,c,x="idle",d=0,C=m,h=null,o=0,a=0,z=0;const f=e.normalizeAll(t,{size:24,color:"",followStrategy:"smooth",anchor:"center",rotateWithVelocity:!1}),p=t.useSemanticTags??!0,g=t.transitionDuration??200,n=t.switchDelay??80,u=t.offset?.[0]??0,y=t.offset?.[1]??0,T=t.defaultState??"default",b=g/2;function v(s){e.css(r,{transform:`scale(${s})`})}function S(s){m=s,r.innerHTML=t.icons[s]??""}let l;return e.definePlugin({name:t.name??"smart-icon",selector:"[data-supermouse-icon]",create:s=>{const A=e.createActor("div");return e.css(A,{zIndex:e.Layers.CURSOR}),p&&s.registerHoverTarget("p, span, h1, h2, h3, h4, h5, h6, li, blockquote, code, pre"),r=e.createActor("div"),e.css(r,{width:"100%",height:"100%",display:"flex",alignItems:"center",justifyContent:"center",transformOrigin:"center center",transform:"scale(1)",transition:`transform ${b}ms cubic-bezier(0.16, 1, 0.3, 1)`}),r.innerHTML=t.icons[m]??"",e.injectStyles("supermouse-smart-icon-styles",`
1
+ (function(L,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("@supermousejs/utils")):typeof define=="function"&&define.amd?define(["exports","@supermousejs/utils"],e):(L=typeof globalThis<"u"?globalThis:L||self,e(L.SupermouseLabs={},L.SupermouseUtils))})(this,(function(L,e){"use strict";function H(t,r,h){const i=t.tagName.toLowerCase(),a=t.isContentEditable||t.closest('[contenteditable=""], [contenteditable="true"], [contenteditable="plaintext-only"]')!==null;if(i==="input"||i==="textarea"||a){const g=t.type;if(["button","submit","checkbox","radio","range","color"].includes(g)){if(r.pointer)return"pointer"}else if(r.text)return"text"}else if((i==="a"||i==="button"||t.closest("a")||t.closest("button"))&&r.pointer)return"pointer";return r.text&&t.closest("p, span, h1, h2, h3, h4, h5, h6, li, blockquote, code, pre")||r.text&&h==="text"?"text":r.grab&&h==="grab"?"grab":null}const N=t=>{let r,h=t.defaultState??"default",i=null,a,g="idle",d=0,C=h,m=null,o=0,c=0,z=0;const f=e.normalizeAll(t,{size:24,color:"",followStrategy:"smooth",anchor:"center",rotateWithVelocity:!1}),S=t.useSemanticDetection??!0,x=t.transitionDuration??200,n=t.switchDelay??80,u=t.offset?.[0]??0,y=t.offset?.[1]??0,T=t.defaultState??"default",b=x/2;function v(s){e.css(r,{transform:`scale(${s})`})}function p(s){h=s,r.innerHTML=t.icons[s]??""}let l;return e.definePlugin({name:t.name??"smart-icon",selector:"[data-supermouse-icon]",create:s=>{const A=e.createActor("div");return e.css(A,{zIndex:e.Layers.CURSOR}),r=e.createActor("div"),e.css(r,{width:"100%",height:"100%",display:"flex",alignItems:"center",justifyContent:"center",transformOrigin:"center center",transform:"scale(1)",transition:`transform ${b}ms cubic-bezier(0.16, 1, 0.3, 1)`}),r.innerHTML=t.icons[h]??"",e.injectStyles("supermouse-smart-icon-styles",`
2
2
  @keyframes sm {
3
3
  0% { transform: rotate(0deg); }
4
4
  100% { transform: rotate(360deg); }
@@ -6,4 +6,4 @@
6
6
  .supermouse-spin {
7
7
  animation: sm 1s linear infinite;
8
8
  }
9
- `),l=s.state.cursorMode,s.setCursor("custom"),A.appendChild(r),A},update:(s,A,w)=>{const $=performance.now(),j=w/1e3,W=t.icons,M=s.state.hoverTarget,D=!!M,I=D&&M!==i;let R=T;if(D){I&&(i=M,c=p?U(M,W):null);const E=s.state.interaction?.icon;E&&W[E]?R=E:c&&(R=c)}else i&&(i=null,c=null);R!==m&&x==="idle"?!!W[R]||R===T?I?(S(R),v(1),h=null,o=0):R!==h?(h=R,o=0):(o+=w,o>=n&&(C=R,x="out",d=$,v(0),h=null,o=0)):(h=null,o=0):R===m&&(h=null,o=0),x==="out"&&$-d>=b&&(S(C),x="in",d=$,v(0)),x==="in"&&$-d>=b&&(x="idle",v(1));const k=f.size(s.state),_=f.color(s.state);e.css(A,{width:`${k}px`,height:`${k}px`,color:_||"inherit"});let P=0,O=0;const F=k/2;switch(f.anchor(s.state)){case"center":P=-F,O=-F;break;case"top-left":P=0,O=0;break;case"top-right":P=-k,O=0;break;case"bottom-left":P=0,O=-k;break;case"bottom-right":P=-k,O=-k;break}const J=m==="pointer"||m==="text";if(f.rotateWithVelocity(s.state)&&!J&&!s.state.reducedMotion){const{x:E,y:H}=s.state.velocity;e.math.dist(E,H)>1&&(z=e.math.angle(E,H));const Q=1-Math.exp(-20*j);a=e.math.lerpAngle(a,z,Q)}else{const E=1-Math.exp(-20*j);a=e.math.lerpAngle(a,0,E)}const V=f.followStrategy(s.state)==="raw"?s.state.pointer:s.state.smooth,K=`translate3d(${V.x+u+P}px, ${V.y+y+O}px, 0) rotate(${a}deg)`;A.style.transform=K},cleanup(s){s.setCursor(l)}},t)},N=(t={})=>{const r=e.normalizeAll(t,{size:20,hoverSize:40,color:"#ffffff",fill:"transparent",borderWidth:2});let m=20,i=20,c=0,x=1,d=1;const C=150;let h=null;return e.definePlugin({name:t.name??"smart-ring",selector:"[data-supermouse-color]",create:o=>{const a=e.createCircle(r.size(o.state),r.fill(o.state));return e.css(a,{zIndex:e.Layers.FOLLOWER,mixBlendMode:t.mixBlendMode??"difference",transition:"border-radius 0.2s ease",borderStyle:"solid",opacity:"0"}),a},onEnable(o,a){const z=r.size(o.state);m=z*.5,i=z*.5,c=0,x=1,d=1,clearTimeout(h??void 0),a.style.display="block",a.style.opacity="1",a.style.transition="border-radius 0.2s ease"},beforeDisable(o,a){const{x:z,y:f}=o.state.smooth;return a.style.transition=`opacity ${C}ms ease, transform ${C}ms ease`,a.style.opacity="0",e.setTransform(a,z,f,0,.2,.2),new Promise(p=>{h=setTimeout(()=>{a.style.transition="border-radius 0.2s ease",p()},C)})},update:(o,a,z)=>{if(a.style.display==="none")return;const f=z/1e3,p=r.size(o.state),g=o.state.shape;let n=p,u=p,y="50%",T=r.color(o.state);g?(n=g.width,u=g.height,y=`${g.borderRadius}px`):(o.state.isHover&&(n=r.hoverSize(o.state),u=r.hoverSize(o.state)),o.state.isDown&&(n*=.9,u*=.9)),o.state.interaction.color&&(T=o.state.interaction.color),m=e.damp(m,n,20,f),i=e.damp(i,u,20,f),e.css(a,{width:`${m}px`,height:`${i}px`,borderRadius:y,borderColor:T,backgroundColor:r.fill(o.state),borderWidth:`${r.borderWidth(o.state)}px`,opacity:"1"});let b=0,v=1,S=1;if(!g&&t.enableSkew&&!o.state.reducedMotion){const{displacement:A}=o.state,w=e.effects.getVelocityDistortion(A.x,A.y);b=w.rotation,v=w.scaleX,S=w.scaleY;const $=1-Math.exp(-20*f);c=e.lerpAngle(c,b,$)}else c=0;x=e.damp(x,v,20,f),d=e.damp(d,S,20,f);const{x:l,y:s}=o.state.smooth;e.setTransform(a,l,s,c,x,d)}},t)},X=(t={})=>{const r=t.count??30,m=t.decay??2.5,i=t.frequency??10,c=t.scatter??5,x=e.normalize(t.color,"#ff00ff"),d=[];let C=0,h=0,o=!1,a=0;const z=(f,p,g)=>{const n=d.find(b=>!b.isActive);if(!n)return;n.isActive=!0,n.life=1,n.x=f+e.math.random(-c,c),n.y=p+e.math.random(-c,c);const u=e.math.random(0,Math.PI*2),y=e.math.random(.5,1.5);n.vx=Math.cos(u)*y,n.vy=Math.sin(u)*y,n.scale=e.math.random(.5,1.2),n.color=g;const T=e.math.random(2,5);e.css(n.el,{width:`${T}px`,height:`${T}px`,backgroundColor:g,opacity:"1"}),e.setTransform(n.el,n.x,n.y,0,n.scale,n.scale)};return e.definePlugin({name:t.name??"sparkles",create:()=>{const f=e.createActor("div");e.css(f,{zIndex:e.Layers.TRACE});for(let p=0;p<r;p++){const g=e.createCircle(0,"transparent");e.css(g,{opacity:"0",willChange:"transform, opacity"}),f.appendChild(g),d.push({el:g,isActive:!1,x:0,y:0,vx:0,vy:0,life:0,scale:1,color:""})}return f},update:(f,p,g)=>{const n=g/1e3,{x:u,y}=f.state.pointer;o||(C=u,h=y,o=!0);const T=u-C,b=y-h,v=Math.hypot(T,b);if(a+=v,a>i){const S=x(f.state),l=Math.floor(a/i);for(let s=0;s<l;s++){const A=s/l;z(C+T*A,h+b*A,S)}a=a%i}C=u,h=y;for(let S=0;S<r;S++){const l=d[S];if(l.isActive)if(l.x+=l.vx*n*60,l.y+=l.vy*n*60,l.life-=m*n,l.life<=0)l.isActive=!1,e.css(l.el,{opacity:"0"});else{const s=l.scale*l.life;e.css(l.el,{opacity:String(l.life)}),e.setTransform(l.el,l.x,l.y,0,s,s)}}},destroy:()=>{d.length=0}},t)};function Y(t,r){return r?t+" ":t}let B=0;const G=(t={})=>{let r,m,i,c,x,d;const C=`supermouse-text-ring-path-${B++}`,h=e.normalizeAll(t,{text:"SUPERMOUSE • SUPERMOUSE • ",radius:60,fontSize:12,speed:30,opacity:1,color:"currentColor"}),o=t.className??"",a=t.spread??!0;let z=0,f="",p=0,g=0;return e.definePlugin({name:t.name??"text-ring",selector:"[data-supermouse-text-ring]",create:n=>{const u=e.createActor("div");e.css(u,{zIndex:e.Layers.FOLLOWER,transition:"opacity 0.2s ease",opacity:"1",width:"0px",height:"0px",overflow:"visible",display:"flex",alignItems:"center",justifyContent:"center"}),o&&u.classList.add(...o.split(" ").filter(Boolean)),r=e.createSVGElement("svg"),e.css(r,{overflow:"visible",position:"absolute",left:"0",top:"0"}),m=e.path(void 0,{id:C,fill:"none"});const y=h.fontSize(n.state);return g=y,c=e.text({"font-size":`${y}px`,fill:"currentColor"}),e.css(c,{textTransform:"uppercase",letterSpacing:"2px"}),i=e.textPath(`#${C}`,{startOffset:"0%"}),x=document.createTextNode(""),i.appendChild(x),c.appendChild(i),r.appendChild(m),r.appendChild(c),d=e.createSVGElement("text"),e.css(d,{visibility:"hidden",position:"absolute",pointerEvents:"none",whiteSpace:"nowrap"}),d.setAttribute("font-size",`${y}px`),d.setAttribute("font-family",getComputedStyle(c).fontFamily||"sans-serif"),d.setAttribute("font-weight",getComputedStyle(c).fontWeight||"normal"),d.setAttribute("font-style",getComputedStyle(c).fontStyle||"normal"),r.appendChild(d),u.appendChild(r),u},update:(n,u,y)=>{const T=y/1e3;let b=h.text(n.state);const v=h.radius(n.state),S=h.fontSize(n.state),l=h.speed(n.state),s=h.opacity(n.state),A=h.color(n.state);e.css(u,{color:A,opacity:String(s)});const w=n.state.interaction;if(w.textRing&&typeof w.textRing=="string"?b=w.textRing:w.text&&typeof w.text=="string"&&(b=w.text),v!==p){m.setAttribute("d",e.circlePath(v));const M=v*2;e.css(r,{width:`${M}px`,height:`${M}px`}),p=v}const $=Y(b,a);if(S!==g&&(c.setAttribute("font-size",`${S}px`),d.setAttribute("font-size",`${S}px`),g=S),$!==f&&(x.textContent=$,f=$),a){const M=e.circumference(v);d.textContent=$;const D=d.getComputedTextLength(),I=$.length;if(I>1){const k=(M-D)/(I-1);e.css(c,{letterSpacing:`${k}px`})}else e.css(c,{letterSpacing:"0px"});c.removeAttribute("textLength"),i.removeAttribute("textLength"),i.removeAttribute("lengthAdjust")}else e.css(c,{letterSpacing:"2px"}),c.removeAttribute("textLength"),i.removeAttribute("textLength"),i.removeAttribute("lengthAdjust");z+=l*T;const{x:j,y:W}=n.state.smooth;e.setTransform(u,j,W,z)}},t)};L.SmartIcon=q,L.SmartRing=N,L.Sparkles=X,L.TextRing=G,Object.defineProperty(L,Symbol.toStringTag,{value:"Module"})}));
9
+ `),l=s.state.cursorMode,s.setCursor("custom"),A.appendChild(r),A},update:(s,A,w)=>{const $=performance.now(),I=w/1e3,W=t.icons,M=s.state.pointerTarget,j=!!M,D=j&&M!==i;let R=T;if(j){D&&(i=M,a=S?H(M,W,s.state.authoredCursor):null);const P=s.state.interaction?.icon;P&&W[P]?R=P:a&&(R=a)}else i&&(i=null,a=null);R!==h&&g==="idle"?!!W[R]||R===T?D?(p(R),v(1),m=null,o=0):R!==m?(m=R,o=0):(o+=w,o>=n&&(C=R,g="out",d=$,v(0),m=null,o=0)):(m=null,o=0):R===h&&(m=null,o=0),g==="out"&&$-d>=b&&(p(C),g="in",d=$,v(0)),g==="in"&&$-d>=b&&(g="idle",v(1));const E=f.size(s.state),_=f.color(s.state);e.css(A,{width:`${E}px`,height:`${E}px`,color:_||"inherit"});let k=0,O=0;const F=E/2;switch(f.anchor(s.state)){case"center":k=-F,O=-F;break;case"top-left":k=0,O=0;break;case"top-right":k=-E,O=0;break;case"bottom-left":k=0,O=-E;break;case"bottom-right":k=-E,O=-E;break}const J=h==="pointer"||h==="text";if(f.rotateWithVelocity(s.state)&&!J&&!s.state.reducedMotion){const{x:P,y:U}=s.state.velocity;e.math.dist(P,U)>1&&(z=e.math.angle(P,U));const Q=1-Math.exp(-20*I);c=e.math.lerpAngle(c,z,Q)}else{const P=1-Math.exp(-20*I);c=e.math.lerpAngle(c,0,P)}const V=f.followStrategy(s.state)==="raw"?s.state.pointer:s.state.smooth,K=`translate3d(${V.x+u+k}px, ${V.y+y+O}px, 0) rotate(${c}deg)`;A.style.transform=K},cleanup(s){s.setCursor(l)}},t)},X=(t={})=>{const r=e.normalizeAll(t,{size:20,hoverSize:40,color:"#ffffff",fill:"transparent",borderWidth:2});let h=20,i=20,a=0,g=1,d=1;const C=150;let m=null;return e.definePlugin({name:t.name??"smart-ring",selector:"[data-supermouse-color]",create:o=>{const c=e.createCircle(r.size(o.state),r.fill(o.state));return e.css(c,{zIndex:e.Layers.FOLLOWER,mixBlendMode:t.mixBlendMode??"difference",transition:"border-radius 0.2s ease",borderStyle:"solid",opacity:"0"}),c},onEnable(o,c){const z=r.size(o.state);h=z*.5,i=z*.5,a=0,g=1,d=1,clearTimeout(m??void 0),c.style.display="block",c.style.opacity="1",c.style.transition="border-radius 0.2s ease"},beforeDisable(o,c){const{x:z,y:f}=o.state.smooth;return c.style.transition=`opacity ${C}ms ease, transform ${C}ms ease`,c.style.opacity="0",e.setTransform(c,z,f,0,.2,.2),new Promise(S=>{m=setTimeout(()=>{c.style.transition="border-radius 0.2s ease",S()},C)})},update:(o,c,z)=>{if(c.style.display==="none")return;const f=z/1e3,S=r.size(o.state),x=o.state.shape;let n=S,u=S,y="50%",T=r.color(o.state);x?(n=x.width,u=x.height,y=`${x.borderRadius}px`):(o.state.isHover&&(n=r.hoverSize(o.state),u=r.hoverSize(o.state)),o.state.isDown&&(n*=.9,u*=.9)),o.state.interaction.color&&(T=o.state.interaction.color),h=e.damp(h,n,20,f),i=e.damp(i,u,20,f),e.css(c,{width:`${h}px`,height:`${i}px`,borderRadius:y,borderColor:T,backgroundColor:r.fill(o.state),borderWidth:`${r.borderWidth(o.state)}px`,opacity:"1"});let b=0,v=1,p=1;if(!x&&t.enableSkew&&!o.state.reducedMotion){const{displacement:A}=o.state,w=e.effects.getVelocityDistortion(A.x,A.y);b=w.rotation,v=w.scaleX,p=w.scaleY;const $=1-Math.exp(-20*f);a=e.lerpAngle(a,b,$)}else a=0;g=e.damp(g,v,20,f),d=e.damp(d,p,20,f);const{x:l,y:s}=o.state.smooth;e.setTransform(c,l,s,a,g,d)}},t)},Y=(t={})=>{const r=t.count??30,h=t.decay??2.5,i=t.frequency??10,a=t.scatter??5,g=e.normalize(t.color,"#ff00ff"),d=[];let C=0,m=0,o=!1,c=0;const z=(f,S,x)=>{const n=d.find(b=>!b.isActive);if(!n)return;n.isActive=!0,n.life=1,n.x=f+e.math.random(-a,a),n.y=S+e.math.random(-a,a);const u=e.math.random(0,Math.PI*2),y=e.math.random(.5,1.5);n.vx=Math.cos(u)*y,n.vy=Math.sin(u)*y,n.scale=e.math.random(.5,1.2),n.color=x;const T=e.math.random(2,5);e.css(n.el,{width:`${T}px`,height:`${T}px`,backgroundColor:x,opacity:"1"}),e.setTransform(n.el,n.x,n.y,0,n.scale,n.scale)};return e.definePlugin({name:t.name??"sparkles",create:()=>{const f=e.createActor("div");e.css(f,{zIndex:e.Layers.TRACE});for(let S=0;S<r;S++){const x=e.createCircle(0,"transparent");e.css(x,{opacity:"0",willChange:"transform, opacity"}),f.appendChild(x),d.push({el:x,isActive:!1,x:0,y:0,vx:0,vy:0,life:0,scale:1,color:""})}return f},update:(f,S,x)=>{const n=x/1e3,{x:u,y}=f.state.pointer;o||(C=u,m=y,o=!0);const T=u-C,b=y-m,v=Math.hypot(T,b);if(c+=v,c>i){const p=g(f.state),l=Math.floor(c/i);for(let s=0;s<l;s++){const A=s/l;z(C+T*A,m+b*A,p)}c=c%i}C=u,m=y;for(let p=0;p<r;p++){const l=d[p];if(l.isActive)if(l.x+=l.vx*n*60,l.y+=l.vy*n*60,l.life-=h*n,l.life<=0)l.isActive=!1,e.css(l.el,{opacity:"0"});else{const s=l.scale*l.life;e.css(l.el,{opacity:String(l.life)}),e.setTransform(l.el,l.x,l.y,0,s,s)}}},destroy:()=>{d.length=0}},t)};function q(t,r){return r?t+" ":t}let B=0;const G=(t={})=>{let r,h,i,a,g,d;const C=`supermouse-text-ring-path-${B++}`,m=e.normalizeAll(t,{text:"SUPERMOUSE • SUPERMOUSE • ",radius:60,fontSize:12,speed:30,opacity:1,color:"currentColor"}),o=t.className??"",c=t.spread??!0;let z=0,f="",S=0,x=0;return e.definePlugin({name:t.name??"text-ring",selector:"[data-supermouse-text-ring]",create:n=>{const u=e.createActor("div");e.css(u,{zIndex:e.Layers.FOLLOWER,transition:"opacity 0.2s ease",opacity:"1",width:"0px",height:"0px",overflow:"visible",display:"flex",alignItems:"center",justifyContent:"center"}),o&&u.classList.add(...o.split(" ").filter(Boolean)),r=e.createSVGElement("svg"),e.css(r,{overflow:"visible",position:"absolute",left:"0",top:"0"}),h=e.path(void 0,{id:C,fill:"none"});const y=m.fontSize(n.state);return x=y,a=e.text({"font-size":`${y}px`,fill:"currentColor"}),e.css(a,{textTransform:"uppercase",letterSpacing:"2px"}),i=e.textPath(`#${C}`,{startOffset:"0%"}),g=document.createTextNode(""),i.appendChild(g),a.appendChild(i),r.appendChild(h),r.appendChild(a),d=e.createSVGElement("text"),e.css(d,{visibility:"hidden",position:"absolute",pointerEvents:"none",whiteSpace:"nowrap"}),d.setAttribute("font-size",`${y}px`),d.setAttribute("font-family",getComputedStyle(a).fontFamily||"sans-serif"),d.setAttribute("font-weight",getComputedStyle(a).fontWeight||"normal"),d.setAttribute("font-style",getComputedStyle(a).fontStyle||"normal"),r.appendChild(d),u.appendChild(r),u},update:(n,u,y)=>{const T=y/1e3;let b=m.text(n.state);const v=m.radius(n.state),p=m.fontSize(n.state),l=m.speed(n.state),s=m.opacity(n.state),A=m.color(n.state);e.css(u,{color:A,opacity:String(s)});const w=n.state.interaction;if(w.textRing&&typeof w.textRing=="string"?b=w.textRing:w.text&&typeof w.text=="string"&&(b=w.text),v!==S){h.setAttribute("d",e.circlePath(v));const M=v*2;e.css(r,{width:`${M}px`,height:`${M}px`}),S=v}const $=q(b,c);if(p!==x&&(a.setAttribute("font-size",`${p}px`),d.setAttribute("font-size",`${p}px`),x=p),$!==f&&(g.textContent=$,f=$),c){const M=e.circumference(v);d.textContent=$;const j=d.getComputedTextLength(),D=$.length;if(D>1){const E=(M-j)/(D-1);e.css(a,{letterSpacing:`${E}px`})}else e.css(a,{letterSpacing:"0px"});a.removeAttribute("textLength"),i.removeAttribute("textLength"),i.removeAttribute("lengthAdjust")}else e.css(a,{letterSpacing:"2px"}),a.removeAttribute("textLength"),i.removeAttribute("textLength"),i.removeAttribute("lengthAdjust");z+=l*T;const{x:I,y:W}=n.state.smooth;e.setTransform(u,I,W,z)}},t)};L.SmartIcon=N,L.SmartRing=X,L.Sparkles=Y,L.TextRing=G,Object.defineProperty(L,Symbol.toStringTag,{value:"Module"})}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supermousejs/labs",
3
- "version": "2.4.4-beta.3",
3
+ "version": "2.4.4-beta.4",
4
4
  "main": "dist/index.umd.js",
5
5
  "module": "dist/index.mjs",
6
6
  "description": "Experimentental state machines and effects for supermouse",
@@ -14,13 +14,13 @@
14
14
  "url": "https://github.com/Whitestar14/supermouse-js",
15
15
  "license": "MIT",
16
16
  "dependencies": {
17
- "@supermousejs/utils": "2.4.4-beta.3"
17
+ "@supermousejs/utils": "2.4.4-beta.4"
18
18
  },
19
19
  "peerDependencies": {
20
- "@supermousejs/core": "2.5.0-beta.3"
20
+ "@supermousejs/core": "2.5.0-beta.4"
21
21
  },
22
22
  "devDependencies": {
23
- "@supermousejs/core": "2.5.0-beta.3"
23
+ "@supermousejs/core": "2.5.0-beta.4"
24
24
  },
25
25
  "repository": {
26
26
  "type": "git",
@@ -42,6 +42,8 @@
42
42
  "access": "public"
43
43
  },
44
44
  "scripts": {
45
- "build": "vite build"
45
+ "build": "vite build",
46
+ "test": "vitest",
47
+ "test:watch": "vitest --watch"
46
48
  }
47
49
  }