Neuron Dot Product Animator
A nine-phase walk-through of how one neuron computes a dot product, ending in a zoom-out that reveals a linear layer is just this, repeated in parallel. The learner taps Step through phases 0–8: the three input pairs (x[i], w[i]) light up one at a time and contribute to a running sum inside the neuron, an arc fires the sum to the output, then the diagram zooms out to a two-neuron layer and animates both dot products at once. The terminal phase pulses both outputs and reveals y = Wx.
The component owns its own phase machine; Step advances it, and once you reach phase 8 the button becomes Replay and re-arms cleanly.
One neuron, three inputs. Watch the dot product compute — one pair at a time.
Installation
npx shadcn@latest add https://craftbits.dev/r/neuron-dot-product-animator.jsonUsage
import { NeuronDotProductAnimator } from "@craft-bits/viz/neuron-dot-product-animator";
<NeuronDotProductAnimator />Re-skin the model — different weights, different inputs:
<NeuronDotProductAnimator
W={[[0.7, -0.4, 1.2], [-1.5, 0.6, 0.3]]}
x={[2, -1, 3]}
/>Drive a parent reducer off each phase change:
<NeuronDotProductAnimator
onPhaseChange={(phase) => {
/* sync with sibling narration, analytics, etc. */
}}
/>Understanding the component
- Coordinate system. The single-neuron view is a 560 × 200 SVG with three inputs on the left, the neuron body in the centre, and the output on the right. The layer view is 560 × 260 and uses the same x-coordinates so the AnimatePresence swap reads as a zoom-out, not a context switch.
- Phase machine. Internal state is the phase index 0 to 8. Step advances; Replay resets to 0. Each phase has its own choreography (intro / pair 0 / pair 1 / pair 2 / sum lands / layer intro / zoom out / layer animates / terminal pop).
- Imperative animation. Every per-frame attribute write lands on a ref via motion's
animate()—strokeDashoffsetfor the connection draw, opacity for chips and glows, scale for the output pop. React only re-renders on phase changes, so the SVG itself never tears. - Connection palette. The three input/weight pairs cycle through
--cb-accent,--cb-warning, and--cb-errorso they stay distinguishable independent of theme. Negative products colour their chip with--cb-errorregardless of pair index, so the eye reads "this contribution pulled the sum down." - Layer view. Phase 6 mounts the layer-view SVG and waits 50ms for refs to bind, then phase 7 draws all six connections in parallel with a tight 0.04s stagger, fills both
Wxsums simultaneously, and pops both outputs. - Reduced motion. Under
prefers-reduced-motion: reduce, every phase collapses to an instant attribute set: the connection lines snap to their drawn state, the chips appear without slide, the arc and output skip their tweens, and the layer-view crossfade still fires but every internal animation is bypassed.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
W | readonly [readonly [number, number, number], readonly [number, number, number]] | [[1, 0.5, -0.5], [2, -1, 0.5]] | 2 × 3 weight matrix. Row 0 drives the single-neuron walk; row 1 enters at phase 6. |
x | readonly [number, number, number] | [1, 2, 4] | Three-element input vector. |
transition | Transition | SPRINGS.bouncy | Override the chip / output pop spring. |
onPhaseChange | (phase) => void | — | Fires after each Step (or Replay) with the new phase index. |
onReset | () => void | — | Fires when the user clicks Replay. |
className | string | — | Merged onto the root via cn(). |
Accessibility
- The active SVG has
role="img"and anaria-labelsummarising the inputs, weight row, and current phase. The layer-view label also includes both output values once they've computed. - A live region below the buttons announces the current phase index and narration prose so screen-reader users get the same narrative as sighted users.
- The narration paragraph also has
aria-live="polite"and reads as plain prose; it is the canonical explanation for each phase. - Colour is never the only signal — every phase change updates the narration text and the live-region status as well as the SVG.
- The Step / Replay button has a visible focus ring via
:focus-visibleand is the only operable control, so the entire animator is reachable in one Tab from the surrounding flow. - Motion respects
prefers-reduced-motion: reduce— every staged animation collapses to an instant attribute set.
Credits
- Extracted from:
craftingattention(app/src/lessons/primitives/math/NeuronDotProductAnimator.tsx). The source was a tightly bundled lesson component — it consumedSvgLabelfor every text run andChallengeBtnfor the Step button, depended on per-track lesson palette tokens, and inlined an ad-hocEASINGS.outimport. The viz extract drops the lesson chrome (raw<text>plus a token-styled button), remaps the colour palette tovar(--cb-*)semantic tokens so consumer themes repaint freely, re-keys the pop spring to the canonicalSPRINGS.bouncy, and replaces the project-specific easing import with a literal cubic-bezier so the component carries no project-specific motion import.