Skip to content

Editor ​

An interactive editor for drawing floor plans. In Vue, bind it with v-model; in React, pass plan and onChange; on the HTML element, set the plan property and listen for change.

vue
<script setup lang="ts">
import { ref } from 'vue'
import { FloorPlanEditor, createEmptyPlan } from '@jbaysolutions/floorplan-vue'

const plan = ref(createEmptyPlan('Head office'))
</script>

<template>
  <div style="height: 600px">
    <FloorPlanEditor v-model="plan" theme="light" :grid-size="10" :wall-thickness="12" />
  </div>
</template>
tsx
import { useState } from 'react'
import { FloorplanEditor, createEmptyPlan } from '@jbaysolutions/floorplan-react'

export function Editor() {
  const [plan, setPlan] = useState(() => createEmptyPlan('Head office'))

  return <FloorplanEditor plan={plan} onChange={setPlan} theme="light" gridSize={10} wallThickness={12} style={{ height: 600 }} />
}
html
<floorplan-editor theme="light" grid-size="10" wall-thickness="12" style="height: 600px"></floorplan-editor>

<script type="module">
  import { createEmptyPlan } from '@jbaysolutions/floorplan-elements'

  const editor = document.querySelector('floorplan-editor')
  editor.plan = createEmptyPlan('Head office')
  editor.addEventListener('change', (e) => console.log('new plan', e.detail.plan))
</script>

Try it on a sample house: select a wall or a room, drag it around, or pick a tool from the toolbar. The event the editor sends is shown under it.

Loading the live demo…
Draw or change something: the new plan is emitted after every edit.

Props ​

PropTypeDefaultDescription
modelValue (v-model)FloorPlan | nullnullThe plan (the whole building) being edited. In React and on the element: plan.
floor (v-model:floor)string | nullground floorId of the floor being edited. See Multi-floor buildings.
theme'light' | 'dark' | 'blueprint' | 'paper' | 'mist' | 'ink' | 'graphite''light'Visual theme. See Themes.
gridSizenumber10Snap step in cm.
wallThicknessnumber12Default thickness (cm) for new walls. Can also be changed in the toolbar.
showGridbooleantrueInitial state of the grid toggle.
showDimensionsbooleantrueInitial state of the wall dimensions toggle.
formatLength(cm: number) => string"3.45 m"Formatter for lengths shown on screen.
catalogFurnitureCatalogItem[]built-inFurniture shown in the Furniture panel. Add-on packs have their own buttons and aren't affected.

In React the props have the same names (gridSize={10}). On the <floorplan-editor> element they are properties with the same names (editor.gridSize = 10); simple values also work as kebab-case attributes (grid-size="10"). Objects, arrays and functions (plan, catalog, formatLength) must be set as properties.

Events ​

EventPayloadWhen
update:modelValueFloorPlanAfter every completed change (not on every mouse move).
changeFloorPlanSame as above, for when you don't use v-model.
selection-changeSelectionThe selected wall, room, opening or furniture changed.
update:floorstringThe user switched floors.

The editor emits a new object on every change, so you can keep your own history or autosave by watching the plan.

The same events in React and on the element:

VueReactHTML element
v-model (update:modelValue, change)plan + onChange(plan)plan property + change event, detail = { plan }
@selection-changeonSelectionChange(selection)selection-change event, detail = { selection }
v-model:floor (update:floor)floor + onFloorChange(floorId)floor property + floor-change event, detail = { floor }
vue
<FloorPlanEditor
  v-model="plan"
  v-model:floor="floorId"
  @selection-change="(selection) => (selected = selection)"
/>
tsx
<FloorplanEditor
  plan={plan}
  onChange={setPlan}
  floor={floorId}
  onFloorChange={setFloorId}
  onSelectionChange={setSelected}
  style={{ height: 600 }}
/>
js
editor.addEventListener('change', (e) => save(e.detail.plan))
editor.addEventListener('selection-change', (e) => (selected = e.detail.selection))
editor.addEventListener('floor-change', (e) => console.log('now on floor', e.detail.floor))

Methods ​

In Vue, call methods through a template ref. In React, the ref is the <floorplan-editor> element itself. On the HTML element, call them on the element.

vue
<script setup lang="ts">
import { ref } from 'vue'
import { FloorPlanEditor } from '@jbaysolutions/floorplan-vue'

const editor = ref<InstanceType<typeof FloorPlanEditor>>()
</script>

<template>
  <FloorPlanEditor ref="editor" v-model="plan" />
  <button @click="editor?.undo()">Undo</button>
</template>
tsx
import { useRef } from 'react'
import { FloorplanEditor, type FloorplanEditorElement } from '@jbaysolutions/floorplan-react'

const editor = useRef<FloorplanEditorElement>(null)

<FloorplanEditor ref={editor} plan={plan} onChange={setPlan} style={{ height: 600 }} />
<button onClick={() => editor.current?.undo()}>Undo</button>
js
const editor = document.querySelector('floorplan-editor')
document.querySelector('#undo').addEventListener('click', () => editor.undo())
MethodDescription
undo() / redo()Step through the editor's history (up to 200 steps).
fit(animate = true)Zoom to fit the whole plan.
clear()Remove everything on the current floor (can be undone).
setFloor(id)Switch to another floor.
addFloor('above' | 'below')Add an empty floor and switch to it.
duplicateFloor()Copy the current floor's layout onto a new floor on top.
setTool(tool)'select', 'pan', 'wall', 'room', 'door', 'window' or 'furniture' (the built-in Furniture panel).
select(selection)Select an item, e.g. { kind: 'room', id }, or null.
getPlan()A copy of the current plan.

Tools ​

ToolKeyHow it works
SelectVClick to select. Drag items to move them; drag the round handles to move wall ends (connected walls follow). Dragging empty space pans.
PanHDrag to pan. You can also pan with the middle mouse button or by holding Space.
WallWClick to start, keep clicking to chain walls. Finish with Esc, Enter, right-click or by clicking the last point again. Clicking the first point closes the loop. Choose Wall or Railing in the toolbar.
RoomRDrag to draw a rectangular room, or click corners to draw any shape (click the first corner to close). Edges in the toolbar decides what goes around it: Walls, Railing (a balcony), None (an open area such as a garden) or Pool (a swimming pool). Edges that already have a wall are skipped.
DoorDHover over a wall and click. Choose single, double or sliding in the toolbar.
WindowNHover over a wall and click.
FurnitureFPick an item in the panel and click to place it. E rotates it before placing.
Add-on packse.g. GEach registered pack gets its own button and panel, which works like Furniture. The garden pack's is Garden (G).

Snapping ​

While drawing, points snap, in order of priority, to:

  1. existing corners and wall ends (ring indicator)
  2. 45° angles from the previous point (15° steps while holding Shift)
  3. the nearest wall (diamond indicator)
  4. the grid, with dashed alignment guides to other corners

Hold Alt to place a point freely, or switch snapping off with the magnet button.

Inspector ​

Selecting an item opens the inspector panel on the right:

  • Wall: wall or railing, length (typing a length moves the end point) and thickness
  • Room: name, floor finish (including grass), colour; or, for a pool, finish, sunk or raised, depths, deep end, corners and glass sides
  • Door / window: type, width, position along the wall, hinge side, swing direction
  • Furniture (and pack items): width, depth, rotation, duplicate

Keyboard shortcuts ​

KeysAction
V H W R D N FSwitch tool (plus each add-on pack's own key, e.g. G for Garden)
Ctrl Z / Ctrl Shift Z / Ctrl YUndo / redo
Delete / BackspaceDelete the selection
EscFinish drawing → back to Select → clear the selection
EnterFinish the current wall chain or polygon room
E / Shift ERotate the selected furniture by 90° clockwise / anticlockwise
Ctrl DDuplicate the selected furniture
Arrow keysMove the selected furniture by one grid step (Shift: 50 cm)
+ / - / 0Zoom in / zoom out / fit
Space (hold)Pan
Page Up / Page DownSwitch to the floor above / below

TIP

Shortcuts only apply while the editor has focus (click inside it), so they never interfere with the rest of your page.

JBay Floorplan is free for open source and companies under €1M yearly revenue. Licensing and pricing