@ue-too/animate 0.14.1 → 0.16.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/README.md +169 -113
- package/animatable-attribute.d.ts +1 -1
- package/composite-animation.d.ts +1 -1
- package/index.d.ts +2 -2
- package/index.js +909 -2
- package/index.js.map +4 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -24,11 +24,13 @@ Keyframe-based animation library for TypeScript canvas applications.
|
|
|
24
24
|
## Installation
|
|
25
25
|
|
|
26
26
|
Using Bun:
|
|
27
|
+
|
|
27
28
|
```bash
|
|
28
29
|
bun add @ue-too/animate
|
|
29
30
|
```
|
|
30
31
|
|
|
31
32
|
Using npm:
|
|
33
|
+
|
|
32
34
|
```bash
|
|
33
35
|
npm install @ue-too/animate
|
|
34
36
|
```
|
|
@@ -44,13 +46,15 @@ let opacity = 0;
|
|
|
44
46
|
|
|
45
47
|
// Create fade-in animation
|
|
46
48
|
const fadeIn = new Animation(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
[
|
|
50
|
+
{ percentage: 0, value: 0 }, // Start at 0% with value 0
|
|
51
|
+
{ percentage: 1, value: 1 }, // End at 100% with value 1
|
|
52
|
+
],
|
|
53
|
+
value => {
|
|
54
|
+
opacity = value;
|
|
55
|
+
}, // Apply function updates the value
|
|
56
|
+
numberHelperFunctions, // Number interpolation helper
|
|
57
|
+
1000 // Duration in milliseconds
|
|
54
58
|
);
|
|
55
59
|
|
|
56
60
|
// Start the animation
|
|
@@ -58,9 +62,9 @@ fadeIn.start();
|
|
|
58
62
|
|
|
59
63
|
// In your animation loop (e.g., requestAnimationFrame)
|
|
60
64
|
function gameLoop(deltaTime: number) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
65
|
+
fadeIn.animate(deltaTime); // Update animation with elapsed time
|
|
66
|
+
console.log('Opacity:', opacity);
|
|
67
|
+
requestAnimationFrame(() => gameLoop(16)); // ~60 FPS
|
|
64
68
|
}
|
|
65
69
|
```
|
|
66
70
|
|
|
@@ -72,18 +76,19 @@ Keyframes define values at specific points in an animation's progress:
|
|
|
72
76
|
|
|
73
77
|
```typescript
|
|
74
78
|
type Keyframe<T> = {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
79
|
+
percentage: number; // 0.0 (start) to 1.0 (end)
|
|
80
|
+
value: T; // Value at this point
|
|
81
|
+
easingFn?: (t: number) => number; // Optional easing for this segment
|
|
78
82
|
};
|
|
79
83
|
```
|
|
80
84
|
|
|
81
85
|
**Example with easing:**
|
|
86
|
+
|
|
82
87
|
```typescript
|
|
83
88
|
const keyframes = [
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
89
|
+
{ percentage: 0, value: 0 },
|
|
90
|
+
{ percentage: 0.5, value: 100, easingFn: t => t * t }, // Ease-in quadratic
|
|
91
|
+
{ percentage: 1, value: 200 },
|
|
87
92
|
];
|
|
88
93
|
```
|
|
89
94
|
|
|
@@ -93,7 +98,7 @@ Helpers provide type-specific interpolation logic:
|
|
|
93
98
|
|
|
94
99
|
```typescript
|
|
95
100
|
interface AnimatableAttributeHelper<T> {
|
|
96
|
-
|
|
101
|
+
lerp(ratio: number, start: Keyframe<T>, end: Keyframe<T>): T;
|
|
97
102
|
}
|
|
98
103
|
```
|
|
99
104
|
|
|
@@ -113,6 +118,7 @@ const animation = new Animation<T>(
|
|
|
113
118
|
```
|
|
114
119
|
|
|
115
120
|
**Methods:**
|
|
121
|
+
|
|
116
122
|
- `start()`: Start the animation
|
|
117
123
|
- `stop()`: Stop and reset the animation
|
|
118
124
|
- `pause()`: Pause at current position
|
|
@@ -124,6 +130,7 @@ const animation = new Animation<T>(
|
|
|
124
130
|
- `tearDown()`: Clean up animation state
|
|
125
131
|
|
|
126
132
|
**Properties:**
|
|
133
|
+
|
|
127
134
|
- `loops: boolean`: Whether animation loops
|
|
128
135
|
- `maxLoopCount?: number`: Maximum number of loops (undefined = infinite)
|
|
129
136
|
- `duration: number`: Animation duration in milliseconds
|
|
@@ -146,6 +153,7 @@ const composite = new CompositeAnimation(
|
|
|
146
153
|
```
|
|
147
154
|
|
|
148
155
|
**Methods:**
|
|
156
|
+
|
|
149
157
|
- `addAnimation(name: string, animator: Animator, startTime: number)`: Add animation at specific time
|
|
150
158
|
- `addAnimationAfter(name: string, animator: Animator, after: string)`: Add after another animation
|
|
151
159
|
- `addAnimationBefore(name: string, animator: Animator, before: string)`: Add before another animation
|
|
@@ -164,13 +172,15 @@ import { Animation, numberHelperFunctions } from '@ue-too/animate';
|
|
|
164
172
|
|
|
165
173
|
let scale = 1;
|
|
166
174
|
const scaleAnimation = new Animation(
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
175
|
+
[
|
|
176
|
+
{ percentage: 0, value: 1 },
|
|
177
|
+
{ percentage: 1, value: 2 },
|
|
178
|
+
],
|
|
179
|
+
value => {
|
|
180
|
+
scale = value;
|
|
181
|
+
},
|
|
182
|
+
numberHelperFunctions,
|
|
183
|
+
500
|
|
174
184
|
);
|
|
175
185
|
```
|
|
176
186
|
|
|
@@ -185,13 +195,15 @@ import { Point } from '@ue-too/math';
|
|
|
185
195
|
let position: Point = { x: 0, y: 0 };
|
|
186
196
|
|
|
187
197
|
const moveAnimation = new Animation(
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
198
|
+
[
|
|
199
|
+
{ percentage: 0, value: { x: 0, y: 0 } },
|
|
200
|
+
{ percentage: 1, value: { x: 100, y: 100 } },
|
|
201
|
+
],
|
|
202
|
+
value => {
|
|
203
|
+
position = value;
|
|
204
|
+
},
|
|
205
|
+
pointHelperFunctions,
|
|
206
|
+
1000
|
|
195
207
|
);
|
|
196
208
|
```
|
|
197
209
|
|
|
@@ -200,19 +212,21 @@ const moveAnimation = new Animation(
|
|
|
200
212
|
Interpolate RGB colors:
|
|
201
213
|
|
|
202
214
|
```typescript
|
|
203
|
-
import { Animation,
|
|
215
|
+
import { Animation, RGB, rgbHelperFunctions } from '@ue-too/animate';
|
|
204
216
|
|
|
205
217
|
let color: RGB = { r: 255, g: 0, b: 0 };
|
|
206
218
|
|
|
207
219
|
const colorAnimation = new Animation(
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
220
|
+
[
|
|
221
|
+
{ percentage: 0, value: { r: 255, g: 0, b: 0 } }, // Red
|
|
222
|
+
{ percentage: 0.5, value: { r: 255, g: 255, b: 0 } }, // Yellow
|
|
223
|
+
{ percentage: 1, value: { r: 0, g: 255, b: 0 } }, // Green
|
|
224
|
+
],
|
|
225
|
+
value => {
|
|
226
|
+
color = value;
|
|
227
|
+
},
|
|
228
|
+
rgbHelperFunctions,
|
|
229
|
+
2000
|
|
216
230
|
);
|
|
217
231
|
```
|
|
218
232
|
|
|
@@ -226,13 +240,15 @@ import { Animation, stringHelperFunctions } from '@ue-too/animate';
|
|
|
226
240
|
let state = 'idle';
|
|
227
241
|
|
|
228
242
|
const stateAnimation = new Animation(
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
243
|
+
[
|
|
244
|
+
{ percentage: 0, value: 'idle' },
|
|
245
|
+
{ percentage: 1, value: 'active' },
|
|
246
|
+
],
|
|
247
|
+
value => {
|
|
248
|
+
state = value;
|
|
249
|
+
},
|
|
250
|
+
stringHelperFunctions,
|
|
251
|
+
500
|
|
236
252
|
);
|
|
237
253
|
```
|
|
238
254
|
|
|
@@ -246,15 +262,17 @@ import { Animation, integerHelperFunctions } from '@ue-too/animate';
|
|
|
246
262
|
let frameIndex = 0;
|
|
247
263
|
|
|
248
264
|
const frameAnimation = new Animation(
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
265
|
+
[
|
|
266
|
+
{ percentage: 0, value: 0 },
|
|
267
|
+
{ percentage: 0.33, value: 1 },
|
|
268
|
+
{ percentage: 0.66, value: 2 },
|
|
269
|
+
{ percentage: 1, value: 3 },
|
|
270
|
+
],
|
|
271
|
+
value => {
|
|
272
|
+
frameIndex = value;
|
|
273
|
+
},
|
|
274
|
+
integerHelperFunctions,
|
|
275
|
+
400
|
|
258
276
|
);
|
|
259
277
|
```
|
|
260
278
|
|
|
@@ -268,23 +286,27 @@ import { Animation, numberHelperFunctions } from '@ue-too/animate';
|
|
|
268
286
|
let opacity = 0;
|
|
269
287
|
|
|
270
288
|
const fadeIn = new Animation(
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
289
|
+
[
|
|
290
|
+
{ percentage: 0, value: 0 },
|
|
291
|
+
{ percentage: 1, value: 1, easingFn: t => t * t }, // Ease-in
|
|
292
|
+
],
|
|
293
|
+
value => {
|
|
294
|
+
opacity = value;
|
|
295
|
+
},
|
|
296
|
+
numberHelperFunctions,
|
|
297
|
+
500
|
|
278
298
|
);
|
|
279
299
|
|
|
280
300
|
const fadeOut = new Animation(
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
301
|
+
[
|
|
302
|
+
{ percentage: 0, value: 1 },
|
|
303
|
+
{ percentage: 1, value: 0, easingFn: t => 1 - (1 - t) * (1 - t) }, // Ease-out
|
|
304
|
+
],
|
|
305
|
+
value => {
|
|
306
|
+
opacity = value;
|
|
307
|
+
},
|
|
308
|
+
numberHelperFunctions,
|
|
309
|
+
500
|
|
288
310
|
);
|
|
289
311
|
```
|
|
290
312
|
|
|
@@ -297,14 +319,20 @@ import { Point } from '@ue-too/math';
|
|
|
297
319
|
let spritePosition: Point = { x: 0, y: 0 };
|
|
298
320
|
|
|
299
321
|
const bounce = new Animation(
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
322
|
+
[
|
|
323
|
+
{ percentage: 0, value: { x: 0, y: 0 } },
|
|
324
|
+
{
|
|
325
|
+
percentage: 0.5,
|
|
326
|
+
value: { x: 0, y: -50 },
|
|
327
|
+
easingFn: t => 1 - Math.pow(1 - t, 3),
|
|
328
|
+
}, // Ease-out up
|
|
329
|
+
{ percentage: 1, value: { x: 0, y: 0 }, easingFn: t => t * t * t }, // Ease-in down
|
|
330
|
+
],
|
|
331
|
+
value => {
|
|
332
|
+
spritePosition = value;
|
|
333
|
+
},
|
|
334
|
+
pointHelperFunctions,
|
|
335
|
+
1000
|
|
308
336
|
);
|
|
309
337
|
|
|
310
338
|
bounce.loops = true; // Loop forever
|
|
@@ -313,30 +341,52 @@ bounce.loops = true; // Loop forever
|
|
|
313
341
|
### Sequential Animation Sequence
|
|
314
342
|
|
|
315
343
|
```typescript
|
|
316
|
-
import {
|
|
344
|
+
import {
|
|
345
|
+
Animation,
|
|
346
|
+
CompositeAnimation,
|
|
347
|
+
numberHelperFunctions,
|
|
348
|
+
pointHelperFunctions,
|
|
349
|
+
} from '@ue-too/animate';
|
|
317
350
|
|
|
318
|
-
let x = 0,
|
|
351
|
+
let x = 0,
|
|
352
|
+
y = 0,
|
|
353
|
+
opacity = 0;
|
|
319
354
|
|
|
320
355
|
// Create individual animations
|
|
321
356
|
const fadeIn = new Animation(
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
357
|
+
[
|
|
358
|
+
{ percentage: 0, value: 0 },
|
|
359
|
+
{ percentage: 1, value: 1 },
|
|
360
|
+
],
|
|
361
|
+
value => {
|
|
362
|
+
opacity = value;
|
|
363
|
+
},
|
|
364
|
+
numberHelperFunctions,
|
|
365
|
+
500
|
|
326
366
|
);
|
|
327
367
|
|
|
328
368
|
const slideRight = new Animation(
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
369
|
+
[
|
|
370
|
+
{ percentage: 0, value: 0 },
|
|
371
|
+
{ percentage: 1, value: 100 },
|
|
372
|
+
],
|
|
373
|
+
value => {
|
|
374
|
+
x = value;
|
|
375
|
+
},
|
|
376
|
+
numberHelperFunctions,
|
|
377
|
+
500
|
|
333
378
|
);
|
|
334
379
|
|
|
335
380
|
const slideDown = new Animation(
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
381
|
+
[
|
|
382
|
+
{ percentage: 0, value: 0 },
|
|
383
|
+
{ percentage: 1, value: 50 },
|
|
384
|
+
],
|
|
385
|
+
value => {
|
|
386
|
+
y = value;
|
|
387
|
+
},
|
|
388
|
+
numberHelperFunctions,
|
|
389
|
+
300
|
|
340
390
|
);
|
|
341
391
|
|
|
342
392
|
// Create sequence: fade in, then slide right, then slide down
|
|
@@ -349,9 +399,9 @@ sequence.start();
|
|
|
349
399
|
|
|
350
400
|
// Update in game loop
|
|
351
401
|
function update(deltaTime: number) {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
402
|
+
sequence.animate(deltaTime);
|
|
403
|
+
// Render sprite at (x, y) with opacity
|
|
404
|
+
requestAnimationFrame(() => update(16));
|
|
355
405
|
}
|
|
356
406
|
```
|
|
357
407
|
|
|
@@ -376,12 +426,12 @@ sequence.addAnimationAfter('scale', scaleAnimation, 'fadeIn');
|
|
|
376
426
|
const animation = new Animation(/* ... */);
|
|
377
427
|
|
|
378
428
|
animation.onStart(() => {
|
|
379
|
-
|
|
429
|
+
console.log('Animation started!');
|
|
380
430
|
});
|
|
381
431
|
|
|
382
432
|
animation.onEnd(() => {
|
|
383
|
-
|
|
384
|
-
|
|
433
|
+
console.log('Animation completed!');
|
|
434
|
+
// Trigger next action
|
|
385
435
|
});
|
|
386
436
|
|
|
387
437
|
animation.start();
|
|
@@ -410,20 +460,23 @@ const easeOut = (t: number) => 1 - (1 - t) * (1 - t);
|
|
|
410
460
|
|
|
411
461
|
// Ease-in-out quadratic
|
|
412
462
|
const easeInOut = (t: number) =>
|
|
413
|
-
|
|
463
|
+
t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;
|
|
414
464
|
|
|
415
465
|
// Elastic ease-out
|
|
416
466
|
const elasticOut = (t: number) => {
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
467
|
+
const c4 = (2 * Math.PI) / 3;
|
|
468
|
+
return t === 0
|
|
469
|
+
? 0
|
|
470
|
+
: t === 1
|
|
471
|
+
? 1
|
|
472
|
+
: Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1;
|
|
420
473
|
};
|
|
421
474
|
|
|
422
475
|
// Use in keyframe
|
|
423
476
|
const keyframe = {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
477
|
+
percentage: 1,
|
|
478
|
+
value: 100,
|
|
479
|
+
easingFn: easeInOut,
|
|
427
480
|
};
|
|
428
481
|
```
|
|
429
482
|
|
|
@@ -440,18 +493,20 @@ This package is written in TypeScript with complete type definitions:
|
|
|
440
493
|
type Position = { x: number; y: number };
|
|
441
494
|
|
|
442
495
|
const posAnimation: Animation<Position> = new Animation(
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
496
|
+
[{ percentage: 0, value: { x: 0, y: 0 } }],
|
|
497
|
+
(value: Position) => {
|
|
498
|
+
/* ... */
|
|
499
|
+
},
|
|
500
|
+
pointHelperFunctions,
|
|
501
|
+
1000
|
|
447
502
|
);
|
|
448
503
|
|
|
449
504
|
// Custom helper functions are type-safe
|
|
450
505
|
const myHelper: AnimatableAttributeHelper<number> = {
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
506
|
+
lerp: (ratio, start, end) => {
|
|
507
|
+
// TypeScript knows start.value and end.value are numbers
|
|
508
|
+
return start.value + ratio * (end.value - start.value);
|
|
509
|
+
},
|
|
455
510
|
};
|
|
456
511
|
```
|
|
457
512
|
|
|
@@ -473,6 +528,7 @@ This animation library follows these principles:
|
|
|
473
528
|
- **Memory**: Each animation retains keyframe data and callbacks
|
|
474
529
|
|
|
475
530
|
**Performance Tips:**
|
|
531
|
+
|
|
476
532
|
- Reuse animation instances when possible
|
|
477
533
|
- Use composite animations to group related animations
|
|
478
534
|
- Unsubscribe from callbacks (`onStart`, `onEnd`) when no longer needed
|
package/composite-animation.d.ts
CHANGED
package/index.d.ts
CHANGED
|
@@ -98,5 +98,5 @@
|
|
|
98
98
|
* @see {@link Animation} for single value animations
|
|
99
99
|
* @see {@link CompositeAnimation} for animation sequencing
|
|
100
100
|
*/
|
|
101
|
-
export * from
|
|
102
|
-
export * from
|
|
101
|
+
export * from './animatable-attribute';
|
|
102
|
+
export * from './composite-animation';
|