← Back to Ships
web · active · 2026-04 → 2026-04

typoface

Real-time typographic portrait — your webcam rendered as a mosaic of colored word pills

Next.js 15TypeScriptTailwind CSSCanvas APIWeb Audio APIMediaRecorder

A live typographic portrait that reads your webcam and rebuilds it every frame as a dense grid of rounded word badges. Each pill’s opacity tracks the local pixel brightness underneath it — bright areas of your face become opaque, vivid pills; shadows fade into the background.

What’s in it

  • 60fps render loop — Float32Array luminance + 22×22 block-mean buffers pre-allocated once, reused every frame
  • Audio-reactive mode — Web Audio AnalyserNode on the mic, bass → pulse amplitude, mid → brightness lift
  • 8 named color themes — K-Pop, Matrix, Sakura, Ocean, Fire, Neon, Mono, Pastel
  • 6 word pools — Korean, Japanese, Arabic, English, Spanish, or fully custom text typed in live
  • 3 visual effects — Wave (sine ripple), Glitch (band shift), Breathe (sync pulse)
  • Capture & record — PNG snapshot with 3-2-1 countdown overlay, or one-click WebM recording via MediaRecorder
  • Keyboard shortcutsM mirror, I invert, C capture, R record, Space randomize theme
  • Side panel + full randomize — single button rolls theme, language, density, FX, contrast all at once
  • All on-device — getUserMedia + Canvas + Web Audio, nothing leaves the browser tab

Learnings

  • Pre-allocating Float32Array luminance + 22×22 block-mean buffers and reusing them every frame is what keeps the canvas at 60fps — re-allocating per frame tanks it to 20fps as the GC kicks in
  • Unsharp masking via `lum + (lum - blockMean) * 1.6` makes the face pop out of the pill grid more than raw luminance does, because flat midtones get pushed apart instead of all landing in the same alpha bucket
  • AnalyserNode bands map cleanly to two visual channels — bass → pulse amplitude, mid → brightness — and that separation feels musical without any beat detection logic
  • All processing on-device (getUserMedia + Canvas + MediaRecorder, no server) avoids the privacy conversation entirely; users hit the URL and the camera stream never leaves the tab
  • Korean / Japanese / Arabic word pools render denser than Latin scripts at the same pill size because the glyphs fill more of the rounded rect — switching language is the cheapest way to change the visual feel