0
# Easing Functions
1
2
Comprehensive collection of easing functions for natural motion feel, plus utilities for creating custom easing curves and modifying existing ones.
3
4
## Capabilities
5
6
### Basic Easing Functions
7
8
Pre-defined easing functions for common animation patterns.
9
10
```typescript { .api }
11
type Easing = (v: number) => number;
12
13
// Linear easing
14
const linear: Easing;
15
16
// Exponential easing
17
const easeIn: Easing;
18
const easeOut: Easing;
19
const easeInOut: Easing;
20
21
// Circular easing
22
const circIn: Easing;
23
const circOut: Easing;
24
const circInOut: Easing;
25
26
// Back easing (with overshoot)
27
const backIn: Easing;
28
const backOut: Easing;
29
const backInOut: Easing;
30
31
// Bounce easing
32
const bounceIn: Easing;
33
const bounceOut: Easing;
34
const bounceInOut: Easing;
35
36
// Special easing
37
const anticipate: Easing;
38
```
39
40
**Usage Examples:**
41
42
```typescript
43
import { animate, easeOut, bounceOut, anticipate } from "popmotion";
44
45
// Using pre-defined easing
46
animate({
47
from: 0,
48
to: 100,
49
duration: 1000,
50
ease: easeOut,
51
onUpdate: (value) => element.style.left = value + "px"
52
});
53
54
// Bounce animation
55
animate({
56
from: 0,
57
to: 100,
58
duration: 800,
59
ease: bounceOut,
60
onUpdate: (value) => element.style.transform = `translateY(${value}px)`
61
});
62
63
// Anticipate for UI interactions
64
animate({
65
from: 1,
66
to: 1.2,
67
duration: 200,
68
ease: anticipate,
69
onUpdate: (scale) => button.style.transform = `scale(${scale})`
70
});
71
```
72
73
### Custom Easing Generators
74
75
Functions for creating custom easing curves with precise control.
76
77
```typescript { .api }
78
/**
79
* Creates a cubic Bezier easing function
80
* @param mX1 - First control point X coordinate (0-1)
81
* @param mY1 - First control point Y coordinate
82
* @param mX2 - Second control point X coordinate (0-1)
83
* @param mY2 - Second control point Y coordinate
84
* @returns Custom cubic Bezier easing function
85
*/
86
function cubicBezier(mX1: number, mY1: number, mX2: number, mY2: number): Easing;
87
88
/**
89
* Creates a stepped easing function for discrete animations
90
* @param steps - Number of steps in the animation
91
* @param direction - Whether to change at start or end of each step
92
* @returns Stepped easing function
93
*/
94
function steps(steps: number, direction?: "start" | "end"): Easing;
95
```
96
97
**Usage Examples:**
98
99
```typescript
100
import { animate, cubicBezier, steps } from "popmotion";
101
102
// Custom cubic Bezier (CSS equivalent: cubic-bezier(0.25, 0.46, 0.45, 0.94))
103
const customEase = cubicBezier(0.25, 0.46, 0.45, 0.94);
104
105
animate({
106
from: 0,
107
to: 100,
108
duration: 1000,
109
ease: customEase,
110
onUpdate: (value) => element.style.opacity = value / 100
111
});
112
113
// Stepped animation (like frame-by-frame)
114
const stepEase = steps(8, "end");
115
116
animate({
117
from: 0,
118
to: 8,
119
duration: 2000,
120
ease: stepEase,
121
onUpdate: (frame) => sprite.style.backgroundPosition = `-${Math.floor(frame) * 64}px 0`
122
});
123
124
// Material Design easing curves
125
const fastOutSlowIn = cubicBezier(0.4, 0, 0.2, 1);
126
const fastOutLinearIn = cubicBezier(0.4, 0, 1, 1);
127
const linearOutSlowIn = cubicBezier(0, 0, 0.2, 1);
128
```
129
130
### Easing Utilities
131
132
Advanced utilities for creating and modifying easing functions.
133
134
```typescript { .api }
135
/**
136
* Mirrors an easing function for the second half of animation
137
* @param easing - Base easing function to mirror
138
* @returns Mirrored easing function that mirrors at halfway point
139
*/
140
function mirrorEasing(easing: Easing): Easing;
141
142
/**
143
* Reverses the direction of an easing function
144
* @param easing - Base easing function to reverse
145
* @returns Reversed easing function (easeIn becomes easeOut)
146
*/
147
function reverseEasing(easing: Easing): Easing;
148
149
/**
150
* Creates exponential easing with custom power
151
* @param power - Exponential power factor (higher = more dramatic)
152
* @returns Custom exponential easing function using p^power
153
*/
154
function createExpoIn(power: number): Easing;
155
156
/**
157
* Creates back easing with custom overshoot
158
* @param power - Overshoot amount (higher = stronger pullback)
159
* @returns Custom back easing function with overshoot effect
160
*/
161
function createBackIn(power: number): Easing;
162
163
/**
164
* Creates anticipate easing with custom power
165
* @param power - Anticipation strength (higher = more pullback)
166
* @returns Custom anticipate easing combining back-in with expo-out
167
*/
168
function createAnticipate(power: number): Easing;
169
170
type EasingModifier = (easing: Easing) => Easing;
171
```
172
173
**Usage Examples:**
174
175
```typescript
176
import {
177
easeIn,
178
mirrorEasing,
179
reverseEasing,
180
createExpoIn,
181
createBackIn,
182
createAnticipate
183
} from "popmotion";
184
185
// Mirror easing for symmetrical motion
186
const mirroredEase = mirrorEasing(easeIn);
187
188
animate({
189
from: 0,
190
to: 100,
191
duration: 2000,
192
ease: mirroredEase, // Ease in for first half, ease out for second half
193
onUpdate: (value) => element.style.left = value + "px"
194
});
195
196
// Reversed easing - converts easeIn to easeOut
197
const reversedEase = reverseEasing(easeIn); // Equivalent to easeOut
198
199
animate({
200
from: 0,
201
to: 100,
202
duration: 1000,
203
ease: reversedEase, // Same curve as easeOut
204
onUpdate: (value) => element.style.opacity = value / 100
205
});
206
207
// Custom exponential easing with different powers
208
const quadratic = createExpoIn(2); // p^2 - gentle curve
209
const cubic = createExpoIn(3); // p^3 - moderate curve
210
const quartic = createExpoIn(4); // p^4 - dramatic curve
211
212
animate({
213
from: 0,
214
to: 100,
215
duration: 1000,
216
ease: quartic, // Very dramatic ease-in
217
onUpdate: (value) => element.style.transform = `scale(${1 + value / 100})`
218
});
219
220
// Custom back easing with different overshoot amounts
221
const subtleBack = createBackIn(2); // Gentle pullback
222
const normalBack = createBackIn(3); // Standard pullback
223
const strongBack = createBackIn(4); // Strong pullback
224
225
animate({
226
from: 0,
227
to: 100,
228
duration: 800,
229
ease: strongBack, // Strong overshoot effect
230
onUpdate: (value) => element.style.left = value + "px"
231
});
232
233
// Custom anticipate easing for UI interactions
234
const subtleAnticipate = createAnticipate(2);
235
const strongAnticipate = createAnticipate(4);
236
237
// Perfect for button hover effects
238
button.addEventListener('mouseenter', () => {
239
animate({
240
from: 1,
241
to: 1.1,
242
duration: 200,
243
ease: subtleAnticipate, // Subtle pullback then forward
244
onUpdate: (scale) => button.style.transform = `scale(${scale})`
245
});
246
});
247
248
// Combining utilities for complex effects
249
const complexEase = mirrorEasing(createExpoIn(3));
250
251
animate({
252
from: 1,
253
to: 0,
254
duration: 1500,
255
ease: complexEase, // Exponential ease-in-out with power 3
256
onUpdate: (value) => element.style.opacity = value
257
});
258
259
// Creating custom modifier chains
260
const customModifier = (easing: Easing) =>
261
mirrorEasing(reverseEasing(easing));
262
263
const uniqueEase = customModifier(createBackIn(2));
264
```
265
266
## Easing Function Guidelines
267
268
### When to Use Each Type
269
270
- **Linear**: Progress bars, loading animations
271
- **EaseOut**: UI interactions, button presses (feels responsive)
272
- **EaseIn**: Exit animations, fade outs
273
- **EaseInOut**: General purpose, smooth animations
274
- **CircIn/Out**: Smooth, natural motion
275
- **BackIn/Out**: Playful, bouncy UI elements
276
- **BounceOut**: Fun interactions, success states
277
- **Anticipate**: Button hover states, micro-interactions
278
279
### Performance Considerations
280
281
- Pre-defined easing functions are optimized
282
- Custom cubic Bezier curves have minimal overhead
283
- Complex easing utilities may have slight performance impact
284
- Cache easing functions when used repeatedly
285
286
### Easing Composition
287
288
```typescript
289
// Combine multiple easing functions
290
const complexEase = (t: number) => {
291
if (t < 0.5) {
292
return easeIn(t * 2) / 2;
293
} else {
294
return (easeOut((t - 0.5) * 2) + 1) / 2;
295
}
296
};
297
298
// Use with animations
299
animate({
300
from: 0,
301
to: 100,
302
duration: 1000,
303
ease: complexEase,
304
onUpdate: (value) => console.log(value)
305
});
306
```