fix(lint): rotation_pivot_drift — off-pivot rotation check (ring/group scope; draft)#2748
Draft
xuanruli wants to merge 4 commits into
Draft
fix(lint): rotation_pivot_drift — off-pivot rotation check (ring/group scope; draft)#2748xuanruli wants to merge 4 commits into
xuanruli wants to merge 4 commits into
Conversation
Catches a rotating element that should spin in place but pivots about the wrong point (e.g. a wheel whose spokes use a hardcoded/incorrect transformOrigin so they swing off-center while every existing check still passes). Cross-sample detection: __hyperframesRotationSample() reports each transformed element's bbox center + decoded rotation angle per layout sample; the driver accumulates them and detectRotationPivotDrift() flags any element that (a) is actually spinning (angle spread > 20deg across >=3 samples), (b) is size-stable (bbox width ratio <= 1.6, excluding scale/entrance growth), and (c) whose bbox center drifts > max(10% of its size, 2% of the min viewport dim). Emits a warning; exempt via data-layout-allow-orbit. Not persistence-tiered, so the warning is preserved (not demoted to info). Validated: fires on an off-transformOrigin spoked wheel (109px drift), clean on non-spinning compositions and on a correctly-centered spinner (drift 0). tsc/oxlint clean, 112/112 existing tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…pivot_drift Review fixes for the size-stability false positive and Fallow CRAP score. - isRotationSizeStable now bounds the bbox ratio in BOTH width and height. The width-only guard let a top-anchored height-scaling element (fixed width, growing height) through: its AABB center moves on its own, so it emitted rotation_pivot_drift and recommended a destructive pivot rewrite. - Factor the guard chain into named single-decision predicates (hasEnoughRotationSamples / isActuallySpinning / isRotationSizeStable / isSizableRotation) so detectRotationPivotDrift reads as a candidate filter + drift test. Drops the CRAP score (complexity + coverage). - Export detectRotationPivotDrift and add direct positive/negative coverage for all five filter stages, including the height-scaling regression. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Run oxfmt on checkPipeline.ts (fixes the red Preflight format:check; oxlint was already clean). - Soften message/fixHint to phrase the finding as the symptom (bbox-center drift, "check transformOrigin/svgOrigin") rather than prescribing a specific authoring cause the DOM sample can't confirm. - Move the detector doc-comment above detectRotationPivotDrift and document the cross-seek selector-stability invariant (nth-of-type fallback can mis-group a classless rotating element). - Add wrap-around angle-spread tests: a ±180° boundary wobble is not spinning; a real spin crossing the seam still fires. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
An 80px absolute floor on the pivot-drift threshold. Below this a "drift" is subpixel/AABB noise on small elements, not an off-pivot bug; a geometry-fuzz eval across 81 diagrams measured every real off-pivot case at >200px while a 30px status-chip fired spuriously. Floor drops the noise with zero true-positive loss. Tests bumped to a 100px synthetic drift to stay above the floor. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds
rotation_pivot_drift, a layout-audit finding for elements that rotate about the wrong pivot — thecommon bug where GSAP
rotation/scaleis applied to an SVG element withoutsvgOrigin, so the pivotsilently resolves to the SVG view-box origin
(0,0)instead of the intended center and the figure swingsoff-center (often off-canvas). Fix hint points at
svgOrigin.Evidence (geometry-fuzz eval, 81 generated diagrams)
I stress-tested this against 81 freshly-generated animated diagrams (wheels/orbits/gauges/graphs), rendered
each, and pixel-measured the actual rotation pivot (circle-fit of the bbox-center trajectory) for every fire.
What it catches (real, confirmed): ring/group off-pivot — 6 samples drifting 700–1800px off their true
center (concentric HUD rings, radar sweeps, energy-pulse groups). All measured off-canvas or grossly
off-center. This class is complementary to a VLM judge, which under-reports fast/faint rotations.
Hardening in this branch: an 80px absolute drift floor (
ROTATION_DRIFT_ABS_FLOOR_PX) — every realoff-pivot case measured >200px, while a 30px status-chip fired spuriously; the floor drops that noise with
zero true-positive loss. Severity stays
warning(never auto-fix).Known limitations (why this is a draft — needs a decision)
Two reasons, both structural: (a)
isRotationSizeStableexcludes elements whose bbox swings >1.6× (a thinarm always does); (b) the core invariant "bbox center stays fixed" cannot discriminate a needle pivot — a
correctly-pivoted needle's bbox center also orbits the hub. Detecting needle pivots needs a different
invariant (compare the element's effective applied pivot against its authored
transformOrigin/hub), whichis a larger change. Decision needed: ship this as a ring/group-scoped check now, or hold for needle
coverage.
satellites/cards orbiting a hub). These must carry
data-layout-allow-orbit(already honored by thesampler). Keep severity at
warninguntil the generator reliably emits that opt-out. A follow-up shouldgate the browser sampler to stable-id selectors (a class-only selector matching N siblings aliases the
drift measurement).
Tests
checkPipeline.rotationPivotDrift.test.ts— 13 cases (fires on drift past threshold incl. the new floor;size-stability, small-angle, tiny-area, ±180° wrap negatives). Green.
🤖 Generated with Claude Code