The 3D viewer#
The viewer plays any sequence of moves on a 3D cube, from any starting state.
It is the same component everywhere it appears — on a case page, inside a
drill, from the timer's solve list, or standalone at /viewer/.
The controls#
- Play / pause — runs the sequence at the current speed.
- Step back / step forward — one move at a time. Stepping is exact: the cube snaps to the state after that move rather than interpolating.
- Scrub — drag the timeline anywhere, forward or backward. Dragging backwards genuinely un-turns the cube; nothing is re-simulated from the start, so scrubbing stays smooth on a long track.
- Speed — from
viewer.speed_mintoviewer.speed_max(0.25× to 8× as shipped, default 2×), in moves per second. - Savepoints — mark the current position with a label. Savepoints appear as ticks on the timeline; clicking one jumps straight there. This is the feature to use when a long solve has one moment you want to watch twenty times.
- Reset — back to the initial state.
The move list under the timeline is live: the current move is highlighted, and clicking any move seeks to it.
Keyboard#
| Key | Action |
|---|---|
Space |
Play / pause |
← → |
Step one move |
Home End |
Jump to start / end |
+ - |
Faster / slower |
M |
Add a savepoint here |
N |
Toggle the flat net |
R |
Reset |
Step segments#
A track is a list of steps, not one flat move list, and each step can carry
a label and a phase (cross, f2l, oll, pll). The timeline is drawn in
segments coloured by phase, so a full solve reads at a glance: blue cross,
green F2L, amber OLL, red PLL. Hovering a segment shows its label.
For a single algorithm this is one segment and the colouring is not very interesting. For a full solve it is the most useful thing on the screen.
The flat net#
The net is the folded-out cube — the classic T-shaped layout with U on top, then L F R B in a row, then D. It is driven by the same timeline as the 3D view, so the two are always showing the same state, and you can have both on screen at once or toggle between them.
The net is better than the 3D view for two things: seeing all six faces at once (no hidden back), and printing. It renders as plain SVG.
Loading anything into the viewer#
The standalone viewer at /viewer/ accepts:
- a scramble — paste any Singmaster sequence, get a cube in that state;
- a scramble plus an algorithm — the usual "here is the case, here is the solution" pair;
- a full track as JSON — multiple labelled steps, savepoints, a camera hint, an arbitrary starting state.
A track does not have to end solved. A track that starts from a solved cube and applies a scramble is a perfectly good track; so is one that solves the cross and stops.
Sharing: permalinks and copy#
Everything in the viewer is a URL.
| Form | Looks like | Use it for |
|---|---|---|
| Human-typable | /viewer/?scramble=R+U+R%27&alg=R+U+R%27+U%27 |
Quick sharing, hand-editing |
| Encoded track | /viewer/?t=<base64url of the JSON> |
Anything with steps, labels or savepoints |
| Stored track | /viewer/?id=<id> |
Tracks too long for a URL |
The Copy button gives you the track as JSON; the Permalink button gives
you a URL, automatically choosing the shortest form that fits. When a track is
too long to encode in a URL, the viewer posts it to POST /api/v1/tracks,
which stores it and returns a short id — so the link keeps working, but only on
that instance.
The JSON format is documented in Developer → Cube engine. It is versioned, so a permalink you saved will keep working.
Permalinks are local
This app runs on your machine. A /viewer/?t=… link works for anyone
pointing at the same instance; a ?id=… link only works against the
instance that stored it. The ?t= and ?scramble= forms are the portable
ones.
Colours and orientation#
The sticker colours come from viewer.colors in config.yml and default to
the standard western scheme: white U, yellow D, green F, blue B, red R, orange
L. An administrator can change them — see
Configuration.
Drag with the mouse or a finger to orbit the cube; a track can carry an
orientation hint so that a case opens at the angle that shows it best.
Double-tap or press R to return to the default view.
Performance#
The renderer is a vendored copy of three.js in app/static/vendor/, loaded as
an ES module with no build step and no CDN. If WebGL is unavailable — an old
browser, a locked-down machine, a headless test — the viewer falls back to the
flat net, which needs nothing but SVG, and says so rather than showing an empty
box.