3D Projections
The 3D library supports five projection types for converting 3D scenes to 2D representations, plus an orbital camera system.
Projection Types
setProjection3D(type, config)
Change the active projection for the 3D scene.
app.setProjection3D('perspective', { fov: 60 });
app.setProjection3D('isometric');
app.setProjection3D('cabinet', { angle: 45, scale: 0.5 });
Perspective
Mimics human vision with realistic depth perception. Objects farther away appear smaller.
app.setProjection3D('perspective', {
fov: 60, // Field of view in degrees (default: 60)
aspect: 1, // Aspect ratio (default: 1)
near: 0.1, // Near clipping plane (default: 0.1)
far: 1000 // Far clipping plane (default: 1000)
});
Best for: Realistic 3D scenes, product visualization, games
Orthographic
Maintains parallel lines and true proportions. No perspective foreshortening.
app.setProjection3D('orthographic', {
width: 400, // View width (default: 400)
height: 400, // View height (default: 400)
near: -500, // Near plane (default: -500)
far: 500 // Far plane (default: 500)
});
Best for: Technical drawings, architectural plans, UI elements
Isometric
Classic 30-degree axonometric view with equal visual weight on all three axes.
app.setProjection3D('isometric', {
scale: 1 // Scale factor (default: 1)
});
Internally applies rotations of ~35.264° (X) and 45° (Y) to achieve the standard isometric angle.
Best for: Strategy games, architectural diagrams, infographics
Cabinet
Oblique projection with depth scaled to half, popular in technical illustration.
app.setProjection3D('cabinet', {
angle: 45, // Shear angle in degrees (default: 45)
scale: 0.5 // Depth scale factor (default: 0.5)
});
Best for: Furniture drawings, mechanical parts, technical manuals
Cavalier
Oblique projection with full depth scale (no depth reduction).
app.setProjection3D('cavalier', {
angle: 45 // Shear angle in degrees (default: 45)
});
Identical to cabinet but with scale: 1.0 — depth lines are not shortened.
Best for: Military projections, simple 3D diagrams
Projection Comparison
| Projection | Depth Reduction | Parallel Lines | Realistic | Use Case |
|---|---|---|---|---|
| Perspective | Yes (1/z) | No | Yes | Visualization |
| Orthographic | No | Yes | No | Technical |
| Isometric | No | Yes | No | Games/Infographics |
| Cabinet | Half (0.5) | Yes | Partial | Technical |
| Cavalier | No | Yes | No | Diagrams |
Camera
setCamera3D(config)
Set the 3D camera position, target, and up vector.
app.setCamera3D({
position: { x: 3, y: 2, z: 5 },
target: { x: 0, y: 0, z: 0 },
up: { x: 0, y: 1, z: 0 }
});
Parameters:
| Param | Type | Default | Description |
|---|---|---|---|
position |
{x,y,z} | {x:0, y:0, z:5} | Camera position in world space |
target |
{x,y,z} | {x:0, y:0, z:0} | Point the camera looks at |
up |
{x,y,z} | {x:0, y:1, z:0} | Up direction vector |
Standalone Camera API
import * as Camera3D from './js/3d/projection/Camera3D.js';
// Create camera
const camera = Camera3D.createCamera({
position: { x: 0, y: 0, z: 5 },
target: { x: 0, y: 0, z: 0 }
});
// Get view matrix (4x4 lookAt matrix)
const viewMatrix = Camera3D.getViewMatrix(camera);
// Orbit around target (horizontal and vertical angles in radians)
const orbited = Camera3D.orbit(camera, Math.PI / 6, Math.PI / 12);
// Re-target while maintaining distance
const retargeted = Camera3D.lookAtTarget(camera, { x: 1, y: 0, z: 0 });
Orbit constraints: Elevation is clamped to [0.01, PI-0.01] radians to prevent gimbal lock at the poles.
Standalone Projection API
import * as Projections from './js/3d/projection/Projections.js';
// Get projection matrix by name
const projMatrix = Projections.getProjection('perspective', { fov: 60 });
// Project 3D vertices to 2D screen coordinates
const result = Projections.projectVertices(
vertices3D, // Array of {x, y, z}
viewProjMatrix, // Combined view * projection matrix
halfWidth, // Canvas width / 2
halfHeight // Canvas height / 2
);
// result: { vertices2D: [{x, y}, ...], depth: number }
Coordinate system: Screen Y is flipped (screenY = -ndcY * halfH + halfH) to match canvas conventions where Y increases downward.