Darkroom
Salt & Sodium
Field notes
A dark photography portfolio where the photos sit on an endless WebGL film strip. Scroll or drag and the strip bends with the speed while the colour channels split; click a photo and it opens full-bleed with its title. Eight hosted photos included, swappable in one file.
- WebGL shader
- Scroll-driven
- Pointer interaction
- Portfolio
- Dark theme
Darkroom is a portfolio for a fictional film photographer, built around one series: eight night photographs from the Atlantic coast. They sit on an endless horizontal strip of WebGL planes. Move it and it curves like film running through a gate, the red and blue channels pull apart with the speed, and every photo away from the centre drains to near-monochrome until it arrives. Click the centred one and it grows to fill the screen, with its title set large in Instrument Serif.
It works with a mouse wheel, a trackpad, a finger or the arrow keys, and snaps to the nearest photo. Until someone touches it, the page plays its own 12-second tour. The photos are hosted with CORS open so the prompt rebuilds anywhere, and replacing them with your own work is a list of URLs in one file. Anyone who prefers reduced motion gets the strip without the bend or the colour split.
How it's built
- Bend by speed: the vertex shader pushes each vertex back by its world x squared times a uniform that grows with the strip's velocity, so a flick curves the whole strip like film in a gate and it flattens as it stops.
- Colour split and fade in one pass: the fragment shader samples red and blue a little either side of green by the same velocity, then mixes towards grey the further a photo is from the centre.
- An endless strip with no clones: each photo's distance from the centre is wrapped into -4 … 4, so eight planes loop forever and the demo's eight flicks land exactly where it started.
- Photos any rebuild can load: they are hosted on basaltframe.com with Access-Control-Allow-Origin open and loaded with crossOrigin set; if one fails, a numbered canvas placeholder takes its place.
Inside the prompt
Every file below is written out in full, so your agent creates the project exactly — no guessing, no missing pieces.
darkroom-portfolio/
├─ .gitignore
├─ index.html
├─ package.json
├─ tsconfig.json
├─ vite.config.ts
└─ src/
├─ App.tsx
├─ index.css
├─ main.tsx
├─ vite-env.d.ts
├─ components/
│ ├─ Gallery.tsx
│ ├─ Overlay.tsx
│ └─ Scene.tsx
└─ lib/
├─ loop.ts
├─ photos.ts
├─ textures.ts
├─ timeline.ts
└─ view.tsRecut it
- Put in your own photos, titles and captions
src/lib/photos.ts → PHOTOS - Rename the photographer, the series and the links
src/components/Overlay.tsx → Overlay() - Tune the bend, colour split and fade to grey
src/components/Gallery.tsx → fragmentShader / useFrame - Resize the photos or change the gap between them
src/components/Gallery.tsx → useLayout() - Change the colours and fonts
src/index.css → @theme - Retime the demo tour
src/lib/timeline.ts → offsetAt() / openAt()
