@vived/core 1.0.1 → 1.2.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/dist/cjs/Entities/RangedNumber.js +36 -0
- package/dist/cjs/Entities/RangedNumber.js.map +1 -0
- package/dist/cjs/Entities/RangedNumber.test.js +96 -0
- package/dist/cjs/Entities/RangedNumber.test.js.map +1 -0
- package/dist/cjs/Entities/index.js +3 -2
- package/dist/cjs/Entities/index.js.map +1 -1
- package/dist/cjs/Utilities/LengthConverters.js +21 -0
- package/dist/cjs/Utilities/LengthConverters.js.map +1 -0
- package/dist/cjs/Utilities/LengthConverters.test.js +24 -0
- package/dist/cjs/Utilities/LengthConverters.test.js.map +1 -0
- package/dist/cjs/Utilities/LerpNumber.js +85 -0
- package/dist/cjs/Utilities/LerpNumber.js.map +1 -0
- package/dist/cjs/Utilities/LerpNumber.test.js +90 -0
- package/dist/cjs/Utilities/LerpNumber.test.js.map +1 -0
- package/dist/cjs/Utilities/degreesToRadians.js +7 -0
- package/dist/cjs/Utilities/degreesToRadians.js.map +1 -0
- package/dist/cjs/Utilities/degreesToRadians.test.js +9 -0
- package/dist/cjs/Utilities/degreesToRadians.test.js.map +1 -0
- package/dist/cjs/Utilities/easeFunctions.js +208 -0
- package/dist/cjs/Utilities/easeFunctions.js.map +1 -0
- package/dist/cjs/Utilities/easeFunctions.test.js +209 -0
- package/dist/cjs/Utilities/easeFunctions.test.js.map +1 -0
- package/dist/cjs/Utilities/generateUniqueID.js +8 -0
- package/dist/cjs/Utilities/generateUniqueID.js.map +1 -0
- package/dist/cjs/Utilities/index.js +22 -0
- package/dist/cjs/Utilities/index.js.map +1 -0
- package/dist/cjs/Utilities/interpolateNumber.js +18 -0
- package/dist/cjs/Utilities/interpolateNumber.js.map +1 -0
- package/dist/cjs/Utilities/interpolateNumber.test.js +26 -0
- package/dist/cjs/Utilities/interpolateNumber.test.js.map +1 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/Entities/RangedNumber.js +32 -0
- package/dist/esm/Entities/RangedNumber.js.map +1 -0
- package/dist/esm/Entities/RangedNumber.test.js +94 -0
- package/dist/esm/Entities/RangedNumber.test.js.map +1 -0
- package/dist/esm/Entities/index.js +3 -2
- package/dist/esm/Entities/index.js.map +1 -1
- package/dist/esm/Utilities/LengthConverters.js +15 -0
- package/dist/esm/Utilities/LengthConverters.js.map +1 -0
- package/dist/esm/Utilities/LengthConverters.test.js +22 -0
- package/dist/esm/Utilities/LengthConverters.test.js.map +1 -0
- package/dist/esm/Utilities/LerpNumber.js +81 -0
- package/dist/esm/Utilities/LerpNumber.js.map +1 -0
- package/dist/esm/Utilities/LerpNumber.test.js +88 -0
- package/dist/esm/Utilities/LerpNumber.test.js.map +1 -0
- package/dist/esm/Utilities/degreesToRadians.js +4 -0
- package/dist/esm/Utilities/degreesToRadians.js.map +1 -0
- package/dist/esm/Utilities/degreesToRadians.test.js +7 -0
- package/dist/esm/Utilities/degreesToRadians.test.js.map +1 -0
- package/dist/esm/Utilities/easeFunctions.js +183 -0
- package/dist/esm/Utilities/easeFunctions.js.map +1 -0
- package/dist/esm/Utilities/easeFunctions.test.js +207 -0
- package/dist/esm/Utilities/easeFunctions.test.js.map +1 -0
- package/dist/esm/Utilities/generateUniqueID.js +5 -0
- package/dist/esm/Utilities/generateUniqueID.js.map +1 -0
- package/dist/esm/Utilities/index.js +6 -0
- package/dist/esm/Utilities/index.js.map +1 -0
- package/dist/esm/Utilities/interpolateNumber.js +15 -0
- package/dist/esm/Utilities/interpolateNumber.js.map +1 -0
- package/dist/esm/Utilities/interpolateNumber.test.js +24 -0
- package/dist/esm/Utilities/interpolateNumber.test.js.map +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/Entities/RangedNumber.d.ts +17 -0
- package/dist/types/Entities/RangedNumber.d.ts.map +1 -0
- package/dist/types/Entities/RangedNumber.test.d.ts +2 -0
- package/dist/types/Entities/RangedNumber.test.d.ts.map +1 -0
- package/dist/types/Entities/index.d.ts +3 -2
- package/dist/types/Entities/index.d.ts.map +1 -1
- package/dist/types/Utilities/LengthConverters.d.ts +5 -0
- package/dist/types/Utilities/LengthConverters.d.ts.map +1 -0
- package/dist/types/Utilities/LengthConverters.test.d.ts +2 -0
- package/dist/types/Utilities/LengthConverters.test.d.ts.map +1 -0
- package/dist/types/Utilities/LerpNumber.d.ts +57 -0
- package/dist/types/Utilities/LerpNumber.d.ts.map +1 -0
- package/dist/types/Utilities/LerpNumber.test.d.ts +2 -0
- package/dist/types/Utilities/LerpNumber.test.d.ts.map +1 -0
- package/dist/types/Utilities/degreesToRadians.d.ts +2 -0
- package/dist/types/Utilities/degreesToRadians.d.ts.map +1 -0
- package/dist/types/Utilities/degreesToRadians.test.d.ts +2 -0
- package/dist/types/Utilities/degreesToRadians.test.d.ts.map +1 -0
- package/dist/types/Utilities/easeFunctions.d.ts +24 -0
- package/dist/types/Utilities/easeFunctions.d.ts.map +1 -0
- package/dist/types/Utilities/easeFunctions.test.d.ts +2 -0
- package/dist/types/Utilities/easeFunctions.test.d.ts.map +1 -0
- package/dist/types/Utilities/generateUniqueID.d.ts +2 -0
- package/dist/types/Utilities/generateUniqueID.d.ts.map +1 -0
- package/dist/types/Utilities/index.d.ts +6 -0
- package/dist/types/Utilities/index.d.ts.map +1 -0
- package/dist/types/Utilities/interpolateNumber.d.ts +2 -0
- package/dist/types/Utilities/interpolateNumber.d.ts.map +1 -0
- package/dist/types/Utilities/interpolateNumber.test.d.ts +2 -0
- package/dist/types/Utilities/interpolateNumber.test.d.ts.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +6 -2
- package/src/Entities/RangedNumber.test.ts +118 -0
- package/src/Entities/RangedNumber.ts +45 -0
- package/src/Entities/index.ts +3 -2
- package/src/Utilities/LengthConverters.test.ts +30 -0
- package/src/Utilities/LengthConverters.ts +18 -0
- package/src/Utilities/LerpNumber.test.ts +109 -0
- package/src/Utilities/LerpNumber.ts +109 -0
- package/src/Utilities/degreesToRadians.test.ts +8 -0
- package/src/Utilities/degreesToRadians.ts +3 -0
- package/src/Utilities/easeFunctions.test.ts +251 -0
- package/src/Utilities/easeFunctions.ts +180 -0
- package/src/Utilities/generateUniqueID.ts +5 -0
- package/src/Utilities/index.ts +6 -0
- package/src/Utilities/interpolateNumber.test.ts +28 -0
- package/src/Utilities/interpolateNumber.ts +21 -0
- package/src/index.ts +1 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { EaseFn } from "../Types";
|
|
2
|
+
import { quintInOut } from "./easeFunctions";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Configuration object for performing a linear interpolation (lerp) operation.
|
|
6
|
+
* @interface LerpNumberDTO
|
|
7
|
+
*/
|
|
8
|
+
export interface LerpNumberDTO {
|
|
9
|
+
/** Starting value of the lerp */
|
|
10
|
+
start: number;
|
|
11
|
+
/** Target/ending value of the lerp */
|
|
12
|
+
end: number;
|
|
13
|
+
/** Callback function that receives the interpolated value on each update */
|
|
14
|
+
update: (value: number) => void;
|
|
15
|
+
/** Duration of the lerp in milliseconds. Defaults to LerpNumber.defaultDurationMS */
|
|
16
|
+
durationMS?: number;
|
|
17
|
+
/** Easing function to modify the interpolation curve. Defaults to LerpNumber.defaultEase */
|
|
18
|
+
ease?: EaseFn;
|
|
19
|
+
/** Optional callback function called when lerp completes naturally */
|
|
20
|
+
onComplete?: () => void;
|
|
21
|
+
/** Optional callback function called when lerp is cancelled */
|
|
22
|
+
onCancel?: () => void;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Utility class for smoothly interpolating between two numbers over time.
|
|
27
|
+
* Uses requestAnimationFrame for smooth animation and supports custom easing functions.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* const lerper = new LerpNumber();
|
|
31
|
+
* // Animate from 0 to 100 over 2 seconds
|
|
32
|
+
* await lerper.lerp({
|
|
33
|
+
* start: 0,
|
|
34
|
+
* end: 100,
|
|
35
|
+
* durationMS: 2000,
|
|
36
|
+
* update: (value) => console.log(value)
|
|
37
|
+
* });
|
|
38
|
+
*/
|
|
39
|
+
export class LerpNumber {
|
|
40
|
+
public defaultDurationMS = 1000;
|
|
41
|
+
public defaultEase: EaseFn = quintInOut;
|
|
42
|
+
|
|
43
|
+
public get isLerping() {
|
|
44
|
+
return this._isLerping;
|
|
45
|
+
}
|
|
46
|
+
private _isLerping = false;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Cancels the current lerp operation if one is in progress.
|
|
50
|
+
* Triggers the onCancel callback if provided in the original lerp configuration.
|
|
51
|
+
*/
|
|
52
|
+
public cancel() {
|
|
53
|
+
if (!this._isLerping) return;
|
|
54
|
+
|
|
55
|
+
this._cancelLerp = true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
private _cancelLerp = false;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Initiates a lerp (linear interpolation) operation.
|
|
62
|
+
* If a lerp is already in progress, it will be cancelled before starting the new one.
|
|
63
|
+
*
|
|
64
|
+
* @param data - Configuration object for the lerp operation
|
|
65
|
+
* @returns Promise that resolves when the lerp completes or is cancelled
|
|
66
|
+
* @throws Never throws, but may reject if the update function throws
|
|
67
|
+
*/
|
|
68
|
+
lerp = (data: LerpNumberDTO): Promise<void> => {
|
|
69
|
+
if (this._isLerping) {
|
|
70
|
+
this.cancel();
|
|
71
|
+
}
|
|
72
|
+
const { start, end, durationMS, ease, onComplete, update, onCancel } = data;
|
|
73
|
+
|
|
74
|
+
const durationToUse = durationMS ?? this.defaultDurationMS;
|
|
75
|
+
const easeToUse = ease ?? this.defaultEase;
|
|
76
|
+
|
|
77
|
+
return new Promise((resolve) => {
|
|
78
|
+
const startTime = performance.now();
|
|
79
|
+
this._isLerping = true;
|
|
80
|
+
|
|
81
|
+
update(start);
|
|
82
|
+
|
|
83
|
+
const interval = setInterval(() => {
|
|
84
|
+
if (this._cancelLerp) {
|
|
85
|
+
clearInterval(interval);
|
|
86
|
+
this._isLerping = false;
|
|
87
|
+
this._cancelLerp = false;
|
|
88
|
+
if (onCancel) onCancel();
|
|
89
|
+
return resolve();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const currentTime = performance.now();
|
|
93
|
+
const elapsedTime = currentTime - startTime;
|
|
94
|
+
const progress = Math.min(elapsedTime / durationToUse, 1);
|
|
95
|
+
const easedProgress = easeToUse(progress);
|
|
96
|
+
const value = start + (end - start) * easedProgress;
|
|
97
|
+
update(value);
|
|
98
|
+
|
|
99
|
+
if (progress >= 1) {
|
|
100
|
+
clearInterval(interval);
|
|
101
|
+
this._isLerping = false;
|
|
102
|
+
update(end);
|
|
103
|
+
if (onComplete) onComplete();
|
|
104
|
+
resolve();
|
|
105
|
+
}
|
|
106
|
+
}, 10);
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import {
|
|
2
|
+
easeLinear,
|
|
3
|
+
quadIn,
|
|
4
|
+
quadInOut,
|
|
5
|
+
quadOut,
|
|
6
|
+
cubicIn,
|
|
7
|
+
cubicInOut,
|
|
8
|
+
cubicOut,
|
|
9
|
+
expoIn,
|
|
10
|
+
expoInOut,
|
|
11
|
+
expoOut,
|
|
12
|
+
sinIn,
|
|
13
|
+
sinInOut,
|
|
14
|
+
sinOut,
|
|
15
|
+
quartIn,
|
|
16
|
+
quartInOut,
|
|
17
|
+
quartOut,
|
|
18
|
+
quintIn,
|
|
19
|
+
quintInOut,
|
|
20
|
+
quintOut,
|
|
21
|
+
circIn,
|
|
22
|
+
circInOut,
|
|
23
|
+
circOut,
|
|
24
|
+
} from "./easeFunctions";
|
|
25
|
+
|
|
26
|
+
it("Returns the proper values for ease linear", () => {
|
|
27
|
+
expect(easeLinear(-1)).toEqual(0);
|
|
28
|
+
expect(easeLinear(0)).toEqual(0);
|
|
29
|
+
expect(easeLinear(0.25)).toEqual(0.25);
|
|
30
|
+
expect(easeLinear(0.5)).toEqual(0.5);
|
|
31
|
+
expect(easeLinear(0.75)).toEqual(0.75);
|
|
32
|
+
expect(easeLinear(1)).toEqual(1);
|
|
33
|
+
expect(easeLinear(2)).toEqual(1);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Quad
|
|
37
|
+
it("Returns the proper val for quad in", () => {
|
|
38
|
+
expect(quadIn(-1)).toEqual(0);
|
|
39
|
+
expect(quadIn(0)).toEqual(0);
|
|
40
|
+
expect(quadIn(0.25)).toEqual(0.0625);
|
|
41
|
+
expect(quadIn(0.5)).toEqual(0.25);
|
|
42
|
+
expect(quadIn(0.75)).toEqual(0.5625);
|
|
43
|
+
expect(quadIn(1)).toEqual(1);
|
|
44
|
+
expect(quadIn(2)).toEqual(1);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("Returns the proper val for quad out", () => {
|
|
48
|
+
expect(quadOut(-1)).toEqual(0);
|
|
49
|
+
expect(quadOut(0)).toEqual(0);
|
|
50
|
+
expect(quadOut(0.25)).toEqual(0.4375);
|
|
51
|
+
expect(quadOut(0.5)).toEqual(0.75);
|
|
52
|
+
expect(quadOut(0.75)).toEqual(0.9375);
|
|
53
|
+
expect(quadOut(1)).toEqual(1);
|
|
54
|
+
expect(quadOut(2)).toEqual(1);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("Returns the proper val for quad in out", () => {
|
|
58
|
+
expect(quadInOut(-1)).toEqual(0);
|
|
59
|
+
expect(quadInOut(0)).toEqual(0);
|
|
60
|
+
expect(quadInOut(0.25)).toEqual(0.125);
|
|
61
|
+
expect(quadInOut(0.5)).toEqual(0.5);
|
|
62
|
+
expect(quadInOut(0.75)).toEqual(0.875);
|
|
63
|
+
expect(quadInOut(1)).toEqual(1);
|
|
64
|
+
expect(quadInOut(2)).toEqual(1);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Cubic
|
|
68
|
+
it("Returns the proper val for cubic in", () => {
|
|
69
|
+
expect(cubicIn(-1)).toEqual(0);
|
|
70
|
+
expect(cubicIn(0)).toEqual(0);
|
|
71
|
+
expect(cubicIn(0.25)).toEqual(0.015625);
|
|
72
|
+
expect(cubicIn(0.5)).toEqual(0.125);
|
|
73
|
+
expect(cubicIn(0.75)).toEqual(0.421875);
|
|
74
|
+
expect(cubicIn(1)).toEqual(1);
|
|
75
|
+
expect(cubicIn(2)).toEqual(1);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("Returns the proper val for cubic out", () => {
|
|
79
|
+
expect(cubicOut(-1)).toEqual(0);
|
|
80
|
+
expect(cubicOut(0)).toEqual(0);
|
|
81
|
+
expect(cubicOut(0.25)).toEqual(0.578125);
|
|
82
|
+
expect(cubicOut(0.5)).toEqual(0.875);
|
|
83
|
+
expect(cubicOut(0.75)).toEqual(0.984375);
|
|
84
|
+
expect(cubicOut(1)).toEqual(1);
|
|
85
|
+
expect(cubicOut(2)).toEqual(1);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("Returns the proper val for cubic in out", () => {
|
|
89
|
+
expect(cubicInOut(-1)).toEqual(0);
|
|
90
|
+
expect(cubicInOut(0)).toEqual(0);
|
|
91
|
+
expect(cubicInOut(0.25)).toEqual(0.0625);
|
|
92
|
+
expect(cubicInOut(0.5)).toEqual(0.5);
|
|
93
|
+
expect(cubicInOut(0.75)).toEqual(0.9375);
|
|
94
|
+
expect(cubicInOut(1)).toEqual(1);
|
|
95
|
+
expect(cubicInOut(2)).toEqual(1);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Expo
|
|
99
|
+
it("Returns the proper val for Expo in", () => {
|
|
100
|
+
expect(expoIn(-1)).toEqual(0);
|
|
101
|
+
expect(expoIn(0)).toEqual(0);
|
|
102
|
+
expect(expoIn(0.25)).toEqual(0.005524271728019902);
|
|
103
|
+
expect(expoIn(0.5)).toEqual(0.03125);
|
|
104
|
+
expect(expoIn(0.75)).toEqual(0.17677669529663687);
|
|
105
|
+
expect(expoIn(1)).toEqual(1);
|
|
106
|
+
expect(expoIn(2)).toEqual(1);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("Returns the proper val for Expo out", () => {
|
|
110
|
+
expect(expoOut(-1)).toEqual(0);
|
|
111
|
+
expect(expoOut(0)).toEqual(0);
|
|
112
|
+
expect(expoOut(0.25)).toEqual(0.8232233047033631);
|
|
113
|
+
expect(expoOut(0.5)).toEqual(0.96875);
|
|
114
|
+
expect(expoOut(0.75)).toEqual(0.99447572827198);
|
|
115
|
+
expect(expoOut(1)).toEqual(1);
|
|
116
|
+
expect(expoOut(2)).toEqual(1);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it("Returns the proper val for Expo in out", () => {
|
|
120
|
+
expect(expoInOut(-1)).toEqual(0);
|
|
121
|
+
expect(expoInOut(0)).toEqual(0);
|
|
122
|
+
expect(expoInOut(0.25)).toEqual(0.015625);
|
|
123
|
+
expect(expoInOut(0.5)).toEqual(0.5);
|
|
124
|
+
expect(expoInOut(0.75)).toEqual(0.984375);
|
|
125
|
+
expect(expoInOut(1)).toEqual(1);
|
|
126
|
+
expect(expoInOut(2)).toEqual(1);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// Sin
|
|
130
|
+
it("Returns the proper val for Sin in", () => {
|
|
131
|
+
expect(sinIn(-1)).toEqual(0);
|
|
132
|
+
expect(sinIn(0)).toEqual(0);
|
|
133
|
+
expect(sinIn(0.25)).toEqual(0.07612046748871326);
|
|
134
|
+
expect(sinIn(0.5)).toEqual(0.2928932188134524);
|
|
135
|
+
expect(sinIn(0.75)).toEqual(0.6173165676349102);
|
|
136
|
+
expect(sinIn(1)).toEqual(1);
|
|
137
|
+
expect(sinIn(2)).toEqual(1);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it("Returns the proper val for Sin out", () => {
|
|
141
|
+
expect(sinOut(-1)).toEqual(0);
|
|
142
|
+
expect(sinOut(0)).toEqual(0);
|
|
143
|
+
expect(sinOut(0.25)).toEqual(0.3826834323650898);
|
|
144
|
+
expect(sinOut(0.5)).toEqual(0.7071067811865475);
|
|
145
|
+
expect(sinOut(0.75)).toEqual(0.9238795325112867);
|
|
146
|
+
expect(sinOut(1)).toEqual(1);
|
|
147
|
+
expect(sinOut(2)).toEqual(1);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it("Returns the proper val for Sin in out", () => {
|
|
151
|
+
expect(sinInOut(-1)).toEqual(0);
|
|
152
|
+
expect(sinInOut(0)).toEqual(0);
|
|
153
|
+
expect(sinInOut(0.25)).toEqual(0.1464466094067262);
|
|
154
|
+
expect(sinInOut(0.5)).toBeCloseTo(0.5);
|
|
155
|
+
expect(sinInOut(0.75)).toEqual(0.8535533905932737);
|
|
156
|
+
expect(sinInOut(1)).toEqual(1);
|
|
157
|
+
expect(sinInOut(2)).toEqual(1);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// Quart
|
|
161
|
+
it("Returns the proper val for Quart in", () => {
|
|
162
|
+
expect(quartIn(-1)).toEqual(0);
|
|
163
|
+
expect(quartIn(0)).toEqual(0);
|
|
164
|
+
expect(quartIn(0.25)).toEqual(0.00390625);
|
|
165
|
+
expect(quartIn(0.5)).toEqual(0.0625);
|
|
166
|
+
expect(quartIn(0.75)).toEqual(0.31640625);
|
|
167
|
+
expect(quartIn(1)).toEqual(1);
|
|
168
|
+
expect(quartIn(2)).toEqual(1);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it("Returns the proper val for Quart out", () => {
|
|
172
|
+
expect(quartOut(-1)).toEqual(0);
|
|
173
|
+
expect(quartOut(0)).toEqual(0);
|
|
174
|
+
expect(quartOut(0.25)).toEqual(0.68359375);
|
|
175
|
+
expect(quartOut(0.5)).toEqual(0.9375);
|
|
176
|
+
expect(quartOut(0.75)).toEqual(0.99609375);
|
|
177
|
+
expect(quartOut(1)).toEqual(1);
|
|
178
|
+
expect(quartOut(2)).toEqual(1);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it("Returns the proper val for Quart in out", () => {
|
|
182
|
+
expect(quartInOut(-1)).toEqual(0);
|
|
183
|
+
expect(quartInOut(0)).toEqual(0);
|
|
184
|
+
expect(quartInOut(0.25)).toEqual(0.03125);
|
|
185
|
+
expect(quartInOut(0.5)).toBeCloseTo(0.5);
|
|
186
|
+
expect(quartInOut(0.75)).toEqual(0.96875);
|
|
187
|
+
expect(quartInOut(1)).toEqual(1);
|
|
188
|
+
expect(quartInOut(2)).toEqual(1);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
// Quint
|
|
192
|
+
it("Returns the proper val for Quint in", () => {
|
|
193
|
+
expect(quintIn(-1)).toEqual(0);
|
|
194
|
+
expect(quintIn(0)).toEqual(0);
|
|
195
|
+
expect(quintIn(0.25)).toEqual(0.0009765625);
|
|
196
|
+
expect(quintIn(0.5)).toEqual(0.03125);
|
|
197
|
+
expect(quintIn(0.75)).toEqual(0.2373046875);
|
|
198
|
+
expect(quintIn(1)).toEqual(1);
|
|
199
|
+
expect(quintIn(2)).toEqual(1);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it("Returns the proper val for Quint out", () => {
|
|
203
|
+
expect(quintOut(-1)).toEqual(0);
|
|
204
|
+
expect(quintOut(0)).toEqual(0);
|
|
205
|
+
expect(quintOut(0.25)).toEqual(0.7626953125);
|
|
206
|
+
expect(quintOut(0.5)).toEqual(0.96875);
|
|
207
|
+
expect(quintOut(0.75)).toEqual(0.9990234375);
|
|
208
|
+
expect(quintOut(1)).toEqual(1);
|
|
209
|
+
expect(quintOut(2)).toEqual(1);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it("Returns the proper val for Quint in out", () => {
|
|
213
|
+
expect(quintInOut(-1)).toEqual(0);
|
|
214
|
+
expect(quintInOut(0)).toEqual(0);
|
|
215
|
+
expect(quintInOut(0.25)).toEqual(0.015625);
|
|
216
|
+
expect(quintInOut(0.5)).toBeCloseTo(0.5);
|
|
217
|
+
expect(quintInOut(0.75)).toEqual(0.984375);
|
|
218
|
+
expect(quintInOut(1)).toEqual(1);
|
|
219
|
+
expect(quintInOut(2)).toEqual(1);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
// Circ
|
|
223
|
+
it("Returns the proper val for Circ in", () => {
|
|
224
|
+
expect(circIn(-1)).toEqual(0);
|
|
225
|
+
expect(circIn(0)).toEqual(0);
|
|
226
|
+
expect(circIn(0.25)).toEqual(0.031754163448145745);
|
|
227
|
+
expect(circIn(0.5)).toEqual(0.1339745962155614);
|
|
228
|
+
expect(circIn(0.75)).toEqual(0.3385621722338523);
|
|
229
|
+
expect(circIn(1)).toEqual(1);
|
|
230
|
+
expect(circIn(2)).toEqual(1);
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
it("Returns the proper val for Circ out", () => {
|
|
234
|
+
expect(circOut(-1)).toEqual(0);
|
|
235
|
+
expect(circOut(0)).toEqual(0);
|
|
236
|
+
expect(circOut(0.25)).toEqual(0.6614378277661477);
|
|
237
|
+
expect(circOut(0.5)).toEqual(0.8660254037844386);
|
|
238
|
+
expect(circOut(0.75)).toEqual(0.9682458365518543);
|
|
239
|
+
expect(circOut(1)).toEqual(1);
|
|
240
|
+
expect(circOut(2)).toEqual(1);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it("Returns the proper val for Circ in out", () => {
|
|
244
|
+
expect(circInOut(-1)).toEqual(0);
|
|
245
|
+
expect(circInOut(0)).toEqual(0);
|
|
246
|
+
expect(circInOut(0.25)).toEqual(0.0669872981077807);
|
|
247
|
+
expect(circInOut(0.5)).toBeCloseTo(0.5);
|
|
248
|
+
expect(circInOut(0.75)).toEqual(0.9330127018922193);
|
|
249
|
+
expect(circInOut(1)).toEqual(1);
|
|
250
|
+
expect(circInOut(2)).toEqual(1);
|
|
251
|
+
});
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { EaseFn } from "../Types";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export const easeLinear: EaseFn = (x: number): number => {
|
|
5
|
+
if (x <= 0) return 0;
|
|
6
|
+
if (x >= 1) return 1;
|
|
7
|
+
|
|
8
|
+
return x;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const quadIn: EaseFn = (x: number) => {
|
|
12
|
+
if (x <= 0) return 0;
|
|
13
|
+
if (x >= 1) return 1;
|
|
14
|
+
|
|
15
|
+
return x * x;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const quadOut: EaseFn = (x: number) => {
|
|
19
|
+
if (x <= 0) return 0;
|
|
20
|
+
if (x >= 1) return 1;
|
|
21
|
+
|
|
22
|
+
return x * (2 - x);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const quadInOut: EaseFn = (x: number): number => {
|
|
26
|
+
if (x <= 0) return 0;
|
|
27
|
+
if (x >= 1) return 1;
|
|
28
|
+
|
|
29
|
+
if (x < 0.5) {
|
|
30
|
+
return 2 * x * x;
|
|
31
|
+
} else {
|
|
32
|
+
return 1 - Math.pow(-2 * x + 2, 2) / 2;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const cubicIn: EaseFn = (x: number): number => {
|
|
37
|
+
if (x <= 0) return 0;
|
|
38
|
+
if (x >= 1) return 1;
|
|
39
|
+
|
|
40
|
+
return x * x * x;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const cubicOut: EaseFn = (x: number): number => {
|
|
44
|
+
if (x <= 0) return 0;
|
|
45
|
+
if (x >= 1) return 1;
|
|
46
|
+
|
|
47
|
+
return --x * x * x + 1;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export const cubicInOut: EaseFn = (x: number): number => {
|
|
51
|
+
if (x <= 0) return 0;
|
|
52
|
+
if (x >= 1) return 1;
|
|
53
|
+
|
|
54
|
+
x *= 2;
|
|
55
|
+
|
|
56
|
+
if (x <= 1) {
|
|
57
|
+
return (x * x * x) / 2;
|
|
58
|
+
} else {
|
|
59
|
+
return ((x -= 2) * x * x + 2) / 2;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export const expoIn: EaseFn = (x: number): number => {
|
|
64
|
+
if (x <= 0) return 0;
|
|
65
|
+
if (x >= 1) return 1;
|
|
66
|
+
|
|
67
|
+
return Math.pow(2, 10 * x - 10);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const expoOut: EaseFn = (x: number): number => {
|
|
71
|
+
if (x <= 0) return 0;
|
|
72
|
+
if (x >= 1) return 1;
|
|
73
|
+
|
|
74
|
+
return 1 - Math.pow(2, -10 * x);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export const expoInOut: EaseFn = (x: number): number => {
|
|
78
|
+
if (x <= 0) return 0;
|
|
79
|
+
if (x >= 1) return 1;
|
|
80
|
+
|
|
81
|
+
return x < 0.5
|
|
82
|
+
? Math.pow(2, 20 * x - 10) / 2
|
|
83
|
+
: (2 - Math.pow(2, -20 * x + 10)) / 2;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export const sinIn: EaseFn = (x: number): number => {
|
|
87
|
+
if (x <= 0) return 0;
|
|
88
|
+
if (x >= 1) return 1;
|
|
89
|
+
|
|
90
|
+
return 1 - Math.cos((x * Math.PI) / 2);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export const sinOut: EaseFn = (x: number): number => {
|
|
94
|
+
if (x <= 0) return 0;
|
|
95
|
+
if (x >= 1) return 1;
|
|
96
|
+
|
|
97
|
+
return Math.sin((x * Math.PI) / 2);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export const sinInOut: EaseFn = (x: number): number => {
|
|
101
|
+
if (x <= 0) return 0;
|
|
102
|
+
if (x >= 1) return 1;
|
|
103
|
+
|
|
104
|
+
return -(Math.cos(Math.PI * x) - 1) / 2;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export const quartIn: EaseFn = (x: number): number => {
|
|
108
|
+
if (x <= 0) return 0;
|
|
109
|
+
if (x >= 1) return 1;
|
|
110
|
+
|
|
111
|
+
return x * x * x * x;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export const quartOut: EaseFn = (x: number): number => {
|
|
115
|
+
if (x <= 0) return 0;
|
|
116
|
+
if (x >= 1) return 1;
|
|
117
|
+
|
|
118
|
+
return 1 - Math.pow(1 - x, 4);
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export const quartInOut: EaseFn = (x: number): number => {
|
|
122
|
+
if (x <= 0) return 0;
|
|
123
|
+
if (x >= 1) return 1;
|
|
124
|
+
|
|
125
|
+
if (x < 0.5) {
|
|
126
|
+
return 8 * x * x * x * x;
|
|
127
|
+
} else {
|
|
128
|
+
return 1 - Math.pow(-2 * x + 2, 4) / 2;
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export const quintIn: EaseFn = (x: number): number => {
|
|
133
|
+
if (x <= 0) return 0;
|
|
134
|
+
if (x >= 1) return 1;
|
|
135
|
+
|
|
136
|
+
return x * x * x * x * x;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export const quintOut: EaseFn = (x: number): number => {
|
|
140
|
+
if (x <= 0) return 0;
|
|
141
|
+
if (x >= 1) return 1;
|
|
142
|
+
|
|
143
|
+
return 1 - Math.pow(1 - x, 5);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
export const quintInOut: EaseFn = (x: number): number => {
|
|
147
|
+
if (x <= 0) return 0;
|
|
148
|
+
if (x >= 1) return 1;
|
|
149
|
+
|
|
150
|
+
if (x < 0.5) {
|
|
151
|
+
return 16 * x * x * x * x * x;
|
|
152
|
+
} else {
|
|
153
|
+
return 1 - Math.pow(-2 * x + 2, 5) / 2;
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export const circIn: EaseFn = (x: number): number => {
|
|
158
|
+
if (x <= 0) return 0;
|
|
159
|
+
if (x >= 1) return 1;
|
|
160
|
+
|
|
161
|
+
return 1 - Math.sqrt(1 - Math.pow(x, 2));
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
export const circOut: EaseFn = (x: number): number => {
|
|
165
|
+
if (x <= 0) return 0;
|
|
166
|
+
if (x >= 1) return 1;
|
|
167
|
+
|
|
168
|
+
return Math.sqrt(1 - Math.pow(x - 1, 2));
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
export const circInOut: EaseFn = (x: number): number => {
|
|
172
|
+
if (x <= 0) return 0;
|
|
173
|
+
if (x >= 1) return 1;
|
|
174
|
+
|
|
175
|
+
if (x < 0.5) {
|
|
176
|
+
return (1 - Math.sqrt(1 - Math.pow(2 * x, 2))) / 2;
|
|
177
|
+
} else {
|
|
178
|
+
return (Math.sqrt(1 - Math.pow(-2 * x + 2, 2)) + 1) / 2;
|
|
179
|
+
}
|
|
180
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { interpolateNumber } from "./interpolateNumber";
|
|
2
|
+
|
|
3
|
+
describe("Lerp number", () => {
|
|
4
|
+
it("Interpolate as expected", () => {
|
|
5
|
+
const lerpedVal = interpolateNumber(0, 10, 0.5);
|
|
6
|
+
expect(lerpedVal).toEqual(5);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it("Interpolate without clamping", () => {
|
|
10
|
+
const lerpedVal = interpolateNumber(0, 10, -0.5);
|
|
11
|
+
expect(lerpedVal).toEqual(-5);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("Interpolate without clamping", () => {
|
|
15
|
+
const lerpedVal = interpolateNumber(0, 10, 1.5);
|
|
16
|
+
expect(lerpedVal).toEqual(15);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("Interpolate with clamping", () => {
|
|
20
|
+
const lerpedVal = interpolateNumber(0, 10, -0.5, true);
|
|
21
|
+
expect(lerpedVal).toEqual(0);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("Interpolate with clamping", () => {
|
|
25
|
+
const lerpedVal = interpolateNumber(0, 10, 1.5, true);
|
|
26
|
+
expect(lerpedVal).toEqual(10);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function interpolateNumber(
|
|
2
|
+
start: number,
|
|
3
|
+
end: number,
|
|
4
|
+
percent: number,
|
|
5
|
+
clamp: boolean = false
|
|
6
|
+
): number {
|
|
7
|
+
const range = end - start;
|
|
8
|
+
|
|
9
|
+
if (!clamp) {
|
|
10
|
+
return percent * range + start;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let clampedP = percent;
|
|
14
|
+
if (clampedP < 0) {
|
|
15
|
+
clampedP = 0;
|
|
16
|
+
} else if (clampedP > 1) {
|
|
17
|
+
clampedP = 1;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return clampedP * range + start;
|
|
21
|
+
}
|