@supermousejs/utils 2.1.1 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/LICENSE.md +21 -21
- package/README.md +14 -15
- package/dist/css.d.ts +12 -0
- package/dist/css.d.ts.map +1 -0
- package/dist/doctor.d.ts +5 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/dom.d.ts +58 -0
- package/dist/dom.d.ts.map +1 -0
- package/dist/effects.d.ts +14 -0
- package/dist/effects.d.ts.map +1 -0
- package/dist/index.d.ts +10 -227
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +92 -92
- package/dist/index.umd.js +1 -7
- package/dist/layers.d.ts +15 -0
- package/dist/layers.d.ts.map +1 -0
- package/dist/math.d.ts +38 -0
- package/dist/math.d.ts.map +1 -0
- package/dist/options.d.ts +11 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/plugin.d.ts +34 -0
- package/dist/plugin.d.ts.map +1 -0
- package/package.json +3 -3
- package/src/css.ts +11 -11
- package/src/doctor.ts +47 -49
- package/src/dom.ts +145 -131
- package/src/effects.ts +34 -35
- package/src/index.ts +10 -10
- package/src/layers.ts +17 -17
- package/src/math.ts +60 -60
- package/src/options.ts +22 -22
- package/src/plugin.ts +147 -147
- package/tsconfig.json +9 -15
- package/tsconfig.tsbuildinfo +1 -0
- package/vite.config.ts +22 -22
package/src/dom.ts
CHANGED
|
@@ -1,131 +1,145 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
});
|
|
122
|
-
return el;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
*
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Injects global CSS styles into the document head safely.
|
|
3
|
+
* Checks for existing IDs to prevent duplication during SPA routing or HMR.
|
|
4
|
+
*
|
|
5
|
+
* @param id A unique identifier for this style block
|
|
6
|
+
* @param css A string of CSS rules to inject.
|
|
7
|
+
*/
|
|
8
|
+
export const injectStyles = (id: string, css: string) => {
|
|
9
|
+
if (typeof document === "undefined") return;
|
|
10
|
+
if (document.getElementById(id)) return;
|
|
11
|
+
|
|
12
|
+
const style = document.createElement("style");
|
|
13
|
+
style.id = id;
|
|
14
|
+
style.innerHTML = css;
|
|
15
|
+
document.head.appendChild(style);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// WeakMap to store previous styles for elements to prevent DOM thrashing
|
|
19
|
+
const styleCache = new WeakMap<HTMLElement, Record<string, string | number>>();
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Smart Style Setter (Batch).
|
|
23
|
+
* Only writes to the DOM if the value has actually changed.
|
|
24
|
+
* @param el The element to style
|
|
25
|
+
* @param styles An object of CSS properties and values
|
|
26
|
+
*/
|
|
27
|
+
export function applyStyles(el: HTMLElement, styles: Partial<CSSStyleDeclaration>) {
|
|
28
|
+
if (typeof document === "undefined" || !el) return;
|
|
29
|
+
|
|
30
|
+
let cache = styleCache.get(el);
|
|
31
|
+
if (!cache) {
|
|
32
|
+
cache = {};
|
|
33
|
+
styleCache.set(el, cache);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
for (const prop in styles) {
|
|
37
|
+
const value = (styles as any)[prop];
|
|
38
|
+
if (cache[prop] !== value) {
|
|
39
|
+
(el.style as any)[prop] = value;
|
|
40
|
+
cache[prop] = value;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Smart Style Setter (Single).
|
|
47
|
+
* Proxies to applyStyles for consistency.
|
|
48
|
+
* @param el The element to style
|
|
49
|
+
* @param property The CSS property to set
|
|
50
|
+
* @param value The value to set for the property
|
|
51
|
+
*/
|
|
52
|
+
export function setStyle(
|
|
53
|
+
el: HTMLElement,
|
|
54
|
+
property: keyof CSSStyleDeclaration,
|
|
55
|
+
value: string | number
|
|
56
|
+
) {
|
|
57
|
+
applyStyles(el, { [property]: value } as any);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Universal Transform Setter.
|
|
62
|
+
* Handles centering (-50%) automatically.
|
|
63
|
+
*
|
|
64
|
+
* @param el The element
|
|
65
|
+
* @param x X Position (px)
|
|
66
|
+
* @param y Y Position (px)
|
|
67
|
+
* @param rotation Rotation (deg) - Default 0
|
|
68
|
+
* @param scaleX Scale X - Default 1
|
|
69
|
+
* @param scaleY Scale Y - Default 1
|
|
70
|
+
* @param skewX Skew X (deg) - Default 0
|
|
71
|
+
* @param skewY Skew Y (deg) - Default 0
|
|
72
|
+
*/
|
|
73
|
+
export function setTransform(
|
|
74
|
+
el: HTMLElement,
|
|
75
|
+
x: number,
|
|
76
|
+
y: number,
|
|
77
|
+
rotation: number = 0,
|
|
78
|
+
scaleX: number = 1,
|
|
79
|
+
scaleY: number = 1,
|
|
80
|
+
skewX: number = 0,
|
|
81
|
+
skewY: number = 0
|
|
82
|
+
) {
|
|
83
|
+
const transform = `translate3d(${x}px, ${y}px, 0) translate(-50%, -50%) rotate(${rotation}deg) skew(${skewX}deg, ${skewY}deg) scale(${scaleX}, ${scaleY})`;
|
|
84
|
+
|
|
85
|
+
setStyle(el, "transform", transform);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Calculates the bounding rectangle of an element relative to a container.
|
|
90
|
+
*/
|
|
91
|
+
export function projectRect(element: HTMLElement, container: HTMLElement = document.body): DOMRect {
|
|
92
|
+
const rect = element.getBoundingClientRect();
|
|
93
|
+
|
|
94
|
+
if (container !== document.body) {
|
|
95
|
+
const containerRect = container.getBoundingClientRect();
|
|
96
|
+
const x = rect.left - containerRect.left;
|
|
97
|
+
const y = rect.top - containerRect.top;
|
|
98
|
+
|
|
99
|
+
return new DOMRect(x, y, rect.width, rect.height);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return rect;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Creates a standard Supermouse actor element with optimal performance settings.
|
|
107
|
+
* Includes absolute positioning, pointer-events: none, and will-change: transform.
|
|
108
|
+
*
|
|
109
|
+
* @param tagName The HTML tag to create (default: 'div')
|
|
110
|
+
*/
|
|
111
|
+
export function createActor(tagName: string = "div"): HTMLElement {
|
|
112
|
+
const el = document.createElement(tagName);
|
|
113
|
+
applyStyles(el, {
|
|
114
|
+
position: "absolute",
|
|
115
|
+
top: "0",
|
|
116
|
+
left: "0",
|
|
117
|
+
pointerEvents: "none",
|
|
118
|
+
boxSizing: "border-box",
|
|
119
|
+
display: "block",
|
|
120
|
+
willChange: "transform"
|
|
121
|
+
});
|
|
122
|
+
return el;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Creates a circular HTML div using the standard actor base.
|
|
127
|
+
*/
|
|
128
|
+
export function createCircle(size: number, color: string): HTMLDivElement {
|
|
129
|
+
const el = createActor("div") as HTMLDivElement;
|
|
130
|
+
applyStyles(el, {
|
|
131
|
+
width: `${size}px`,
|
|
132
|
+
height: `${size}px`,
|
|
133
|
+
borderRadius: "50%",
|
|
134
|
+
backgroundColor: color
|
|
135
|
+
});
|
|
136
|
+
return el;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Legacy alias for createActor.
|
|
141
|
+
* @deprecated Use createActor() instead.
|
|
142
|
+
*/
|
|
143
|
+
export function createDiv(): HTMLDivElement {
|
|
144
|
+
return createActor("div") as HTMLDivElement;
|
|
145
|
+
}
|
package/src/effects.ts
CHANGED
|
@@ -1,35 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* @param
|
|
8
|
-
* @param
|
|
9
|
-
* @param
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
1
|
+
import { dist, angle, clamp } from "./math";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Calculates Rotation and Scale based on velocity to create a "Squash and Stretch" effect.
|
|
5
|
+
*
|
|
6
|
+
* @param vx Velocity X
|
|
7
|
+
* @param vy Velocity Y
|
|
8
|
+
* @param intensity Stretch factor (default: 0.004)
|
|
9
|
+
* @param maxStretch Max stretch percentage (default: 0.5 = 150% length)
|
|
10
|
+
*/
|
|
11
|
+
export function getVelocityDistortion(vx: number, vy: number, intensity = 0.004, maxStretch = 0.5) {
|
|
12
|
+
const speed = dist(vx, vy);
|
|
13
|
+
|
|
14
|
+
// Deadzone: If moving too slow, don't rotate (prevents jittering at rest)
|
|
15
|
+
if (speed < 0.1) {
|
|
16
|
+
return { rotation: 0, scaleX: 1, scaleY: 1 };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// 1. Point towards movement
|
|
20
|
+
const rotation = angle(vx, vy);
|
|
21
|
+
|
|
22
|
+
// 2. Stretch based on speed
|
|
23
|
+
const stretch = clamp(speed * intensity, 0, maxStretch);
|
|
24
|
+
|
|
25
|
+
// 3. Scale X grows, Scale Y shrinks (to preserve volume-ish)
|
|
26
|
+
const scaleX = 1 + stretch;
|
|
27
|
+
const scaleY = 1 - stretch * 0.5; // Squash factor
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
rotation,
|
|
31
|
+
scaleX,
|
|
32
|
+
scaleY
|
|
33
|
+
};
|
|
34
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import * as math from
|
|
2
|
-
import * as dom from
|
|
3
|
-
import * as effects from
|
|
4
|
-
|
|
5
|
-
export { math, dom, effects };
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
8
|
-
export * from
|
|
9
|
-
export * from
|
|
10
|
-
export * from
|
|
1
|
+
import * as math from "./math";
|
|
2
|
+
import * as dom from "./dom";
|
|
3
|
+
import * as effects from "./effects";
|
|
4
|
+
|
|
5
|
+
export { math, dom, effects };
|
|
6
|
+
export * from "./layers";
|
|
7
|
+
export * from "./css";
|
|
8
|
+
export * from "./plugin";
|
|
9
|
+
export * from "./options";
|
|
10
|
+
export * from "./doctor";
|
package/src/layers.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Standard Z-Index layers for the Supermouse ecosystem.
|
|
3
|
-
* Relative to the Supermouse Container.
|
|
4
|
-
*/
|
|
5
|
-
export const Layers = {
|
|
6
|
-
/** The top-most layer. For text, tooltips, and crucial UI. */
|
|
7
|
-
OVERLAY:
|
|
8
|
-
|
|
9
|
-
/** The main cursor layer. For the primary Dot/Pointer. */
|
|
10
|
-
CURSOR:
|
|
11
|
-
|
|
12
|
-
/** The secondary layer. For Rings, brackets, or followers. */
|
|
13
|
-
FOLLOWER:
|
|
14
|
-
|
|
15
|
-
/** The background layer. For trails, sparkles, and particles. */
|
|
16
|
-
TRACE:
|
|
17
|
-
} as const;
|
|
1
|
+
/**
|
|
2
|
+
* Standard Z-Index layers for the Supermouse ecosystem.
|
|
3
|
+
* Relative to the Supermouse Container.
|
|
4
|
+
*/
|
|
5
|
+
export const Layers = {
|
|
6
|
+
/** The top-most layer. For text, tooltips, and crucial UI. */
|
|
7
|
+
OVERLAY: "400",
|
|
8
|
+
|
|
9
|
+
/** The main cursor layer. For the primary Dot/Pointer. */
|
|
10
|
+
CURSOR: "300",
|
|
11
|
+
|
|
12
|
+
/** The secondary layer. For Rings, brackets, or followers. */
|
|
13
|
+
FOLLOWER: "200",
|
|
14
|
+
|
|
15
|
+
/** The background layer. For trails, sparkles, and particles. */
|
|
16
|
+
TRACE: "100"
|
|
17
|
+
} as const;
|
package/src/math.ts
CHANGED
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Linear Interpolation between two values.
|
|
3
|
-
*/
|
|
4
|
-
export function lerp(start: number, end: number, factor: number): number {
|
|
5
|
-
return start + (end - start) * factor;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Frame-rate independent damping (Time-based Lerp).
|
|
10
|
-
* Ensures smooth animation consistent across 60hz, 120hz, etc.
|
|
11
|
-
*
|
|
12
|
-
* @param a Current value
|
|
13
|
-
* @param b Target value
|
|
14
|
-
* @param lambda Smoothing factor (approx 1-20). Higher is faster.
|
|
15
|
-
* @param dt Delta time in seconds (not milliseconds)
|
|
16
|
-
*/
|
|
17
|
-
export function damp(a: number, b: number, lambda: number, dt: number): number {
|
|
18
|
-
return lerp(a, b, 1 - Math.exp(-lambda * dt));
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Linear Interpolation between two angles in degrees, taking the shortest path.
|
|
23
|
-
* Handles wrap-around at 360 degrees.
|
|
24
|
-
*/
|
|
25
|
-
export function lerpAngle(start: number, end: number, factor: number): number {
|
|
26
|
-
const diff = ((((end - start) % 360) + 540) % 360) - 180;
|
|
27
|
-
return start + diff * factor;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Returns a random number between min and max.
|
|
32
|
-
* Usage: math.random(10, 20) -> 14.5
|
|
33
|
-
*/
|
|
34
|
-
export function random(min: number, max: number): number {
|
|
35
|
-
return Math.random() * (max - min) + min;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Constrains a value between a minimum and maximum.
|
|
40
|
-
*/
|
|
41
|
-
export function clamp(value: number, min: number, max: number): number {
|
|
42
|
-
return Math.min(Math.max(value, min), max);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Calculates the distance (hypotenuse) between two points (or magnitude of a vector).
|
|
47
|
-
* If x2/y2 are omitted, calculates magnitude of vector x1/y1.
|
|
48
|
-
*/
|
|
49
|
-
export function dist(x1: number, y1: number, x2: number = 0, y2: number = 0): number {
|
|
50
|
-
const dx = x1 - x2;
|
|
51
|
-
const dy = y1 - y2;
|
|
52
|
-
return Math.sqrt(dx * dx + dy * dy);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Calculates the angle in degrees between two points (or vector direction).
|
|
57
|
-
*/
|
|
58
|
-
export function angle(x: number, y: number): number {
|
|
59
|
-
return Math.atan2(y, x) * (180 / Math.PI);
|
|
60
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Linear Interpolation between two values.
|
|
3
|
+
*/
|
|
4
|
+
export function lerp(start: number, end: number, factor: number): number {
|
|
5
|
+
return start + (end - start) * factor;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Frame-rate independent damping (Time-based Lerp).
|
|
10
|
+
* Ensures smooth animation consistent across 60hz, 120hz, etc.
|
|
11
|
+
*
|
|
12
|
+
* @param a Current value
|
|
13
|
+
* @param b Target value
|
|
14
|
+
* @param lambda Smoothing factor (approx 1-20). Higher is faster.
|
|
15
|
+
* @param dt Delta time in seconds (not milliseconds)
|
|
16
|
+
*/
|
|
17
|
+
export function damp(a: number, b: number, lambda: number, dt: number): number {
|
|
18
|
+
return lerp(a, b, 1 - Math.exp(-lambda * dt));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Linear Interpolation between two angles in degrees, taking the shortest path.
|
|
23
|
+
* Handles wrap-around at 360 degrees.
|
|
24
|
+
*/
|
|
25
|
+
export function lerpAngle(start: number, end: number, factor: number): number {
|
|
26
|
+
const diff = ((((end - start) % 360) + 540) % 360) - 180;
|
|
27
|
+
return start + diff * factor;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Returns a random number between min and max.
|
|
32
|
+
* Usage: math.random(10, 20) -> 14.5
|
|
33
|
+
*/
|
|
34
|
+
export function random(min: number, max: number): number {
|
|
35
|
+
return Math.random() * (max - min) + min;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Constrains a value between a minimum and maximum.
|
|
40
|
+
*/
|
|
41
|
+
export function clamp(value: number, min: number, max: number): number {
|
|
42
|
+
return Math.min(Math.max(value, min), max);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Calculates the distance (hypotenuse) between two points (or magnitude of a vector).
|
|
47
|
+
* If x2/y2 are omitted, calculates magnitude of vector x1/y1.
|
|
48
|
+
*/
|
|
49
|
+
export function dist(x1: number, y1: number, x2: number = 0, y2: number = 0): number {
|
|
50
|
+
const dx = x1 - x2;
|
|
51
|
+
const dy = y1 - y2;
|
|
52
|
+
return Math.sqrt(dx * dx + dy * dy);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Calculates the angle in degrees between two points (or vector direction).
|
|
57
|
+
*/
|
|
58
|
+
export function angle(x: number, y: number): number {
|
|
59
|
+
return Math.atan2(y, x) * (180 / Math.PI);
|
|
60
|
+
}
|
package/src/options.ts
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import type { MouseState, ValueOrGetter } from
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Returns a function that always resolves the option value.
|
|
5
|
-
* Eliminates 'typeof' checks inside the render loop by normalizing
|
|
6
|
-
* static values into getter functions during initialization.
|
|
7
|
-
*
|
|
8
|
-
* @param option The option passed by the user
|
|
9
|
-
* @param defaultValue Fallback value
|
|
10
|
-
*/
|
|
11
|
-
export function normalize<T>(
|
|
12
|
-
option: ValueOrGetter<T> | undefined,
|
|
13
|
-
defaultValue: T
|
|
14
|
-
): (state: MouseState) => T {
|
|
15
|
-
if (option === undefined) {
|
|
16
|
-
return () => defaultValue;
|
|
17
|
-
}
|
|
18
|
-
if (typeof option ===
|
|
19
|
-
return option as (state: MouseState) => T;
|
|
20
|
-
}
|
|
21
|
-
return () => option;
|
|
22
|
-
}
|
|
1
|
+
import type { MouseState, ValueOrGetter } from "@supermousejs/core";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns a function that always resolves the option value.
|
|
5
|
+
* Eliminates 'typeof' checks inside the render loop by normalizing
|
|
6
|
+
* static values into getter functions during initialization.
|
|
7
|
+
*
|
|
8
|
+
* @param option The option passed by the user
|
|
9
|
+
* @param defaultValue Fallback value
|
|
10
|
+
*/
|
|
11
|
+
export function normalize<T>(
|
|
12
|
+
option: ValueOrGetter<T> | undefined,
|
|
13
|
+
defaultValue: T
|
|
14
|
+
): (state: MouseState) => T {
|
|
15
|
+
if (option === undefined) {
|
|
16
|
+
return () => defaultValue;
|
|
17
|
+
}
|
|
18
|
+
if (typeof option === "function") {
|
|
19
|
+
return option as (state: MouseState) => T;
|
|
20
|
+
}
|
|
21
|
+
return () => option;
|
|
22
|
+
}
|