A browser toy. You allow the camera, tap your own face, and it morphs into an egg, a potato, a heart, a moai, a splatter — fifteen shapes in total. Then it delivers a verdict about you. The verdicts are rude on purpose.
Nothing leaves your device. Face tracking runs entirely in the browser, the video never touches a server, and there is no account, no cookie, no analytics pixel.
How to use
- Open it on a phone — that’s the intended screen. Desktop works too.
- Allow the camera, then tap the face to roll a new shape.
- Hold record to capture a clip. The watermark is baked in, the stats line is not — the recording stays clean.
- Switch language — Ukrainian and English, top-right corner.
How it works
MediaPipe Face Landmarker (float16, 468 landmarks) tracks the face in real time. There is no Three.js and no WebGL — the whole render is plain canvas 2d.
Each shape is a signed distance field: a handful of ellipsoid blobs unioned with a smooth minimum, some of them carved out afterwards. The face mesh is projected onto that field, so the morph is continuous rather than a crossfade between two pictures. Shapes and verdicts live in one JSON file and get injected at build time — the geometry, the colours and all seventy-five verdicts have a single source of truth.
Recording uses captureStream() on the canvas, which copies pixels and nothing else. That one fact decides the whole layout: the @dormouse.weirdo watermark is drawn on the canvas so it survives into the video, and the session counter is DOM so it physically cannot.
Session counter
A small line in the corner counts unique sessions and names the city that stared at itself the longest.
A session opens when someone actually turns the camera on — not on page load, otherwise it would be a crawler counter. Duration is pinged only while the tab is visible and capped at thirty minutes, so a forgotten tab can’t win. The city comes from Cloudflare’s edge; no IP and no cookie is ever stored, which keeps it GDPR-clean by construction.
State lives in a single Durable Object on SQLite. A counter is inherently sequential, and DO is the one primitive in Workers that gives strong consistency without a race.
Stack
- MediaPipe Tasks Vision — face landmarker, 468 points, in-browser
- Canvas 2D — rendering, morph, watermark, video capture
- SDF geometry — 15 shapes as blob unions with smooth-min and carve
- Cloudflare Workers + Static Assets — static first, Worker only sees
/api/* - Durable Object (SQLite backend) — strongly consistent session counter
- Python tooling — ASCII shape previews for iterating on geometry without a browser
What’s next
More shapes, more verdicts. A clickable link inside an Instagram Story turned out to be impossible for a static site — Meta simply does not expose it — so the fallback is baking the call to action into the video itself.