Three.js Scroll 3D Book — Bending Page Flip Snippet

Three.js Scroll 3D Book Page Flip · Scroll · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

Spine hinge via geo.translate — the page's left edge becomes its rotation origin, no pivot Groups
Mid-flip paper bend: half-sine vertex displacement, amplitude peaking mid-arc, zero at rest
Pristine base-vertex copy restored each frame so bends never accumulate or drift
Overlapping flip windows (65% offset) so pages leaf naturally, two or three airborne at once
Stack transfer: completed pages re-stack left in mirrored height order as the right pile thins
Printed text lines as page children — they flip with the page through scene-graph parenting
computeVertexNormals() after each bend keeps warm lamp lighting correct on curved paper
HUD counts completed flips, matching the visible stacks at every scroll position

About this UI Snippet

How to Build a Scroll-Driven 3D Book With Bending Page Flips in Three.js

Screenshot of the Three.js Scroll 3D Book Page Flip snippet rendered live

The Three.js Scroll 3D Book Page Flip snippet lays an open book on a desk and lets scroll turn its twelve pages one by one — each page arcing over the spine with a genuine mid-flip paper bend, printed text lines riding along, and the right-hand stack visibly transferring to the left as reading progresses. GSAP's ScrollTrigger scrubs one progress value; overlapping per-page windows and a vertex-bend pass do the rest.

The hinge is a geometry translation

A page must rotate about the book's spine, not its own center. Rather than wrapping each page in a pivot Group, the snippet translates the PlaneGeometry itself — geo.translate(PW/2, 0, 0) — so the page's left edge sits at its local origin. After that, plain rotation.z *is* the page turn: 0 lies flat right, −π lies flat left. This one-line trick eliminates a whole layer of pivot objects and is worth stealing for any hinged element: doors, lids, cards, lever arms.

Paper bends with a half-sine, not physics

Rigid rotating planes look like plastic sheets. Real paper lifts in an arc — the free edge lags, the middle bows. Each page's geometry has 20 width segments, and every frame its vertices are displaced in local Y by sin(x/PW × π) × bend, a half-sine that is zero at the hinge and free edge and maximal mid-page. The bend amplitude itself is sin(flipProgress × π) × 1.15 — zero when the page rests on either side, peaking mid-flip. Vertices are restored from a pristine slice() copy of the flat geometry each frame, the same base-copy pattern as the ocean dive surface, so bends never accumulate. computeVertexNormals() after displacement keeps lighting on the curved paper correct.

Overlapping flip windows read as leafing

Sequential page turns — each finishing before the next lifts — feel mechanical. The window arithmetic gives page i a slice starting at i × win × 0.65, so each new page lifts when its predecessor is 65% through its arc. Two or three pages are airborne at busy moments, the way a reader leafs through a book. It is the same derived-stagger technique as the voxel build, tuned by a single overlap constant.

Stack transfer and printed text for free

Unflipped pages stack on the right with each successive page 0.012 lower; the moment a page's flip completes, its rest height switches to the mirrored left-stack order (PAGES − i) × −0.012. The right pile visibly thins while the left thickens — a small state change that sells the passage of reading. The printed lines are thin dark boxes added as *children* of each page mesh, so they rotate and translate with the page automatically through scene-graph parenting (they float 0.012 above the surface rather than re-bending — invisible at reading distance). Line widths vary by a deterministic modulo so paragraphs look ragged-right, like real typesetting.

A reading camera, a HUD that counts

The camera hovers at an overhead reading angle, drifting a half-radian across the scroll with a slight descent — enough parallax to feel present at the desk without upstaging the pages, plus the series-standard clock bob for idle life. The HUD counts pages whose flip has completed, so PAGE 7 / 12 always matches what the stacks show. Scrolling backwards un-turns pages in exact reverse order, bends included. For 2D scroll storytelling with the same "chapters" energy, compare the scroll pin story and scroll before/after snippets.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You do not need to work out hinge translations and bend envelopes from scratch. Paste this snippet's HTML, CSS, and JS into an AI assistant like Claude and ask it to explain why geo.translate turns rotation.z into a spine hinge, how the two nested sines create the paper bow, or why base vertices are restored each frame. The same assistant can level the book up — rendering real content onto pages with CanvasTexture (titles, images, your actual copy), adding a cover-opening prologue phase before page one, a soft page-turn shadow cast on the page beneath, or click-to-flip that tweens the same progress object GSAP scrubs. It can also recalculate the overlap constant for a riffle-through effect. Treat the code as a starting point to interrogate and reshape, not a finished artifact.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a "scroll-driven 3D book with bending page flips" in plain HTML, CSS, and JavaScript using Three.js and GSAP's ScrollTrigger plugin, all loaded from a CDN (no bundler, no build step).

Requirements:
- A pinned full-viewport section with a canvas, WebGLRenderer, PerspectiveCamera (~45° FOV, resized with aspect on window resize), warm ambient + directional lamp light, a dark desk BoxGeometry, and two cover slabs flanking the spine.
- 12 pages from PlaneGeometry(PW=8, PH=11, 20, 1), each rotated flat and then geometry-TRANSLATED by PW/2 so the left edge sits at the local origin — rotation.z alone must perform the spine flip (0 = flat right, −π = flat left). Slightly varied warm paper tints, DoubleSide.
- Keep a pristine Float32Array copy (slice()) of each page's flat vertices at build time.
- Printed text: thin dark BoxGeometry strips added as CHILDREN of even pages (7 lines each, widths varied by a deterministic modulo), so they ride the flip automatically.
- One GSAP tween (ease "none") scrubbing p 0→1 on a ScrollTrigger with pin: true, scrub ~0.5, end ~+=550%.
- Overlapping flip windows: page i animates across [i × win × 0.65, + win] where win = 1 / (PAGES − 0.35 × (PAGES − 1)); local progress passes through easeInOutQuad, rotation.z = −π × eased.
- Paper bend each frame: rewrite vertices from the stored base with localY += sin(x/PW × π) × sin(eased × π) × 1.15, then computeVertexNormals(). Bends must be zero when pages rest on either side.
- Stack transfer: unflipped pages stack right at i × −0.012; when a page's local progress reaches 1, its rest height becomes (PAGES − i) × −0.012 on the left stack.
- A PAGE n / 12 HUD counting completed flips, an overhead reading camera drifting ~0.5 rad with progress plus a slight clock bob, and an intro overlay fading at p > 0.02.
- Confirm scrolling backwards un-turns pages in exact reverse order, bends included.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Step by step

How to Use

  1. 1
    Load the three CDN scriptsAdd three.min.js, gsap.min.js, and ScrollTrigger.min.js in that order before the snippet JS.
  2. 2
    Paste HTML, CSS, and JSAn open book lies on a desk under warm lamp light — twelve pages stacked right, purple covers on both sides, PAGE 0 / 12 in the HUD.
  3. 3
    Scroll to readPages arc over the spine with a visible paper bow, printed lines riding each page; the next page lifts before the last one lands.
  4. 4
    Watch the stacksThe right pile thins and the left thickens as flipped pages settle in mirrored order — the HUD counts completed flips.
  5. 5
    Scroll backPages un-turn in exact reverse, bends and all — every flip is a pure function of the scrubbed progress.
  6. 6
    Make it your bookChange PAGES, page colors, or replace the line-strip children with CanvasTexture images to show real page content.

Real-world uses

Common Use Cases

Publishing, author, and bookstore sites
The obvious fit — let visitors leaf through a real 3D book, then link chapters to content sections via scrollto anchor nav.
Portfolio as a storybook
Map each spread to a project with CanvasTexture pages — a tactile alternative to a scroll gallery pin.
Wedding, event, and memory pages
A guestbook or photo album that turns as guests scroll, with warm lamp lighting setting the mood.
Teaching hinge and bend techniques
Two transferable tricks in one scene: geometry-translation hinges and amplitude-enveloped vertex bends with base restoration.
SHOP
Catalog and lookbook launches
Fashion and furniture brands can page through a season's lookbook before the product grid, pairing with thumbnail gallery.
Narrative game and visual-novel promos
The storybook frame is native to narrative games — drop title art on page one and chapter beats per spread.

Got questions?

Frequently Asked Questions

The PlaneGeometry is translated after creation — geo.translate(PW/2, 0, 0) — moving its vertices so the left edge lies at local x = 0. Rotation always happens about the local origin, so once the edge is the origin, plain rotation.z sweeps the page over the spine. No pivot Group, no matrix juggling: one translation converts center-rotation into hinge-rotation permanently.

Each page has 20 width segments, and every frame its vertices get a local-Y displacement of sin(x/PW × π) × bend — zero at the hinge and free edge, maximal mid-page. The bend amplitude is itself sin(flipProgress × π) × 1.15, so a page is flat at rest on either side and bows most at the vertical midpoint of its arc. Vertices are rewritten from a stored flat copy each frame, so displacement never compounds.

If each page finished before the next lifted, the book would tick like a metronome — twelve identical sequential events. Starting page i at i × win × 0.65 lets the next page lift while its predecessor is still falling, so at busy moments two or three pages are airborne, which is how actual leafing looks. One constant (0.65) tunes the whole feel: raise it toward 1 for sequential turns, lower it for a riffle.

They are children of the page mesh, so its rotation and position carry them automatically. They do not re-bend with the vertex displacement — they hover 0.012 units above the surface — but at reading distance and 1.15 units of maximum bow the mismatch is imperceptible. For exact adhesion you would draw lines into a CanvasTexture on the page material instead, at the cost of a texture per page.

Yes. Export with the JSX, Vue, Angular, or Tailwind buttons. Build pages, base-vertex copies, and the ScrollTrigger inside a mount effect against a canvas ref; the base arrays must live in effect scope alongside the meshes. On cleanup kill the ScrollTrigger, dispose every page geometry/material and line-strip child, and call renderer.dispose() to release the pin and WebGL context.