Automattic / Automattic/data-liberation-agent

Image geometry is measured mid-flight on scroll-driven animations

Open
#139 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.