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
This commit is contained in:
@@ -52,6 +52,28 @@
|
||||
.room-item.active { background: #4a90d9; color: #fff; }
|
||||
.room-item .area { font-size: 11px; opacity: 0.7; }
|
||||
|
||||
.theme-btn {
|
||||
display: inline-block;
|
||||
padding: 4px 10px;
|
||||
margin: 2px 3px 2px 0;
|
||||
border: 2px solid #ccc;
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.theme-btn.active { border-color: #4a90d9; }
|
||||
.theme-swatch {
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 2px;
|
||||
vertical-align: middle;
|
||||
margin-right: 4px;
|
||||
border: 1px solid rgba(0,0,0,0.15);
|
||||
}
|
||||
|
||||
#info {
|
||||
position: fixed;
|
||||
bottom: 16px;
|
||||
@@ -74,6 +96,8 @@
|
||||
<div id="floor-buttons"></div>
|
||||
<h3>Rooms</h3>
|
||||
<div id="room-list"></div>
|
||||
<h3>Theme</h3>
|
||||
<div id="theme-buttons"></div>
|
||||
</div>
|
||||
|
||||
<div id="info">Click a room to select it. Click furniture to edit. Scroll to zoom, drag to orbit.</div>
|
||||
@@ -90,6 +114,7 @@
|
||||
import { HouseRenderer } from './renderer.js';
|
||||
import { DesignState } from './state.js';
|
||||
import { InteractionManager } from './interaction.js';
|
||||
import { ThemeManager } from './themes.js';
|
||||
|
||||
const viewer = document.getElementById('viewer');
|
||||
const houseRenderer = new HouseRenderer(viewer);
|
||||
@@ -97,6 +122,7 @@
|
||||
let selectedRoom = null;
|
||||
let designState = null;
|
||||
let interaction = null;
|
||||
let themeManager = null;
|
||||
|
||||
houseRenderer.loadHouse('../data/sample-house.json').then(async (house) => {
|
||||
document.getElementById('house-name').textContent = house.name;
|
||||
@@ -117,8 +143,10 @@
|
||||
}
|
||||
});
|
||||
|
||||
themeManager = new ThemeManager(houseRenderer);
|
||||
buildFloorButtons();
|
||||
buildRoomList();
|
||||
buildThemeButtons();
|
||||
}).catch(err => {
|
||||
document.getElementById('house-name').textContent = 'Error loading data';
|
||||
document.getElementById('info').textContent = err.message;
|
||||
@@ -170,6 +198,23 @@
|
||||
viewer.addEventListener('roomclick', (e) => {
|
||||
selectRoom(e.detail.roomId);
|
||||
});
|
||||
|
||||
function buildThemeButtons() {
|
||||
const container = document.getElementById('theme-buttons');
|
||||
container.innerHTML = '';
|
||||
for (const theme of themeManager.getThemes()) {
|
||||
const btn = document.createElement('button');
|
||||
btn.className = 'theme-btn' + (theme.id === themeManager.currentTheme ? ' active' : '');
|
||||
btn.innerHTML = `<span class="theme-swatch" style="background:${theme.swatch}"></span>${theme.name}`;
|
||||
btn.addEventListener('click', () => {
|
||||
themeManager.applyTheme(theme.id);
|
||||
document.querySelectorAll('.theme-btn').forEach(b => b.classList.remove('active'));
|
||||
btn.classList.add('active');
|
||||
buildRoomList(); // re-render room list since floor was rebuilt
|
||||
});
|
||||
container.appendChild(btn);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user