@praxisjs/motion 0.2.3 → 1.1.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 +65 -0
- package/dist/__tests__/decorators.test.d.ts +2 -0
- package/dist/__tests__/decorators.test.d.ts.map +1 -0
- package/dist/__tests__/decorators.test.js +179 -0
- package/dist/__tests__/decorators.test.js.map +1 -0
- package/dist/__tests__/easings.test.js +82 -55
- package/dist/__tests__/easings.test.js.map +1 -1
- package/dist/__tests__/spring.test.js +80 -34
- package/dist/__tests__/spring.test.js.map +1 -1
- package/dist/__tests__/transition.test.js +111 -43
- package/dist/__tests__/transition.test.js.map +1 -1
- package/dist/__tests__/tween.test.js +107 -94
- package/dist/__tests__/tween.test.js.map +1 -1
- package/dist/decorators.d.ts +3 -1
- package/dist/decorators.d.ts.map +1 -1
- package/dist/decorators.js +39 -16
- package/dist/decorators.js.map +1 -1
- package/dist/easings.d.ts.map +1 -1
- package/dist/easings.js +7 -1
- package/dist/easings.js.map +1 -1
- package/dist/index.d.ts +2 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -6
- package/dist/index.js.map +1 -1
- package/dist/spring.d.ts.map +1 -1
- package/dist/spring.js +3 -0
- package/dist/spring.js.map +1 -1
- package/dist/transition.d.ts.map +1 -1
- package/dist/transition.js +34 -18
- package/dist/transition.js.map +1 -1
- package/dist/tween.d.ts.map +1 -1
- package/dist/tween.js +2 -1
- package/dist/tween.js.map +1 -1
- package/package.json +3 -2
- package/src/__tests__/decorators.test.ts +196 -0
- package/src/__tests__/easings.test.ts +86 -57
- package/src/__tests__/spring.test.ts +90 -34
- package/src/__tests__/transition.test.ts +122 -45
- package/src/__tests__/tween.test.ts +116 -97
- package/src/decorators.ts +42 -15
- package/src/easings.ts +6 -1
- package/src/index.ts +2 -15
- package/src/spring.ts +4 -0
- package/src/transition.ts +28 -18
- package/src/tween.ts +2 -1
- package/dist/__tests__/use-motion.test.d.ts +0 -2
- package/dist/__tests__/use-motion.test.d.ts.map +0 -1
- package/dist/__tests__/use-motion.test.js +0 -139
- package/dist/__tests__/use-motion.test.js.map +0 -1
- package/dist/use-motion.d.ts +0 -20
- package/dist/use-motion.d.ts.map +0 -1
- package/dist/use-motion.js +0 -58
- package/dist/use-motion.js.map +0 -1
- package/src/__tests__/use-motion.test.ts +0 -172
- package/src/use-motion.ts +0 -89
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/spring.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spring.d.ts","sourceRoot":"","sources":["../src/spring.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB;;;;
|
|
1
|
+
{"version":3,"file":"spring.d.ts","sourceRoot":"","sources":["../src/spring.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB;;;;EA+ClE"}
|
package/dist/spring.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { signal, computed, effect } from "@praxisjs/core/internal";
|
|
2
2
|
export function spring(initial, options = {}) {
|
|
3
3
|
const { stiffness = 0.15, damping = 0.8, mass = 1, precision = 0.001, } = options;
|
|
4
|
+
if (stiffness <= 0) {
|
|
5
|
+
throw new Error("stiffness must be greater than 0");
|
|
6
|
+
}
|
|
4
7
|
const _value = signal(initial);
|
|
5
8
|
const _target = signal(initial);
|
|
6
9
|
let velocity = 0;
|
package/dist/spring.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spring.js","sourceRoot":"","sources":["../src/spring.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AASnE,MAAM,UAAU,MAAM,CAAC,OAAe,EAAE,UAAyB,EAAE;IACjE,MAAM,EACJ,SAAS,GAAG,IAAI,EAChB,OAAO,GAAG,GAAG,EACb,IAAI,GAAG,CAAC,EACR,SAAS,GAAG,KAAK,GAClB,GAAG,OAAO,CAAC;IAEZ,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAChC,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,GAAuB,CAAC;IAE5B,SAAS,IAAI;QACX,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,OAAO,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,SAAS,CAAC;QAC7C,QAAQ,GAAG,CAAC,QAAQ,GAAG,KAAK,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC;QAE/C,MAAM,IAAI,GAAG,OAAO,GAAG,QAAQ,CAAC;QAChC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEjB,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,SAAS,EAAE,CAAC;YAC1E,GAAG,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACnB,QAAQ,GAAG,CAAC,CAAC;QACf,CAAC;IACH,CAAC;IAED,MAAM,CAAC,GAAG,EAAE;QACV,KAAK,OAAO,EAAE,CAAC;QACf,IAAI,GAAG;YAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC;QACnC,GAAG,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,KAAK,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC;QAC/B,MAAM,EAAE,OAAO;QACf,IAAI;YACF,IAAI,GAAG;gBAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC;QACrC,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"spring.js","sourceRoot":"","sources":["../src/spring.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AASnE,MAAM,UAAU,MAAM,CAAC,OAAe,EAAE,UAAyB,EAAE;IACjE,MAAM,EACJ,SAAS,GAAG,IAAI,EAChB,OAAO,GAAG,GAAG,EACb,IAAI,GAAG,CAAC,EACR,SAAS,GAAG,KAAK,GAClB,GAAG,OAAO,CAAC;IAEZ,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAChC,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,GAAuB,CAAC;IAE5B,SAAS,IAAI;QACX,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,OAAO,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,SAAS,CAAC;QAC7C,QAAQ,GAAG,CAAC,QAAQ,GAAG,KAAK,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC;QAE/C,MAAM,IAAI,GAAG,OAAO,GAAG,QAAQ,CAAC;QAChC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEjB,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,SAAS,EAAE,CAAC;YAC1E,GAAG,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACnB,QAAQ,GAAG,CAAC,CAAC;QACf,CAAC;IACH,CAAC;IAED,MAAM,CAAC,GAAG,EAAE;QACV,KAAK,OAAO,EAAE,CAAC;QACf,IAAI,GAAG;YAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC;QACnC,GAAG,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,KAAK,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC;QAC/B,MAAM,EAAE,OAAO;QACf,IAAI;YACF,IAAI,GAAG;gBAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC;QACrC,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/transition.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transition.d.ts","sourceRoot":"","sources":["../src/transition.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAC;IACpC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAC;CACrC;AAED,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,iBAAsB;cAIlD,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"transition.d.ts","sourceRoot":"","sources":["../src/transition.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAC;IACpC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAC;CACrC;AAED,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,iBAAsB;cAIlD,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;cAmB3B,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;EAoBxC"}
|
package/dist/transition.js
CHANGED
|
@@ -2,28 +2,44 @@ export function createTransition(options = {}) {
|
|
|
2
2
|
const { name = "transition", duration = 300, onEnter, onLeave } = options;
|
|
3
3
|
return {
|
|
4
4
|
enter(el) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
return new Promise((res, rej) => {
|
|
6
|
+
try {
|
|
7
|
+
onEnter?.(el);
|
|
8
|
+
}
|
|
9
|
+
catch (err) {
|
|
10
|
+
rej(err instanceof Error ? err : new Error(String(err)));
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
el.classList.add(`${name}-enter-from`);
|
|
14
|
+
requestAnimationFrame(() => {
|
|
15
|
+
el.classList.remove(`${name}-enter-from`);
|
|
16
|
+
el.classList.add(`${name}-enter-to`);
|
|
17
|
+
});
|
|
18
|
+
setTimeout(() => {
|
|
19
|
+
el.classList.remove(`${name}-enter-to`);
|
|
20
|
+
res();
|
|
21
|
+
}, duration);
|
|
10
22
|
});
|
|
11
|
-
return new Promise((res) => setTimeout(() => {
|
|
12
|
-
el.classList.remove(`${name}-enter-to`);
|
|
13
|
-
res();
|
|
14
|
-
}, duration));
|
|
15
23
|
},
|
|
16
24
|
leave(el) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
25
|
+
return new Promise((res, rej) => {
|
|
26
|
+
try {
|
|
27
|
+
onLeave?.(el);
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
rej(err instanceof Error ? err : new Error(String(err)));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
el.classList.add(`${name}-leave-from`);
|
|
34
|
+
requestAnimationFrame(() => {
|
|
35
|
+
el.classList.remove(`${name}-leave-from`);
|
|
36
|
+
el.classList.add(`${name}-leave-to`);
|
|
37
|
+
});
|
|
38
|
+
setTimeout(() => {
|
|
39
|
+
el.classList.remove(`${name}-leave-to`);
|
|
40
|
+
res();
|
|
41
|
+
}, duration);
|
|
22
42
|
});
|
|
23
|
-
return new Promise((res) => setTimeout(() => {
|
|
24
|
-
el.classList.remove(`${name}-leave-to`);
|
|
25
|
-
res();
|
|
26
|
-
}, duration));
|
|
27
43
|
},
|
|
28
44
|
};
|
|
29
45
|
}
|
package/dist/transition.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transition.js","sourceRoot":"","sources":["../src/transition.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,gBAAgB,CAAC,UAA6B,EAAE;IAC9D,MAAM,EAAE,IAAI,GAAG,YAAY,EAAE,QAAQ,GAAG,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAE1E,OAAO;QACL,KAAK,CAAC,EAAe;YACnB,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"transition.js","sourceRoot":"","sources":["../src/transition.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,gBAAgB,CAAC,UAA6B,EAAE;IAC9D,MAAM,EAAE,IAAI,GAAG,YAAY,EAAE,QAAQ,GAAG,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAE1E,OAAO;QACL,KAAK,CAAC,EAAe;YACnB,OAAO,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;gBAC9B,IAAI,CAAC;oBACH,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;gBAChB,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,GAAG,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;oBACzD,OAAO;gBACT,CAAC;gBACD,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,aAAa,CAAC,CAAC;gBACvC,qBAAqB,CAAC,GAAG,EAAE;oBACzB,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,aAAa,CAAC,CAAC;oBAC1C,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC;gBACvC,CAAC,CAAC,CAAC;gBACH,UAAU,CAAC,GAAG,EAAE;oBACd,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC;oBACxC,GAAG,EAAE,CAAC;gBACR,CAAC,EAAE,QAAQ,CAAC,CAAC;YACf,CAAC,CAAC,CAAC;QACL,CAAC;QACD,KAAK,CAAC,EAAe;YACnB,OAAO,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;gBAC9B,IAAI,CAAC;oBACH,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;gBAChB,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,GAAG,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;oBACzD,OAAO;gBACT,CAAC;gBACD,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,aAAa,CAAC,CAAC;gBACvC,qBAAqB,CAAC,GAAG,EAAE;oBACzB,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,aAAa,CAAC,CAAC;oBAC1C,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC;gBACvC,CAAC,CAAC,CAAC;gBACH,UAAU,CAAC,GAAG,EAAE;oBACd,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC;oBACxC,GAAG,EAAE,CAAC;gBACR,CAAC,EAAE,QAAQ,CAAC,CAAC;YACf,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/tween.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tween.d.ts","sourceRoot":"","sources":["../src/tween.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AAEvD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACvB,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC3B,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3B,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,IAAI,IAAI,CAAC;CACf;AAED,wBAAgB,KAAK,CACnB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,OAAO,GAAE,YAAiB,GACzB,KAAK,
|
|
1
|
+
{"version":3,"file":"tween.d.ts","sourceRoot":"","sources":["../src/tween.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AAEvD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACvB,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC3B,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3B,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,IAAI,IAAI,CAAC;CACf;AAED,wBAAgB,KAAK,CACnB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,OAAO,GAAE,YAAiB,GACzB,KAAK,CA0DP"}
|
package/dist/tween.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { signal, computed, effect } from "@praxisjs/core/internal";
|
|
2
2
|
import { resolveEasing } from "./easings";
|
|
3
3
|
export function tween(from, to, options = {}) {
|
|
4
|
-
const { duration = 300, easing = "easeOut", delay = 0 } = options;
|
|
4
|
+
const { duration: rawDuration = 300, easing = "easeOut", delay = 0 } = options;
|
|
5
|
+
const duration = Math.max(1, rawDuration);
|
|
5
6
|
const easeFn = resolveEasing(easing);
|
|
6
7
|
const _value = signal(from);
|
|
7
8
|
const _target = signal(to);
|
package/dist/tween.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tween.js","sourceRoot":"","sources":["../src/tween.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGnE,OAAO,EAAE,aAAa,EAAe,MAAM,WAAW,CAAC;AAiBvD,MAAM,UAAU,KAAK,CACnB,IAAY,EACZ,EAAU,EACV,UAAwB,EAAE;IAE1B,MAAM,EAAE,QAAQ,GAAG,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"tween.js","sourceRoot":"","sources":["../src/tween.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGnE,OAAO,EAAE,aAAa,EAAe,MAAM,WAAW,CAAC;AAiBvD,MAAM,UAAU,KAAK,CACnB,IAAY,EACZ,EAAU,EACV,UAAwB,EAAE;IAE1B,MAAM,EAAE,QAAQ,EAAE,WAAW,GAAG,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC;IAC/E,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAErC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAC5B,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;IAC3B,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAC5B,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAE/B,IAAI,GAAuB,CAAC;IAC5B,IAAI,SAA6B,CAAC;IAClC,IAAI,UAAU,GAAG,IAAI,CAAC;IAEtB,SAAS,OAAO,CAAC,SAAiB;QAChC,SAAS,KAAK,SAAS,GAAG,KAAK,CAAC;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC,CAAC;QACnD,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC;QAE1C,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACjB,MAAM,CAAC,GAAG,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE,GAAG,UAAU,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAE9D,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACV,GAAG,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACtB,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAED,SAAS,KAAK;QACZ,IAAI,GAAG;YAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC;QACnC,UAAU,GAAG,MAAM,EAAE,CAAC;QACtB,SAAS,GAAG,SAAS,CAAC;QACtB,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnB,GAAG,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,CAAC,GAAG,EAAE;QACV,KAAK,OAAO,EAAE,CAAC;QACf,KAAK,EAAE,CAAC;IACV,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,KAAK,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC;QAC/B,MAAM,EAAE,OAAO;QACf,OAAO,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;QACnC,QAAQ,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC;QACrC,IAAI;YACF,IAAI,GAAG;gBAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC;YACnC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;QACD,KAAK;YACH,IAAI,GAAG;gBAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC;YACnC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACjB,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACnB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@praxisjs/motion",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"typescript": "^5.9.3"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@praxisjs/core": "
|
|
17
|
+
"@praxisjs/core": "1.1.0",
|
|
18
|
+
"@praxisjs/decorators": "0.6.0",
|
|
18
19
|
"@praxisjs/shared": "0.2.0"
|
|
19
20
|
},
|
|
20
21
|
"scripts": {
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
import { describe, it, expect, vi } from "vitest";
|
|
3
|
+
|
|
4
|
+
import { Tween, Spring } from "../decorators";
|
|
5
|
+
|
|
6
|
+
function makeCtx(name: string) {
|
|
7
|
+
const initializers: Array<(this: unknown) => void> = [];
|
|
8
|
+
return {
|
|
9
|
+
ctx: {
|
|
10
|
+
name,
|
|
11
|
+
kind: "field" as const,
|
|
12
|
+
addInitializer(fn: (this: unknown) => void) { initializers.push(fn); },
|
|
13
|
+
} as ClassFieldDecoratorContext,
|
|
14
|
+
run(instance: unknown) {
|
|
15
|
+
initializers.forEach((fn) => { fn.call(instance); });
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// ── @Tween ────────────────────────────────────────────────────────────────────
|
|
21
|
+
|
|
22
|
+
describe("@Tween", () => {
|
|
23
|
+
it("returns 0 before any value is set", () => {
|
|
24
|
+
vi.useFakeTimers();
|
|
25
|
+
const { ctx, run } = makeCtx("opacity");
|
|
26
|
+
Tween()(undefined, ctx);
|
|
27
|
+
const instance: Record<string, unknown> = {};
|
|
28
|
+
run(instance);
|
|
29
|
+
expect(instance.opacity).toBe(0);
|
|
30
|
+
vi.clearAllTimers();
|
|
31
|
+
vi.useRealTimers();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("creates a numeric getter/setter on first assignment", () => {
|
|
35
|
+
vi.useFakeTimers();
|
|
36
|
+
const { ctx, run } = makeCtx("x");
|
|
37
|
+
Tween()(undefined, ctx);
|
|
38
|
+
const instance: Record<string, unknown> = {};
|
|
39
|
+
run(instance);
|
|
40
|
+
instance.x = 10;
|
|
41
|
+
expect(typeof instance.x).toBe("number");
|
|
42
|
+
vi.clearAllTimers();
|
|
43
|
+
vi.useRealTimers();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("updating the property updates the tween target", () => {
|
|
47
|
+
vi.useFakeTimers();
|
|
48
|
+
const { ctx, run } = makeCtx("scale");
|
|
49
|
+
Tween()(undefined, ctx);
|
|
50
|
+
const instance: Record<string, unknown> = {};
|
|
51
|
+
run(instance);
|
|
52
|
+
instance.scale = 1;
|
|
53
|
+
instance.scale = 2;
|
|
54
|
+
expect(typeof instance.scale).toBe("number");
|
|
55
|
+
vi.clearAllTimers();
|
|
56
|
+
vi.useRealTimers();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("accepts TweenOptions", () => {
|
|
60
|
+
vi.useFakeTimers();
|
|
61
|
+
const { ctx, run } = makeCtx("y");
|
|
62
|
+
Tween({ duration: 500, easing: "linear", delay: 50 })(undefined, ctx);
|
|
63
|
+
const instance: Record<string, unknown> = {};
|
|
64
|
+
run(instance);
|
|
65
|
+
instance.y = 100;
|
|
66
|
+
expect(typeof instance.y).toBe("number");
|
|
67
|
+
vi.clearAllTimers();
|
|
68
|
+
vi.useRealTimers();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("each instance gets its own tween", () => {
|
|
72
|
+
vi.useFakeTimers();
|
|
73
|
+
const { ctx, run } = makeCtx("val");
|
|
74
|
+
Tween()(undefined, ctx);
|
|
75
|
+
const a: Record<string, unknown> = {};
|
|
76
|
+
const b: Record<string, unknown> = {};
|
|
77
|
+
run(a);
|
|
78
|
+
run(b);
|
|
79
|
+
a.val = 10;
|
|
80
|
+
b.val = 50;
|
|
81
|
+
expect(a.val).not.toBe(b.val);
|
|
82
|
+
vi.clearAllTimers();
|
|
83
|
+
vi.useRealTimers();
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// ── @Spring ───────────────────────────────────────────────────────────────────
|
|
88
|
+
|
|
89
|
+
describe("@Spring", () => {
|
|
90
|
+
it("returns 0 before any value is set", () => {
|
|
91
|
+
vi.useFakeTimers();
|
|
92
|
+
const { ctx, run } = makeCtx("x");
|
|
93
|
+
Spring()(undefined, ctx);
|
|
94
|
+
const instance: Record<string, unknown> = {};
|
|
95
|
+
run(instance);
|
|
96
|
+
expect(instance.x).toBe(0);
|
|
97
|
+
vi.clearAllTimers();
|
|
98
|
+
vi.useRealTimers();
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("creates a numeric getter/setter on first assignment", () => {
|
|
102
|
+
vi.useFakeTimers();
|
|
103
|
+
const { ctx, run } = makeCtx("y");
|
|
104
|
+
Spring()(undefined, ctx);
|
|
105
|
+
const instance: Record<string, unknown> = {};
|
|
106
|
+
run(instance);
|
|
107
|
+
instance.y = 42;
|
|
108
|
+
expect(typeof instance.y).toBe("number");
|
|
109
|
+
vi.clearAllTimers();
|
|
110
|
+
vi.useRealTimers();
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("updating the property sets the spring target", () => {
|
|
114
|
+
vi.useFakeTimers();
|
|
115
|
+
const { ctx, run } = makeCtx("scale");
|
|
116
|
+
Spring()(undefined, ctx);
|
|
117
|
+
const instance: Record<string, unknown> = {};
|
|
118
|
+
run(instance);
|
|
119
|
+
instance.scale = 1;
|
|
120
|
+
instance.scale = 2;
|
|
121
|
+
expect(typeof instance.scale).toBe("number");
|
|
122
|
+
vi.clearAllTimers();
|
|
123
|
+
vi.useRealTimers();
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it("accepts SpringOptions", () => {
|
|
127
|
+
vi.useFakeTimers();
|
|
128
|
+
const { ctx, run } = makeCtx("opacity");
|
|
129
|
+
Spring({ stiffness: 0.3, damping: 0.9, mass: 2 })(undefined, ctx);
|
|
130
|
+
const instance: Record<string, unknown> = {};
|
|
131
|
+
run(instance);
|
|
132
|
+
instance.opacity = 1;
|
|
133
|
+
expect(typeof instance.opacity).toBe("number");
|
|
134
|
+
vi.clearAllTimers();
|
|
135
|
+
vi.useRealTimers();
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it("each instance gets its own spring", () => {
|
|
139
|
+
vi.useFakeTimers();
|
|
140
|
+
const { ctx, run } = makeCtx("val");
|
|
141
|
+
Spring()(undefined, ctx);
|
|
142
|
+
const a: Record<string, unknown> = {};
|
|
143
|
+
const b: Record<string, unknown> = {};
|
|
144
|
+
run(a);
|
|
145
|
+
run(b);
|
|
146
|
+
a.val = 10;
|
|
147
|
+
b.val = 50;
|
|
148
|
+
expect(a.val).not.toBe(b.val);
|
|
149
|
+
vi.clearAllTimers();
|
|
150
|
+
vi.useRealTimers();
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// ── Edge case tests ───────────────────────────────────────────────────────────
|
|
155
|
+
|
|
156
|
+
describe("@Tween edge cases", () => {
|
|
157
|
+
it("setting NaN on @Tween field does not crash", () => {
|
|
158
|
+
vi.useFakeTimers();
|
|
159
|
+
const { ctx, run } = makeCtx("opacity");
|
|
160
|
+
Tween()(undefined, ctx);
|
|
161
|
+
const instance: Record<string, unknown> = {};
|
|
162
|
+
run(instance);
|
|
163
|
+
expect(() => { instance.opacity = NaN; }).not.toThrow();
|
|
164
|
+
vi.clearAllTimers();
|
|
165
|
+
vi.useRealTimers();
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it("two @Tween fields on same class — independent animations", () => {
|
|
169
|
+
vi.useFakeTimers();
|
|
170
|
+
const { ctx: ctxX, run: runX } = makeCtx("x");
|
|
171
|
+
const { ctx: ctxY, run: runY } = makeCtx("y");
|
|
172
|
+
Tween()(undefined, ctxX);
|
|
173
|
+
Tween()(undefined, ctxY);
|
|
174
|
+
const instance: Record<string, unknown> = {};
|
|
175
|
+
runX(instance);
|
|
176
|
+
runY(instance);
|
|
177
|
+
instance.x = 10;
|
|
178
|
+
instance.y = 50;
|
|
179
|
+
expect(instance.x).not.toBe(instance.y);
|
|
180
|
+
vi.clearAllTimers();
|
|
181
|
+
vi.useRealTimers();
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
describe("@Spring edge cases", () => {
|
|
186
|
+
it("setting Infinity on @Spring field does not crash", () => {
|
|
187
|
+
vi.useFakeTimers();
|
|
188
|
+
const { ctx, run } = makeCtx("scale");
|
|
189
|
+
Spring()(undefined, ctx);
|
|
190
|
+
const instance: Record<string, unknown> = {};
|
|
191
|
+
run(instance);
|
|
192
|
+
expect(() => { instance.scale = Infinity; }).not.toThrow();
|
|
193
|
+
vi.clearAllTimers();
|
|
194
|
+
vi.useRealTimers();
|
|
195
|
+
});
|
|
196
|
+
});
|
|
@@ -2,82 +2,111 @@ import { describe, it, expect } from "vitest";
|
|
|
2
2
|
|
|
3
3
|
import { easings, resolveEasing } from "../easings";
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
describe("easings.linear", () => {
|
|
6
|
+
it("returns 0 at t=0", () => expect(easings.linear(0)).toBe(0));
|
|
7
|
+
it("returns 0.5 at t=0.5", () => expect(easings.linear(0.5)).toBe(0.5));
|
|
8
|
+
it("returns 1 at t=1", () => expect(easings.linear(1)).toBe(1));
|
|
9
|
+
});
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
describe("easings.easeIn", () => {
|
|
12
|
+
it("returns 0 at t=0", () => expect(easings.easeIn(0)).toBe(0));
|
|
13
|
+
it("returns 0.25 at t=0.5", () => expect(easings.easeIn(0.5)).toBe(0.25));
|
|
14
|
+
it("returns 1 at t=1", () => expect(easings.easeIn(1)).toBe(1));
|
|
15
|
+
});
|
|
10
16
|
|
|
11
|
-
describe("easings", () => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
describe("easings.easeOut", () => {
|
|
18
|
+
it("returns 0 at t=0", () => expect(easings.easeOut(0)).toBe(0));
|
|
19
|
+
it("returns 0.75 at t=0.5", () => expect(easings.easeOut(0.5)).toBe(0.75));
|
|
20
|
+
it("returns 1 at t=1", () => expect(easings.easeOut(1)).toBe(1));
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe("easings.easeInOut", () => {
|
|
24
|
+
it("returns 0 at t=0", () => expect(easings.easeInOut(0)).toBe(0));
|
|
25
|
+
it("returns 0.5 at t=0.5", () => expect(easings.easeInOut(0.5)).toBe(0.5));
|
|
26
|
+
it("returns 1 at t=1", () => expect(easings.easeInOut(1)).toBe(1));
|
|
27
|
+
it("uses easeIn branch for t<0.5", () => {
|
|
28
|
+
expect(easings.easeInOut(0.25)).toBeCloseTo(0.125);
|
|
29
|
+
});
|
|
30
|
+
it("uses easeOut branch for t>=0.5", () => {
|
|
31
|
+
expect(easings.easeInOut(0.75)).toBeCloseTo(0.875);
|
|
21
32
|
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe("easings.easeInCubic", () => {
|
|
36
|
+
it("returns 0 at t=0", () => expect(easings.easeInCubic(0)).toBe(0));
|
|
37
|
+
it("returns 0.125 at t=0.5", () => expect(easings.easeInCubic(0.5)).toBe(0.125));
|
|
38
|
+
it("returns 1 at t=1", () => expect(easings.easeInCubic(1)).toBe(1));
|
|
39
|
+
});
|
|
22
40
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
41
|
+
describe("easings.bounce", () => {
|
|
42
|
+
it("returns 0 at t=0", () => expect(easings.bounce(0)).toBe(0));
|
|
43
|
+
it("returns 1 at t=1", () => expect(easings.bounce(1)).toBeCloseTo(1));
|
|
44
|
+
it("handles first branch (t < 1/2.75)", () => {
|
|
45
|
+
const t = 0.2;
|
|
46
|
+
expect(easings.bounce(t)).toBeGreaterThan(0);
|
|
47
|
+
});
|
|
48
|
+
it("handles second branch (t < 2/2.75)", () => {
|
|
49
|
+
const t = 0.5;
|
|
50
|
+
expect(easings.bounce(t)).toBeGreaterThan(0.7);
|
|
51
|
+
});
|
|
52
|
+
it("handles third branch (t < 2.5/2.75)", () => {
|
|
53
|
+
const t = 0.85;
|
|
54
|
+
expect(easings.bounce(t)).toBeGreaterThan(0.9);
|
|
28
55
|
});
|
|
56
|
+
it("handles fourth branch (t >= 2.5/2.75)", () => {
|
|
57
|
+
const t = 0.97;
|
|
58
|
+
expect(easings.bounce(t)).toBeGreaterThan(0.98);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
29
61
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
62
|
+
describe("easings.elastic", () => {
|
|
63
|
+
it("returns 0 at t=0", () => expect(easings.elastic(0)).toBe(0));
|
|
64
|
+
it("returns 1 at t=1", () => expect(easings.elastic(1)).toBe(1));
|
|
65
|
+
it("returns a negative value mid-range (overshoot)", () => {
|
|
66
|
+
expect(easings.elastic(0.5)).toBeLessThan(0);
|
|
34
67
|
});
|
|
68
|
+
});
|
|
35
69
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
70
|
+
describe("resolveEasing", () => {
|
|
71
|
+
it("resolves a named easing", () => {
|
|
72
|
+
const fn = resolveEasing("linear");
|
|
73
|
+
expect(fn(0.5)).toBe(0.5);
|
|
40
74
|
});
|
|
41
75
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
76
|
+
it("returns a custom function as-is", () => {
|
|
77
|
+
const custom = (t: number) => t * 2;
|
|
78
|
+
const fn = resolveEasing(custom);
|
|
79
|
+
expect(fn).toBe(custom);
|
|
80
|
+
expect(fn(0.5)).toBe(1);
|
|
47
81
|
});
|
|
48
82
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
83
|
+
it("resolves all named easings", () => {
|
|
84
|
+
const names = ["linear", "easeIn", "easeOut", "easeInOut", "easeInCubic", "bounce", "elastic"] as const;
|
|
85
|
+
for (const name of names) {
|
|
86
|
+
const fn = resolveEasing(name);
|
|
87
|
+
expect(typeof fn).toBe("function");
|
|
88
|
+
}
|
|
53
89
|
});
|
|
54
90
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
for (let t = 0; t <= 1; t += 0.1) {
|
|
58
|
-
const v = easings.bounce(t);
|
|
59
|
-
expect(v).toBeGreaterThanOrEqual(0);
|
|
60
|
-
expect(v).toBeLessThanOrEqual(1 + EPSILON);
|
|
61
|
-
}
|
|
62
|
-
});
|
|
91
|
+
it('resolveEasing("notARealEasing") throws a descriptive error', () => {
|
|
92
|
+
expect(() => resolveEasing("notARealEasing" as never)).toThrow(/notARealEasing/);
|
|
63
93
|
});
|
|
64
94
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
expect(easings.
|
|
69
|
-
}
|
|
95
|
+
it("all easings with t < 0 — do not crash", () => {
|
|
96
|
+
const names = ["linear", "easeIn", "easeOut", "easeInOut", "easeInCubic", "bounce", "elastic"] as const;
|
|
97
|
+
for (const name of names) {
|
|
98
|
+
expect(() => easings[name](-0.1)).not.toThrow();
|
|
99
|
+
}
|
|
70
100
|
});
|
|
71
|
-
});
|
|
72
101
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
|
|
102
|
+
it("all easings with t > 1 — do not crash", () => {
|
|
103
|
+
const names = ["linear", "easeIn", "easeOut", "easeInOut", "easeInCubic", "bounce", "elastic"] as const;
|
|
104
|
+
for (const name of names) {
|
|
105
|
+
expect(() => easings[name](1.1)).not.toThrow();
|
|
106
|
+
}
|
|
77
107
|
});
|
|
78
108
|
|
|
79
|
-
it("
|
|
80
|
-
|
|
81
|
-
expect(resolveEasing(custom)).toBe(custom);
|
|
109
|
+
it("easeInOut(0.5) returns exactly 0.5 (smooth boundary)", () => {
|
|
110
|
+
expect(easings.easeInOut(0.5)).toBe(0.5);
|
|
82
111
|
});
|
|
83
112
|
});
|