Galle, LK--:--5/6 sites live

Planform Studio: Browser CAD for Hotel Concepts in SVG and Three.js

Metre-accurate SVG drafting, hand-calibrated reference images, 1–12 independent storeys and a strict object budget — CAD that stays honest about being concept design.

6 Jul 20264 min read#SVG#Three.js#React#CAD
Planform Studio

Hotel developers in Sri Lanka often start with a drone photo of a sloping plot and a sketch on paper. The next step is usually an architect's CAD seat, which is expensive for a conversation that's still about "how many rooms could fit here?"

Planform Studio is a browser workspace for that conversation: image-assisted floor plans and multi-storey hotel concepts, edited as SVG geometry in metres, inspected storey by storey in Three.js, and downloaded as local files. No backend, no API key.

Concept design only — not construction-ready, code-certified or structurally verified. The app says this on every export, and so does this post.

Planform Studio workspace


Decision 1 — SVG for drafting, Three.js only for looking

A floor plan needs millimetre precision, infinite zoom, clean print output and a click target per wall and room. SVG gives all four natively: every room is a DOM node with its own events, zoom is a viewBox change, and exports are vector. WebGL is great at rendering and bad at being a drafting surface.

So the 2D editor is SVG, and Three.js is a viewer: Whole building renders visible storeys together; Active floor only isolates one floor at its true elevation. All floors share one plan coordinate system, so hiding a middle floor doesn't collapse the ones above. If WebGL 2 is missing, the 2D editor and calculators still work.

Decision 2 — calibrate images, never interpret them

Import a PNG, JPEG or WebP (up to 15 MB / 32 MP). On a flat drawing, pick two points and confirm their known distance — or enter the full image width — and the underlay is scaled. Position, rotation, opacity and visibility are editable. Calibration changes the image scale, never existing room dimensions.

Two explicit refusals:

  • No AI tracing. Reference images are calibrated and traced by hand. A model guessing walls from a photo produces confident nonsense at architectural scale.
  • No perspective photos for scale. A perspective photograph cannot supply a reliable uniform scale, and the app says so instead of pretending.

Decision 3 — a building is a stack of independent plans

A Building v3 document holds 1–12 independent Project v2 plans. Floors can be selected, renamed, added, duplicated, reordered, hidden or locked. Repeated starting layouts become independently editable plans, not linked copies — because the third floor of a real hotel always ends up different from the second. Whole-building undo/redo keeps 40 steps.

There's a hard budget: 1,500 objects per building, 250 per floor, including rooms, openings and furniture. Not every input combination is accepted (12 storeys × 8 bays per side exceeds it), and the app explains why rather than freezing the tab.


Hotel presets

Projects → Hotels opens a searchable catalogue with a storey filter. A preset gives a dimensional brief — guest module depth 5.8–8.5 m, corridor 1.8–3.2 m, and so on — which are zoning dimensions including entry and ensuite, not finished clear widths. The ground floor holds public and service zones; upper floors hold guest modules with aligned cores.

Applying a preset replaces the whole building in one undoable change, behind a confirmation checkbox that resets whenever the proposal or source changes. The same modal has 100 mountain-cabana concepts (MC-001–MC-100: ten families × ten variations).

Keyboard-first drafting

KeysAction
V H R D W B MSelect, pan, room, door, window, furniture, measure
Scroll · Space-dragZoom at pointer · pan
F G S · AltFit, grid, snap · bypass snap during a gesture
Shift while measuringOrthogonal measurement
⌘Z · ⌘⇧Z · ⌘SUndo · redo · download building JSON
⌘K · ?Command search · drafting guide

Engineering

React + TypeScript + Vite on Node 24 LTS. npm test runs Vitest suites; npm run build type-checks with tsc -b before bundling, so a type error never reaches dist/. The geometry engine is plain functions over metre coordinates — the SVG and Three.js views are both projections of the same document.

See the case study →