PDF Flipbook Builder
<SKILL_DIR> = the folder that contains this SKILL.md (normally
~/.claude/skills/pdf-flipbook). Resolve it once to an absolute path before
running commands - PowerShell/cmd do not expand ~ inside quotes.
Builds a self-contained static site that lets users flip through a PDF like a real book, and deploys it to a shareable URL. Pages are pre-rendered to high-DPI WebP (sharp, fast, lazy-loaded). Flip engine is StPageFlip, bundled locally.
When to use
User has a PDF (local file or a flipbook viewer link such as heyzine) and wants an interactive page-turning website — typically to share a link.
Key design facts (learned, don't re-derive)
- RTL is the default (Hebrew books): cover on the right, pages turn right-to-left.
- RTL is done with a double-mirror on an OUTER wrapper (
#flip-mirror), NOT on the StPageFlip block — StPageFlip resets the transform on its own element. Each page<img>is un-mirrored so content stays readable, and the inner block is forceddir="ltr"so the library's own RTL positioning doesn't fight the mirror. This makes both the page order AND the flip animation correct. - Use HTML render (
loadFromHtmlwith real<img>), NOTloadFromImages(canvas). Canvas blurs on zoom and breaks the mirror mid-animation. - Render at 300 DPI (source images are usually ~1024×1536). 150 DPI looks blurry, especially when zoomed.
- Single large page (
usePortrait: true) beats a two-page spread for text-heavy / slide content: more readable, and a spread would show pages in reversed order under the mirror.
Workflow
1. Get a PDF
- Local PDF → use it directly.
- Flipbook link (heyzine etc.) → extract the original PDF from its CDN:
If that finds nothing, fetch the page HTML and grep forpython "<SKILL_DIR>/scripts/fetch_pdf.py" "<URL>" --download "<PROJECT_DIR>/book.pdf".pdf, or fall back to thebrowser-album-downloaderapproach. Always grab the original PDF, never screenshots of the viewer.
2. Build the site
pip install pymupdf pillow # if missing
python "<SKILL_DIR>/scripts/build_flipbook.py" \
"/path/to/book.pdf" "<PROJECT_DIR>" \
--title "כותרת הספר" --subtitle "תת-כותרת (optional)"
- Title falls back to PDF metadata then filename if
--titleomitted. - Add
--ltrfor left-to-right (non-Hebrew) books. --dpi/--qualitytune size vs. sharpness (defaults 300 / 90 are good).
The script renders all pages, writes assets/manifest.json, and assembles index.html + css/ + js/ + lib/ + vercel.json.
3. Verify locally (recommended)
python -m http.server 8901 --directory "<PROJECT_DIR>"
Open with Playwright and check: book loads, content is readable (not mirrored), flip animation goes the right way (RTL: pages move left→right when advancing), zoom is sharp, thumbnails + keyboard work. The #flip-mirror computed transform should be matrix(-1, 0, 0, 1, 0, 0) for RTL.
4. Deploy
cd "<PROJECT_DIR>" && vercel --prod --yes
Return the Aliased short URL (e.g. https://<project>.vercel.app). Verify it loads publicly (not behind Vercel auth) before handing it over.
Features the site ships with
Page-curl flip (RTL/LTR) · single large readable page · zoom (buttons / Ctrl+wheel / double-click) + pan · fullscreen · thumbnails drawer · keyboard (arrows respect RTL, Home/End, +/−, F, Esc) · original-PDF download · lazy-loaded images · navy+gold dark theme · loading/error states.
Files
scripts/build_flipbook.py PDF → full site (render + assemble)
scripts/fetch_pdf.py extract source PDF from a flipbook viewer link
templates/index.html UI shell (title/subtitle/download filled from manifest by app.js)
templates/style.css RTL theme + mirror + zoom/thumbs styles
templates/app.js flip init, RTL mirror, zoom/pan, thumbnails, keyboard, lazy-load
templates/page-flip.browser.js StPageFlip (bundled, offline)
templates/vercel.json static hosting + cache headers
Re-rendering after a PDF change
Replace the PDF and re-run build_flipbook.py with the same output dir. The templates are generic — the title, subtitle, page count and download link all come from manifest.json, so nothing in the HTML/JS needs editing per-book.