Skip to content

Commit e4966fd

Browse files
feat(math): add easing functions
- add easing functions, ported from thi.ng/shader-ast-std pkg
1 parent 80412b9 commit e4966fd

File tree

3 files changed

+108
-0
lines changed

3 files changed

+108
-0
lines changed

packages/math/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"animation",
5252
"bezier",
5353
"cubic",
54+
"easing",
5455
"hermite",
5556
"interpolation",
5657
"interval",
@@ -89,6 +90,9 @@
8990
"./crossing": {
9091
"default": "./crossing.js"
9192
},
93+
"./easing": {
94+
"default": "./easing.js"
95+
},
9296
"./eqdelta": {
9397
"default": "./eqdelta.js"
9498
},

packages/math/src/easing.ts

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import type { FnN } from "@thi.ng/api";
2+
import { HALF_PI, PI, TAU } from "./api.js";
3+
4+
const { cos, sin, sqrt } = Math;
5+
6+
export const defEaseInExp =
7+
(k: number): FnN =>
8+
(t) =>
9+
t ** k;
10+
11+
export const defEaseOutExp =
12+
(k: number): FnN =>
13+
(t) =>
14+
1 - (1 - t) ** k;
15+
16+
export const defEaseInOutExp = (k: number): FnN => {
17+
const k2 = 2 ** (k - 1);
18+
return (t) => (t < 0.5 ? k2 * t ** k : 1 - (-2 * t + 2) ** k / 2);
19+
};
20+
21+
export const easeLinear: FnN = (t) => t;
22+
23+
export const easeIn2 = defEaseInExp(2);
24+
export const easeOut2 = defEaseOutExp(2);
25+
export const easeInOut2 = defEaseInOutExp(2);
26+
27+
export const easeIn3 = defEaseInExp(3);
28+
export const easeOut3 = defEaseOutExp(3);
29+
export const easeInOut3 = defEaseInOutExp(3);
30+
31+
export const easeIn4 = defEaseInExp(4);
32+
export const easeOut4 = defEaseOutExp(4);
33+
export const easeInOut4 = defEaseInOutExp(4);
34+
35+
export const easeIn5 = defEaseInExp(5);
36+
export const easeOut5 = defEaseOutExp(5);
37+
export const easeInOut5 = defEaseInOutExp(5);
38+
39+
export const easeInBack: FnN = (t) => 2.70158 * t ** 3 - 1.70158 * t ** 2;
40+
export const easeOutBack: FnN = (t) =>
41+
2.70158 * (t - 1) ** 3 + 1 + 1.70158 * (t - 1) ** 2;
42+
export const easeInOutBack: FnN = (t) =>
43+
t < 0.5
44+
? ((2 * t) ** 2 * ((2.5949095 + 1) * 2 * t - 2.5949095)) / 2
45+
: ((2 * t - 2) ** 2 * ((2.5949095 + 1) * (t * 2 - 2) + 2.5949095) + 2) /
46+
2;
47+
48+
export const easeInBounce: FnN = (t) => 1 - easeOutBounce(1 - t);
49+
export const easeOutBounce: FnN = (t) =>
50+
t < 1 / 2.75
51+
? 7.5625 * (t * t)
52+
: t < 2 / 2.75
53+
? 7.5625 * (t - 1.5 / 2.75) * (t - 1.5 / 2.75) + 0.75
54+
: t < 2.5 / 2.75
55+
? 7.5625 * (t - 2.25 / 2.75) * (t - 2.25 / 2.75) + 0.9375
56+
: 7.5625 * (t - 2.625 / 2.75) * (t - 2.625 / 2.75) + 0.984375;
57+
export const easeInOutBounce: FnN = (t) =>
58+
t < 0.5
59+
? (1 - easeOutBounce(1 - 2 * t)) / 2
60+
: (1 + easeOutBounce(2 * t - 1)) / 2;
61+
62+
export const easeInCirc: FnN = (t) => 1 - sqrt(1 - t ** 2);
63+
export const easeOutCirc: FnN = (t) => sqrt(1 - (t - 1) ** 2);
64+
export const easeInOutCirc: FnN = (t) =>
65+
t < 0.5
66+
? (1 - sqrt(1 - (2 * t) ** 2)) / 2
67+
: (sqrt(1 - (-2 * t + 2) ** 2) + 1) / 2;
68+
69+
export const easeInElastic: FnN = (t) =>
70+
t <= 0
71+
? 0
72+
: t >= 1
73+
? 1
74+
: -(2 ** (10 * t - 10)) * sin((t * 10 - 10.75) * (TAU / 3));
75+
export const easeOutElastic: FnN = (t) =>
76+
t <= 0
77+
? 0
78+
: t >= 1
79+
? 1
80+
: 2 ** (-10 * t) * sin((t * 10 - 0.75) * (TAU / 3)) + 1;
81+
export const easeInOutElastic: FnN = (t) =>
82+
t <= 0
83+
? 0
84+
: t >= 1
85+
? 1
86+
: t < 0.5
87+
? -(2 ** (20 * t - 10) * sin((20 * t - 11.125) * (TAU / 4.5))) / 2
88+
: (2 ** (-20 * t + 10) * sin((20 * t - 11.125) * (TAU / 4.5))) / 2 + 1;
89+
90+
export const easeInExp2: FnN = (t) => (t <= 0 ? 0 : 2 ** (10 * t - 10));
91+
export const easeOutExp2: FnN = (t) => (t >= 1 ? 1 : 1 - 2 ** (-10 * t));
92+
export const easeInOutExp2: FnN = (t) =>
93+
t < 0
94+
? 0
95+
: t >= 1
96+
? 1
97+
: t < 0.5
98+
? 2 ** (20 * t - 10) / 2
99+
: (2 - 2 ** (-20 * t + 10)) / 2;
100+
101+
export const easeInSine: FnN = (t) => 1 - cos(t * HALF_PI);
102+
export const easeOutSine: FnN = (t) => sin(t * HALF_PI);
103+
export const easeInOutSine: FnN = (t) => -(cos(PI * t) - 1) / 2;

packages/math/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export * from "./angle.js";
44
export * from "./crossing.js";
55
export * from "./eqdelta.js";
66
export * from "./extrema.js";
7+
export * from "./easing.js";
78
export * from "./fit.js";
89
export * from "./int.js";
910
export * from "./interval.js";

0 commit comments

Comments
 (0)