Skip to content

Fix/edge dash animation loop - #76

Open
Ken-vdE wants to merge 2 commits into
Vrun-design:mainfrom
Ken-vdE:fix/edge-dash-animation-loop
Open

Fix/edge dash animation loop#76
Ken-vdE wants to merge 2 commits into
Vrun-design:mainfrom
Ken-vdE:fix/edge-dash-animation-loop

Conversation

@Ken-vdE

@Ken-vdE Ken-vdE commented Aug 24, 2026

Copy link
Copy Markdown

Animated edges snapped their dash pattern backwards every cycle because React
Flow's built-in dashdraw always travels 10 units, regardless of the dash
pattern 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

Ken van der Eerden 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
Ken-vdE force-pushed the fix/edge-dash-animation-loop branch from 592b9e8 to 5124b8f Compare August 26, 2026 07:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant