@robinweitzel/floor-planner
v1.1.0
Published
Interactive 2D floor-plan editor — draw walls, place doors/windows and furniture on an HTML Canvas
Maintainers
Readme
floor-planner
Interactive 2D floor-plan editor — draw walls, place doors/windows and furniture on an HTML Canvas.
Install
npm install floor-plannerQuick start
import { FloorPlanner } from 'floor-planner';
// 1. Create
const planner = new FloorPlanner(document.getElementById('editor')!, {
mode: 'edit',
snap: { grid: true, endpoint: true, gridSize: 10 },
selectableTypes: ['sofa'],
});
// 2. Register furniture types before placing them
planner.registerFurniture({
id: 'sofa', label: 'Sofa', shape: 'rectangle',
defaultWidth: 80, defaultHeight: 35,
});
// 3. Activate a tool
planner.setTool('furniture', { typeId: 'sofa' });
// 4. Listen for events
planner.on('change', ({ plan }) => saveToServer(plan));
// 5. Serialize / restore
const data = planner.toJSON();
planner.loadJSON(data);
// 6. Clean up
planner.destroy();API
new FloorPlanner(container, options?)
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| mode | 'edit' \| 'view' | 'edit' | Initial interaction mode |
| snap.grid | boolean | true | Snap to grid |
| snap.endpoint | boolean | true | Snap to wall endpoints |
| snap.gridSize | number | 10 | Grid cell size in px |
| selectableTypes | string[] | [] | Furniture type IDs selectable in view mode |
| maxHistoryDepth | number | 50 | Undo stack limit |
| shortcuts | ShortcutMap | (see below) | Override or disable keyboard shortcuts |
Methods
| Method | Description |
|--------|-------------|
| registerFurniture(config) | Register a furniture type so it can be placed on the plan |
| setMode(mode) | Switch between 'edit' and 'view' modes |
| setTool(tool, options?) | Activate a drawing/editing tool (see below) |
| toJSON() | Serialize the floor plan to a plain object |
| loadJSON(data) | Replace the floor plan with previously serialized data (clears undo) |
| on(event, handler) | Subscribe to an event; returns an unsubscribe function |
| undo() | Undo the last change |
| redo() | Redo the last undone change |
| deleteSelected() | Delete the currently selected item |
| flipDoorDirection() | Flip the swing direction of the selected door |
| zoomToFit() | Pan and zoom the viewport to fit all content |
| destroy() | Remove listeners, stop render loop, disconnect observers |
setTool(tool, options?)
| Tool | Options | Description |
|------|---------|-------------|
| 'select' | — | Select, move, resize, and rotate items |
| 'wall' | — | Draw walls by clicking start and end points |
| 'furniture' | { typeId: string } | Place a registered furniture type |
| 'opening' | { type: 'door' \| 'window' } | Place a door or window on a wall |
registerFurniture(config)
interface FurnitureTypeConfig {
id: string; // unique type identifier
label: string; // display name
shape: 'rectangle' | 'circle' | 'ellipse';
defaultWidth: number;
defaultHeight: number;
}Events
| Event | Payload | Fired when |
|-------|---------|------------|
| 'select' | { item: FurnitureItemData \| null } | Item selected/deselected in view mode |
| 'change' | { plan: FloorPlanData } | Any mutation (wall drawn, furniture moved, etc.) |
| 'tool:complete' | { tool: ToolType; result: unknown } | A tool finishes an operation |
Keyboard shortcuts
Default shortcuts (all configurable via options.shortcuts):
| Action | Default key | Description |
|--------|-------------|-------------|
| undo | Ctrl/Cmd+Z | Undo the last change |
| redo | Ctrl/Cmd+Shift+Z | Redo the last undone change |
| delete | Delete / Backspace | Remove the selected item |
| flipDirection | F | Flip door swing direction |
| escape | Escape | Cancel the current wall chain |
Customizing shortcuts
const planner = new FloorPlanner(container, {
shortcuts: {
delete: { key: 'x' }, // rebind delete to 'x'
flipDirection: false, // disable flip shortcut
undo: { key: 'z', ctrlOrCmd: true }, // keep default (or customize)
},
});Set any action to false to disable it. Omitted actions keep their defaults.
You can also call actions programmatically:
planner.deleteSelected();
planner.flipDoorDirection();Types
All public types are exported from the package entry point:
import type {
FloorPlannerOptions,
FloorPlannerMode,
ToolType,
FloorPlanData,
FurnitureTypeConfig,
FurnitureItemData,
WallData,
OpeningData,
FloorPlannerEventMap,
SnapOptions,
ShortcutMap,
KeyBinding,
Point,
Rect,
} from 'floor-planner';Per-item selectability
In view mode, items are selectable if their typeId is in selectableTypes. You can also override this per-item by setting selectable: true | false in the item's data:
planner.loadJSON({
version: 1,
walls: [],
openings: [],
furniture: [
{ id: '1', typeId: 'sofa', x: 100, y: 100, rotation: 0,
width: 80, height: 35, selectable: true },
],
});License
ISC
