Files
house-design/src/themes.js
m 08248c6cad Add theme system with 5 presets and selector UI
- 5 themes: Standard, Modern, Warm, Dark, Scandinavian
- ThemeManager mutates shared COLORS, clears cache, re-renders
- Updates scene background and light intensities per theme
- Theme selector buttons with color swatch in sidebar
- Exported COLORS from renderer.js for theme access
2026-02-07 12:24:58 +01:00

125 lines
3.5 KiB
JavaScript

import { COLORS } from './renderer.js';
const THEMES = {
default: {
name: 'Standard',
swatch: '#e8e0d4',
colors: {
wall: { exterior: 0xe8e0d4, interior: 0xf5f0eb },
floor: { tile: 0xc8beb0, hardwood: 0xb5894e },
ceiling: 0xfaf8f5,
door: 0x8b6914,
window: 0x87ceeb,
windowFrame: 0xd0d0d0,
grid: 0xcccccc,
selected: 0x4a90d9
},
scene: { background: 0xf0f0f0, ambientIntensity: 0.6, directionalIntensity: 0.8 }
},
modern: {
name: 'Modern',
swatch: '#f5f5f5',
colors: {
wall: { exterior: 0xf5f5f5, interior: 0xffffff },
floor: { tile: 0xe0e0e0, hardwood: 0xc4a882 },
ceiling: 0xffffff,
door: 0x333333,
window: 0xa8d4f0,
windowFrame: 0x666666,
grid: 0xe0e0e0,
selected: 0x2196f3
},
scene: { background: 0xfafafa, ambientIntensity: 0.7, directionalIntensity: 0.6 }
},
warm: {
name: 'Warm',
swatch: '#ddd0b8',
colors: {
wall: { exterior: 0xddd0b8, interior: 0xf0e8d8 },
floor: { tile: 0xb8a890, hardwood: 0x9b6b3a },
ceiling: 0xf5efe5,
door: 0x6b4423,
window: 0x8bc4e0,
windowFrame: 0x8b7355,
grid: 0xc8b8a0,
selected: 0xd48b2c
},
scene: { background: 0xf5efe5, ambientIntensity: 0.5, directionalIntensity: 0.9 }
},
dark: {
name: 'Dark',
swatch: '#3a3a3a',
colors: {
wall: { exterior: 0x3a3a3a, interior: 0x4a4a4a },
floor: { tile: 0x2a2a2a, hardwood: 0x5a4030 },
ceiling: 0x333333,
door: 0x5a4030,
window: 0x4080b0,
windowFrame: 0x555555,
grid: 0x444444,
selected: 0x64b5f6
},
scene: { background: 0x222222, ambientIntensity: 0.4, directionalIntensity: 1.0 }
},
scandinavian: {
name: 'Scandi',
swatch: '#f0ece4',
colors: {
wall: { exterior: 0xf0ece4, interior: 0xfaf6f0 },
floor: { tile: 0xe8ddd0, hardwood: 0xd4b88c },
ceiling: 0xffffff,
door: 0xc4a87a,
window: 0xc0ddf0,
windowFrame: 0xb0b0b0,
grid: 0xd8d8d8,
selected: 0x5b9bd5
},
scene: { background: 0xf8f6f2, ambientIntensity: 0.65, directionalIntensity: 0.7 }
}
};
/**
* ThemeManager — applies visual themes by mutating COLORS and re-rendering.
*/
export class ThemeManager {
constructor(renderer) {
this.renderer = renderer;
this.currentTheme = 'default';
}
applyTheme(themeId) {
const theme = THEMES[themeId];
if (!theme) return;
this.currentTheme = themeId;
// Mutate the shared COLORS object
Object.assign(COLORS.wall, theme.colors.wall);
Object.assign(COLORS.floor, theme.colors.floor);
COLORS.ceiling = theme.colors.ceiling;
COLORS.door = theme.colors.door;
COLORS.window = theme.colors.window;
COLORS.windowFrame = theme.colors.windowFrame;
COLORS.grid = theme.colors.grid;
COLORS.selected = theme.colors.selected;
// Update scene background and lights
this.renderer.scene.background.setHex(theme.scene.background);
this.renderer.scene.traverse(child => {
if (child.isAmbientLight) child.intensity = theme.scene.ambientIntensity;
if (child.isDirectionalLight) child.intensity = theme.scene.directionalIntensity;
});
// Clear cached materials/geometry and re-render to pick up new colors
this.renderer._clearFloor();
this.renderer.showFloor(this.renderer.currentFloor);
}
getThemes() {
return Object.entries(THEMES).map(([id, t]) => ({
id,
name: t.name,
swatch: t.swatch
}));
}
}