Dot Product Dial
Two vectors share an origin: a is fixed along the positive x-axis and b rotates by θ from a. The dot product a · b = |a| · |b| · cos(θ) is rendered live as a numeric readout, color-coded by sign. An optional perpendicular drop from b onto a visualizes the geometric reading of the dot product as "magnitude × projection."
Dot product 0.50; angle 60 degrees; vector a magnitude 1.00, vector b magnitude 1.00.
a · b = |a| · |b| · cos θ = 1.00 · 1.00 · 0.50 = 0.50
Customize
Angle
60°
Magnitudes
1.00
1.00
Overlays
Installation
npx shadcn@latest add https://craftbits.dev/r/dot-product-dial.jsonUsage
import { DotProductDial } from "@craft-bits/core";
<DotProductDial defaultTheta={Math.PI / 3} />Control θ from outside (e.g. to drive it from a parent animation):
const [theta, setTheta] = useState(Math.PI / 4);
<DotProductDial
theta={theta}
onThetaChange={setTheta}
aMagnitude={2}
bMagnitude={1.5}
/>Hide the projection or the formula readout for a minimal embed:
<DotProductDial
defaultTheta={Math.PI / 2}
showProjection={false}
showFormula={false}
/>Understanding the component
- Vector a is fixed; vector b rotates. a sits along the positive x-axis with magnitude
aMagnitude. b shares the origin and rotates bythetaradians (CCW positive). Math coordinates feed an internal SVG transform — y is flipped automatically. - Native slider as the primary controller. A
<input type="range">covers[0, 2π]in 1° steps. Browsers ship full a11y for free —Tabto focus,←/→to nudge, screen readers announcearia-valuetext. - Projection geometry. When
showProjectionis on (default), a dotted segment drops perpendicular from b's tip onto the x-axis. The opaque segment from origin to the drop foot is the projection of b onto a — its signed length equals|b|·cos(θ), exactly the dot product divided by|a|. - Perpendicular detection. When
|a · b| < 0.05the component renders a small right-angle glyph at the origin, and the formula readout switches tone — a no-cost visual cue that the vectors are orthogonal. - Semantic tone follows the dot product sign. Positive →
cb-success, negative →cb-error, perpendicular →cb-fg-muted. The same color drives the formula readout and the projection-on-a highlight. - Spring transitions. The b-vector tip follows
thetawithSPRINGS.snap; the projection segments useSPRINGS.smooth.prefers-reduced-motion: reducecollapses both toduration: 0. - Controlled and uncontrolled. Pass
theta+onThetaChangefor controlled, ordefaultThetafor uncontrolled. Default initial angle isπ/3(60°), which lands on a clean positive dot product.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
aMagnitude | number | 1 | Length of vector a along the x-axis. |
bMagnitude | number | 1 | Length of vector b before rotation. |
theta | number | — | Controlled angle in radians. Pair with onThetaChange. |
defaultTheta | number | Math.PI / 3 | Uncontrolled initial angle. |
onThetaChange | (theta: number) => void | — | Fires on every slider change. |
showProjection | boolean | true | Render the dotted projection of b onto a. |
showFormula | boolean | true | Render the |a||b|cos(θ) readout below the dial. |
transition | Transition | SPRINGS.snap | Spring for the b-vector tip. |
className | string | — | Merged onto the root <div> via cn(). |
Accessibility
- The SVG is
role="figure"with anaria-labelledbyheading that's also rendered as a visually hiddenaria-live="polite"summary — screen readers hear the dot product, angle, and magnitudes whenever θ changes. - The slider is a native
<input type="range">carryingaria-valuemin/aria-valuemax/aria-valuenow/aria-valuetext. Keyboard parity is automatic. - Motion respects
prefers-reduced-motion: reduce— every spring collapses to an instant swap. - The right-angle glyph at θ = 90° / 270° doubles as a sighted-user cue that pairs with the semantic tone change on the formula readout.
Credits
- Extracted from:
craftingattention(app/src/lessons/primitives/math/DotProductDial.tsx). The source paired the visualization with an Explore / Challenge mode strip, narration heuristics, a 5-round target-matching game, an auto-rotate sweep timer, a "predict the value" gate, and a synchronized cosine-wave panel. The library extract is the pure visualization primitive — two vectors, one angle, optional projection + formula.