3d-interior-studio / index.html
codebeat77's picture
Add 3 files
9ce43f4 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D Interior Design Studio</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/loaders/GLTFLoader.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
<style>
#designer-container {
position: relative;
width: 100%;
height: 70vh;
background-color: #f0f0f0;
overflow: hidden;
}
#room-3d-view {
width: 100%;
height: 100%;
}
.tooltip {
position: absolute;
background: rgba(0,0,0,0.7);
color: white;
padding: 5px 10px;
border-radius: 4px;
font-size: 12px;
pointer-events: none;
z-index: 100;
}
.furniture-item {
transition: all 0.2s;
cursor: pointer;
}
.furniture-item:hover {
transform: scale(1.05);
box-shadow: 0 0 15px rgba(0,0,0,0.2);
}
.color-option {
width: 30px;
height: 30px;
border-radius: 50%;
margin: 5px;
cursor: pointer;
border: 2px solid transparent;
}
.color-option.selected {
border-color: #000;
transform: scale(1.1);
}
.wall-selection {
position: absolute;
top: 10px;
left: 10px;
z-index: 10;
}
.loading-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255,255,255,0.8);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.spinner {
border: 5px solid #f3f3f3;
border-top: 5px solid #3498db;
border-radius: 50%;
width: 50px;
height: 50px;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
</head>
<body class="bg-gray-100">
<header class="bg-indigo-800 text-white shadow-lg">
<div class="container mx-auto px-4 py-6">
<div class="flex justify-between items-center">
<div class="flex items-center space-x-2">
<i class="fas fa-couch text-3xl"></i>
<h1 class="text-2xl font-bold">3D Interior Design Studio</h1>
</div>
<nav>
<ul class="flex space-x-6">
<li><a href="#" class="hover:text-indigo-200">Home</a></li>
<li><a href="#" class="hover:text-indigo-200">Templates</a></li>
<li><a href="#" class="hover:text-indigo-200">Gallery</a></li>
<li><a href="#" class="hover:text-indigo-200">Help</a></li>
</ul>
</nav>
</div>
</div>
</header>
<main class="container mx-auto px-4 py-8">
<div class="grid grid-cols-1 lg:grid-cols-4 gap-8">
<!-- Left sidebar - Controls -->
<div class="lg:col-span-1 bg-white p-6 rounded-lg shadow-md">
<h2 class="text-xl font-semibold mb-4 border-b pb-2">Design Controls</h2>
<!-- Room Creation -->
<div class="mb-6">
<h3 class="font-medium mb-2 flex items-center">
<i class="fas fa-ruler-combined mr-2"></i> Room Dimensions
</h3>
<div class="grid grid-cols-2 gap-2 mb-3">
<div>
<label class="block text-sm text-gray-600">Length (ft)</label>
<input type="number" id="room-length" value="12" min="5" max="50" class="w-full p-2 border rounded">
</div>
<div>
<label class="block text-sm text-gray-600">Width (ft)</label>
<input type="number" id="room-width" value="10" min="5" max="50" class="w-full p-2 border rounded">
</div>
</div>
<div>
<label class="block text-sm text-gray-600">Height (ft)</label>
<input type="number" id="room-height" value="8" min="5" max="20" class="w-full p-2 border rounded">
</div>
<button id="create-room-btn" class="mt-3 w-full bg-indigo-600 text-white py-2 rounded hover:bg-indigo-700 transition">
Create Room
</button>
</div>
<!-- Wall Customization -->
<div class="mb-6">
<h3 class="font-medium mb-2 flex items-center">
<i class="fas fa-paint-roller mr-2"></i> Wall Customization
</h3>
<div id="wall-selection" class="mb-3">
<label class="block text-sm text-gray-600 mb-1">Select Wall</label>
<select id="wall-select" class="w-full p-2 border rounded">
<option value="all">All Walls</option>
<option value="north">North Wall</option>
<option value="east">East Wall</option>
<option value="south">South Wall</option>
<option value="west">West Wall</option>
</select>
</div>
<div>
<label class="block text-sm text-gray-600 mb-1">Wall Color</label>
<div class="flex flex-wrap">
<div class="color-option bg-white selected" data-color="#ffffff" onclick="selectColor(this, 'wall')"></div>
<div class="color-option bg-gray-200" data-color="#e5e7eb" onclick="selectColor(this, 'wall')"></div>
<div class="color-option bg-blue-100" data-color="#dbeafe" onclick="selectColor(this, 'wall')"></div>
<div class="color-option bg-green-100" data-color="#d1fae5" onclick="selectColor(this, 'wall')"></div>
<div class="color-option bg-yellow-100" data-color="#fef3c7" onclick="selectColor(this, 'wall')"></div>
<div class="color-option bg-red-100" data-color="#fee2e2" onclick="selectColor(this, 'wall')"></div>
<div class="color-option bg-indigo-100" data-color="#e0e7ff" onclick="selectColor(this, 'wall')"></div>
<div class="color-option bg-purple-100" data-color="#ede9fe" onclick="selectColor(this, 'wall')"></div>
</div>
</div>
</div>
<!-- Floor Customization -->
<div class="mb-6">
<h3 class="font-medium mb-2 flex items-center">
<i class="fas fa-border-style mr-2"></i> Floor & Ceiling
</h3>
<div class="mb-3">
<label class="block text-sm text-gray-600 mb-1">Floor Material</label>
<select id="floor-material" class="w-full p-2 border rounded">
<option value="wood">Wood</option>
<option value="tile">Tile</option>
<option value="carpet">Carpet</option>
<option value="concrete">Concrete</option>
</select>
</div>
<div>
<label class="block text-sm text-gray-600 mb-1">Ceiling Color</label>
<div class="flex flex-wrap">
<div class="color-option bg-white selected" data-color="#ffffff" onclick="selectColor(this, 'ceiling')"></div>
<div class="color-option bg-gray-100" data-color="#f3f4f6" onclick="selectColor(this, 'ceiling')"></div>
<div class="color-option bg-blue-50" data-color="#eff6ff" onclick="selectColor(this, 'ceiling')"></div>
</div>
</div>
</div>
<!-- Lighting -->
<div class="mb-6">
<h3 class="font-medium mb-2 flex items-center">
<i class="fas fa-lightbulb mr-2"></i> Lighting
</h3>
<div class="flex items-center mb-2">
<input type="checkbox" id="natural-light" class="mr-2" checked>
<label for="natural-light" class="text-sm">Natural Light</label>
</div>
<div class="flex items-center mb-3">
<input type="range" id="light-intensity" min="0" max="2" step="0.1" value="1" class="w-full">
</div>
<button id="add-light-btn" class="w-full bg-indigo-600 text-white py-2 rounded hover:bg-indigo-700 transition">
Add Light Fixture
</button>
</div>
</div>
<!-- Main 3D Viewer -->
<div class="lg:col-span-2">
<div id="designer-container">
<div id="room-3d-view"></div>
<div id="tooltip" class="tooltip" style="display: none;"></div>
<div id="loading-overlay" class="loading-overlay" style="display: none;">
<div class="spinner"></div>
</div>
</div>
<!-- Camera Controls -->
<div class="bg-white p-4 mt-4 rounded-lg shadow-md">
<h3 class="font-medium mb-3 flex items-center">
<i class="fas fa-camera mr-2"></i> Camera Controls
</h3>
<div class="grid grid-cols-4 gap-2">
<button id="view-front" class="bg-gray-200 p-2 rounded hover:bg-gray-300">
<i class="fas fa-arrow-up"></i> Front
</button>
<button id="view-back" class="bg-gray-200 p-2 rounded hover:bg-gray-300">
<i class="fas fa-arrow-down"></i> Back
</button>
<button id="view-left" class="bg-gray-200 p-2 rounded hover:bg-gray-300">
<i class="fas fa-arrow-left"></i> Left
</button>
<button id="view-right" class="bg-gray-200 p-2 rounded hover:bg-gray-300">
<i class="fas fa-arrow-right"></i> Right
</button>
</div>
<div class="mt-3">
<button id="reset-camera" class="w-full bg-gray-600 text-white py-2 rounded hover:bg-gray-700 transition">
Reset View
</button>
</div>
</div>
</div>
<!-- Right sidebar - Furniture Library -->
<div class="lg:col-span-1 bg-white p-6 rounded-lg shadow-md">
<h2 class="text-xl font-semibold mb-4 border-b pb-2">Furniture Library</h2>
<!-- Furniture Categories -->
<div class="mb-4">
<h3 class="font-medium mb-2">Categories</h3>
<div class="flex flex-wrap gap-2">
<button class="category-btn active bg-indigo-100 text-indigo-800 px-3 py-1 rounded-full text-sm" data-category="all">All</button>
<button class="category-btn bg-gray-100 px-3 py-1 rounded-full text-sm" data-category="seating">Seating</button>
<button class="category-btn bg-gray-100 px-3 py-1 rounded-full text-sm" data-category="tables">Tables</button>
<button class="category-btn bg-gray-100 px-3 py-1 rounded-full text-sm" data-category="storage">Storage</button>
<button class="category-btn bg-gray-100 px-3 py-1 rounded-full text-sm" data-category="beds">Beds</button>
<button class="category-btn bg-gray-100 px-3 py-1 rounded-full text-sm" data-category="lighting">Lighting</button>
<button class="category-btn bg-gray-100 px-3 py-1 rounded-full text-sm" data-category="decor">Decor</button>
</div>
</div>
<!-- Search -->
<div class="mb-4 relative">
<input type="text" placeholder="Search furniture..." class="w-full p-2 pl-8 border rounded">
<i class="fas fa-search absolute left-2 top-3 text-gray-400"></i>
</div>
<!-- Furniture Items -->
<div class="overflow-y-auto" style="max-height: 400px;">
<div class="grid grid-cols-2 gap-3">
<!-- Sofa -->
<div class="furniture-item p-3 border rounded" data-type="sofa" data-category="seating" onclick="addFurniture('sofa')">
<div class="bg-gray-100 h-24 mb-2 flex items-center justify-center">
<i class="fas fa-couch text-3xl text-gray-500"></i>
</div>
<h4 class="font-medium text-sm">Sofa</h4>
<p class="text-xs text-gray-500">3-seater</p>
</div>
<!-- Armchair -->
<div class="furniture-item p-3 border rounded" data-type="armchair" data-category="seating" onclick="addFurniture('armchair')">
<div class="bg-gray-100 h-24 mb-2 flex items-center justify-center">
<i class="fas fa-chair text-3xl text-gray-500"></i>
</div>
<h4 class="font-medium text-sm">Armchair</h4>
<p class="text-xs text-gray-500">Single</p>
</div>
<!-- Coffee Table -->
<div class="furniture-item p-3 border rounded" data-type="coffee-table" data-category="tables" onclick="addFurniture('coffee-table')">
<div class="bg-gray-100 h-24 mb-2 flex items-center justify-center">
<i class="fas fa-coffee text-3xl text-gray-500"></i>
</div>
<h4 class="font-medium text-sm">Coffee Table</h4>
<p class="text-xs text-gray-500">Round</p>
</div>
<!-- Dining Table -->
<div class="furniture-item p-3 border rounded" data-type="dining-table" data-category="tables" onclick="addFurniture('dining-table')">
<div class="bg-gray-100 h-24 mb-2 flex items-center justify-center">
<i class="fas fa-utensils text-3xl text-gray-500"></i>
</div>
<h4 class="font-medium text-sm">Dining Table</h4>
<p class="text-xs text-gray-500">6-seater</p>
</div>
<!-- Bookshelf -->
<div class="furniture-item p-3 border rounded" data-type="bookshelf" data-category="storage" onclick="addFurniture('bookshelf')">
<div class="bg-gray-100 h-24 mb-2 flex items-center justify-center">
<i class="fas fa-book text-3xl text-gray-500"></i>
</div>
<h4 class="font-medium text-sm">Bookshelf</h4>
<p class="text-xs text-gray-500">5 shelves</p>
</div>
<!-- Wardrobe -->
<div class="furniture-item p-3 border rounded" data-type="wardrobe" data-category="storage" onclick="addFurniture('wardrobe')">
<div class="bg-gray-100 h-24 mb-2 flex items-center justify-center">
<i class="fas fa-tshirt text-3xl text-gray-500"></i>
</div>
<h4 class="font-medium text-sm">Wardrobe</h4>
<p class="text-xs text-gray-500">2 doors</p>
</div>
<!-- Bed -->
<div class="furniture-item p-3 border rounded" data-type="bed" data-category="beds" onclick="addFurniture('bed')">
<div class="bg-gray-100 h-24 mb-2 flex items-center justify-center">
<i class="fas fa-bed text-3xl text-gray-500"></i>
</div>
<h4 class="font-medium text-sm">Bed</h4>
<p class="text-xs text-gray-500">Queen size</p>
</div>
<!-- Lamp -->
<div class="furniture-item p-3 border rounded" data-type="lamp" data-category="lighting" onclick="addFurniture('lamp')">
<div class="bg-gray-100 h-24 mb-2 flex items-center justify-center">
<i class="fas fa-lightbulb text-3xl text-gray-500"></i>
</div>
<h4 class="font-medium text-sm">Table Lamp</h4>
<p class="text-xs text-gray-500">Modern</p>
</div>
</div>
</div>
<!-- Selected Furniture Controls -->
<div id="furniture-controls" class="mt-4 p-3 bg-gray-50 rounded" style="display: none;">
<h3 class="font-medium mb-2">Selected Item</h3>
<div class="flex justify-between items-center mb-2">
<span id="selected-furniture-name" class="font-medium">Sofa</span>
<button id="remove-furniture" class="text-red-500 hover:text-red-700">
<i class="fas fa-trash"></i>
</button>
</div>
<div class="grid grid-cols-3 gap-2 mb-3">
<div>
<label class="block text-xs text-gray-600">X Position</label>
<input type="number" id="furniture-x" class="w-full p-1 border rounded text-sm">
</div>
<div>
<label class="block text-xs text-gray-600">Y Position</label>
<input type="number" id="furniture-y" class="w-full p-1 border rounded text-sm">
</div>
<div>
<label class="block text-xs text-gray-600">Z Position</label>
<input type="number" id="furniture-z" class="w-full p-1 border rounded text-sm">
</div>
</div>
<div class="grid grid-cols-2 gap-2">
<div>
<label class="block text-xs text-gray-600">Rotation</label>
<input type="number" id="furniture-rotation" class="w-full p-1 border rounded text-sm">
</div>
<div>
<label class="block text-xs text-gray-600">Scale</label>
<input type="number" id="furniture-scale" value="1" step="0.1" min="0.5" max="2" class="w-full p-1 border rounded text-sm">
</div>
</div>
<div class="mt-2">
<label class="block text-xs text-gray-600 mb-1">Color</label>
<div class="flex flex-wrap">
<div class="color-option bg-brown-500" style="background-color: #78350f;" data-color="#78350f" onclick="selectColor(this, 'furniture')"></div>
<div class="color-option bg-gray-700" style="background-color: #374151;" data-color="#374151" onclick="selectColor(this, 'furniture')"></div>
<div class="color-option bg-black" style="background-color: #000000;" data-color="#000000" onclick="selectColor(this, 'furniture')"></div>
<div class="color-option bg-white" style="background-color: #ffffff;" data-color="#ffffff" onclick="selectColor(this, 'furniture')"></div>
<div class="color-option bg-blue-500" style="background-color: #3b82f6;" data-color="#3b82f6" onclick="selectColor(this, 'furniture')"></div>
<div class="color-option bg-red-500" style="background-color: #ef4444;" data-color="#ef4444" onclick="selectColor(this, 'furniture')"></div>
</div>
</div>
</div>
</div>
</div>
<!-- Save/Export Section -->
<div class="mt-8 bg-white p-6 rounded-lg shadow-md">
<h2 class="text-xl font-semibold mb-4 border-b pb-2">Save & Export</h2>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div class="border rounded p-4 text-center hover:bg-gray-50 cursor-pointer">
<i class="fas fa-save text-3xl text-indigo-600 mb-2"></i>
<h3 class="font-medium">Save Project</h3>
<p class="text-sm text-gray-600">Save your current design</p>
</div>
<div class="border rounded p-4 text-center hover:bg-gray-50 cursor-pointer">
<i class="fas fa-file-image text-3xl text-indigo-600 mb-2"></i>
<h3 class="font-medium">Export Image</h3>
<p class="text-sm text-gray-600">Save as PNG or JPG</p>
</div>
<div class="border rounded p-4 text-center hover:bg-gray-50 cursor-pointer">
<i class="fas fa-file-pdf text-3xl text-indigo-600 mb-2"></i>
<h3 class="font-medium">Export PDF</h3>
<p class="text-sm text-gray-600">Generate a PDF report</p>
</div>
</div>
</div>
</main>
<footer class="bg-gray-800 text-white py-8 mt-12">
<div class="container mx-auto px-4">
<div class="grid grid-cols-1 md:grid-cols-4 gap-8">
<div>
<h3 class="text-lg font-semibold mb-4">3D Interior Design Studio</h3>
<p class="text-gray-400">Create beautiful interior designs with our easy-to-use 3D tool.</p>
</div>
<div>
<h3 class="text-lg font-semibold mb-4">Quick Links</h3>
<ul class="space-y-2">
<li><a href="#" class="text-gray-400 hover:text-white">Home</a></li>
<li><a href="#" class="text-gray-400 hover:text-white">Templates</a></li>
<li><a href="#" class="text-gray-400 hover:text-white">Gallery</a></li>
<li><a href="#" class="text-gray-400 hover:text-white">Pricing</a></li>
</ul>
</div>
<div>
<h3 class="text-lg font-semibold mb-4">Resources</h3>
<ul class="space-y-2">
<li><a href="#" class="text-gray-400 hover:text-white">Blog</a></li>
<li><a href="#" class="text-gray-400 hover:text-white">Tutorials</a></li>
<li><a href="#" class="text-gray-400 hover:text-white">FAQ</a></li>
<li><a href="#" class="text-gray-400 hover:text-white">Support</a></li>
</ul>
</div>
<div>
<h3 class="text-lg font-semibold mb-4">Contact</h3>
<ul class="space-y-2">
<li class="text-gray-400">info@interiordesign.com</li>
<li class="text-gray-400">+1 (555) 123-4567</li>
<li class="text-gray-400">123 Design St, Creative City</li>
</ul>
</div>
</div>
<div class="border-t border-gray-700 mt-8 pt-8 text-center text-gray-400">
<p>&copy; 2023 3D Interior Design Studio. All rights reserved.</p>
</div>
</div>
</footer>
<script>
// Three.js variables
let scene, camera, renderer, controls;
let room = null;
let walls = {};
let floor = null;
let ceiling = null;
let furniture = [];
let selectedFurniture = null;
let selectedWall = 'all';
let wallColors = {
north: '#ffffff',
east: '#ffffff',
south: '#ffffff',
west: '#ffffff'
};
let ceilingColor = '#ffffff';
let floorMaterial = 'wood';
// Initialize the 3D scene
function init() {
// Create scene
scene = new THREE.Scene();
scene.background = new THREE.Color(0xf0f0f0);
// Create camera
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(10, 10, 10);
// Create renderer
const container = document.getElementById('room-3d-view');
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(container.clientWidth, container.clientHeight);
container.appendChild(renderer.domElement);
// Add orbit controls
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
// Add lights
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(5, 10, 7);
scene.add(directionalLight);
// Add grid helper
const gridHelper = new THREE.GridHelper(50, 50);
scene.add(gridHelper);
// Add axes helper
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);
// Handle window resize
window.addEventListener('resize', onWindowResize);
// Event listeners for UI controls
setupEventListeners();
// Start animation loop
animate();
}
// Animation loop
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}
// Handle window resize
function onWindowResize() {
const container = document.getElementById('room-3d-view');
camera.aspect = container.clientWidth / container.clientHeight;
camera.updateProjectionMatrix();
renderer.setSize(container.clientWidth, container.clientHeight);
}
// Create a room with specified dimensions
function createRoom(length, width, height) {
// Remove existing room if any
if (room) {
scene.remove(room);
Object.values(walls).forEach(wall => scene.remove(wall));
if (floor) scene.remove(floor);
if (ceiling) scene.remove(ceiling);
}
// Convert feet to Three.js units (1 unit = 1 foot)
const l = length;
const w = width;
const h = height;
// Create walls
const wallThickness = 0.2;
const wallHeight = h;
// North wall
const northWallGeometry = new THREE.BoxGeometry(l, wallHeight, wallThickness);
const northWallMaterial = new THREE.MeshStandardMaterial({ color: new THREE.Color(wallColors.north) });
walls.north = new THREE.Mesh(northWallGeometry, northWallMaterial);
walls.north.position.set(0, wallHeight/2, w/2);
walls.north.userData.type = 'wall';
walls.north.userData.wallId = 'north';
scene.add(walls.north);
// East wall
const eastWallGeometry = new THREE.BoxGeometry(wallThickness, wallHeight, w);
const eastWallMaterial = new THREE.MeshStandardMaterial({ color: new THREE.Color(wallColors.east) });
walls.east = new THREE.Mesh(eastWallGeometry, eastWallMaterial);
walls.east.position.set(l/2, wallHeight/2, 0);
walls.east.userData.type = 'wall';
walls.east.userData.wallId = 'east';
scene.add(walls.east);
// South wall
const southWallGeometry = new THREE.BoxGeometry(l, wallHeight, wallThickness);
const southWallMaterial = new THREE.MeshStandardMaterial({ color: new THREE.Color(wallColors.south) });
walls.south = new THREE.Mesh(southWallGeometry, southWallMaterial);
walls.south.position.set(0, wallHeight/2, -w/2);
walls.south.userData.type = 'wall';
walls.south.userData.wallId = 'south';
scene.add(walls.south);
// West wall
const westWallGeometry = new THREE.BoxGeometry(wallThickness, wallHeight, w);
const westWallMaterial = new THREE.MeshStandardMaterial({ color: new THREE.Color(wallColors.west) });
walls.west = new THREE.Mesh(westWallGeometry, westWallMaterial);
walls.west.position.set(-l/2, wallHeight/2, 0);
walls.west.userData.type = 'wall';
walls.west.userData.wallId = 'west';
scene.add(walls.west);
// Create floor
const floorGeometry = new THREE.BoxGeometry(l, 0.1, w);
let floorMaterial;
switch (floorMaterial) {
case 'wood':
floorMaterial = new THREE.MeshStandardMaterial({
color: 0x8B4513,
roughness: 0.3,
metalness: 0.1
});
break;
case 'tile':
floorMaterial = new THREE.MeshStandardMaterial({
color: 0xDDDDDD,
roughness: 0.2,
metalness: 0.5
});
break;
case 'carpet':
floorMaterial = new THREE.MeshStandardMaterial({
color: 0x1E90FF,
roughness: 0.8,
metalness
</html>