canvas-js-3d 0.1.0 → 0.1.1
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 +220 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,15 +1,225 @@
|
|
|
1
|
-
|
|
1
|
+
# canvas-js-3d
|
|
2
2
|
|
|
3
|
+
A lightweight 3D graphics library that uses the Canvas API for wireframe rendering. Zero dependencies, pure vanilla JavaScript.
|
|
3
4
|
|
|
5
|
+
## Features
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
- **Pure JavaScript** - No external dependencies
|
|
8
|
+
- **ES6 Modules** - Clean, modular architecture
|
|
9
|
+
- **Wavefront OBJ Loading** - Import 3D models from .obj files
|
|
10
|
+
- **Wireframe Rendering** - Canvas 2D-based edge rendering
|
|
11
|
+
- **Transform System** - Position, rotation, and scale
|
|
12
|
+
- **Frame Update Hook** - Per-frame logic with delta-time for framerate-independent animations
|
|
6
13
|
|
|
7
|
-
|
|
8
|
-
* ES6 Modules - Clean, modular architecture
|
|
9
|
-
* Wavefront OBJ Loading - Import 3D models from .obj files
|
|
10
|
-
* Wireframe Rendering - Canvas 2D-based edge rendering
|
|
11
|
-
* Transform System - Position, rotation, and scale
|
|
12
|
-
* Frame Update Hook - Per-frame client logic with delta-time for framerate-independent animations
|
|
13
|
-
* Scene Object System - Manage multiple meshes with independent transforms
|
|
14
|
-
* Mobile Responsive Demo - Touch-friendly demo with responsive layout
|
|
14
|
+
## Quick Start
|
|
15
15
|
|
|
16
|
+
### Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install canvas-js-3d
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Tutorial: Load and Render an OBJ
|
|
23
|
+
|
|
24
|
+
Here's a minimal example that loads a 3D model and renders it with rotation:
|
|
25
|
+
|
|
26
|
+
```html
|
|
27
|
+
<!DOCTYPE html>
|
|
28
|
+
<html>
|
|
29
|
+
<head>
|
|
30
|
+
<title>canvas-js-3d Example</title>
|
|
31
|
+
</head>
|
|
32
|
+
<body>
|
|
33
|
+
<canvas id="canvas" width="500" height="500"></canvas>
|
|
34
|
+
<script type="module" src="app.js"></script>
|
|
35
|
+
</body>
|
|
36
|
+
</html>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```javascript
|
|
40
|
+
// app.js
|
|
41
|
+
import { Engine, SceneObject, Transform, Vector3, WavefrontMeshConverter } from 'canvas-js-3d';
|
|
42
|
+
|
|
43
|
+
// Get canvas and create engine with foreground/background colors
|
|
44
|
+
const canvas = document.getElementById('canvas');
|
|
45
|
+
const engine = new Engine(canvas, 'green', 'black');
|
|
46
|
+
|
|
47
|
+
// Load an OBJ mesh from URL
|
|
48
|
+
const mesh = await WavefrontMeshConverter.fromUrl('./model.obj');
|
|
49
|
+
|
|
50
|
+
// Create a scene object with position, rotation, and scale
|
|
51
|
+
const obj = new SceneObject(
|
|
52
|
+
mesh,
|
|
53
|
+
new Transform(new Vector3(0, 0, 5), 0, 1) // position, rotation, scale
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
// Add to engine
|
|
57
|
+
engine.addSceneObject(obj);
|
|
58
|
+
|
|
59
|
+
// Animate: rotate the object each frame
|
|
60
|
+
engine.onUpdate = (deltaTime) => {
|
|
61
|
+
obj.transform.rotation += Math.PI * 0.5 * deltaTime;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// Start the render loop
|
|
65
|
+
engine.start();
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Alternative: Create a Mesh Manually
|
|
69
|
+
|
|
70
|
+
If you don't want to load an OBJ file, you can create geometry directly:
|
|
71
|
+
|
|
72
|
+
```javascript
|
|
73
|
+
import { Engine, Mesh, SceneObject, Transform, Vector3 } from 'canvas-js-3d';
|
|
74
|
+
|
|
75
|
+
const canvas = document.getElementById('canvas');
|
|
76
|
+
const engine = new Engine(canvas, 'cyan', 'black');
|
|
77
|
+
|
|
78
|
+
// Define vertices for a cube
|
|
79
|
+
const vertices = [
|
|
80
|
+
new Vector3(-1, -1, -1), // 0: back-bottom-left
|
|
81
|
+
new Vector3( 1, -1, -1), // 1: back-bottom-right
|
|
82
|
+
new Vector3( 1, 1, -1), // 2: back-top-right
|
|
83
|
+
new Vector3(-1, 1, -1), // 3: back-top-left
|
|
84
|
+
new Vector3(-1, -1, 1), // 4: front-bottom-left
|
|
85
|
+
new Vector3( 1, -1, 1), // 5: front-bottom-right
|
|
86
|
+
new Vector3( 1, 1, 1), // 6: front-top-right
|
|
87
|
+
new Vector3(-1, 1, 1), // 7: front-top-left
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
// Define faces as arrays of vertex indices
|
|
91
|
+
const faceIndices = [
|
|
92
|
+
[0, 1, 2, 3], // back
|
|
93
|
+
[4, 5, 6, 7], // front
|
|
94
|
+
[0, 4, 7, 3], // left
|
|
95
|
+
[1, 5, 6, 2], // right
|
|
96
|
+
[3, 2, 6, 7], // top
|
|
97
|
+
[0, 1, 5, 4], // bottom
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
const mesh = new Mesh(vertices, faceIndices);
|
|
101
|
+
const cube = new SceneObject(mesh, new Transform(new Vector3(0, 0, 5), 0, 1));
|
|
102
|
+
|
|
103
|
+
engine.addSceneObject(cube);
|
|
104
|
+
engine.onUpdate = (dt) => { cube.transform.rotation += dt; };
|
|
105
|
+
engine.start();
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Architecture
|
|
109
|
+
|
|
110
|
+
### Rendering Pipeline
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
Mesh (vertices + face indices)
|
|
114
|
+
↓
|
|
115
|
+
SceneObject (applies Transform: scale → rotate → translate)
|
|
116
|
+
↓
|
|
117
|
+
Camera.projectSceneObject() (perspective projection via x/z, y/z division)
|
|
118
|
+
↓
|
|
119
|
+
Renderer (Canvas 2D wireframe edges)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Module Structure
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
src/
|
|
126
|
+
├── index.js # Main entry point
|
|
127
|
+
├── math/ # Vector and transform math
|
|
128
|
+
│ ├── vector2.js
|
|
129
|
+
│ ├── vector3.js
|
|
130
|
+
│ └── transform.js
|
|
131
|
+
├── core/ # Scene data structures and engine
|
|
132
|
+
│ ├── mesh.js
|
|
133
|
+
│ ├── sceneObject.js
|
|
134
|
+
│ └── engine.js
|
|
135
|
+
├── rendering/ # Display components
|
|
136
|
+
│ ├── camera.js
|
|
137
|
+
│ └── renderer.js
|
|
138
|
+
└── wavefront-loading/ # OBJ file loading
|
|
139
|
+
├── index.js
|
|
140
|
+
├── wavefront-mesh-converter.js
|
|
141
|
+
├── wavefront-file-loader.js
|
|
142
|
+
├── wavefront-lexer.js
|
|
143
|
+
└── wavefront-parser.js
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Usage
|
|
147
|
+
|
|
148
|
+
### Engine
|
|
149
|
+
|
|
150
|
+
The main render loop and scene manager.
|
|
151
|
+
|
|
152
|
+
```javascript
|
|
153
|
+
const engine = new Engine(canvas, 'white', 'black'); // canvas, fgColor, bgColor
|
|
154
|
+
|
|
155
|
+
engine.addSceneObject(obj); // Add object to scene
|
|
156
|
+
engine.removeSceneObject(obj); // Remove object from scene
|
|
157
|
+
|
|
158
|
+
engine.onUpdate = (deltaTime) => {
|
|
159
|
+
// Called every frame with time since last frame (in seconds)
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
engine.start(); // Start render loop
|
|
163
|
+
engine.stop(); // Stop render loop
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### SceneObject
|
|
167
|
+
|
|
168
|
+
Combines a Mesh with a Transform for positioning in the scene.
|
|
169
|
+
|
|
170
|
+
```javascript
|
|
171
|
+
const obj = new SceneObject(mesh, transform);
|
|
172
|
+
|
|
173
|
+
obj.mesh; // The Mesh geometry
|
|
174
|
+
obj.transform; // The Transform (position, rotation, scale)
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Transform
|
|
178
|
+
|
|
179
|
+
Defines position, rotation, and scale. Transform order: scale → rotate → translate.
|
|
180
|
+
|
|
181
|
+
```javascript
|
|
182
|
+
const transform = new Transform(
|
|
183
|
+
new Vector3(0, 0, 5), // position
|
|
184
|
+
0, // rotation (radians, XZ plane)
|
|
185
|
+
1.0 // scale (uniform)
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
transform.position = new Vector3(1, 2, 3);
|
|
189
|
+
transform.rotation += Math.PI * 0.5;
|
|
190
|
+
transform.scale = 2.0;
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Vector3
|
|
194
|
+
|
|
195
|
+
Immutable-style 3D vector math. Methods return new instances.
|
|
196
|
+
|
|
197
|
+
```javascript
|
|
198
|
+
const v = new Vector3(1, 2, 3);
|
|
199
|
+
|
|
200
|
+
v.getTranslated(new Vector3(1, 0, 0)); // Returns new Vector3(2, 2, 3)
|
|
201
|
+
v.getScaled(2); // Returns new Vector3(2, 4, 6)
|
|
202
|
+
v.getRotatedXZ(Math.PI / 2); // Rotate around Y axis
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### WavefrontMeshConverter
|
|
206
|
+
|
|
207
|
+
Load OBJ files from various sources.
|
|
208
|
+
|
|
209
|
+
```javascript
|
|
210
|
+
// From URL
|
|
211
|
+
const mesh = await WavefrontMeshConverter.fromUrl('./model.obj');
|
|
212
|
+
|
|
213
|
+
// From File object (e.g., from <input type="file">)
|
|
214
|
+
const mesh = await WavefrontMeshConverter.fromFile(file);
|
|
215
|
+
|
|
216
|
+
// From file dialog (opens browser file picker)
|
|
217
|
+
const mesh = await WavefrontMeshConverter.fromFileDialog();
|
|
218
|
+
|
|
219
|
+
// From raw OBJ text
|
|
220
|
+
const mesh = WavefrontMeshConverter.fromText(objString);
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## License
|
|
224
|
+
|
|
225
|
+
MIT
|