3d-viewer / index.html
DK9's picture
Add 2 files
f94b64a verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D Creation 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://kit.fontawesome.com/a076d05399.js" crossorigin="anonymous"></script>
<style>
#scene-container {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 0;
}
.sidebar-slide {
transition: transform 0.3s ease-in-out;
}
.tool-icon {
transition: all 0.2s ease;
}
.tool-icon:hover {
transform: scale(1.1);
filter: drop-shadow(0 0 8px rgba(59, 130, 246, 0.5));
}
.scene-overlay {
pointer-events: none;
}
.grid-toggle.active {
background-color: #3b82f6;
color: white;
}
</style>
</head>
<body class="bg-gray-900 text-gray-200 overflow-hidden">
<!-- Top Navigation Bar -->
<header class="bg-gray-800 bg-opacity-90 border-b border-gray-700 fixed top-0 left-0 right-0 z-50 h-14 flex items-center px-4 shadow-lg">
<div class="flex items-center space-x-2">
<div class="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center">
<i class="fas fa-cube text-white"></i>
</div>
<h1 class="text-xl font-bold text-blue-400">3D Creation Studio</h1>
</div>
<div class="ml-auto flex items-center space-x-4">
<button class="px-3 py-1 bg-gray-700 hover:bg-gray-600 rounded-md text-sm flex items-center space-x-1">
<i class="fas fa-save"></i>
<span>Save</span>
</button>
<button class="px-3 py-1 bg-gray-700 hover:bg-gray-600 rounded-md text-sm flex items-center space-x-1">
<i class="fas fa-share-alt"></i>
<span>Export</span>
</button>
<div class="w-px h-6 bg-gray-600"></div>
<button class="w-8 h-8 rounded-full bg-gray-700 hover:bg-gray-600 flex items-center justify-center">
<i class="fas fa-user"></i>
</button>
</div>
</header>
<!-- Right Sidebar -->
<aside class="fixed right-0 top-14 bottom-0 w-64 bg-gray-800 bg-opacity-90 border-l border-gray-700 z-40 flex flex-col shadow-xl">
<div class="p-4 border-b border-gray-700">
<h2 class="font-semibold text-lg flex items-center justify-between">
<span>Scene Properties</span>
<i class="fas fa-cog text-blue-400"></i>
</h2>
</div>
<div class="flex-1 overflow-y-auto p-4 space-y-6">
<!-- Object Properties -->
<div>
<h3 class="font-medium text-sm uppercase text-gray-400 mb-2">Selected Object</h3>
<div class="space-y-3">
<div class="flex justify-between items-center">
<span>Position</span>
<div class="flex space-x-2">
<input type="number" class="w-16 bg-gray-700 rounded px-2 py-1 text-sm" placeholder="X">
<input type="number" class="w-16 bg-gray-700 rounded px-2 py-1 text-sm" placeholder="Y">
<input type="number" class="w-16 bg-gray-700 rounded px-2 py-1 text-sm" placeholder="Z">
</div>
</div>
<div class="flex justify-between items-center">
<span>Rotation</span>
<div class="flex space-x-2">
<input type="number" class="w-16 bg-gray-700 rounded px-2 py-1 text-sm" placeholder="X">
<input type="number" class="w-16 bg-gray-700 rounded px-2 py-1 text-sm" placeholder="Y">
<input type="number" class="w-16 bg-gray-700 rounded px-2 py-1 text-sm" placeholder="Z">
</div>
</div>
<div class="flex justify-between items-center">
<span>Scale</span>
<div class="flex space-x-2">
<input type="number" class="w-16 bg-gray-700 rounded px-2 py-1 text-sm" value="1">
</div>
</div>
</div>
</div>
<!-- Material Properties -->
<div>
<h3 class="font-medium text-sm uppercase text-gray-400 mb-2">Material</h3>
<div class="space-y-3">
<div class="flex justify-between items-center">
<span>Color</span>
<input type="color" class="w-8 h-8 bg-gray-700 rounded cursor-pointer" value="#3b82f6">
</div>
<div class="flex justify-between items-center">
<span>Metalness</span>
<input type="range" min="0" max="1" step="0.1" class="w-24" value="0">
</div>
<div class="flex justify-between items-center">
<span>Roughness</span>
<input type="range" min="0" max="1" step="0.1" class="w-24" value="1">
</div>
</div>
</div>
<!-- Lighting -->
<div>
<h3 class="font-medium text-sm uppercase text-gray-400 mb-2">Lighting</h3>
<div class="space-y-2">
<div class="flex justify-between items-center">
<span>Intensity</span>
<input type="range" min="0" max="2" step="0.1" class="w-24" value="1">
</div>
<div class="flex justify-between items-center">
<span>Ambient Light</span>
<input type="range" min="0" max="1" step="0.1" class="w-24" value="0.2">
</div>
</div>
</div>
</div>
</aside>
<!-- Tools Panel -->
<div class="fixed right-4 bottom-4 z-50 flex flex-col space-y-2">
<button id="grid-toggle" class="grid-toggle w-12 h-12 bg-gray-700 hover:bg-gray-600 rounded-full flex items-center justify-center shadow-lg tool-icon">
<i class="fas fa-th"></i>
</button>
<button class="w-12 h-12 bg-gray-700 hover:bg-gray-600 rounded-full flex items-center justify-center shadow-lg tool-icon">
<i class="fas fa-ruler-combined"></i>
</button>
<button class="w-12 h-12 bg-gray-700 hover:bg-gray-600 rounded-full flex items-center justify-center shadow-lg tool-icon">
<i class="fas fa-lightbulb"></i>
</button>
<button class="w-12 h-12 bg-blue-600 hover:bg-blue-500 rounded-full flex items-center justify-center shadow-lg tool-icon">
<i class="fas fa-question"></i>
</button>
</div>
<!-- Scene Container -->
<div id="scene-container"></div>
<!-- Scene Overlay -->
<div class="scene-overlay fixed top-14 left-0 right-64 bottom-0 flex items-center justify-center pointer-events-none">
<div class="absolute top-4 left-4 bg-gray-800 bg-opacity-70 px-3 py-1 rounded-md text-sm">
<span class="text-blue-400">Perspective</span> | <span>FPS: <span id="fps-counter">60</span></span>
</div>
</div>
<!-- Object Creation Menu -->
<div class="fixed left-4 top-20 bg-gray-800 bg-opacity-90 rounded-lg shadow-xl p-2 z-40">
<h3 class="text-sm font-medium mb-2 px-2">Create Object</h3>
<div class="grid grid-cols-3 gap-2">
<button class="p-2 bg-gray-700 hover:bg-gray-600 rounded flex flex-col items-center tool-icon">
<i class="fas fa-cube mb-1"></i>
<span class="text-xs">Cube</span>
</button>
<button class="p-2 bg-gray-700 hover:bg-gray-600 rounded flex flex-col items-center tool-icon">
<i class="fas fa-circle mb-1"></i>
<span class="text-xs">Sphere</span>
</button>
<button class="p-2 bg-gray-700 hover:bg-gray-600 rounded flex flex-col items-center tool-icon">
<i class="fas fa-cylinder mb-1"></i>
<span class="text-xs">Cylinder</span>
</button>
<button class="p-2 bg-gray-700 hover:bg-gray-600 rounded flex flex-col items-center tool-icon">
<i class="fas fa-cone mb-1"></i>
<span class="text-xs">Cone</span>
</button>
<button class="p-2 bg-gray-700 hover:bg-gray-600 rounded flex flex-col items-center tool-icon">
<i class="fas fa-torus mb-1"></i>
<span class="text-xs">Torus</span>
</button>
<button class="p-2 bg-gray-700 hover:bg-gray-600 rounded flex flex-col items-center tool-icon">
<i class="fas fa-lightbulb mb-1"></i>
<span class="text-xs">Light</span>
</button>
</div>
</div>
<script>
// Initialize Three.js scene
let scene, camera, renderer, controls;
function initThreeJS() {
const container = document.getElementById('scene-container');
// Scene
scene = new THREE.Scene();
scene.background = new THREE.Color(0x1a1a1a);
// Camera
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(5, 5, 5);
// Renderer
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
container.appendChild(renderer.domElement);
// Controls
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
// Lights
const ambientLight = new THREE.AmbientLight(0x404040, 0.5);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(5, 10, 7);
directionalLight.castShadow = true;
scene.add(directionalLight);
// Grid helper
const gridHelper = new THREE.GridHelper(20, 20, 0x555555, 0x333333);
scene.add(gridHelper);
// Axes helper
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);
// Simple cube for demonstration
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshStandardMaterial({
color: 0x3b82f6,
metalness: 0.1,
roughness: 0.5
});
const cube = new THREE.Mesh(geometry, material);
cube.castShadow = true;
scene.add(cube);
// Plane
const planeGeometry = new THREE.PlaneGeometry(20, 20);
const planeMaterial = new THREE.MeshStandardMaterial({
color: 0x222222,
side: THREE.DoubleSide
});
const plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -Math.PI / 2;
plane.receiveShadow = true;
scene.add(plane);
// Handle window resize
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
// FPS counter
let lastTime = performance.now();
let frames = 0;
// Animation loop
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
// Update FPS counter every second
frames++;
const now = performance.now();
if (now >= lastTime + 1000) {
document.getElementById('fps-counter').textContent = frames;
frames = 0;
lastTime = now;
}
}
animate();
}
// Initialize UI interactions
function initUI() {
// Grid toggle
document.getElementById('grid-toggle').addEventListener('click', function() {
this.classList.toggle('active');
// In a real app, you would toggle the grid helper visibility here
});
// Tooltips would be implemented here in a real app
}
// Initialize everything when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
initThreeJS();
initUI();
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=DK9/3d-viewer" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>