ComponentMgr Guide
The Three.js Configurator is a headless Three.js library — it has zero UI dependencies. You bring your own Vue, React, or vanilla UI and wire it up through the event and method API.
What the Library Is
The configurator manages snap-based 3D block assembly in a Three.js scene:
- Parses GLTF files into typed
Snappable+Socketobjects - Handles hover raycasting, snap-matrix calculation, ghost preview, and collision detection
- Emits events (
block-placed,block-removed,block-selected) that your UI reacts to - Exposes an imperative API for rotation, selection, socket visibility, and serialisation
Architecture
Integration Pattern
A typical integration uses three objects working together:
- Your SceneManager — owns the Three.js
Scene,Camera, and render loop - ComponentMgr — owns block lifecycle, snapping, and collision
- CanvasInputAdapter — translates canvas pointer events into NDC coordinates and forwards them to ComponentMgr
Quick Start
This section shows the minimum code needed to get a working snap-based 3D configurator scene in five steps.
Prerequisites
- A Three.js scene with a camera and a render loop
- A
.glbfile with at least one block - The configurator library imported into your project
Step 1 — Parse the GLTF
copyExtrasToUserData must be called first to ensure metadata visibility. The returned blocks map is what you reference to get a Snappable.
import { GltfBlockParser } from './configurator';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
const loader = new GLTFLoader();
const gltf = await loader.loadAsync('/path/to/blocks.glb');
GltfBlockParser.copyExtrasToUserData(gltf.scene);
const { blocks, blocksData } = await GltfBlockParser.parse(gltf);
Step 2 — Create ComponentMgr
ComponentMgr owns the block lifecycle and snapping.
import { ComponentMgr } from './configurator';
const componentMgr = new ComponentMgr({
camera: myCamera,
scene: myScene,
});
Step 3 — Wire Canvas Input
CanvasInputAdapter bridges DOM pointer events to NDC coordinates.
import { CanvasInputAdapter } from './configurator';
const inputAdapter = new CanvasInputAdapter({
$el: myCanvas,
componentMgr,
});
Step 4 — Set a Block as Current
const snappable = blocks.get('leg-short');
componentMgr.setCurrent(snappable);
Step 5 — Call tick() in Render Loop
ComponentMgr.tick() must be called every frame.
function animate() {
requestAnimationFrame(animate);
componentMgr.tick();
renderer.render(myScene, myCamera);
}
animate();
Raw calculations
To dive deeper into the snapping calculations, check out the Math page.