Make editorial "interactive posters" in your browser. Drop in a photo, type your headline, and the image becomes a grid of pixels that scatter and dissolve under your cursor and reassemble — wrapped in poster typography. Then record a clip or save a still. No build step, no npm install, runs offline.
Move your cursor over the image and it dissolves:
- 🌸 Cursor‑driven pixel‑dissolve hero — your photo is rendered as a grid of square cells that scatter, tumble and reassemble around the pointer (WebGL / three.js).
- 🎛 Live control panel — drop an image, type the headline + corner labels, and tweak the effect with sliders. No code.
- 🎬 Export — record a clip (with a hands‑free auto‑cursor sweep) or save a full‑resolution still PNG.
- 🅰 Editorial typography — high‑contrast serif headline, grotesque labels, ruler tick‑marks and a rotated date — rendered as crisp DOM text over the canvas.
- 💾 Save / load your poster as JSON, or export a standalone HTML file that plays anywhere.
- ⚡ Zero‑build — plain ES modules + a tiny Python static server. three.js and the fonts are vendored, so it works offline.
git clone https://github.com/Erik5000/interactive-poster-studio.git
cd interactive-poster-studio
python3 serve.py # or double-click start.command on macOSIt opens automatically in your browser. Use Google Chrome — especially for recording clips (Safari can view, edit and save stills, but its clip recording is unreliable).
ES modules require an HTTP origin, so it won't run from a
file://page — that's all the little server is for. Any static server works (npx serve,python3 -m http.server, etc.).
Content — drop an image (or click to choose; it's center‑cropped to fit). Type the headline and the four corner labels (top‑right, bottom‑left, date, tag). Pick a serif for the headline and a grotesque for the labels. Set the background color.
Effect — drag the sliders:
| Slider | What it does |
|---|---|
| Grid Density | number of cells (higher = finer mosaic) |
| Cell Size / Grid Gap | cell scale and the dark gap between cells |
| Scatter Radius / Strength / Chaos | how cells fly apart near the cursor |
| Return / Lag | how quickly they reassemble |
| RGB Split | chromatic fringe on displaced cells |
| Idle Shimmer | subtle life at rest |
| Glow / Brightness / Contrast | tone of the image |
Export — set the clip length, leave Auto‑cursor on for a hands‑free sweep, and hit Record Clip (saves a .webm). Double‑click convert-to-mp4.command to turn the newest .webm into a Twitter/QuickTime‑friendly .mp4. Or Save Still PNG for a 1620×1080 image. Copy as Standalone HTML bundles the current poster (config + image) into one shareable file.
H— hide / show the control panel#demo— append to the URL for hands‑free attract mode (auto‑cursor loop, panel hidden)#clean— append to the URL to hide the panel (clean poster, e.g. for presenting)
- Hero effect — a subdivided plane rendered as instanced quads (one per cell). Displacement happens in a vertex shader as a pure function of a damped cursor + a decaying "energy" value, so cells return home on their own when you leave — no per‑particle simulation state. Colors are sampled per‑cell from the image for the LED‑grid look; displaced cells get an RGB split and additive glow.
- Typography is HTML/CSS over the WebGL canvas (crisp web fonts), driven by a shared layout model so the export matches the live poster exactly.
- Export composites the WebGL frame and the type layer into one canvas (
captureStream→MediaRecorderfor clips,toBlobfor stills).
index.html stage + canvas + panel mount
serve.py tiny static server (auto-opens the browser)
start.command double-click launcher (macOS)
convert-to-mp4.command WebM → MP4 via your system ffmpeg
css/ reset · poster (stage + type) · panel
js/
main.js boot + render loop + wiring
effect.js + shaders.js the instanced-quad hero effect
poster.js + layout.js + ruler the type layer
pointer.js + autopath.js cursor damping + scripted record path
exporter.js + compositor.js still PNG + clip recording
panel.js · config.js · state.js · standalone.js · …
vendor/three/ three.js (vendored, MIT)
fonts/ Playfair Display + Space Grotesk (OFL)
assets/ default image + preset
Vanilla JavaScript (ES modules) · three.js (vendored) · Python http.server · ffmpeg for the optional MP4 conversion. No bundler, no dependencies to install.
- Code — MIT (see LICENSE).
- three.js — MIT (vendor/three/LICENSE).
- Fonts — Playfair Display & Space Grotesk, SIL Open Font License (fonts/OFL.txt).
- Default image — "Lotus Flower in bloom", U.S. National Park Service, public domain (via Wikimedia Commons). Replace it with your own photo.
Inspired by the interactive‑poster experiments floating around design Twitter/X.
MIT © 2026 Erik5000


