@supermousejs/labs 2.4.4-beta.3 → 2.4.4-beta.5
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 +55 -0
- package/dist/index.d.ts +8 -1
- package/dist/index.mjs +154 -161
- package/dist/index.umd.js +2 -2
- package/package.json +7 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,60 @@
|
|
|
1
1
|
# @supermousejs/labs
|
|
2
2
|
|
|
3
|
+
## 2.4.4-beta.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- d82c62d: ---
|
|
8
|
+
|
|
9
|
+
Beta.5 — cursor policy flattening, suppression simplification, and API renames.
|
|
10
|
+
|
|
11
|
+
## Changed — breaking
|
|
12
|
+
- `cursorPolicy` option renamed to `nativeCursorSelectors` and flattened to a plain `string[]`. Migration: `cursorPolicy: { native: [".x"] }` → `nativeCursorSelectors: [".x"]`. The `hide` key is gone; cursor suppression is unconditional and no longer configurable.
|
|
13
|
+
- `CursorPolicy` and `CursorPolicyInput` types removed from the public export surface. Code importing them fails at compile time. The only remaining shape is `string[]`.
|
|
14
|
+
- `DEFAULT_CURSOR_POLICY` renamed to `DEFAULT_NATIVE_CURSOR_SELECTORS`. Value reduced to `["select", "[contenteditable]"]`.
|
|
15
|
+
- `registerHoverTarget(selector)` renamed to `addHoverSelectors(selectors)`. Same behavior — comma-separated selectors are added to the current scope's shared hover set. The new name matches `hoverSelectors` and reflects that it mutates a set rather than registering a single element.
|
|
16
|
+
- `@supermousejs/utils`: `VisualConfig.selector` renamed to `hoverSelector`. Update `definePlugin({ ..., selector: "x" })` to `definePlugin({ ..., hoverSelector: "x" })`.
|
|
17
|
+
|
|
18
|
+
## Changed — behavior
|
|
19
|
+
- `input` and `textarea` removed from the default native cursor list. Text inputs and textareas are unaffected — their UA cursor is `text`, which the probe reads and treats as a fallback trigger. Button-like inputs (`<input type="button">`, `<input type="submit">`) and checkboxes/radios change: their UA cursor is `default`, which the probe classifies as non-fallback, so the custom cursor now shows over them. This matches the pre-existing treatment of `<button>`.
|
|
20
|
+
- Cursor suppression is now a single wildcard rule per scope instead of a wildcard plus per-selector rules. Behavior is unchanged — verified in Chromium and Firefox against `<a>`, `<button>`, `<input>` (all types), `<textarea>`, `<select>`, `[contenteditable]`, `[role="button"]`, `[tabindex]`, `<label>`, and a `<canvas>` with site CSS. Range slider thumb pseudo-elements retain their explicit rules (`*` does not match pseudo-elements).
|
|
21
|
+
|
|
22
|
+
## Fixed
|
|
23
|
+
- `handleMouseOut` no longer leaves `state.isHover` and `state.isNative` stale when the pointer leaves from a descendant of the tracked element. Moving from `<span>` inside `<button>` directly outside the button previously failed to clear `hoverTarget` — the containment check was inverted.
|
|
24
|
+
|
|
25
|
+
## Internal
|
|
26
|
+
- `policy.ts` removed from `@supermousejs/core`. The default moved to `constants.ts`; `normalizePolicy` dissolved into `??` fallbacks at the call sites.
|
|
27
|
+
- `Scope.hideSelectors` field removed.
|
|
28
|
+
- Size budget re-tightened to 6.2 kB gzip / 5.5 kB brotli.
|
|
29
|
+
|
|
30
|
+
- Updated dependencies [d82c62d]
|
|
31
|
+
- @supermousejs/utils@2.4.4-beta.5
|
|
32
|
+
- @supermousejs/core@2.5.0-beta.5
|
|
33
|
+
|
|
34
|
+
## 2.4.4-beta.4
|
|
35
|
+
|
|
36
|
+
### Patch Changes
|
|
37
|
+
|
|
38
|
+
- cb9bf9a: Beta.4
|
|
39
|
+
|
|
40
|
+
**Added**
|
|
41
|
+
- `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`).
|
|
42
|
+
- `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.
|
|
43
|
+
|
|
44
|
+
**Fixed**
|
|
45
|
+
- 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.
|
|
46
|
+
|
|
47
|
+
**Changed**
|
|
48
|
+
- `@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.
|
|
49
|
+
- `@supermousejs/labs`: `SmartIconOptions.useSemanticTags` renamed to `useSemanticDetection`. The old name referred to a `registerHoverTarget` sweep that no longer runs.
|
|
50
|
+
|
|
51
|
+
**Internal**
|
|
52
|
+
- 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.
|
|
53
|
+
|
|
54
|
+
- Updated dependencies [cb9bf9a]
|
|
55
|
+
- @supermousejs/core@2.5.0-beta.4
|
|
56
|
+
- @supermousejs/utils@2.4.4-beta.4
|
|
57
|
+
|
|
3
58
|
## 2.4.4-beta.3
|
|
4
59
|
|
|
5
60
|
### 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
|
-
|
|
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
|
|
2
|
-
function ct(t,
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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 (
|
|
10
|
-
} else if ((
|
|
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
|
-
|
|
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
|
|
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.
|
|
32
|
-
function v(
|
|
33
|
-
x(
|
|
24
|
+
}), p = 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(
|
|
36
|
-
|
|
28
|
+
function S(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
|
-
|
|
43
|
-
create: (
|
|
44
|
-
const
|
|
45
|
-
return x(
|
|
35
|
+
hoverSelector: "[data-supermouse-icon]",
|
|
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
|
-
}),
|
|
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 =
|
|
58
|
+
), l = o.state.cursorMode, o.setCursor("custom"), A.appendChild(n), A;
|
|
66
59
|
},
|
|
67
|
-
update: (
|
|
68
|
-
const
|
|
69
|
-
let
|
|
70
|
-
if (
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
|
|
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 = p ? 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,
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
x(
|
|
79
|
-
width: `${
|
|
80
|
-
height: `${
|
|
68
|
+
a && (a = null, r = null);
|
|
69
|
+
T !== u && g === "idle" ? !!D[T] || T === w ? O ? (S(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 && (S(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 =
|
|
85
|
-
switch (d.anchor(
|
|
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 = -
|
|
86
|
+
P = -L, W = 0;
|
|
94
87
|
break;
|
|
95
88
|
case "bottom-left":
|
|
96
|
-
P = 0, W = -
|
|
89
|
+
P = 0, W = -L;
|
|
97
90
|
break;
|
|
98
91
|
case "bottom-right":
|
|
99
|
-
P = -
|
|
92
|
+
P = -L, W = -L;
|
|
100
93
|
break;
|
|
101
94
|
}
|
|
102
|
-
const K =
|
|
103
|
-
if (d.rotateWithVelocity(
|
|
104
|
-
const { x:
|
|
105
|
-
M.dist(
|
|
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
|
-
|
|
100
|
+
i = M.lerpAngle(i, z, Z);
|
|
108
101
|
} else {
|
|
109
|
-
const
|
|
110
|
-
|
|
102
|
+
const k = 1 - Math.exp(-20 * F);
|
|
103
|
+
i = M.lerpAngle(i, 0, k);
|
|
111
104
|
}
|
|
112
|
-
const q = d.followStrategy(
|
|
113
|
-
|
|
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(
|
|
116
|
-
|
|
108
|
+
cleanup(o) {
|
|
109
|
+
o.setCursor(l);
|
|
117
110
|
}
|
|
118
111
|
},
|
|
119
112
|
t
|
|
120
113
|
);
|
|
121
114
|
}, gt = (t = {}) => {
|
|
122
|
-
const
|
|
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
|
|
122
|
+
let u = 20, a = 20, r = 0, g = 1, c = 1;
|
|
130
123
|
const C = 150;
|
|
131
|
-
let
|
|
124
|
+
let f = null;
|
|
132
125
|
return N(
|
|
133
126
|
{
|
|
134
127
|
name: t.name ?? "smart-ring",
|
|
135
|
-
|
|
136
|
-
create: (
|
|
137
|
-
const
|
|
138
|
-
return x(
|
|
128
|
+
hoverSelector: "[data-supermouse-color]",
|
|
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
|
-
}),
|
|
137
|
+
}), i;
|
|
145
138
|
},
|
|
146
|
-
onEnable(
|
|
147
|
-
const z =
|
|
148
|
-
|
|
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(
|
|
151
|
-
const { x: z, y: d } =
|
|
152
|
-
return
|
|
153
|
-
|
|
154
|
-
|
|
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((p) => {
|
|
146
|
+
f = setTimeout(() => {
|
|
147
|
+
i.style.transition = "border-radius 0.2s ease", p();
|
|
155
148
|
}, C);
|
|
156
149
|
});
|
|
157
150
|
},
|
|
158
|
-
update: (
|
|
159
|
-
if (
|
|
160
|
-
const d = z / 1e3, p =
|
|
161
|
-
let
|
|
162
|
-
m ? (
|
|
163
|
-
width: `${
|
|
151
|
+
update: (s, i, z) => {
|
|
152
|
+
if (i.style.display === "none") return;
|
|
153
|
+
const d = z / 1e3, p = n.size(s.state), m = s.state.shape;
|
|
154
|
+
let e = p, h = p, 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:
|
|
167
|
-
backgroundColor:
|
|
168
|
-
borderWidth: `${
|
|
159
|
+
borderColor: w,
|
|
160
|
+
backgroundColor: n.fill(s.state),
|
|
161
|
+
borderWidth: `${n.borderWidth(s.state)}px`,
|
|
169
162
|
opacity: "1"
|
|
170
163
|
});
|
|
171
164
|
let b = 0, v = 1, S = 1;
|
|
172
|
-
if (!m && t.enableSkew && !
|
|
173
|
-
const { displacement:
|
|
165
|
+
if (!m && t.enableSkew && !s.state.reducedMotion) {
|
|
166
|
+
const { displacement: A } = s.state, $ = et.getVelocityDistortion(A.x, A.y);
|
|
174
167
|
b = $.rotation, v = $.scaleX, S = $.scaleY;
|
|
175
|
-
const
|
|
176
|
-
|
|
168
|
+
const R = 1 - Math.exp(-20 * d);
|
|
169
|
+
r = nt(r, b, R);
|
|
177
170
|
} else
|
|
178
|
-
|
|
179
|
-
g =
|
|
180
|
-
const { x: l, y:
|
|
181
|
-
|
|
171
|
+
r = 0;
|
|
172
|
+
g = j(g, v, 20, d), c = j(c, S, 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
|
|
188
|
-
let C = 0,
|
|
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;
|
|
189
182
|
const z = (d, p, m) => {
|
|
190
|
-
const
|
|
191
|
-
if (!
|
|
192
|
-
|
|
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 = p + M.random(-r, r);
|
|
193
186
|
const h = M.random(0, Math.PI * 2), y = M.random(0.5, 1.5);
|
|
194
|
-
|
|
195
|
-
const
|
|
196
|
-
x(
|
|
197
|
-
width: `${
|
|
198
|
-
height: `${
|
|
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
|
-
}),
|
|
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 =
|
|
200
|
+
const d = H("div");
|
|
208
201
|
x(d, { zIndex: U.TRACE });
|
|
209
|
-
for (let p = 0; p <
|
|
202
|
+
for (let p = 0; p < n; p++) {
|
|
210
203
|
const m = _(0, "transparent");
|
|
211
204
|
x(m, {
|
|
212
205
|
opacity: "0",
|
|
@@ -226,26 +219,26 @@ const xt = (t) => {
|
|
|
226
219
|
return d;
|
|
227
220
|
},
|
|
228
221
|
update: (d, p, m) => {
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
const
|
|
232
|
-
if (
|
|
233
|
-
const S = g(d.state), l = Math.floor(
|
|
234
|
-
for (let
|
|
235
|
-
const
|
|
236
|
-
z(C +
|
|
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 S = 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, S);
|
|
237
230
|
}
|
|
238
|
-
|
|
231
|
+
i = i % a;
|
|
239
232
|
}
|
|
240
|
-
C = h,
|
|
241
|
-
for (let S = 0; S <
|
|
233
|
+
C = h, f = y;
|
|
234
|
+
for (let S = 0; S < n; S++) {
|
|
242
235
|
const l = c[S];
|
|
243
236
|
if (l.isActive)
|
|
244
|
-
if (l.x += l.vx *
|
|
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
|
|
248
|
-
x(l.el, { opacity: String(l.life) }),
|
|
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,
|
|
260
|
-
return
|
|
252
|
+
function dt(t, n) {
|
|
253
|
+
return n ? t + " " : t;
|
|
261
254
|
}
|
|
262
255
|
let ft = 0;
|
|
263
|
-
const
|
|
264
|
-
let
|
|
265
|
-
const C = `supermouse-text-ring-path-${ft++}`,
|
|
256
|
+
const St = (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
|
-
}),
|
|
265
|
+
}), s = t.className ?? "", i = t.spread ?? !0;
|
|
273
266
|
let z = 0, d = "", p = 0, m = 0;
|
|
274
267
|
return N(
|
|
275
268
|
{
|
|
276
269
|
name: t.name ?? "text-ring",
|
|
277
|
-
|
|
278
|
-
create: (
|
|
279
|
-
const h =
|
|
270
|
+
hoverSelector: "[data-supermouse-text-ring]",
|
|
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
|
-
}),
|
|
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
|
-
}),
|
|
296
|
-
const y =
|
|
297
|
-
return m = y,
|
|
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),
|
|
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(
|
|
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: (
|
|
308
|
-
const
|
|
309
|
-
let b =
|
|
310
|
-
const v =
|
|
311
|
-
x(h, { color:
|
|
312
|
-
const $ =
|
|
300
|
+
update: (e, h, y) => {
|
|
301
|
+
const w = y / 1e3;
|
|
302
|
+
let b = f.text(e.state);
|
|
303
|
+
const v = f.radius(e.state), S = 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;
|
|
313
306
|
if ($.textRing && typeof $.textRing == "string" ? b = $.textRing : $.text && typeof $.text == "string" && (b = $.text), v !== p) {
|
|
314
|
-
|
|
315
|
-
const
|
|
316
|
-
x(
|
|
317
|
-
width: `${
|
|
318
|
-
height: `${
|
|
307
|
+
u.setAttribute("d", ot(v));
|
|
308
|
+
const E = v * 2;
|
|
309
|
+
x(n, {
|
|
310
|
+
width: `${E}px`,
|
|
311
|
+
height: `${E}px`
|
|
319
312
|
}), p = v;
|
|
320
313
|
}
|
|
321
|
-
const
|
|
322
|
-
if (S !== m && (
|
|
323
|
-
const
|
|
324
|
-
c.textContent =
|
|
325
|
-
const
|
|
326
|
-
if (
|
|
327
|
-
const
|
|
328
|
-
x(
|
|
314
|
+
const R = dt(b, i);
|
|
315
|
+
if (S !== m && (r.setAttribute("font-size", `${S}px`), c.setAttribute("font-size", `${S}px`), m = S), 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(
|
|
331
|
-
|
|
323
|
+
x(r, { letterSpacing: "0px" });
|
|
324
|
+
r.removeAttribute("textLength"), a.removeAttribute("textLength"), a.removeAttribute("lengthAdjust");
|
|
332
325
|
} else
|
|
333
|
-
x(
|
|
334
|
-
z += l *
|
|
335
|
-
const { x: F, y:
|
|
336
|
-
|
|
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
|
|
@@ -343,5 +336,5 @@ export {
|
|
|
343
336
|
xt as SmartIcon,
|
|
344
337
|
gt as SmartRing,
|
|
345
338
|
yt as Sparkles,
|
|
346
|
-
|
|
339
|
+
St as TextRing
|
|
347
340
|
};
|
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
|
|
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",hoverSelector:"[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(),
|
|
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",hoverSelector:"[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",hoverSelector:"[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
|
+
"version": "2.4.4-beta.5",
|
|
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.
|
|
17
|
+
"@supermousejs/utils": "2.4.4-beta.5"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
|
-
"@supermousejs/core": "2.5.0-beta.
|
|
20
|
+
"@supermousejs/core": "2.5.0-beta.5"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@supermousejs/core": "2.5.0-beta.
|
|
23
|
+
"@supermousejs/core": "2.5.0-beta.5"
|
|
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
|
}
|