@objectifthunes/three-book
v0.5.4
Published
A procedural, interactive 3D book for [Three.js](https://threejs.org/) — drag pages to turn them, apply textures to every surface, and drop the whole thing into your scene as a regular `THREE.Group`.
Readme
@objectifthunes/three-book
A procedural, interactive 3D book for Three.js — drag pages to turn them, apply textures to every surface, and drop the whole thing into your scene as a regular THREE.Group.
Features
- Drag-to-turn pages — raycaster-based interaction, works with mouse or touch.
- Programmatic page turns — auto-turn API for scripted animations.
- Per-surface textures — assign a
THREE.Texture(ornull) to each cover side and page side independently. - Configurable geometry — page/cover width, height, thickness, stiffness, color.
- Built-in binding —
StapleBookBindinghandles spine positioning out of the box. - Standard scene-graph citizen —
BookextendsTHREE.Group; add it, transform it, remove it like anything else.
Installation
npm install @objectifthunes/three-book threeor
pnpm add @objectifthunes/three-book threePeer dependency: three >= 0.150.0 (ESM).
Quick Start
import * as THREE from 'three';
import {
Book,
BookContent,
BookDirection,
StapleBookBinding,
} from '@objectifthunes/three-book';
// 1. Set up your scene as usual
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 0.1, 100);
camera.position.set(0, 4, 5);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
// 2. Describe the book's content
const content = new BookContent();
content.direction = BookDirection.LeftToRight;
content.covers.push(frontOuterTex, frontInnerTex, backInnerTex, backOuterTex);
content.pages.push(page1Tex, page2Tex, page3Tex, page4Tex);
// 3. Create the book
const book = new Book({
content,
binding: new StapleBookBinding(),
castShadows: true,
alignToGround: true,
pagePaperSetup: {
width: 2,
height: 3,
thickness: 0.02,
stiffness: 0.2,
color: new THREE.Color(1, 1, 1),
material: null,
},
coverPaperSetup: {
width: 2.1,
height: 3.1,
thickness: 0.04,
stiffness: 0.5,
color: new THREE.Color(1, 1, 1),
material: null,
},
});
book.init();
scene.add(book);
// 4. Update every frame
const clock = new THREE.Clock();
function animate() {
requestAnimationFrame(animate);
book.update(clock.getDelta());
renderer.render(scene, camera);
}
animate();Page Dragging
Wire up your own pointer/raycaster, then call three methods:
book.startTurning(ray); // pointer down
book.updateTurning(ray); // pointer move
book.stopTurning(); // pointer upAuto Turn
Turn pages programmatically:
import { AutoTurnDirection, AutoTurnSettings } from '@objectifthunes/three-book';
const settings = new AutoTurnSettings();
book.startAutoTurning(AutoTurnDirection.Next, settings, 3);Content Model
Covers — 4 entries, one per surface:
| Index | Surface | |-------|---------| | 0 | Front outer | | 1 | Front inner | | 2 | Back inner | | 3 | Back outer |
Pages — ordered list of page-side textures. Each entry can be a THREE.Texture, an IPageContent implementation, or null (renders the base paper color).
Lifecycle
new Book(options)— create.book.init()— build geometry (call once).book.update(dt)— call every frame.book.dispose()— clean up when done.
Material Tinting
Final color = texture * paperColor. Keep color white (new THREE.Color(1, 1, 1)) if you want textures to appear unmodified.
API Surface
| Category | Exports |
|----------|---------|
| Core | Book, BookContent, BookDirection, Paper, PaperSetup, PaperUVMargin |
| Binding | BookBinding, BookBound, StapleBookBinding, StapleBookBound, StapleSetup |
| Content | IPageContent, PageContent, SpritePageContent2 |
| Auto turn | AutoTurnDirection, AutoTurnMode, AutoTurnSettings, AutoTurnSetting |
| Low-level | PaperMeshData, PaperPattern, PaperNode, PaperMeshUtility, PaperMaterialData, RendererFactory, BookRenderer, MeshFactory, PaperMeshDataPool |
Development
From the workspace root:
pnpm install
pnpm build # build the library
pnpm dev # build library + start demo app