Commit f2edfe8
committed
feat(Timeline): e2e visual tests + restart boundary alignment fix
Two related workstreams on the feat/timeline branch:
### 1. E2E visual regression testing (examples 03, 20, 21, 22)
Added Playwright-based e2e tests with visual snapshot regression for the
timeline and graphs examples. Uses a deterministic requestAnimationFrame hijack
(__tickFrame/__advanceTo) so timeline tests produce identical output every
run — no real-time frame variance.
- e2e/graphs.spec.ts — snapshot of the 03_graphs easing curve thumbnails
(waits for fonts via document.fonts.ready to prevent cross-platform diff).
- e2e/timeline.spec.ts — 3 test suites:
- 20_timeline — sequential, parallel, and label-based animation (16 frames
at 200ms steps, 0–3000ms).
- 21_timeline_slider — slider-driven scrubbing forward (17 frames at 400ms
steps, 0–6400ms) and backward (17 frames, 6400→0ms), without rAF hijack
(no animation loop — purely slider input events).
- 22_timeline_repeat — repeat×3, yoyo, and yoyo+repeat×2 animation (16
frames at 200ms steps, 0–3000ms).
- e2e/playwright.config.ts — serves the repo via npx serve on port 3333.
- 62 baseline snapshots (.webp, Chrome on macOS).
Example fixes caught during testing:
- examples/20_timeline.html — fixed the "parallel" example (target2) so it
actually demonstrates parallelism (y 0→200→100 instead of 0→200→0 on the
chained third tween); wrapped the label-based inner timeline in an outer
timeline for correct coordinated playback.
- examples/22_timeline_repeat.html — switched from X to Y axis translation
for clearer visual distinction between boxes; added CSS color comments.
- e2e/graphs.spec.ts — switched waitUntil to networkidle and added
document.fonts.ready to prevent font-loading snapshot diffs.
### 2. Timeline restart boundary alignment (fixes sub-frame sync drift)
Problem: When a short yoyo timeline (1200ms cycle) restarted via
timeline.start(time), _startTime was set to the wall-clock time
(~1200.024ms — one frame overshoot). Children subsequently saw
elapsedTime = t - 1200.024, a 0.024ms offset. A longer yoyo+repeat×2
timeline (2400ms cycle) avoided this because its clone at offset 1200 started
at the exact offset with no wall-clock overshoot. The offset propagated
through Quadratic.InOut easing to a ~0.016px value difference mid-cycle,
growing with variable frame timing.
Root cause: Timeline.start(time) unconditionally set _startTime = time.
Fix (3 changes in src/Timeline.ts):
- New field _nextStartTime: number | undefined — stores the ideal
_startTime + _duration boundary when the timeline finishes.
- In update(), before returning false, store the boundary.
- In start(), use the stored boundary when time >= _nextStartTime
(forward restart — snaps to exact boundary); fall through to time when
time < _nextStartTime (deliberate scrub-back) or _nextStartTime is
undefined (fresh start). Resets _lastUpdateTime = -Infinity to prevent
false scrub-back detection on restart.
Backward compatibility: All 1063 unit assertions pass. Scrub-back test
updated — children not yet reached in forward play now preserve their stale
forward-play values rather than eagerly snapping to start values.
Documentation: dev-docs/02-timeline-restart-boundary-alignment.md —
full write-up with concrete frame data showing the before/after diff.1 parent ce21da7 commit f2edfe8
85 files changed
Lines changed: 476 additions & 80 deletions
File tree
- dev-docs
- dist
- e2e
- timeline.spec.ts-snapshots
- examples
- src
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | | - | |
| 17 | + | |
18 | 18 | | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
578 | 578 | | |
579 | 579 | | |
580 | 580 | | |
581 | | - | |
582 | 581 | | |
583 | | - | |
584 | 582 | | |
585 | 583 | | |
586 | 584 | | |
| |||
1043 | 1041 | | |
1044 | 1042 | | |
1045 | 1043 | | |
| 1044 | + | |
1046 | 1045 | | |
1047 | 1046 | | |
1048 | 1047 | | |
| |||
1423 | 1422 | | |
1424 | 1423 | | |
1425 | 1424 | | |
1426 | | - | |
| 1425 | + | |
| 1426 | + | |
| 1427 | + | |
| 1428 | + | |
| 1429 | + | |
| 1430 | + | |
| 1431 | + | |
1427 | 1432 | | |
1428 | 1433 | | |
1429 | 1434 | | |
| |||
1507 | 1512 | | |
1508 | 1513 | | |
1509 | 1514 | | |
| 1515 | + | |
| 1516 | + | |
| 1517 | + | |
| 1518 | + | |
| 1519 | + | |
| 1520 | + | |
1510 | 1521 | | |
1511 | 1522 | | |
1512 | 1523 | | |
1513 | 1524 | | |
1514 | | - | |
1515 | | - | |
1516 | | - | |
| 1525 | + | |
| 1526 | + | |
1517 | 1527 | | |
1518 | 1528 | | |
1519 | 1529 | | |
1520 | 1530 | | |
1521 | 1531 | | |
1522 | 1532 | | |
1523 | | - | |
1524 | | - | |
1525 | | - | |
| 1533 | + | |
| 1534 | + | |
| 1535 | + | |
| 1536 | + | |
| 1537 | + | |
| 1538 | + | |
| 1539 | + | |
| 1540 | + | |
| 1541 | + | |
| 1542 | + | |
| 1543 | + | |
| 1544 | + | |
| 1545 | + | |
| 1546 | + | |
| 1547 | + | |
| 1548 | + | |
1526 | 1549 | | |
1527 | | - | |
1528 | | - | |
1529 | | - | |
1530 | 1550 | | |
1531 | 1551 | | |
1532 | 1552 | | |
| |||
1539 | 1559 | | |
1540 | 1560 | | |
1541 | 1561 | | |
| 1562 | + | |
| 1563 | + | |
| 1564 | + | |
| 1565 | + | |
1542 | 1566 | | |
1543 | 1567 | | |
1544 | 1568 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
580 | 580 | | |
581 | 581 | | |
582 | 582 | | |
583 | | - | |
584 | 583 | | |
585 | | - | |
586 | 584 | | |
587 | 585 | | |
588 | 586 | | |
| |||
1045 | 1043 | | |
1046 | 1044 | | |
1047 | 1045 | | |
| 1046 | + | |
1048 | 1047 | | |
1049 | 1048 | | |
1050 | 1049 | | |
| |||
1425 | 1424 | | |
1426 | 1425 | | |
1427 | 1426 | | |
1428 | | - | |
| 1427 | + | |
| 1428 | + | |
| 1429 | + | |
| 1430 | + | |
| 1431 | + | |
| 1432 | + | |
| 1433 | + | |
1429 | 1434 | | |
1430 | 1435 | | |
1431 | 1436 | | |
| |||
1509 | 1514 | | |
1510 | 1515 | | |
1511 | 1516 | | |
| 1517 | + | |
| 1518 | + | |
| 1519 | + | |
| 1520 | + | |
| 1521 | + | |
| 1522 | + | |
1512 | 1523 | | |
1513 | 1524 | | |
1514 | 1525 | | |
1515 | 1526 | | |
1516 | | - | |
1517 | | - | |
1518 | | - | |
| 1527 | + | |
| 1528 | + | |
1519 | 1529 | | |
1520 | 1530 | | |
1521 | 1531 | | |
1522 | 1532 | | |
1523 | 1533 | | |
1524 | 1534 | | |
1525 | | - | |
1526 | | - | |
1527 | | - | |
| 1535 | + | |
| 1536 | + | |
| 1537 | + | |
| 1538 | + | |
| 1539 | + | |
| 1540 | + | |
| 1541 | + | |
| 1542 | + | |
| 1543 | + | |
| 1544 | + | |
| 1545 | + | |
| 1546 | + | |
| 1547 | + | |
| 1548 | + | |
| 1549 | + | |
| 1550 | + | |
1528 | 1551 | | |
1529 | | - | |
1530 | | - | |
1531 | | - | |
1532 | 1552 | | |
1533 | 1553 | | |
1534 | 1554 | | |
| |||
1541 | 1561 | | |
1542 | 1562 | | |
1543 | 1563 | | |
| 1564 | + | |
| 1565 | + | |
| 1566 | + | |
| 1567 | + | |
1544 | 1568 | | |
1545 | 1569 | | |
1546 | 1570 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
303 | 303 | | |
304 | 304 | | |
305 | 305 | | |
| 306 | + | |
| 307 | + | |
306 | 308 | | |
307 | 309 | | |
308 | 310 | | |
| |||
0 commit comments