@supermousejs/utils 2.3.1 → 2.4.1
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 +35 -0
- package/README.md +613 -8
- package/dist/css.d.ts +14 -0
- package/dist/css.d.ts.map +1 -1
- package/dist/doctor.d.ts +7 -4
- package/dist/doctor.d.ts.map +1 -1
- package/dist/dom.d.ts +24 -14
- package/dist/dom.d.ts.map +1 -1
- package/dist/index.d.ts +10 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +425 -131
- package/dist/index.umd.js +5 -1
- package/dist/math.d.ts +1 -0
- package/dist/math.d.ts.map +1 -1
- package/dist/options.d.ts +30 -0
- package/dist/options.d.ts.map +1 -1
- package/dist/plugin.d.ts +99 -22
- package/dist/plugin.d.ts.map +1 -1
- package/dist/svg.d.ts +36 -0
- package/dist/svg.d.ts.map +1 -0
- package/package.json +6 -4
- package/src/css.ts +18 -0
- package/src/doctor.ts +285 -32
- package/src/dom.ts +53 -31
- package/src/index.ts +15 -11
- package/src/math.ts +4 -0
- package/src/options.ts +65 -22
- package/src/plugin.ts +183 -119
- package/src/svg.ts +119 -0
- package/dist/layers.d.ts +0 -15
- package/dist/layers.d.ts.map +0 -1
- package/src/layers.ts +0 -17
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# @supermousejs/utils
|
|
2
2
|
|
|
3
|
+
## 2.4.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 1048a35: Fixed repository metadata pointing to @supermousejs/core instead of their respective directory in package.json
|
|
8
|
+
- Updated dependencies [1048a35]
|
|
9
|
+
- Updated dependencies [be2d65d]
|
|
10
|
+
- @supermousejs/core@2.4.1
|
|
11
|
+
|
|
12
|
+
## 2.4.0
|
|
13
|
+
|
|
14
|
+
### Minor Changes
|
|
15
|
+
|
|
16
|
+
- faf6e9c: Added svg helpers and restructured the utility to be completely tree-shakeable
|
|
17
|
+
- baa6cff: - Updated SmartRing, Sparkles, TextRing, Pointer, Ring, Stick, and other plugins to use `normalizeAll` for better option management where possible.
|
|
18
|
+
- Enhanced the `doctor` utility to provide detailed diagnostics for plugin configurations and potential issues.
|
|
19
|
+
- Removed the deprecated layers utility and integrated layer constants directly into the CSS utility.
|
|
20
|
+
- Improved code readability and consistency across various plugins by standardizing the use of `dom.css` for style application.
|
|
21
|
+
- dea1e57: Made enhancements and many improvements to `options.ts`:
|
|
22
|
+
- **Removed `styles` map compilation** in `definePlugin` — no more per-plugin style setter arrays and `normalize` calls for properties that were never used
|
|
23
|
+
- **Collapsed `setStyle`/`applyStyles` into `css()`** — single WeakMap cache instead of scattered helpers, fewer function allocations
|
|
24
|
+
- **Slimmed `definePlugin` itself** — dropped the `defaults` parameter and `O` type parameter, less generic instantiation overhead
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- 36d5366: Added proper description messages to package meta
|
|
29
|
+
- 9681b6c: Enhanced @supermouse/utils with `circumference` in math and `circlePath` in svg
|
|
30
|
+
- c43a720: Added `beforeDisable` lifecycle hook for plugins that want to run hooks/animation before core runs the `onDisable()` hook
|
|
31
|
+
- Updated dependencies [53b7276]
|
|
32
|
+
- Updated dependencies [36d5366]
|
|
33
|
+
- Updated dependencies [4fc5aed]
|
|
34
|
+
- Updated dependencies [0cd6a04]
|
|
35
|
+
- Updated dependencies [ab3cad2]
|
|
36
|
+
- @supermousejs/core@2.4.0
|
|
37
|
+
|
|
3
38
|
## 2.3.1
|
|
4
39
|
|
|
5
40
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,14 +1,619 @@
|
|
|
1
1
|
# @supermousejs/utils
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Used primarily by plugin authors.
|
|
3
|
+
The `@supermousejs/utils` package provides a collection of tree-shakable helper functions for building Supermouse plugins and integrations. All utilities are framework-agnostic and optimized for performance in animation loops.
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
---
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
- **DOM:** `createActor`, `setStyle` (cached), `setTransform`.
|
|
10
|
-
- **Plugin:** `definePlugin` helper for type-safe plugin creation.
|
|
7
|
+
## Installation
|
|
11
8
|
|
|
12
|
-
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @supermousejs/utils
|
|
11
|
+
```
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
```bash
|
|
14
|
+
npm install @supermousejs/utils
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
yarn add @supermousejs/utils
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Importing
|
|
24
|
+
|
|
25
|
+
All utilities are available as named exports for optimal tree‑shaking:
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import { css, setTransform, damp, clamp, definePlugin } from "@supermousejs/utils";
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Legacy namespace imports are still supported for backward compatibility, though they may reduce tree‑shaking effectiveness:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { math, dom, svg } from "@supermousejs/utils";
|
|
35
|
+
|
|
36
|
+
math.lerp(0, 1, 0.5);
|
|
37
|
+
dom.css(el, { opacity: 1 });
|
|
38
|
+
svg.circle({ cx: 10, cy: 10, r: 5 });
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
> **Note:** For the smallest bundle size, always prefer named imports.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Math Utilities
|
|
46
|
+
|
|
47
|
+
Mathematical helpers for smooth, frame‑rate independent animations.
|
|
48
|
+
|
|
49
|
+
### `lerp(start, end, factor)`
|
|
50
|
+
|
|
51
|
+
Linear interpolation between two numbers.
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { lerp } from "@supermousejs/utils";
|
|
55
|
+
|
|
56
|
+
const value = lerp(0, 100, 0.25); // 25
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Parameters**
|
|
60
|
+
|
|
61
|
+
| Name | Type | Description |
|
|
62
|
+
| -------- | -------- | -------------------------- |
|
|
63
|
+
| `start` | `number` | Starting value |
|
|
64
|
+
| `end` | `number` | Target value |
|
|
65
|
+
| `factor` | `number` | Interpolation amount (0–1) |
|
|
66
|
+
|
|
67
|
+
**Returns:** `number`
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
### `damp(current, target, lambda, dt)`
|
|
72
|
+
|
|
73
|
+
Frame‑rate independent exponential smoothing. Ideal for cursor physics and smooth follow effects.
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
import { damp } from "@supermousejs/utils";
|
|
77
|
+
|
|
78
|
+
let pos = 0;
|
|
79
|
+
function update(dt: number) {
|
|
80
|
+
pos = damp(pos, target, 12, dt);
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Parameters**
|
|
85
|
+
|
|
86
|
+
| Name | Type | Description |
|
|
87
|
+
| --------- | -------- | ------------------------------- |
|
|
88
|
+
| `current` | `number` | Current value |
|
|
89
|
+
| `target` | `number` | Desired value |
|
|
90
|
+
| `lambda` | `number` | Response rate (higher = faster) |
|
|
91
|
+
| `dt` | `number` | Delta time in **seconds** |
|
|
92
|
+
|
|
93
|
+
**Returns:** `number`
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
### `lerpAngle(start, end, factor)`
|
|
98
|
+
|
|
99
|
+
Interpolates between two angles in degrees, taking the shortest path. Handles 360° wrap‑around.
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
import { lerpAngle } from "@supermousejs/utils";
|
|
103
|
+
|
|
104
|
+
let rotation = 0;
|
|
105
|
+
rotation = lerpAngle(rotation, targetAngle, 0.15);
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Parameters**
|
|
109
|
+
|
|
110
|
+
| Name | Type | Description |
|
|
111
|
+
| -------- | -------- | ------------------------ |
|
|
112
|
+
| `start` | `number` | Starting angle (degrees) |
|
|
113
|
+
| `end` | `number` | Target angle (degrees) |
|
|
114
|
+
| `factor` | `number` | Interpolation amount |
|
|
115
|
+
|
|
116
|
+
**Returns:** `number`
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
### `clamp(value, min, max)`
|
|
121
|
+
|
|
122
|
+
Constrains a number between a minimum and maximum.
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
import { clamp } from "@supermousejs/utils";
|
|
126
|
+
|
|
127
|
+
const alpha = clamp(raw, 0, 1);
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Returns:** `number`
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
### `dist(x1, y1, x2?, y2?)`
|
|
135
|
+
|
|
136
|
+
Calculates the distance between two points, or the magnitude of a vector if the second point is omitted.
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
import { dist } from "@supermousejs/utils";
|
|
140
|
+
|
|
141
|
+
const speed = dist(vx, vy); // magnitude
|
|
142
|
+
const gap = dist(x1, y1, x2, y2); // distance
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Returns:** `number`
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
### `angle(x, y)`
|
|
150
|
+
|
|
151
|
+
Calculates the angle in degrees from the origin to a point (or vector direction).
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
import { angle } from "@supermousejs/utils";
|
|
155
|
+
|
|
156
|
+
const direction = angle(vx, vy);
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Returns:** `number` (degrees)
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
### `random(min, max)`
|
|
164
|
+
|
|
165
|
+
Returns a random floating‑point number between `min` and `max`.
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
import { random } from "@supermousejs/utils";
|
|
169
|
+
|
|
170
|
+
const jitter = random(-4, 4);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Returns:** `number`
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## DOM Utilities
|
|
178
|
+
|
|
179
|
+
Utilities for safe, performant DOM manipulation inside animation loops.
|
|
180
|
+
|
|
181
|
+
### `css(el, styles)`
|
|
182
|
+
|
|
183
|
+
Applies an object of CSS properties to an element. Only writes to the DOM when a value has changed, preventing layout thrashing.
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
import { css } from "@supermousejs/utils";
|
|
187
|
+
|
|
188
|
+
css(el, {
|
|
189
|
+
width: `${size}px`,
|
|
190
|
+
height: `${size}px`,
|
|
191
|
+
opacity: state.isHover ? 1 : 0,
|
|
192
|
+
backgroundColor: state.interaction.color || "#000"
|
|
193
|
+
});
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**Parameters**
|
|
197
|
+
|
|
198
|
+
| Name | Type | Description |
|
|
199
|
+
| -------- | ---------------------------------- | ------------------------- |
|
|
200
|
+
| `el` | `HTMLElement \| SVGElement` | Target element |
|
|
201
|
+
| `styles` | `Record<string, string \| number>` | CSS properties and values |
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
### `setTransform(el, x, y, rotation?, scaleX?, scaleY?, skewX?, skewY?)`
|
|
206
|
+
|
|
207
|
+
Applies a CSS transform with automatic centering (`translate(-50%, -50%)`). This is the recommended way to position cursor elements.
|
|
208
|
+
|
|
209
|
+
```ts
|
|
210
|
+
import { setTransform } from "@supermousejs/utils";
|
|
211
|
+
|
|
212
|
+
setTransform(el, x, y, rotation, scaleX, scaleY);
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Parameters**
|
|
216
|
+
|
|
217
|
+
| Name | Type | Default | Description |
|
|
218
|
+
| ---------- | --------------------------- | ------- | ------------------------ |
|
|
219
|
+
| `el` | `HTMLElement \| SVGElement` | | Target element |
|
|
220
|
+
| `x` | `number` | | Horizontal position (px) |
|
|
221
|
+
| `y` | `number` | | Vertical position (px) |
|
|
222
|
+
| `rotation` | `number` | `0` | Rotation in degrees |
|
|
223
|
+
| `scaleX` | `number` | `1` | Horizontal scale |
|
|
224
|
+
| `scaleY` | `number` | `1` | Vertical scale |
|
|
225
|
+
| `skewX` | `number` | `0` | Horizontal skew (deg) |
|
|
226
|
+
| `skewY` | `number` | `0` | Vertical skew (deg) |
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
### `injectStyles(id, css)`
|
|
231
|
+
|
|
232
|
+
Injects a global `<style>` tag into the document head. Safe for SPA routing and HMR.
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
import { injectStyles } from "@supermousejs/utils";
|
|
236
|
+
|
|
237
|
+
injectStyles("my-plugin-style", `.my-plugin { cursor: none; }`);
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
### `projectRect(element, container?)`
|
|
243
|
+
|
|
244
|
+
Calculates the bounding rectangle of an element relative to a container.
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
import { projectRect } from "@supermousejs/utils";
|
|
248
|
+
|
|
249
|
+
const rect = projectRect(target, app.container);
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
**Parameters**
|
|
253
|
+
|
|
254
|
+
| Name | Type | Default | Description |
|
|
255
|
+
| ----------- | ------------------------------ | --------------- | ------------------ |
|
|
256
|
+
| `element` | `HTMLElement \| SVGSVGElement` | | Element to measure |
|
|
257
|
+
| `container` | `HTMLElement \| SVGSVGElement` | `document.body` | Relative container |
|
|
258
|
+
|
|
259
|
+
**Returns:** `DOMRect`
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
### `createActor(tagName?)`
|
|
264
|
+
|
|
265
|
+
Creates a standard Supermouse actor element with absolute positioning, `pointer-events: none`, and `will-change: transform`.
|
|
266
|
+
|
|
267
|
+
```ts
|
|
268
|
+
import { createActor } from "@supermousejs/utils";
|
|
269
|
+
|
|
270
|
+
const layer = createActor("div");
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
**Returns:** `HTMLElement | SVGSVGElement`
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
### `createCircle(size, color)`
|
|
278
|
+
|
|
279
|
+
Creates a circular HTML element.
|
|
280
|
+
|
|
281
|
+
```ts
|
|
282
|
+
import { createCircle } from "@supermousejs/utils";
|
|
283
|
+
|
|
284
|
+
const dot = createCircle(8, "#f59e0b");
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
**Returns:** `HTMLDivElement`
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
### `createDiv()`
|
|
292
|
+
|
|
293
|
+
Legacy alias for `createActor("div")`.
|
|
294
|
+
|
|
295
|
+
```ts
|
|
296
|
+
import { createDiv } from "@supermousejs/utils";
|
|
297
|
+
|
|
298
|
+
const el = createDiv();
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
**Deprecated:** Use `createActor("div")` instead.
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
### `setStyle(el, prop, value)` _(deprecated)_
|
|
306
|
+
|
|
307
|
+
Legacy single‑style writer. Use `css()` instead.
|
|
308
|
+
|
|
309
|
+
```ts
|
|
310
|
+
import { setStyle } from "@supermousejs/utils";
|
|
311
|
+
|
|
312
|
+
setStyle(el, "opacity", 0);
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### `applyStyles(el, styles)` _(deprecated)_
|
|
316
|
+
|
|
317
|
+
Legacy bulk style writer. Use `css()` instead.
|
|
318
|
+
|
|
319
|
+
```ts
|
|
320
|
+
import { applyStyles } from "@supermousejs/utils";
|
|
321
|
+
|
|
322
|
+
applyStyles(el, { opacity: 0, color: "red" });
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## Effects
|
|
328
|
+
|
|
329
|
+
### `getVelocityDistortion(vx, vy, intensity?, maxStretch?)`
|
|
330
|
+
|
|
331
|
+
Calculates rotation and squash/stretch values based on velocity. Ideal for motion‑reactive cursor effects.
|
|
332
|
+
|
|
333
|
+
```ts
|
|
334
|
+
import { getVelocityDistortion } from "@supermousejs/utils";
|
|
335
|
+
import { setTransform } from "@supermousejs/utils";
|
|
336
|
+
|
|
337
|
+
const { rotation, scaleX, scaleY } = getVelocityDistortion(vx, vy);
|
|
338
|
+
setTransform(el, x, y, rotation, scaleX, scaleY);
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
**Parameters**
|
|
342
|
+
|
|
343
|
+
| Name | Type | Default | Description |
|
|
344
|
+
| ------------ | -------- | ------- | ---------------------- |
|
|
345
|
+
| `vx` | `number` | | Velocity X |
|
|
346
|
+
| `vy` | `number` | | Velocity Y |
|
|
347
|
+
| `intensity` | `number` | `0.004` | Stretch factor |
|
|
348
|
+
| `maxStretch` | `number` | `0.5` | Maximum stretch amount |
|
|
349
|
+
|
|
350
|
+
**Returns:** `{ rotation: number; scaleX: number; scaleY: number }`
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
## Options Utilities
|
|
355
|
+
|
|
356
|
+
### `normalize(option, defaultValue)`
|
|
357
|
+
|
|
358
|
+
Converts a static value, reactive getter, or `undefined` into a function that always returns the resolved value. This removes `typeof` checks from hot loops.
|
|
359
|
+
|
|
360
|
+
```ts
|
|
361
|
+
import { normalize } from "@supermousejs/utils";
|
|
362
|
+
|
|
363
|
+
const getSize = normalize(options.size, 20);
|
|
364
|
+
const size = getSize(app.state);
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
**Parameters**
|
|
368
|
+
|
|
369
|
+
| Name | Type | Description |
|
|
370
|
+
| -------------- | ------------------------------- | -------------------- |
|
|
371
|
+
| `option` | `ValueOrGetter<T> \| undefined` | User‑provided option |
|
|
372
|
+
| `defaultValue` | `T` | Fallback value |
|
|
373
|
+
|
|
374
|
+
**Returns:** `(state: MouseState) => T`
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
### `normalizeAll(options, defaults)`
|
|
379
|
+
|
|
380
|
+
Normalizes multiple options in one call.
|
|
381
|
+
|
|
382
|
+
```ts
|
|
383
|
+
import { normalizeAll } from "@supermousejs/utils";
|
|
384
|
+
|
|
385
|
+
const cfg = normalizeAll(options, {
|
|
386
|
+
size: 20,
|
|
387
|
+
color: "#fff",
|
|
388
|
+
opacity: 1
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
const size = cfg.size(app.state);
|
|
392
|
+
const color = cfg.color(app.state);
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
**Returns:** `{ [K in keyof T]: (state: MouseState) => T[K] }`
|
|
396
|
+
|
|
397
|
+
---
|
|
398
|
+
|
|
399
|
+
### `hasFinePointer()`
|
|
400
|
+
|
|
401
|
+
Returns `true` if the device has a fine pointer (mouse), `false` for coarse pointers (touch).
|
|
402
|
+
|
|
403
|
+
```ts
|
|
404
|
+
import { hasFinePointer } from "@supermousejs/utils";
|
|
405
|
+
|
|
406
|
+
if (hasFinePointer()) {
|
|
407
|
+
// enable custom cursor
|
|
408
|
+
}
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
**Returns:** `boolean`
|
|
412
|
+
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
## Plugin Helper
|
|
416
|
+
|
|
417
|
+
### `definePlugin(config, userOptions?)`
|
|
418
|
+
|
|
419
|
+
Creates a Supermouse plugin from a declarative configuration.
|
|
420
|
+
|
|
421
|
+
**Two overloads:**
|
|
422
|
+
|
|
423
|
+
- **Visual Plugin:** The config includes `create()` and optionally `update`, `selector`, `beforeDisable`, etc. The helper mounts the returned element to the **stage** and toggles visibility automatically.
|
|
424
|
+
- **Logic Plugin:** The config omits `create`; all lifecycle hooks are passed through directly.
|
|
425
|
+
|
|
426
|
+
#### Visual Plugin Example
|
|
427
|
+
|
|
428
|
+
```ts
|
|
429
|
+
import { definePlugin, css, setTransform } from "@supermousejs/utils";
|
|
430
|
+
|
|
431
|
+
export const Dot = (options = {}) =>
|
|
432
|
+
definePlugin(
|
|
433
|
+
{
|
|
434
|
+
name: "dot",
|
|
435
|
+
create: () => document.createElement("div"),
|
|
436
|
+
update(app, el, dt) {
|
|
437
|
+
const size = getSize(app.state);
|
|
438
|
+
css(el, {
|
|
439
|
+
width: `${size}px`,
|
|
440
|
+
height: `${size}px`,
|
|
441
|
+
backgroundColor: getColor(app.state)
|
|
442
|
+
});
|
|
443
|
+
const { x, y } = app.state.smooth;
|
|
444
|
+
setTransform(el, x, y);
|
|
445
|
+
}
|
|
446
|
+
},
|
|
447
|
+
options
|
|
448
|
+
);
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
#### Logic Plugin Example
|
|
452
|
+
|
|
453
|
+
```ts
|
|
454
|
+
import { definePlugin } from "@supermousejs/utils";
|
|
455
|
+
|
|
456
|
+
const Gravity = definePlugin({
|
|
457
|
+
name: "gravity",
|
|
458
|
+
priority: -10,
|
|
459
|
+
update(app, dt) {
|
|
460
|
+
app.state.target.y += 5;
|
|
461
|
+
}
|
|
462
|
+
});
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
**Configuration Interfaces**
|
|
466
|
+
|
|
467
|
+
- `BasePluginOptions` – Common options for all plugins (`name`, `isEnabled`).
|
|
468
|
+
- `LogicConfig` – Lifecycle hooks for logic plugins.
|
|
469
|
+
- `VisualConfig<E>` – Factory and lifecycle for visual plugins.
|
|
470
|
+
|
|
471
|
+
**Exit Animations with `beforeDisable`**
|
|
472
|
+
|
|
473
|
+
Both `LogicConfig` and `VisualConfig` accept a `beforeDisable` hook. This hook runs before the plugin is disabled and can return a `Promise`. The core will wait for the promise to resolve before hiding the element and calling `onDisable`.
|
|
474
|
+
|
|
475
|
+
```ts
|
|
476
|
+
beforeDisable(app, el) {
|
|
477
|
+
el.style.transition = "opacity 0.2s ease, transform 0.2s ease";
|
|
478
|
+
el.style.opacity = "0";
|
|
479
|
+
el.style.transform = "scale(0.5)";
|
|
480
|
+
return new Promise(resolve => setTimeout(resolve, 200));
|
|
481
|
+
}
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
For logic plugins, `beforeDisable` receives only `app`.
|
|
485
|
+
|
|
486
|
+
## SVG Utilities
|
|
487
|
+
|
|
488
|
+
A collection of helpers that remove `document.createElementNS` / `setAttribute` boilerplate.
|
|
489
|
+
|
|
490
|
+
### `svg.create(tag, attrs?)`
|
|
491
|
+
|
|
492
|
+
Creates any SVG element with attributes.
|
|
493
|
+
|
|
494
|
+
```ts
|
|
495
|
+
import { svg } from "@supermousejs/utils";
|
|
496
|
+
|
|
497
|
+
const svgEl = svg.create("svg", { width: 100, height: 100 });
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
### Individual named exports
|
|
501
|
+
|
|
502
|
+
All functions are also available as named exports for better tree‑shaking:
|
|
503
|
+
|
|
504
|
+
```ts
|
|
505
|
+
import { createSVGElement, circle, gaussianBlur } from "@supermousejs/utils";
|
|
506
|
+
|
|
507
|
+
const el = createSVGElement("svg", { width: 100 });
|
|
508
|
+
const c = circle({ cx: 50, cy: 50, r: 5 });
|
|
509
|
+
const blur = gaussianBlur(2);
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
**Available functions**
|
|
513
|
+
|
|
514
|
+
| Function | Description |
|
|
515
|
+
| ------------------------------------- | ------------------------- |
|
|
516
|
+
| `createSVGElement(tag, attrs?)` | Base SVG element factory |
|
|
517
|
+
| `setSVGAttrs(el, attrs)` | Set multiple attributes |
|
|
518
|
+
| `group(attrs?)` | Create `<g>` |
|
|
519
|
+
| `circle(attrs?)` | Create `<circle>` |
|
|
520
|
+
| `rect(attrs?)` | Create `<rect>` |
|
|
521
|
+
| `path(d?, attrs?)` | Create `<path>` |
|
|
522
|
+
| `text(attrs?, content?)` | Create `<text>` |
|
|
523
|
+
| `textPath(href, attrs?)` | Create `<textPath>` |
|
|
524
|
+
| `filter(id, attrs?, children?)` | Create `<filter>` |
|
|
525
|
+
| `gaussianBlur(stdDeviation?, attrs?)` | Create `<feGaussianBlur>` |
|
|
526
|
+
| `turbulence(baseFrequency?, attrs?)` | Create `<feTurbulence>` |
|
|
527
|
+
| `mergeNode(inAttr?)` | Create `<feMergeNode>` |
|
|
528
|
+
| `merge(nodes?)` | Create `<feMerge>` |
|
|
529
|
+
|
|
530
|
+
---
|
|
531
|
+
|
|
532
|
+
## CSS Constants
|
|
533
|
+
|
|
534
|
+
### `Layers`
|
|
535
|
+
|
|
536
|
+
Standard z‑index layers for the Supermouse ecosystem.
|
|
537
|
+
|
|
538
|
+
```ts
|
|
539
|
+
import { Layers } from "@supermousejs/utils";
|
|
540
|
+
|
|
541
|
+
el.style.zIndex = Layers.CURSOR;
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
| Key | Value | Description |
|
|
545
|
+
| ---------- | ------- | ------------------------------ |
|
|
546
|
+
| `OVERLAY` | `"400"` | Topmost layer (text, tooltips) |
|
|
547
|
+
| `CURSOR` | `"300"` | Primary cursor layer |
|
|
548
|
+
| `FOLLOWER` | `"200"` | Secondary followers |
|
|
549
|
+
| `TRACE` | `"100"` | Background effects |
|
|
550
|
+
|
|
551
|
+
### `Easings`
|
|
552
|
+
|
|
553
|
+
Common cubic‑bezier easing strings for CSS transitions.
|
|
554
|
+
|
|
555
|
+
```ts
|
|
556
|
+
import { Easings } from "@supermousejs/utils";
|
|
557
|
+
|
|
558
|
+
el.style.transition = `transform 0.4s ${Easings.EASE_OUT_EXPO}`;
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
| Key | Value |
|
|
562
|
+
| --------------- | ----------------------------------- |
|
|
563
|
+
| `EASE_OUT_EXPO` | `cubic-bezier(0.16, 1, 0.3, 1)` |
|
|
564
|
+
| `ELASTIC_OUT` | `cubic-bezier(0.34, 1.56, 0.64, 1)` |
|
|
565
|
+
| `SMOOTH` | `ease-out` |
|
|
566
|
+
|
|
567
|
+
---
|
|
568
|
+
|
|
569
|
+
## Doctor
|
|
570
|
+
|
|
571
|
+
### `doctor(app?)`
|
|
572
|
+
|
|
573
|
+
Diagnostic utility that audits a Supermouse instance or performs a lightweight DOM scan.
|
|
574
|
+
|
|
575
|
+
```ts
|
|
576
|
+
import { doctor } from "@supermousejs/utils";
|
|
577
|
+
|
|
578
|
+
// Full instance check
|
|
579
|
+
doctor(app);
|
|
580
|
+
|
|
581
|
+
// DOM-only scan
|
|
582
|
+
doctor();
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
**Instance checks:**
|
|
586
|
+
|
|
587
|
+
- Plugin priority ordering (logic vs visual)
|
|
588
|
+
- Missing `element` property on visual plugins
|
|
589
|
+
- Multiple instance conflicts
|
|
590
|
+
- Container positioning mutation
|
|
591
|
+
- Cursor mode validation and nested `"both"` warnings
|
|
592
|
+
|
|
593
|
+
**DOM‑only checks:**
|
|
594
|
+
|
|
595
|
+
- Supermouse initialization
|
|
596
|
+
- Inline cursor styles
|
|
597
|
+
- Body cursor leak (only when applicable)
|
|
598
|
+
|
|
599
|
+
---
|
|
600
|
+
|
|
601
|
+
## Tree‑Shaking
|
|
602
|
+
|
|
603
|
+
All functions are exported as named ES modules. When you import only what you need, bundlers (Vite, Webpack, Rollup) can drop unused code.
|
|
604
|
+
|
|
605
|
+
---
|
|
606
|
+
|
|
607
|
+
## Deprecated APIs
|
|
608
|
+
|
|
609
|
+
| Function | Replacement |
|
|
610
|
+
| ------------- | -------------------- |
|
|
611
|
+
| `setStyle` | `css` |
|
|
612
|
+
| `applyStyles` | `css` |
|
|
613
|
+
| `createDiv` | `createActor("div")` |
|
|
614
|
+
|
|
615
|
+
---
|
|
616
|
+
|
|
617
|
+
## License
|
|
618
|
+
|
|
619
|
+
MIT
|
package/dist/css.d.ts
CHANGED
|
@@ -9,4 +9,18 @@ export declare const Easings: {
|
|
|
9
9
|
/** Standard smooth movement */
|
|
10
10
|
readonly SMOOTH: "ease-out";
|
|
11
11
|
};
|
|
12
|
+
/**
|
|
13
|
+
* Standard Z-Index layers for the Supermouse ecosystem.
|
|
14
|
+
* Relative to the Supermouse Container.
|
|
15
|
+
*/
|
|
16
|
+
export declare const Layers: {
|
|
17
|
+
/** The top-most layer. For text, tooltips, and crucial UI. */
|
|
18
|
+
readonly OVERLAY: "400";
|
|
19
|
+
/** The main cursor layer. For the primary Dot/Pointer. */
|
|
20
|
+
readonly CURSOR: "300";
|
|
21
|
+
/** The secondary layer. For Rings, brackets, or followers. */
|
|
22
|
+
readonly FOLLOWER: "200";
|
|
23
|
+
/** The background layer. For trails, sparkles, and particles. */
|
|
24
|
+
readonly TRACE: "100";
|
|
25
|
+
};
|
|
12
26
|
//# sourceMappingURL=css.d.ts.map
|
package/dist/css.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"css.d.ts","sourceRoot":"","sources":["../src/css.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,OAAO;IAClB,6DAA6D;;IAE7D,0CAA0C;;IAE1C,+BAA+B;;CAEvB,CAAC"}
|
|
1
|
+
{"version":3,"file":"css.d.ts","sourceRoot":"","sources":["../src/css.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,OAAO;IAClB,6DAA6D;;IAE7D,0CAA0C;;IAE1C,+BAA+B;;CAEvB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,MAAM;IACjB,8DAA8D;;IAG9D,0DAA0D;;IAG1D,8DAA8D;;IAG9D,iEAAiE;;CAEzD,CAAC"}
|
package/dist/doctor.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
export interface DoctorIssue {
|
|
2
|
+
severity: "error" | "warn" | "info";
|
|
3
|
+
code: string;
|
|
4
|
+
message: string;
|
|
5
|
+
hint?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function doctor(app?: any): void;
|
|
5
8
|
//# sourceMappingURL=doctor.d.ts.map
|
package/dist/doctor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAoCD,wBAAgB,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,CAGtC"}
|