Coffee drops dry into dark rings, beside two tricks that make them dry evenly.
The edge of an evaporating drop stays pinned and loses liquid fastest, so liquid flows outward to replace it and drags the coffee particles along (Deegan's capillary flow, which speeds up toward the end). Thousands of particles ride that 3D shear flow with Brownian jitter, pile up at the contact line into a ring that grows inward, and land wherever the liquid gets thinner than they are. Elongated particles instead get trapped at the surface and lock into an even skin, and a surfactant drives a Marangoni flow inward along the surface that pulls the stain toward the middle. Each drop is shaded per pixel as a thinning spherical cap over paper, with Beer-Lambert color, refraction, a dark rim, a glint and a soft shadow.
Try it. Click the paper to place a drop of the selected kind, chosen with the chips or keys 1 to 3. Space fast-forwards the drying, N starts the next comparison and C wipes the surface. The side view shows the flow inside a drying drop.
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build a simulation of the coffee ring effect, a drop of coffee drying into a dark ring, with JavaScript and the HTML canvas element. Put everything in a single index.html file with no libraries or build step, so I can open it directly in a browser.
Start simple:
- Make a canvas that fills the window, stays sharp on high-DPI screens (scale by devicePixelRatio), and resizes with the window. Paint it off-white.
- Draw one big circular drop in the middle and fill it with about 8,000 particles at random positions, in coordinates where the drop's radius is 1.
- Let drying time t run from 0 to 1 over about ten seconds. The edge stays pinned while the drop flattens and evaporates fastest at the edge, so liquid flows outward with depth-averaged speed v(r, t) = (1 / (4 (1 - t))) * (1 / r) * ((1 - r^2)^(-1/2) - (1 - r^2)). Move every particle outward by that speed (capped near the edge) plus a little jitter.
- When a particle reaches the edge, freeze it there: it is deposited. At t = 1, freeze whatever is left in place.
- Draw the liquid as a translucent brown disc that fades as t grows, and particles as dark dots.
Once that works, make it beautiful:
- Accumulate deposits into a density array and color the paper with Beer-Lambert absorption, exp(-k * density) with a larger k for blue than red, so it reads as a coffee stain.
- Let the ring grow inward: track how deep the pile is in each angular bin and stop new particles at its inner edge.
- Shade the drop as a thin dome: darker where it is thicker, a soft highlight, and a slightly darker rim.
Explain the key ideas in short code comments. When you're done, tell me how to open it and suggest three directions I could take it next, such as elongated particles that stick at the surface and dry evenly, a Marangoni flow that runs inward along the surface, or two drops side by side to compare.