Automattic / Automattic/data-liberation-agent
Image geometry is measured mid-flight on scroll-driven animations
- Dominant language
- TypeScript
- Stars
- 31
- Forks
- 3
- Avg merge
- 10h 14m
- Merged PRs (30d)
- 81
Description
The image-geometry check measures a scroll-driven animation while it is running, and compares it against a source element that is standing still. The result is a failure that reports a size difference where there is no fidelity difference.
This was invisible until #138, because the animations it depends on were not running at all.
## What happens
`compare` on a fresh liberation of the four-route Wix site, after #138:
```
/ 1600px FAIL: image geometry differs for 1 matched image(s):
a9ff3b_66d752921e1b47eeabac83d8330cedc4 source 64x62 at (852,643), copy 55x53 at (857,647)
/ 1728px FAIL: image geometry differs for 1 matched image(s):
a9ff3b_66d752921e1b47eeabac83d8330cedc4 source 64x62 at (916,643), copy 55x53 at (921,647)
```
The image sits inside `#Clprt1-d7x`, which carries a restored two-layer entrance:
```css
#Clprt1-d7x{animation:motion-fadeIn 1200ms 1ms linear backwards 1, motion-expandIn 1200ms 1ms cubic-bezier(0.645, 0.045, 0.355, 1) backwards 1;--motion-scale:0;animation-play-state:running;animation-timeline:view();animation-range:entry 0% cover 40%}
```
`motion-expandIn` scales from `--motion-scale: 0`, and `animation-timeline: view()` with `animation-range: entry 0% cover 40%` ties progress to scroll position rather than to elapsed time. At the position the observer samples, the element is partway through: 55×53 against a final 64×62, about 86%.
The live source has the same animation, but the builder's runtime parks it `paused` until the element scrolls in, so at the same viewport the source element is at rest at its final size. The check therefore compares a moving element against a stationary one and reports the difference as a defect.
## Why it is a measurement problem, not a fidelity problem
The copy is more faithful after #138, not less: it reproduces 29 of the source's 29 entrance animations, where it previously reproduced 1. The geometry check began failing precisely *because* fidelity improved.
Waiting longer does not settle it. A scroll-timeline animation's progress is a function of scroll position, not time, so it is stable at whatever value the current scroll implies and will sit there indefinitely.
## Options
1. **Sample geometry at a settled scroll position.** The observer already performs a controlled scroll for the motion check. Reading geometry after driving each in-view scroll-timeline animation to its end — or at `cover 100%` — compares end states on both sides.
2. **Let a check declare that it needs motion held still,** and have the observer neutralise scroll-driven animations (`animation-play-state: paused` at 100% progress, or `animation-timeline: auto` with the animation finished) for geometry and typography while leaving them alone for the motion check.
3. **Exclude elements with an active non-document timeline** from geometry comparison, and rely on the motion check for them. Cheapest, but it silently stops measuring geometry on exactly the elements a builder animates, which on a Wix site is most of the page.
Option 2 fits the existing `checks.ts` registry: a check already declares its own evidence directory, and declaring its measurement preconditions is the same kind of statement.
## Acceptance
- A liberated page whose entrance animations match the source exactly does not fail image geometry because of those animations.
- The motion check still sees animations running, so #138's regression coverage does not weaken.
- A genuine geometry difference on an animated element is still reported.
## Context
Related: #137 / #138 restored the animations that expose this. #133 covers the wider point that the comparison's thresholds and preconditions are scattered rather than declared.
---
*AI assistance: found and written by Claude via Claude Code while verifying #138 end-to-end against a live site. The attribution to in-flight scroll-driven animation was confirmed by locating the failing image inside the specific element whose animation that PR restores, and by reading the emitted rule's `animation-range`, rather than inferred from the failure text. Chris Huber orchestrated and reviewed the work and is responsible for what is filed here.*
Contributor guide
Research direction
Start in the checks.ts registry and the observer's controlled-scroll code; trace how geometry and motion checks obtain their measurements. Compare the listed measurement-precondition approaches while preserving running animations for the motion check. Done means the four-route Wix comparison no longer reports animation-only geometry failures, still detects genuine differences, and keeps motion regression coverage.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- css, typescript
- Domain
- frontend, testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100