mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-12 15:20:13 +00:00
feat(lint): flag text-reflow props in gsap_non_transform_motion
Extend the rule beyond positional layout props to the text-reflow props letterSpacing / wordSpacing / fontSize. Animating them reflows text and snaps glyph positions to the pixel grid, so a slow ease-out tail micro-stutters exactly like left/top — measured on a real composition, a slow letterSpacing "settle" rendered 19/30 unique frames vs 30/30 for the transform-driven motion in the same piece. They have no transform replacement (fix: settle via scale or hold the value), and the snap happens during browser layout, upstream of the canvas raster, so they are never html-in-canvas-exempt. width/height stay excluded (legit animated uses — progress bars, reveals). Restructure the finding's message/fixHint to compose per category (positional -> x/y; reflow -> scale/hold; roundProps -> remove) instead of a two-branch ternary. Skill guidance (gsap-transforms-and-perf.md) broadened: "layout property" includes reflow; letterSpacing/fontSize named as the settle-trap. Migrate the one surfaced positive: registry/components/vignette/demo.html title settle letterSpacing -> a subtle scale settle (render-verified 20/20 unique frames, smooth). Blast radius across the registry was this one comp, zero false positives. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
58f7dc1c72
commit
082280e8de
@@ -59,10 +59,12 @@ Animate any custom property. Works for color, length, number — anything CSS wi
|
||||
|
||||
### Animate transforms, not layout properties
|
||||
|
||||
Animate `x`, `y`, `scale`, `rotation`, `opacity`. Never animate `left`, `right`, `top`, `bottom`, `width`, `height`, `margin*` — and never `roundProps`.
|
||||
Animate `x`, `y`, `scale`, `rotation`, `opacity`. Never animate `left`, `right`, `top`, `bottom`, `width`, `height`, `margin*`, the text-reflow props `letterSpacing` / `wordSpacing` / `fontSize` — and never `roundProps`.
|
||||
|
||||
This is a **render-correctness** rule in HyperFrames, not just a GPU-performance nicety. The renderer seeks frame-by-frame and screenshots each frame, and the browser compositor snaps layout properties to whole device pixels. On a fast tween the per-frame step is several pixels, so the snap is invisible; on a slow tween or a long ease-out tail the value moves less than a pixel per frame — it holds the same pixel for several frames, then jumps a whole one. The result is motion that looks smooth when fast but visibly stutters when slow. Transforms interpolate sub-pixel and stay smooth at any speed. `roundProps` forces the same integer snap onto a transform — don't use it.
|
||||
|
||||
"Layout property" is broader than position: anything that triggers **reflow** snaps the same way. `letterSpacing` / `fontSize` are the common trap — a slow "settle" that crawls letter-spacing or font-size by a fraction of a pixel per frame dwells on a handful of discrete glyph layouts (visible micro-stutter). For a text settle, animate `scale` (or hold the final value) instead. Unlike positional props, reflow props snap during browser **layout** — upstream of the canvas raster — so they stutter even in html-in-canvas, and the exception below does **not** apply to them.
|
||||
|
||||
**Convert a position animation to a transform** by leaving the element at its resting `left`/`top` in CSS and animating the _offset_ with `x`/`y`:
|
||||
|
||||
```javascript
|
||||
|
||||
Reference in New Issue
Block a user