@objectifthunes/three-book 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -66
- package/package.json +31 -30
package/README.md
CHANGED
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
# @objectifthunes/three-book
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
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`.
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<img src="../../docs/images/default.png" width="49%" alt="Closed book" />
|
|
7
|
+
<img src="../../docs/images/open-half.png" width="49%" alt="Book opened halfway" />
|
|
8
|
+
</p>
|
|
9
|
+
<p align="center">
|
|
10
|
+
<img src="../../docs/images/page-curl.png" width="49%" alt="Page mid-curl" />
|
|
11
|
+
<img src="../../docs/images/demo-ui.png" width="49%" alt="Demo app with tweakable controls" />
|
|
12
|
+
</p>
|
|
4
13
|
|
|
5
14
|
## Features
|
|
6
15
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
- Configurable
|
|
11
|
-
-
|
|
12
|
-
-
|
|
16
|
+
- **Drag-to-turn pages** — raycaster-based interaction, works with mouse or touch.
|
|
17
|
+
- **Programmatic page turns** — auto-turn API for scripted animations.
|
|
18
|
+
- **Per-surface textures** — assign a `THREE.Texture` (or `null`) to each cover side and page side independently.
|
|
19
|
+
- **Configurable geometry** — page/cover width, height, thickness, stiffness, color.
|
|
20
|
+
- **Built-in binding** — `StapleBookBinding` handles spine positioning out of the box.
|
|
21
|
+
- **Standard scene-graph citizen** — `Book` extends `THREE.Group`; add it, transform it, remove it like anything else.
|
|
13
22
|
|
|
14
23
|
## Installation
|
|
15
24
|
|
|
@@ -23,6 +32,8 @@ or
|
|
|
23
32
|
pnpm add @objectifthunes/three-book three
|
|
24
33
|
```
|
|
25
34
|
|
|
35
|
+
Peer dependency: `three >= 0.150.0` (ESM).
|
|
36
|
+
|
|
26
37
|
## Quick Start
|
|
27
38
|
|
|
28
39
|
```ts
|
|
@@ -34,6 +45,7 @@ import {
|
|
|
34
45
|
StapleBookBinding,
|
|
35
46
|
} from '@objectifthunes/three-book';
|
|
36
47
|
|
|
48
|
+
// 1. Set up your scene as usual
|
|
37
49
|
const scene = new THREE.Scene();
|
|
38
50
|
const camera = new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 0.1, 100);
|
|
39
51
|
camera.position.set(0, 4, 5);
|
|
@@ -42,21 +54,40 @@ const renderer = new THREE.WebGLRenderer({ antialias: true });
|
|
|
42
54
|
renderer.setSize(innerWidth, innerHeight);
|
|
43
55
|
document.body.appendChild(renderer.domElement);
|
|
44
56
|
|
|
57
|
+
// 2. Describe the book's content
|
|
45
58
|
const content = new BookContent();
|
|
46
59
|
content.direction = BookDirection.LeftToRight;
|
|
47
60
|
content.covers.push(frontOuterTex, frontInnerTex, backInnerTex, backOuterTex);
|
|
48
61
|
content.pages.push(page1Tex, page2Tex, page3Tex, page4Tex);
|
|
49
62
|
|
|
63
|
+
// 3. Create the book
|
|
50
64
|
const book = new Book({
|
|
51
65
|
content,
|
|
52
66
|
binding: new StapleBookBinding(),
|
|
53
67
|
castShadows: true,
|
|
54
68
|
alignToGround: true,
|
|
69
|
+
pagePaperSetup: {
|
|
70
|
+
width: 2,
|
|
71
|
+
height: 3,
|
|
72
|
+
thickness: 0.02,
|
|
73
|
+
stiffness: 0.2,
|
|
74
|
+
color: new THREE.Color(1, 1, 1),
|
|
75
|
+
material: null,
|
|
76
|
+
},
|
|
77
|
+
coverPaperSetup: {
|
|
78
|
+
width: 2.1,
|
|
79
|
+
height: 3.1,
|
|
80
|
+
thickness: 0.04,
|
|
81
|
+
stiffness: 0.5,
|
|
82
|
+
color: new THREE.Color(1, 1, 1),
|
|
83
|
+
material: null,
|
|
84
|
+
},
|
|
55
85
|
});
|
|
56
86
|
|
|
57
87
|
book.init();
|
|
58
88
|
scene.add(book);
|
|
59
89
|
|
|
90
|
+
// 4. Update every frame
|
|
60
91
|
const clock = new THREE.Clock();
|
|
61
92
|
function animate() {
|
|
62
93
|
requestAnimationFrame(animate);
|
|
@@ -66,17 +97,19 @@ function animate() {
|
|
|
66
97
|
animate();
|
|
67
98
|
```
|
|
68
99
|
|
|
69
|
-
##
|
|
100
|
+
## Page Dragging
|
|
70
101
|
|
|
71
|
-
|
|
102
|
+
Wire up your own pointer/raycaster, then call three methods:
|
|
72
103
|
|
|
73
104
|
```ts
|
|
74
|
-
book.startTurning(ray); //
|
|
75
|
-
book.updateTurning(ray); //
|
|
76
|
-
book.stopTurning(); //
|
|
105
|
+
book.startTurning(ray); // pointer down
|
|
106
|
+
book.updateTurning(ray); // pointer move
|
|
107
|
+
book.stopTurning(); // pointer up
|
|
77
108
|
```
|
|
78
109
|
|
|
79
|
-
## Auto
|
|
110
|
+
## Auto Turn
|
|
111
|
+
|
|
112
|
+
Turn pages programmatically:
|
|
80
113
|
|
|
81
114
|
```ts
|
|
82
115
|
import { AutoTurnDirection, AutoTurnSettings } from '@objectifthunes/three-book';
|
|
@@ -87,55 +120,37 @@ book.startAutoTurning(AutoTurnDirection.Next, settings, 3);
|
|
|
87
120
|
|
|
88
121
|
## Content Model
|
|
89
122
|
|
|
90
|
-
|
|
91
|
-
- index 0: front outer
|
|
92
|
-
- index 1: front inner
|
|
93
|
-
- index 2: back inner
|
|
94
|
-
- index 3: back outer
|
|
95
|
-
- `BookContent.pages`: page sides in order.
|
|
96
|
-
- Each entry can be:
|
|
97
|
-
- `THREE.Texture`
|
|
98
|
-
- `IPageContent` implementation
|
|
99
|
-
- `null`
|
|
100
|
-
|
|
101
|
-
`null` entries still render the base paper/cover material color.
|
|
102
|
-
|
|
103
|
-
## Lifecycle
|
|
123
|
+
**Covers** — 4 entries, one per surface:
|
|
104
124
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
125
|
+
| Index | Surface |
|
|
126
|
+
|-------|---------|
|
|
127
|
+
| 0 | Front outer |
|
|
128
|
+
| 1 | Front inner |
|
|
129
|
+
| 2 | Back inner |
|
|
130
|
+
| 3 | Back outer |
|
|
109
131
|
|
|
110
|
-
|
|
132
|
+
**Pages** — ordered list of page-side textures. Each entry can be a `THREE.Texture`, an `IPageContent` implementation, or `null` (renders the base paper color).
|
|
111
133
|
|
|
112
|
-
##
|
|
113
|
-
|
|
114
|
-
This package applies both texture map and material color.
|
|
134
|
+
## Lifecycle
|
|
115
135
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
136
|
+
1. `new Book(options)` — create.
|
|
137
|
+
2. `book.init()` — build geometry (call once).
|
|
138
|
+
3. `book.update(dt)` — call every frame.
|
|
139
|
+
4. `book.dispose()` — clean up when done.
|
|
119
140
|
|
|
120
|
-
##
|
|
141
|
+
## Material Tinting
|
|
121
142
|
|
|
122
|
-
|
|
123
|
-
- `Book`, `BookContent`, `BookDirection`
|
|
124
|
-
- `Paper`, `PaperSetup`, `PaperUVMargin`
|
|
125
|
-
- `BookBinding`, `BookBound`
|
|
126
|
-
- `StapleBookBinding`, `StapleBookBound`, `StapleSetup`
|
|
127
|
-
- Content:
|
|
128
|
-
- `IPageContent`, `PageContent`, `SpritePageContent2`
|
|
129
|
-
- Auto turn:
|
|
130
|
-
- `AutoTurnDirection`, `AutoTurnMode`, `AutoTurnSettings`, `AutoTurnSetting`
|
|
131
|
-
- Low-level:
|
|
132
|
-
- `PaperMeshData`, `PaperPattern`, `PaperNode`, `PaperMeshUtility`
|
|
133
|
-
- `PaperMaterialData`, `RendererFactory`, `BookRenderer`, `MeshFactory`, `PaperMeshDataPool`
|
|
143
|
+
Final color = `texture * paperColor`. Keep color white (`new THREE.Color(1, 1, 1)`) if you want textures to appear unmodified.
|
|
134
144
|
|
|
135
|
-
##
|
|
145
|
+
## API Surface
|
|
136
146
|
|
|
137
|
-
|
|
138
|
-
|
|
147
|
+
| Category | Exports |
|
|
148
|
+
|----------|---------|
|
|
149
|
+
| Core | `Book`, `BookContent`, `BookDirection`, `Paper`, `PaperSetup`, `PaperUVMargin` |
|
|
150
|
+
| Binding | `BookBinding`, `BookBound`, `StapleBookBinding`, `StapleBookBound`, `StapleSetup` |
|
|
151
|
+
| Content | `IPageContent`, `PageContent`, `SpritePageContent2` |
|
|
152
|
+
| Auto turn | `AutoTurnDirection`, `AutoTurnMode`, `AutoTurnSettings`, `AutoTurnSetting` |
|
|
153
|
+
| Low-level | `PaperMeshData`, `PaperPattern`, `PaperNode`, `PaperMeshUtility`, `PaperMaterialData`, `RendererFactory`, `BookRenderer`, `MeshFactory`, `PaperMeshDataPool` |
|
|
139
154
|
|
|
140
155
|
## Development
|
|
141
156
|
|
|
@@ -143,16 +158,6 @@ From the workspace root:
|
|
|
143
158
|
|
|
144
159
|
```bash
|
|
145
160
|
pnpm install
|
|
146
|
-
pnpm build
|
|
147
|
-
pnpm dev
|
|
161
|
+
pnpm build # build the library
|
|
162
|
+
pnpm dev # build library + start demo app
|
|
148
163
|
```
|
|
149
|
-
|
|
150
|
-
- `pnpm build`: builds the library package.
|
|
151
|
-
- `pnpm dev`: builds the library first, then starts demo app.
|
|
152
|
-
|
|
153
|
-
## Troubleshooting
|
|
154
|
-
|
|
155
|
-
- `404` on npm publish for scoped package:
|
|
156
|
-
- Ensure the npm token/account has permission for the target org scope.
|
|
157
|
-
- Cover/page colors look unexpectedly tinted:
|
|
158
|
-
- Check `coverPaperSetup.color` / `pagePaperSetup.color`; non-white tints textures.
|
package/package.json
CHANGED
|
@@ -1,30 +1,31 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@objectifthunes/three-book",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"type": "module",
|
|
5
|
-
"main": "./dist/index.js",
|
|
6
|
-
"types": "./dist/index.d.ts",
|
|
7
|
-
"exports": {
|
|
8
|
-
".": {
|
|
9
|
-
"import": "./dist/index.js",
|
|
10
|
-
"types": "./dist/index.d.ts"
|
|
11
|
-
}
|
|
12
|
-
},
|
|
13
|
-
"files": [
|
|
14
|
-
"dist"
|
|
15
|
-
],
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@objectifthunes/three-book",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "vite build && tsc --emitDeclarationOnly",
|
|
18
|
+
"typecheck": "tsc --noEmit",
|
|
19
|
+
"prepack": "pnpm run build"
|
|
20
|
+
},
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"three": ">=0.150.0"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"three": "^0.172.0",
|
|
26
|
+
"@types/three": "^0.172.0",
|
|
27
|
+
"typescript": "^5.7.0",
|
|
28
|
+
"vite": "^6.0.0",
|
|
29
|
+
"vite-plugin-dts": "^4.0.0"
|
|
30
|
+
}
|
|
31
|
+
}
|