Files
house-plan-maker/apps/client/src/components/editor/templates/roomTemplates.ts
T
alexei.dolgolyov af8b9fe00f feat: complete house plan maker application
Full-featured house/apartment floor plan editor with:

- Turborepo monorepo (React/Vite client, Fastify/Prisma server, shared Zod schemas)
- 2D room editor with walls, doors, windows, furniture, electrical elements
- 3D room preview with Three.js (auto-hide nearest walls, bird's eye default)
- Wall projection views with interactive drag (elevation, position)
- Apartment floor plan view with room positioning
- Copy/paste, alignment tools, measurement tool, annotations
- Item-attached annotations with leader lines (visible on projections)
- Door open direction (LEFT/RIGHT/INWARD/OUTWARD) with swing arc
- Floor type textures (wood, tile, concrete, laminate, herringbone)
- Wall color picker for 3D view
- Furniture: bed, desk, wardrobe, sofa, table, chair, shelf, nightstand, dresser, bookcase, TV (with stand toggle), AC unit
- Furniture elevation support (wall-mounted items)
- Auto-save with dirty state tracking, batch save API
- Rotation-aware collision detection (SAT/OBB) with 3D elevation check
- Rotation-aware hit testing
- i18n (English/Russian) with locale-aware number formatting
- Dark mode with system preference detection
- Undo/redo, keyboard shortcuts, scale bar
- PDF/PNG/JSON export and JSON import
- Focus trap modal, toast notifications, tooltips
- Responsive layout with overlay palettes
2026-04-05 22:34:03 +03:00

119 lines
3.2 KiB
TypeScript

import type { Point, CreateRoomDto } from '@house-plan-maker/shared';
export interface RoomTemplate {
readonly id: string;
readonly name: string;
readonly description: string;
readonly icon: string;
readonly defaultWidth: number;
readonly defaultHeight: number;
readonly wallHeight: number;
readonly shape: readonly Point[];
/** Suggested door positions (positionAlongWall on wall index) */
readonly suggestedDoors: readonly { readonly wallIndex: number; readonly position: number }[];
/** Suggested window positions */
readonly suggestedWindows: readonly { readonly wallIndex: number; readonly position: number }[];
}
function rectangularShape(width: number, height: number): readonly Point[] {
return [
{ x: 0, y: 0 },
{ x: width, y: 0 },
{ x: width, y: height },
{ x: 0, y: height },
];
}
export const ROOM_TEMPLATES: readonly RoomTemplate[] = [
{
id: 'bedroom',
name: 'Bedroom',
description: 'Standard bedroom (4m x 3.5m) with door and window',
icon: '\u{1F6CF}',
defaultWidth: 4,
defaultHeight: 3.5,
wallHeight: 2.7,
shape: rectangularShape(4, 3.5),
suggestedDoors: [{ wallIndex: 3, position: 1 }],
suggestedWindows: [{ wallIndex: 1, position: 2 }],
},
{
id: 'kitchen',
name: 'Kitchen',
description: 'Kitchen (3.5m x 3m) with door',
icon: '\u{1F373}',
defaultWidth: 3.5,
defaultHeight: 3,
wallHeight: 2.7,
shape: rectangularShape(3.5, 3),
suggestedDoors: [{ wallIndex: 3, position: 1.5 }],
suggestedWindows: [{ wallIndex: 1, position: 1.5 }],
},
{
id: 'bathroom',
name: 'Bathroom',
description: 'Bathroom (2.5m x 2m)',
icon: '\u{1F6C1}',
defaultWidth: 2.5,
defaultHeight: 2,
wallHeight: 2.7,
shape: rectangularShape(2.5, 2),
suggestedDoors: [{ wallIndex: 3, position: 1 }],
suggestedWindows: [],
},
{
id: 'living-room',
name: 'Living Room',
description: 'Spacious living room (5m x 4m) with window',
icon: '\u{1F6CB}',
defaultWidth: 5,
defaultHeight: 4,
wallHeight: 2.7,
shape: rectangularShape(5, 4),
suggestedDoors: [{ wallIndex: 3, position: 1 }],
suggestedWindows: [{ wallIndex: 1, position: 2 }, { wallIndex: 2, position: 2.5 }],
},
{
id: 'office',
name: 'Office',
description: 'Home office (3m x 2.5m)',
icon: '\u{1F4BB}',
defaultWidth: 3,
defaultHeight: 2.5,
wallHeight: 2.7,
shape: rectangularShape(3, 2.5),
suggestedDoors: [{ wallIndex: 3, position: 1.25 }],
suggestedWindows: [{ wallIndex: 1, position: 1.25 }],
},
{
id: 'empty',
name: 'Empty Room',
description: 'Custom empty room (3m x 3m)',
icon: '\u25A1',
defaultWidth: 3,
defaultHeight: 3,
wallHeight: 2.7,
shape: rectangularShape(3, 3),
suggestedDoors: [],
suggestedWindows: [],
},
];
/**
* Convert a room template into a CreateRoomDto.
*/
export function templateToCreateRoomDto(
template: RoomTemplate,
name?: string,
order?: number,
): CreateRoomDto {
return {
name: name ?? template.name,
shape: [...template.shape],
width: template.defaultWidth,
height: template.defaultHeight,
wallHeight: template.wallHeight,
order: order ?? 0,
};
}