Fix/edge dash animation loop - #76
Open
Ken-vdE wants to merge 2 commits into
Open
Conversation
added 2 commits
August 24, 2026 13:39
An animated edge snapped its dash pattern backwards on every cycle. Very visible on the dash-dot preset, where the eye tracks individual dots. A `stroke-dashoffset` loop only joins up when the distance it travels per cycle equals the dash pattern's period. React Flow animates every path in an `.animated` edge with its own `dashdraw`, which travels a fixed 10 — correct for its own `stroke-dasharray: 5`, wrong for any pattern the app sets inline. Measured on a dash-dot edge: period 18, travelling 10, so each cycle boundary jumped back by exactly 8. Every preset was affected: dashed `8 4` period 12 jumped 4 dotted `2 4` period 6 jumped 4 dashdot `8 4 2 4` period 18 jumped 8 Replace it with a period-aware animation. `getDashPatternPeriod` derives the period (handling SVG's odd-length doubling, and declining `%`/`em` patterns it cannot resolve without the path length), `CustomEdgeWrapper` publishes it on the edge path as `--flow-edge-dash-period`, and the keyframes travel that far. `.react-flow__edge.animated .react-flow__edge-path` carries three classes, so it outranks React Flow's `.react-flow__edge.animated path` without `!important`. Each consumer declares the default for its own pattern in CSS. The drag connection line had the same mismatch: a `6 8` pattern, period 14, animated over 20. Also stop React Flow's rule from dashing the invisible hover hit target, which left hover on an animated edge working only on the dashes.
Two of the previous commit's claims did not hold. The hover hit target was still dashed and still animating. `strokeDasharray` in JSX renders as a presentation attribute, which ranks below every author stylesheet rule, so React Flow's `.react-flow__edge.animated path` kept winning — confirmed in the browser: the attribute was present while the computed value stayed `5px` with `dashdraw` running. Overriding inline (which does beat a non-important rule) now yields `stroke-dasharray: none` and `animation: none`. The animated overlay kept the snap-back. It only renders inside an `.animated` edge, where React Flow's `.react-flow__edge.animated path` (0,2,1) outranks `.flow-edge-animated-overlay` (0,1,0) and hijacked it back to `dashdraw`'s fixed travel of 10 against a default period of 16. Added the three-class override, so it runs `flow-edge-dash` and consumes the period the component publishes. Also: - Extract `withDashPeriodVar` so the visible edge path's period publication is covered by unit tests. Nothing pinned it before: deleting the call from `CustomEdgeWrapper` re-broke every preset with a green suite. - Assert the connection line's keyframes actually read the custom property, not just that the component publishes it. - Reject numbers CSS itself rejects. `8.` matched the old pattern, so an invalid declaration the browser drops could still publish a period, which is the silent mismatch this helper exists to prevent. - Drop the `?? 0` on the connection line's period. A custom property of 0 satisfies `var()`, so the keyframes' fallback would never fire and the animation would freeze instead.
Ken-vdE
force-pushed
the
fix/edge-dash-animation-loop
branch
from
August 26, 2026 07:41
592b9e8 to
5124b8f
Compare
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.
Animated edges snapped their dash pattern backwards every cycle because React
Flow's built-in
dashdrawalways travels 10 units, regardless of the dashpattern the app sets. The travelled distance is now derived from the pattern's
actual period, so every preset loops seamlessly. Also fixes the same mismatch on
the drag connection line, and stops the invisible hover hit target being dashed
and animated.
Before
https://github.com/user-attachments/assets/6f43c360-d86c-4baf-99fd-95ed8c146aad
After
https://github.com/user-attachments/assets/dbf08462-eb1f-4e09-b93f-039953077bef