Blog · · 4 min read
Take-apart 3D: building exploded views procedurally in three.js
An exploded view in three.js is one number, from 0 to 1, that slides every part along its own offset vector. Give each part a closed position and an open position, multiply the open offset by that number every frame, and the whole machine comes apart and goes back together. The craft is in what you do around it: stagger the parts, give the number a fast attack and a slow release, and make repeated parts instances so thousands of bolts cost almost nothing. Here is how three of our newest demos do it.
By the AnimatedWebs team
The three demos in this post are a six-axis robot arm, a 75 percent mechanical keyboard and a dual-boiler espresso machine. They are new in our repository and not published yet, so there are no links to them here. Everything below comes from their source, and the closing section points to exploded-view templates that are in the catalog today. None of the three loads a model file: every part is built from primitives in code.
One number, many offsets
The keyboard is the plainest version. It has six layers, bottom to top: case, foam, circuit board, plate, switches and keycaps. Each layer stores its resting height and an explode distance, in key-pitch units: the case drops 1.6, the foam 0.8, the circuit board stays put, the plate rises 1.15, the switches 2.15 and the keycaps 4.7. Every frame the layer's height is its rest height plus the distance times the explode amount.
LAYERS.forEach((L, i) => {
// focus lifts the layer you are reading a little further
const lift = focus >= 0 ? Math.max(0, 1 - Math.abs(focus - i)) * 0.5 * e : 0;
layer[L.id].position.y = L.explode * e + lift;
});Choosing the distances is the design work. The circuit board is the anchor, so it does not move, and the gaps grow toward the top so the keycaps, which are what people recognize, clear everything and read first.
The espresso machine uses the same idea with two vectors per assembly. Each group has a strip vector, where it goes when the shell comes off, and an explode vector, where it goes in the diagram. Its position is the strip vector times one amount plus the explode vector times another. Two numbers give you three states: whole, stripped to show the internals, and exploded.
Stagger, or it looks like a zoom
If every part moves at the same moment, the result reads as scaling, not disassembly. The robot arm offsets each joint by 0.08 of the timeline. Joint k starts separating when the explode amount passes 0.08 times k and finishes 0.45 later, using a smoothstep. Each joint unit is also four layers, a reducer, a motor, an encoder and a cover, and those slide out along the joint axis like drawers a beat after their joint lets go, between 0.18 and 0.62 past the same offset. The chain comes apart base first, then each unit opens.
for (let k = 0; k < 6; k++) {
const o = k * 0.08;
chain[k] = smooth(o, o + 0.45, E); // joint leaves its parent
fan[k] = smooth(o + 0.18, o + 0.62, E); // its layers slide out
}The espresso machine does a version of this with order instead of offsets: the shell fades only once it is clear of the internals, so the move reads before the cover disappears.
Attack fast, release slow
The explode amount itself is never set directly. In the arm demo you hold a button to take it apart. A target jumps to 1 while you hold and returns to 0 when you let go, and the amount chases the target with an exponential: a rate of 3.4 per second going out and 1.3 coming back. Opening feels responsive, and closing feels like something heavy settling. The keyboard does the same for a key press, with rates of 42 down and 11 back up.
On the espresso page there is no button. Scrolling blends seven camera poses, and each pose carries its own strip and explode values. Between poses everything is interpolated with a smoothstep and then eased toward the target at a rate of about 4.2 per second, so a fast scroll never snaps the machine apart.
Repeated parts are instances
A keyboard has 83 keys and a lot of small parts under them: switch bottoms, leaves, sockets, diodes, wires, stabilizers and screws. Giving each its own mesh would mean hundreds of draw calls. Instead each part type is one InstancedMesh, which draws every copy in a single call, and the demo writes each copy's matrix once per frame.
The arm adds a rule that makes explosion work with instances: every instance remembers the object it rides on and a local matrix, and is re-posed from that parent's world matrix each frame. When a joint unit slides out, its bolts, gear teeth and cable clips go with it, with no extra code per explosion. The espresso machine does the same through small kits that re-pose their instanced parts from the same group offsets, so one number still takes the whole machine apart.
for (const it of items) {
tmp.multiplyMatrices(it.parent.matrixWorld, it.local);
mesh.setMatrixAt(i++, tmp);
}
mesh.instanceMatrix.needsUpdate = true;What makes it read as engineering
- Dim the rest. The arm has an isolate gesture that lifts one joint and dims the other six, using a per-part color multiplier on the instances.
- Name the parts. The espresso machine anchors callouts with a part number and a name to the exploded parts, which is what makes the diagram look like a service manual.
- Respect the pause button. Gestures still respond when the page is paused, but nothing moves on its own.
- Keep it in frame. The camera distance grows with the explode amount (the arm adds up to 32 percent) so the exploded machine still fits the frame.
Exploded views you can open today
Three catalog templates show the technique. Halo Headphones Exploded View has a live demo. Mechanical Keyboard Layer Explode and Exploded AI Chip Stack cover the layered version. Each page has the full build prompt. For another way to turn one input into a whole scene, read A year of sunlight in six seconds.


