Skip to content

Commit a988286

Browse files
committed
feat(vanilla): canvas update transitions on the shared transition clock
Keyed data-update transitions now drive the scatter canvas layer from the same rAF loop that tweens the SVG axes, trendline and annotations, so a 4,341-point morph reads as one motion instead of two clocks drifting apart. Points are tweened as a single packed record rather than one per mark: geometry lives in parallel typed arrays lerped inline, written straight into the layer's SoA. No DOM, no per-frame allocation. Enters fade in on the whole-mark `enterAlpha` channel (not `fillOpacity`, which must not drag the stroke down with it, matching SVG's `fill-opacity`); exits become canvas ghosts under the live points; survivors interpolate and retarget from a `snapshot()` on interruption. The snapshot entries stay plain `{type:'point'}` so an interrupted transition retargets correctly across an svg <-> canvas flip. Gate 8 now sizes against `max(prev, next)` rather than `next` alone. Exit ghosts render in the DESTINATION mode, so a 4,341-point canvas chart updating down to 400 SVG points would otherwise mint ~3,941 SVG ghost circles -- the exact jank the cap exists to prevent. Canvas mode gets its own default of 20,000 (`CANVAS_DEFAULT_UPDATE_MAX_MARKS`), two orders above the SVG cap because the per-frame cost model is batched fills, not DOM writes. Gridline tick-value matching is extracted to a pure `computeGridlineDeltas` so the canvas path reuses it; the SVG behavior it replaces is pinned first by a 15-test characterization suite. Tick labels keep their SVG tween and share the canvas gridlines' clock, so a label never separates from its line. The from-state pass now ends with a synchronous `canvas.repaint()`: state writes alone leave the bitmap at the destination, rAF-before-paint is an accident of ordering, and manual mode has no paint at all between `beginManualUpdate()` and the first `step()`. Verified: 4078 tests pass. Gate-8's max rule, the canvas cap, the sync from-state repaint, the per-step repaint and the exit ghost array were each mutation-tested and each fails its guard when reverted.
1 parent baed972 commit a988286

7 files changed

Lines changed: 1745 additions & 41 deletions

File tree

0 commit comments

Comments
 (0)