mohamedtsou commited on
Commit
ca90ee2
·
verified ·
1 Parent(s): bed8541

Update view.html

Browse files
Files changed (1) hide show
  1. view.html +219 -81
view.html CHANGED
@@ -3,107 +3,245 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Visualisation 3D</title>
7
  <style>
8
- body { margin: 0; overflow: hidden; background: #111; color: white; font-family: Arial; }
 
 
 
 
 
 
9
  #info {
10
- position: absolute; top: 20px; left: 20px;
11
- background: rgba(0,0,0,0.7); padding: 15px 25px;
12
- border-radius: 8px; border-left: 4px solid #00aaff;
13
- z-index: 100;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  }
15
  #status {
16
- position: absolute; bottom: 30px; left: 50%;
 
 
17
  transform: translateX(-50%);
18
- background: rgba(0,0,0,0.7); color: #ffaa00;
19
- padding: 10px 20px; border-radius: 30px;
20
- z-index: 100;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  }
22
  </style>
23
  </head>
24
  <body>
 
 
25
  <div id="info">
26
- <h2>🔬 Modèle: SubTool-0-3517926.OBJ</h2>
27
- <p>Souris: Rotation | Scroll: Zoom</p>
 
 
 
 
 
 
 
 
28
  </div>
29
- <div id="status">Chargement...</div>
30
 
 
31
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
32
  <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.js"></script>
33
  <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/loaders/OBJLoader.js"></script>
34
 
35
  <script>
36
- const statusDiv = document.getElementById('status');
37
-
38
- // Scene
39
- const scene = new THREE.Scene();
40
- scene.background = new THREE.Color(0x111122);
41
-
42
- // Camera
43
- const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
44
- camera.position.set(5, 3, 8);
45
-
46
- // Renderer
47
- const renderer = new THREE.WebGLRenderer({ antialias: true });
48
- renderer.setSize(window.innerWidth, window.innerHeight);
49
- document.body.appendChild(renderer.domElement);
50
-
51
- // Controls
52
- const controls = new THREE.OrbitControls(camera, renderer.domElement);
53
- controls.enableDamping = true;
54
- controls.autoRotate = true;
55
- controls.autoRotateSpeed = 2;
56
-
57
- // Lumières
58
- scene.add(new THREE.AmbientLight(0x404060));
59
- const light = new THREE.DirectionalLight(0xffffff, 1);
60
- light.position.set(2, 5, 3);
61
- scene.add(light);
62
-
63
- // Grille
64
- scene.add(new THREE.GridHelper(10, 20, 0x88aaff, 0x335588));
65
-
66
- // Chargement
67
- statusDiv.innerHTML = '🔍 Chargement du modèle...';
68
-
69
- const loader = new THREE.OBJLoader();
70
- loader.load(
71
- 'SubTool-0-3517926.OBJ',
72
- (obj) => {
73
- // Centrer
74
- const box = new THREE.Box3().setFromObject(obj);
75
- const center = box.getCenter(new THREE.Vector3());
76
- obj.position.set(-center.x, -center.y, -center.z);
77
 
78
- scene.add(obj);
79
- statusDiv.innerHTML = '✅ Modèle chargé!';
80
- },
81
- (xhr) => {
82
- if (xhr.lengthComputable) {
83
- const pct = Math.round((xhr.loaded / xhr.total) * 100);
84
- statusDiv.innerHTML = `📊 Chargement: ${pct}%`;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  }
86
- },
87
- (error) => {
88
- statusDiv.innerHTML = '❌ Erreur de chargement';
89
- console.error(error);
 
 
 
 
 
 
 
 
 
90
  }
91
- );
92
-
93
- // Animation
94
- function animate() {
95
- requestAnimationFrame(animate);
96
- controls.update();
97
- renderer.render(scene, camera);
98
- }
99
- animate();
100
-
101
- // Resize
102
- window.addEventListener('resize', () => {
103
- camera.aspect = window.innerWidth / window.innerHeight;
104
- camera.updateProjectionMatrix();
105
- renderer.setSize(window.innerWidth, window.innerHeight);
106
- });
107
  </script>
108
  </body>
109
  </html>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Visualisation 3D - SubTool</title>
7
  <style>
8
+ * { margin: 0; padding: 0; box-sizing: border-box; }
9
+ body {
10
+ margin: 0;
11
+ overflow: hidden;
12
+ font-family: 'Segoe UI', system-ui, sans-serif;
13
+ background-color: #0a0a1a;
14
+ }
15
  #info {
16
+ position: absolute;
17
+ top: 20px;
18
+ left: 20px;
19
+ background: rgba(10, 10, 26, 0.85);
20
+ backdrop-filter: blur(10px);
21
+ color: white;
22
+ padding: 16px 24px;
23
+ border-radius: 12px;
24
+ border: 1px solid rgba(255,255,255,0.1);
25
+ box-shadow: 0 8px 32px rgba(0,0,0,0.4);
26
+ z-index: 1000;
27
+ pointer-events: none;
28
+ border-left: 4px solid #3b82f6;
29
+ }
30
+ #info h2 {
31
+ font-size: 1.1rem;
32
+ font-weight: 500;
33
+ margin-bottom: 4px;
34
+ color: #3b82f6;
35
+ }
36
+ #info p {
37
+ font-size: 0.85rem;
38
+ opacity: 0.7;
39
  }
40
  #status {
41
+ position: absolute;
42
+ bottom: 30px;
43
+ left: 50%;
44
  transform: translateX(-50%);
45
+ background: rgba(0, 0, 0, 0.7);
46
+ backdrop-filter: blur(10px);
47
+ color: #fbbf24;
48
+ padding: 12px 28px;
49
+ border-radius: 40px;
50
+ font-size: 0.95rem;
51
+ font-weight: 500;
52
+ border: 1px solid rgba(255,255,255,0.1);
53
+ box-shadow: 0 4px 16px rgba(0,0,0,0.3);
54
+ z-index: 1000;
55
+ letter-spacing: 0.3px;
56
+ }
57
+ #hf-badge {
58
+ position: absolute;
59
+ bottom: 30px;
60
+ right: 30px;
61
+ color: rgba(255,255,255,0.4);
62
+ font-size: 0.8rem;
63
+ background: rgba(0,0,0,0.3);
64
+ padding: 6px 12px;
65
+ border-radius: 20px;
66
+ backdrop-filter: blur(5px);
67
+ z-index: 1000;
68
+ }
69
+ .loading-bar {
70
+ position: fixed;
71
+ top: 0;
72
+ left: 0;
73
+ height: 3px;
74
+ background: linear-gradient(90deg, #3b82f6, #8b5cf6);
75
+ width: 0%;
76
+ transition: width 0.3s ease;
77
+ z-index: 2000;
78
  }
79
  </style>
80
  </head>
81
  <body>
82
+ <div class="loading-bar" id="loadingBar"></div>
83
+
84
  <div id="info">
85
+ <h2>🔬 SubTool-0-3517926.OBJ</h2>
86
+ <p>🖱️ Rotation · Scroll: Zoom · Glisser: Déplacer</p>
87
+ </div>
88
+
89
+ <div id="status">
90
+ <span id="statusText">Initialisation...</span>
91
+ </div>
92
+
93
+ <div id="hf-badge">
94
+ 🤗 Hugging Face Spaces · Docker
95
  </div>
 
96
 
97
+ <!-- Three.js depuis CDN -->
98
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
99
  <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.js"></script>
100
  <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/loaders/OBJLoader.js"></script>
101
 
102
  <script>
103
+ (function() {
104
+ const statusText = document.getElementById('statusText');
105
+ const loadingBar = document.getElementById('loadingBar');
106
+
107
+ // Mise à jour du statut
108
+ function setStatus(message, percent) {
109
+ statusText.textContent = message;
110
+ if (percent !== undefined) {
111
+ loadingBar.style.width = percent + '%';
112
+ }
113
+ }
114
+
115
+ try {
116
+ // Vérifier que Three.js est chargé
117
+ if (typeof THREE === 'undefined') {
118
+ throw new Error('Three.js non chargé');
119
+ }
120
+
121
+ setStatus('Préparation de la scène...', 10);
122
+
123
+ // --- Configuration de base ---
124
+ const scene = new THREE.Scene();
125
+ scene.background = new THREE.Color(0x0a0a1a);
126
+
127
+ const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
128
+ camera.position.set(5, 3, 8);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
 
130
+ const renderer = new THREE.WebGLRenderer({ antialias: true, powerPreference: "high-performance" });
131
+ renderer.setSize(window.innerWidth, window.innerHeight);
132
+ renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
133
+ document.body.appendChild(renderer.domElement);
134
+
135
+ // --- Contrôles ---
136
+ const controls = new THREE.OrbitControls(camera, renderer.domElement);
137
+ controls.enableDamping = true;
138
+ controls.dampingFactor = 0.05;
139
+ controls.autoRotate = true;
140
+ controls.autoRotateSpeed = 2.0;
141
+ controls.enableZoom = true;
142
+ controls.enablePan = true;
143
+ controls.target.set(0, 0, 0);
144
+
145
+ // --- Lumières ---
146
+ scene.add(new THREE.AmbientLight(0x404060));
147
+
148
+ const light1 = new THREE.DirectionalLight(0xffffff, 1.2);
149
+ light1.position.set(2, 5, 3);
150
+ scene.add(light1);
151
+
152
+ const light2 = new THREE.DirectionalLight(0xffaa88, 0.8);
153
+ light2.position.set(-3, 2, -4);
154
+ scene.add(light2);
155
+
156
+ // --- Grille et axes ---
157
+ const gridHelper = new THREE.GridHelper(10, 20, 0x3b82f6, 0x1e293b);
158
+ scene.add(gridHelper);
159
+
160
+ setStatus('Chargement du modèle...', 30);
161
+
162
+ // --- Chargement du modèle OBJ ---
163
+ const loader = new THREE.OBJLoader();
164
+
165
+ loader.load(
166
+ 'SubTool-0-3517926.OBJ',
167
+ (object) => {
168
+ console.log('✅ Modèle chargé avec succès');
169
+
170
+ // Centrer le modèle
171
+ const box = new THREE.Box3().setFromObject(object);
172
+ const center = box.getCenter(new THREE.Vector3());
173
+ const size = box.getSize(new THREE.Vector3());
174
+
175
+ object.position.set(-center.x, -center.y, -center.z);
176
+
177
+ // Ajouter une couleur si le modèle n'en a pas
178
+ object.traverse((child) => {
179
+ if (child.isMesh) {
180
+ if (!child.material) {
181
+ child.material = new THREE.MeshStandardMaterial({
182
+ color: 0x88aaff,
183
+ roughness: 0.4,
184
+ metalness: 0.2,
185
+ emissive: 0x112233
186
+ });
187
+ }
188
+ // Optimisation
189
+ child.frustumCulled = true;
190
+ child.castShadow = false;
191
+ child.receiveShadow = false;
192
+ }
193
+ });
194
+
195
+ scene.add(object);
196
+
197
+ // Ajuster la caméra en fonction de la taille
198
+ const maxDim = Math.max(size.x, size.y, size.z);
199
+ if (maxDim > 0) {
200
+ camera.position.set(maxDim * 1.5, maxDim * 0.8, maxDim * 1.5);
201
+ controls.target.set(0, size.y/2, 0);
202
+ }
203
+
204
+ setStatus(`✅ Prêt (${size.x.toFixed(2)} x ${size.y.toFixed(2)} x ${size.z.toFixed(2)})`, 100);
205
+
206
+ // Cacher la barre après 1 seconde
207
+ setTimeout(() => {
208
+ loadingBar.style.opacity = '0';
209
+ }, 1000);
210
+ },
211
+ (xhr) => {
212
+ if (xhr.lengthComputable) {
213
+ const percent = Math.round((xhr.loaded / xhr.total) * 70) + 30; // 30-100%
214
+ setStatus(`Chargement: ${Math.round((xhr.loaded / xhr.total) * 100)}%`, percent);
215
+ }
216
+ },
217
+ (error) => {
218
+ console.error('Erreur de chargement:', error);
219
+ setStatus('❌ Erreur de chargement', 100);
220
+ loadingBar.style.backgroundColor = '#ef4444';
221
+ }
222
+ );
223
+
224
+ // --- Animation ---
225
+ function animate() {
226
+ requestAnimationFrame(animate);
227
+ controls.update();
228
+ renderer.render(scene, camera);
229
  }
230
+ animate();
231
+
232
+ // --- Gestion du redimensionnement ---
233
+ window.addEventListener('resize', () => {
234
+ camera.aspect = window.innerWidth / window.innerHeight;
235
+ camera.updateProjectionMatrix();
236
+ renderer.setSize(window.innerWidth, window.innerHeight);
237
+ });
238
+
239
+ } catch (error) {
240
+ console.error('Erreur critique:', error);
241
+ setStatus('❌ Erreur: ' + error.message, 100);
242
+ loadingBar.style.backgroundColor = '#ef4444';
243
  }
244
+ })();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
  </script>
246
  </body>
247
  </html>