trace the hypotenuse
Pythagoras, live — the right triangle behind every cursor distance.
53 specimens · all live
Animation and interaction studies built while figuring out how interfaces should feel — from cursor math to SVG drawing to particle systems. Nothing here is a screenshot. Go ahead and touch it.
Cursor distance, transform origins, and the small feedback loops that make interfaces feel attentive. Built natively for this site.
trace the hypotenuse
Pythagoras, live — the right triangle behind every cursor distance.
clampedNormalize(62) → 5.7
clampedNormalize — one range in, another out, never past the rails.
Hundreds of SVG dots scaled by proximity, painted outside the React render path.
move closer
Blur and lift resolve as the cursor closes the distance.
rotate( 0deg) scale(1.00)
Pointer position drives rotation and scale through a single transform.
top left
Same animation, nine origins — growth should start at the anchor.
Two staggered keyframes spawn a wave at the exact click point.
renders at the viewport edge
Stacked, timed, dismissed — notification motion that stays out of the way.
Strokes that draw themselves, paths as motion rails, masks, morphs, and the odd corners of the SVG spec. Exercises straight out of the sandbox.
stroke-dasharray plus dashoffset — the classic self-drawing line.
pathLength normalizes any path to 100 — draw loops without measuring.
A reusable underline swoop, drawn on hover through an SVG <use>.
A dash animation revealed through an SVG mask.
A dotted path draws itself by masking a solid twin underneath.
The strike-through draws across the bell — and unmasks itself on the way out.
A pulse of light travels the wire between two nodes.
A repeating gradient slides along the strokes like current through wires.
SMIL sends a dash of light around a tangled scribble.
A menu icon whose dashes travel their paths between states.
A chained SMIL sequence — the arrow drops, morphs, and resets.
Point interpolation morphs a triangle flat and back again.
Path interpolation via the Motion library — play melts into pause.
offset-path slides the disc into the player along a curve.
Shapes traced with raw M, L, and Z commands — the path syntax, learned by hand.
Three dashes race a circuit board, growing and shrinking as they go.
The SVG arc command dissected, one A segment at a time.
Pan the camera, not the shapes — animating the viewBox with rAF.
vector-effect keeps line weight constant while the artwork scales.
min-width lets the artwork squish gracefully instead of shrinking away.
paint-order: stroke fill — outlined type without the crusty overlap.
A range input drives a circular progress ring through dashoffset.
A chart that draws itself on hover, scaled with normalize().
0:30
The ring drains and the hand sweeps — SMIL triggered straight from the play button.
The polygon morphs on a spline while the labels count along the same curve.
Keyframes from scratch, then particle systems — one dispersion study at a time, from first burst to magic wand.
A hand-rolled animate() — easing functions over requestAnimationFrame.
Three balls, one keyframe — distance and duration set by custom properties.
Oscillation tuned per ball with CSS variables; the button freezes them mid-flight.
Eyes blink by animating the ellipse ry attribute straight from CSS.
A sheen sweeps the buy button on hover — and on focus, for keyboards.
Exhaust particles spawn on an interval beneath a gently hovering rocket.
The first burst — particles scatter from the heart with random offsets.
JS does the math once and hands the offsets to CSS as custom properties.
Angle and distance instead of x/y — even spread around the circle.
Evenly spaced angles with a touch of jitter — order, with a little chaos.
Twenty-five particles interpolated around the full circle.
Keyframes without a from block inherit each particle's starting state.
Click anywhere — sparkles burst from the cursor with sin/cos offsets.
Particles hue-rotate as they fade — one filter, the whole rainbow.
The minimal cut of the heart-burst pattern.
A pop ring grown with an SVG mask — r is animatable from CSS.
Each like slides a rect beneath the mask — exponential easing tops it off.
Confetti rain — emoji spawned, animated, and cleaned up on a timer.
The same burst, gated by prefers-reduced-motion in both CSS and JS.
Where the dispersion series lands — pop, hue-shift, and twinkle, with React owning the particle list.
Several of these grew into long-form write-ups — read the essays in Craft.