feat(animation): letter_spacing and draw_start become keyframe properties - #404
Merged
Merged
Conversation
…ties Both were blocked on the same thing: a new field on `AnimatedProperties`, in a file another workstream owned while #363/#380 and #377 were in flight. Neither agent reached across the boundary, and one of them explicitly refused to add `letter_spacing` to `KNOWN_MOTION_PROPERTIES` on its own — that alone would have made it validate and stay inert, which is the exact defect #363 was about. **`letter_spacing`.** The intrinsic measurement keeps the static `style.letter-spacing`, so animating it does not re-run layout — the same policy every other layout property follows. The consequence is real and documented rather than hidden: a text whose spacing opens overflows its box. Two mechanisms now share a name. A `timeline` changing `letter-spacing` snaps, and the validator warns; a `keyframes` track on `letter_spacing` interpolates. Different subsystems, deliberately different behaviour, said plainly in the rule file. **`draw_start`.** `draw_progress` advances the head of a stroke; this advances its tail. Together they are a window travelling along the path — a line that runs rather than one that grows. On its own it erases the beginning of a finished stroke. `line` and `svg` both trim through `PathMeasure::get_segment`, the primitive #403 added, rather than a dash effect. That is what keeps a zero-length dash with a round cap from painting the stray dot #376 had to remove. `shape` keeps its own component-level `draw_start` from #403: it carries `path_morph` too, and the two belong together. Five tests. Three fail without the wiring — `tight=48px, loose=48px` for spacing, and a painted first half for the trim. Two assert equality and pass both ways on purpose: an absent animated value must leave the declared one alone, which is why the field defaults to NaN rather than zero. One probe stops six pixels short of the cut on purpose, with the reason in the assertion: a round cap extends half the stroke width back past the trim, which is the cap working, not the trim failing. Closes #380 Closes #377
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.
Closes #380. Closes #377. Refs #388.
Both halves were blocked on the same thing — a new field on
AnimatedProperties, in a file another workstream owned while #363/#380 and #377 were in flight.One of those agents explicitly refused to work around it, and was right to: adding
letter_spacingtoKNOWN_MOTION_PROPERTIESalone would have made it validate and stay completely inert, which is the exact defect #363 was fixing. It stopped and reported instead. This PR is the other side of that boundary, now that the file is free.letter_spacing{ "property": "letter_spacing", "keyframes": [{ "time": 0, "value": 0 }, { "time": 0.8, "value": 18 }], "easing": "ease_out" }The intrinsic measurement keeps the static
style.letter-spacing, so animating it does not re-run layout — the policy every layout property follows here. The consequence is real, and the rule file leads with it rather than hiding it: a text whose spacing opens overflows its box. Size the box for the final value, or accept the overflow knowingly.Two mechanisms now share a name, which is worth knowing before it surprises someone: a
timelinechangingletter-spacingsnaps and the validator warns about it; akeyframestrack onletter_spacinginterpolates. Different subsystems, deliberately different behaviour.draw_startdraw_progressadvances the head of a stroke;draw_startadvances its tail. Together they are a window travelling along the path — a line that runs rather than one that grows. On its own it erases the beginning of a finished stroke.lineandsvgboth trim throughPathMeasure::get_segment— the primitive #403 added — rather than a dash effect. That is what keeps a zero-length dash with a round cap from painting the stray dot #376 had to remove; reusing the dash trick here would have reintroduced it on a different component.shapekeeps its own component-leveldraw_startfrom #403, because it carriespath_morphtoo and the two belong together. The rule file says which is which.Verification
Five tests. Three fail without the wiring:
Two assert equality and pass both ways on purpose — an absent animated value must leave the declared one alone, which is why the field defaults to
NaNrather than0.One probe deliberately stops six pixels short of the cut, with the reason written into the assertion: a round cap extends half the 8px stroke back past the trim. That is the cap working, not the trim failing — and it was worth writing down rather than quietly widening the tolerance.
cargo fmt --all --check,cargo clippy --workspace --all-targets -- -D warnings,cargo test --workspace(1718) all clean.Written comment-free, per the codebase-wide rule from #345.