Projects · Birthdays · Front End · Oct 2026
Your Virtual Scrapbook
A flip-through birthday book where each friend's note and photos become their own designed page.
Next.js, GSAP and canvas-confetti turn a data object into a book with 3D page turns and a page style per friend. The repo is the engine pulled out of one real gift book, with multi-user sharing and AI page picking still on the roadmap.
The Problem
The first book was a one-off build for a friend’s 22nd birthday: 15 friends, about 100 photos and videos, opened almost entirely on iPhones and iPads. It works, but it stays private and it is tied to that one person. The repo takes the reusable part, the engine, and moves every personal detail into data, on its way to becoming something anyone can make.
What I Built
A book engine plus a demo book. Each friend’s contribution becomes one page, and every page uses a design chosen to fit what they sent: a postcard from where they are, polaroids and a friendship receipt, photos pegged to fairy lights you drag sideways, a home-video frame with a timecode, a photo-booth strip, instant photos that develop when tapped, toy blocks with real physics, tap-through stories, a slider through the years, a 3x3 jigsaw, airplane window shades, plates ordered at a little restaurant, two neon lines that merge, a route with checkpoints, and simpler photo piles.
The README’s demo is local: run it and open /demo for a fictional book for Alex from fourteen fictional friends, one for each page style. The images in it are generated illustrations, not real photos.
How It Works
- Book data
src/engine/types.tsdefines a Book: the recipient, the page setup for each friend, and their contributions. Every style reads its text, titles, stamps and checkpoints, from that data, with neutral defaults. - A page style per friendThe README’s table lists the styles, from
postcardandyearstobirthdays,dumpandauto.src/demo/book.tsshows an example of each. - The engine
src/engine/holds the 3D page turns, the photo viewer, stickers, sound and the styles. It began as plain browser scripts inlegacy/;mount.tssupplies the globals they expect and loads them in order inside the<Scrapbook>client component. - Demo media
scripts/make-demo-media.mjsgenerates the demo’s illustrated placeholder photos and videos. - A book you flip throughPages turn in 3D, jumps from the contents page play a single turn, and the whole thing runs in the browser.
Four things learned the hard way on real phones, now built in:
- Long jumps skip ahead. Jumping from the contents page moves silently to the page before the target and plays one turn, instead of drawing every page in between, which crashed iPhones.
- Pages sit a fraction of a pixel apart in 3D, because Safari sorts 3D layers by depth and ignores z-index.
- The turning page’s shadow is its own layer, faded by opacity, so iOS doesn’t repaint the whole page each frame.
- No SVG
filtereffects, because they are redrawn in software every frame of a 3D page turn.
Where It Stands
Roadmap step 1 is done: the engine is extracted, the personal details live in data, and there is a demo book. npm run dev serves it at localhost:3000/demo, npm run build makes a production build, and node scripts/make-demo-media.mjs regenerates the demo media. The README lists the stack as Next.js, GSAP and canvas-confetti.
Limitations
- The demo images are generated illustrations, not real photos.
- The original book stays private. This repo is only the engine, so nothing here contains the real 15-friend book.
- No shared books yet. Roadmap step 2, an organizer creating a book and sharing one invite link so friends add notes and media from their phone with no account, is not built. Supabase for accounts, database and storage is planned.
- No AI yet. Reading each note to pick a style and its details for the organizer to review is roadmap step 3, and the Claude API is listed as planned rather than in use.
- The engine is still legacy scripts. The README says they will be ported to typed modules over time, so the page styles run through the globals that
mount.tssupplies. - The README’s demo route is local, at
localhost:3000/demoafternpm run dev. - Roadmap step 4, a live photo wall for the day itself, video support and polish, is still ahead.