Projects

Experiments

Unfinished on purpose. Each one exists to work out a single technique in isolation, which is usually where the interesting problems turn up first. Most run in the browser, here on the page.

Thread drawing, pick a color and draw on the shirt Canvas · Path2D

One canvas, no DOM elements. The shirt is a Path2D, so isPointInPath decides whether a stroke lands on the garment and clip keeps the thread inside the silhouette. The drawable area is the shape itself, not a rectangle standing in for it. Points are only recorded past a minimum distance, so a slow drag doesn't pile up hundreds of coordinates in one spot, and the whole layout, swatches included, is recomputed from the canvas size on resize.

Face cloud. 478 landmarks, tracked live and drawn as points of light. Source Three.js · MediaPipe · WebGL

One buffer holds both states. With no face it's a slow ring, and when tracking starts each point is handed a new target and interpolates toward it, so the idle animation becomes a face instead of being replaced by one. Detection and rendering are separate loops, so the render keeps interpolating at full frame rate while the detector only runs on new video frames. The camera stays off until you press the button, and if it's refused, WebGL is missing, or reduced motion is on, it falls back to the idle cloud rather than breaking.

The SVG and Canvas panels of Incense, Five Ways: a line drawing of an incense stick beside a painted one trailing smoke.
Incense, five ways. One subject, five rendering tools. Open it SVG · Canvas · WebGL · Three.js · GSAP

Each panel does the one job its tool is actually for: a diagram you can point at, smoke that stains the page, heat haze on every pixel, a scene you walk around, and a sequence. Porting one animation to every renderer only showed five copies of the same picture, so the comparison became about what each tool is for rather than how it draws.

A landscape in blue, pink, green and orange beside the same picture predicted in two riso inks, purple and fluorescent green, where the orange sun turns pale green.
Riso ink chooser. Which two inks, for this image. Open it Canvas · Color science

A riso print usually gets two or three inks, each on its own drum, and the choice is made before anything is printed. This tries every pair of inks against your image and ranks them by how close they get, measured as perceptual distance in Lab color. Inks are modeled as see-through filters that multiply, so each pair can only make a flat sheet of colors, and the page shows that sheet with your image's colors placed on it and the lost ones ringed. Not yet checked against a real print.

Experience

Design, product, DevRel and front-end work.