bruinjoe917 commited on
Commit
648f43a
·
verified ·
1 Parent(s): 213099a

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +604 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: 3d Heart
3
- emoji: 😻
4
- colorFrom: pink
5
- colorTo: purple
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: 3d-heart
3
+ emoji: 🐳
4
+ colorFrom: blue
5
+ colorTo: blue
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,604 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>3D Heart Visualization</title>
7
+ <style>
8
+ body {
9
+ margin: 0;
10
+ padding: 0;
11
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
12
+ background-color: #f5f5f5;
13
+ color: #333;
14
+ overflow: hidden;
15
+ }
16
+
17
+ #container {
18
+ position: absolute;
19
+ width: 100%;
20
+ height: 100%;
21
+ display: flex;
22
+ }
23
+
24
+ #viewer {
25
+ flex: 1;
26
+ }
27
+
28
+ #controls {
29
+ width: 300px;
30
+ background-color: white;
31
+ padding: 20px;
32
+ box-shadow: -2px 0 10px rgba(0, 0, 0, 0.1);
33
+ overflow-y: auto;
34
+ z-index: 100;
35
+ }
36
+
37
+ h1 {
38
+ color: #e74c3c;
39
+ text-align: center;
40
+ margin-bottom: 20px;
41
+ font-size: 1.5em;
42
+ }
43
+
44
+ .control-group {
45
+ margin-bottom: 20px;
46
+ border-bottom: 1px solid #eee;
47
+ padding-bottom: 15px;
48
+ }
49
+
50
+ .control-group h2 {
51
+ font-size: 1.2em;
52
+ color: #333;
53
+ margin-bottom: 10px;
54
+ display: flex;
55
+ align-items: center;
56
+ }
57
+
58
+ .color-indicator {
59
+ display: inline-block;
60
+ width: 20px;
61
+ height: 20px;
62
+ border-radius: 50%;
63
+ margin-right: 10px;
64
+ border: 1px solid #ddd;
65
+ }
66
+
67
+ .toggle {
68
+ display: flex;
69
+ align-items: center;
70
+ margin-bottom: 8px;
71
+ }
72
+
73
+ .toggle input {
74
+ margin-right: 10px;
75
+ }
76
+
77
+ .toggle label {
78
+ display: flex;
79
+ align-items: center;
80
+ cursor: pointer;
81
+ }
82
+
83
+ .info-text {
84
+ font-size: 0.85em;
85
+ color: #666;
86
+ margin-top: 5px;
87
+ margin-left: 30px;
88
+ }
89
+
90
+ #loading {
91
+ position: absolute;
92
+ top: 50%;
93
+ left: 50%;
94
+ transform: translate(-50%, -50%);
95
+ background-color: rgba(255, 255, 255, 0.9);
96
+ padding: 20px;
97
+ border-radius: 5px;
98
+ text-align: center;
99
+ z-index: 1000;
100
+ }
101
+
102
+ .progress-bar {
103
+ width: 100%;
104
+ background-color: #e0e0e0;
105
+ border-radius: 5px;
106
+ margin-top: 10px;
107
+ }
108
+
109
+ .progress {
110
+ height: 10px;
111
+ background-color: #e74c3c;
112
+ border-radius: 5px;
113
+ width: 0%;
114
+ transition: width 0.3s;
115
+ }
116
+
117
+ .reset-btn {
118
+ background-color: #e74c3c;
119
+ color: white;
120
+ border: none;
121
+ padding: 8px 15px;
122
+ border-radius: 4px;
123
+ cursor: pointer;
124
+ font-weight: bold;
125
+ width: 100%;
126
+ margin-top: 15px;
127
+ transition: background-color 0.3s;
128
+ }
129
+
130
+ .reset-btn:hover {
131
+ background-color: #c0392b;
132
+ }
133
+
134
+ .legend {
135
+ display: flex;
136
+ flex-wrap: wrap;
137
+ margin-top: 20px;
138
+ }
139
+
140
+ .legend-item {
141
+ display: flex;
142
+ align-items: center;
143
+ margin: 5px 15px 5px 0;
144
+ font-size: 0.8em;
145
+ }
146
+
147
+ .legend-color {
148
+ width: 15px;
149
+ height: 15px;
150
+ border-radius: 50%;
151
+ margin-right: 5px;
152
+ border: 1px solid #ddd;
153
+ }
154
+
155
+ @media (max-width: 768px) {
156
+ #container {
157
+ flex-direction: column;
158
+ }
159
+
160
+ #controls {
161
+ width: 100%;
162
+ height: 300px;
163
+ }
164
+ }
165
+ </style>
166
+ </head>
167
+ <body>
168
+ <div id="container">
169
+ <div id="viewer"></div>
170
+ <div id="controls">
171
+ <h1>Interactive 3D Heart Anatomy</h1>
172
+
173
+ <div class="control-group">
174
+ <h2><span class="color-indicator" style="background-color: #ff1744;"></span>Left Ventricle</h2>
175
+ <div class="toggle">
176
+ <input type="checkbox" id="leftVentricleToggle" checked>
177
+ <label for="leftVentricleToggle">Show Left Ventricle</label>
178
+ </div>
179
+ <p class="info-text">Pumps oxygenated blood to the body through the aorta.</p>
180
+ </div>
181
+
182
+ <div class="control-group">
183
+ <h2><span class="color-indicator" style="background-color: #3d5afe;"></span>Right Ventricle</h2>
184
+ <div class="toggle">
185
+ <input type="checkbox" id="rightVentricleToggle" checked>
186
+ <label for="rightVentricleToggle">Show Right Ventricle</label>
187
+ </div>
188
+ <p class="info-text">Pumps deoxygenated blood to the lungs.</p>
189
+ </div>
190
+
191
+ <div class="control-group">
192
+ <h2><span class="color-indicator" style="background-color: #ff5252;"></span>Left Atrium</h2>
193
+ <div class="toggle">
194
+ <input type="checkbox" id="leftAtriumToggle" checked>
195
+ <label for="leftAtriumToggle">Show Left Atrium</label>
196
+ </div>
197
+ <p class="info-text">Receives oxygenated blood from the lungs.</p>
198
+ </div>
199
+
200
+ <div class="control-group">
201
+ <h2><span class="color-indicator" style="background-color: #448aff;"></span>Right Atrium</h2>
202
+ <div class="toggle">
203
+ <input type="checkbox" id="rightAtriumToggle" checked>
204
+ <label for="rightAtriumToggle">Show Right Atrium</label>
205
+ </div>
206
+ <p class="info-text">Receives deoxygenated blood from the body.</p>
207
+ </div>
208
+
209
+ <div class="control-group">
210
+ <h2><span class="color-indicator" style="background-color: #d32f2f;"></span>Aorta</h2>
211
+ <div class="toggle">
212
+ <input type="checkbox" id="aortaToggle" checked>
213
+ <label for="aortaToggle">Show Aorta</label>
214
+ </div>
215
+ <p class="info-text">Main artery carrying oxygenated blood from the left ventricle.</p>
216
+ </div>
217
+
218
+ <div class="control-group">
219
+ <h2><span class="color-indicator" style="background-color: #1e88e5;"></span>Pulmonary Arteries</h2>
220
+ <div class="toggle">
221
+ <input type="checkbox" id="pulmonaryArteriesToggle" checked>
222
+ <label for="pulmonaryArteriesToggle">Show Pulmonary Arteries</label>
223
+ </div>
224
+ <p class="info-text">Carry deoxygenated blood from the right ventricle to the lungs.</p>
225
+ </div>
226
+
227
+ <div class="control-group">
228
+ <h2><span class="color-indicator" style="background-color: #ff7043;"></span>Pulmonary Veins</h2>
229
+ <div class="toggle">
230
+ <input type="checkbox" id="pulmonaryVeinsToggle" checked>
231
+ <label for="pulmonaryVeinsToggle">Show Pulmonary Veins</label>
232
+ </div>
233
+ <p class="info-text">Carry oxygenated blood from the lungs to the left atrium.</p>
234
+ </div>
235
+
236
+ <div class="control-group">
237
+ <h2><span class="color-indicator" style="background-color: #43a047;"></span>Cardiac Fat</h2>
238
+ <div class="toggle">
239
+ <input type="checkbox" id="fatToggle" checked>
240
+ <label for="fatToggle">Show Cardiac Fat</label>
241
+ </div>
242
+ <p class="info-text">Fatty deposits surrounding the heart.</p>
243
+ </div>
244
+
245
+ <button class="reset-btn" id="resetView">Reset View</button>
246
+
247
+ <div class="legend">
248
+ <div class="legend-item">
249
+ <div class="legend-color" style="background-color: #ff1744;"></div>
250
+ Left Ventricle
251
+ </div>
252
+ <div class="legend-item">
253
+ <div class="legend-color" style="background-color: #3d5afe;"></div>
254
+ Right Ventricle
255
+ </div>
256
+ <div class="legend-item">
257
+ <div class="legend-color" style="background-color: #ff5252;"></div>
258
+ Left Atrium
259
+ </div>
260
+ <div class="legend-item">
261
+ <div class="legend-color" style="background-color: #448aff;"></div>
262
+ Right Atrium
263
+ </div>
264
+ <div class="legend-item">
265
+ <div class="legend-color" style="background-color: #d32f2f;"></div>
266
+ Aorta
267
+ </div>
268
+ <div class="legend-item">
269
+ <div class="legend-color" style="background-color: #1e88e5;"></div>
270
+ Pulmonary Arteries
271
+ </div>
272
+ <div class="legend-item">
273
+ <div class="legend-color" style="background-color: #ff7043;"></div>
274
+ Pulmonary Veins
275
+ </div>
276
+ <div class="legend-item">
277
+ <div class="legend-color" style="background-color: #43a047;"></div>
278
+ Cardiac Fat
279
+ </div>
280
+ </div>
281
+ </div>
282
+ </div>
283
+
284
+ <div id="loading">
285
+ <h2>Loading Heart Model</h2>
286
+ <p>Please wait while we prepare your 3D heart visualization...</p>
287
+ <div class="progress-bar">
288
+ <div class="progress" id="progress"></div>
289
+ </div>
290
+ </div>
291
+
292
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
293
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/controls/OrbitControls.min.js"></script>
294
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/loaders/GLTFLoader.min.js"></script>
295
+ <script>
296
+ // Initialize Three.js scene
297
+ const scene = new THREE.Scene();
298
+ scene.background = new THREE.Color(0xf5f5f5);
299
+
300
+ // Set up camera
301
+ const camera = new THREE.PerspectiveCamera(75, window.innerWidth / (window.innerHeight - 300), 0.1, 1000);
302
+ camera.position.z = 5;
303
+
304
+ // Set up renderer with WebGL
305
+ const renderer = new THREE.WebGLRenderer({ antialias: true });
306
+ renderer.setSize(window.innerWidth - 300, window.innerHeight);
307
+ document.getElementById('viewer').appendChild(renderer.domElement);
308
+
309
+ // Add orbit controls for interaction
310
+ const controls = new THREE.OrbitControls(camera, renderer.domElement);
311
+ controls.enableDamping = true;
312
+ controls.dampingFactor = 0.25;
313
+
314
+ // Add lights to the scene
315
+ const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
316
+ scene.add(ambientLight);
317
+
318
+ const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
319
+ directionalLight.position.set(1, 1, 1);
320
+ scene.add(directionalLight);
321
+
322
+ // Create a group to hold all heart parts
323
+ const heartGroup = new THREE.Group();
324
+ scene.add(heartGroup);
325
+
326
+ // Heart parts with their materials (colors)
327
+ const heartParts = {
328
+ leftVentricle: {
329
+ object: null,
330
+ color: 0xff1744,
331
+ visible: true
332
+ },
333
+ rightVentricle: {
334
+ object: null,
335
+ color: 0x3d5afe,
336
+ visible: true
337
+ },
338
+ leftAtrium: {
339
+ object: null,
340
+ color: 0xff5252,
341
+ visible: true
342
+ },
343
+ rightAtrium: {
344
+ object: null,
345
+ color: 0x448aff,
346
+ visible: true
347
+ },
348
+ aorta: {
349
+ object: null,
350
+ color: 0xd32f2f,
351
+ visible: true
352
+ },
353
+ pulmonaryArteries: {
354
+ object: null,
355
+ color: 0x1e88e5,
356
+ visible: true
357
+ },
358
+ pulmonaryVeins: {
359
+ object: null,
360
+ color: 0xff7043,
361
+ visible: true
362
+ },
363
+ fat: {
364
+ object: null,
365
+ color: 0x43a047,
366
+ visible: true
367
+ }
368
+ };
369
+
370
+ // Function to create simplified heart parts (in a real app, you would load 3D models)
371
+ function createHeartParts() {
372
+ // Left Ventricle
373
+ const leftVentricleGeometry = new THREE.SphereGeometry(1, 32, 32);
374
+ leftVentricleGeometry.scale(1, 1.3, 0.7);
375
+ const leftVentricleMaterial = new THREE.MeshPhongMaterial({
376
+ color: heartParts.leftVentricle.color,
377
+ shininess: 50,
378
+ transparent: true,
379
+ opacity: 0.9
380
+ });
381
+ heartParts.leftVentricle.object = new THREE.Mesh(leftVentricleGeometry, leftVentricleMaterial);
382
+ heartParts.leftVentricle.object.position.set(-0.7, 0, 0);
383
+ heartGroup.add(heartParts.leftVentricle.object);
384
+
385
+ updateLoadingProgress(12.5);
386
+
387
+ // Right Ventricle
388
+ const rightVentricleGeometry = new THREE.SphereGeometry(0.9, 32, 32);
389
+ rightVentricleGeometry.scale(1, 1.2, 0.6);
390
+ const rightVentricleMaterial = new THREE.MeshPhongMaterial({
391
+ color: heartParts.rightVentricle.color,
392
+ shininess: 50,
393
+ transparent: true,
394
+ opacity: 0.9
395
+ });
396
+ heartParts.rightVentricle.object = new THREE.Mesh(rightVentricleGeometry, rightVentricleMaterial);
397
+ heartParts.rightVentricle.object.position.set(0.7, 0, 0);
398
+ heartGroup.add(heartParts.rightVentricle.object);
399
+
400
+ updateLoadingProgress(25);
401
+
402
+ // Left Atrium
403
+ const leftAtriumGeometry = new THREE.SphereGeometry(0.7, 32, 32);
404
+ leftAtriumGeometry.scale(1, 0.8, 0.7);
405
+ const leftAtriumMaterial = new THREE.MeshPhongMaterial({
406
+ color: heartParts.leftAtrium.color,
407
+ shininess: 50,
408
+ transparent: true,
409
+ opacity: 0.9
410
+ });
411
+ heartParts.leftAtrium.object = new THREE.Mesh(leftAtriumGeometry, leftAtriumMaterial);
412
+ heartParts.leftAtrium.object.position.set(-0.8, 1.2, 0);
413
+ heartGroup.add(heartParts.leftAtrium.object);
414
+
415
+ updateLoadingProgress(37.5);
416
+
417
+ // Right Atrium
418
+ const rightAtriumGeometry = new THREE.SphereGeometry(0.7, 32, 32);
419
+ rightAtriumGeometry.scale(1, 0.8, 0.7);
420
+ const rightAtriumMaterial = new THREE.MeshPhongMaterial({
421
+ color: heartParts.rightAtrium.color,
422
+ shininess: 50,
423
+ transparent: true,
424
+ opacity: 0.9
425
+ });
426
+ heartParts.rightAtrium.object = new THREE.Mesh(rightAtriumGeometry, rightAtriumMaterial);
427
+ heartParts.rightAtrium.object.position.set(0.8, 1.2, 0);
428
+ heartGroup.add(heartParts.rightAtrium.object);
429
+
430
+ updateLoadingProgress(50);
431
+
432
+ // Aorta (a tube-like structure)
433
+ const aortaGeometry = new THREE.CylinderGeometry(0.4, 0.35, 1.5, 32);
434
+ const aortaMaterial = new THREE.MeshPhongMaterial({
435
+ color: heartParts.aorta.color,
436
+ shininess: 50,
437
+ transparent: true,
438
+ opacity: 0.9
439
+ });
440
+ heartParts.aorta.object = new THREE.Mesh(aortaGeometry, aortaMaterial);
441
+ heartParts.aorta.object.position.set(-0.6, 0.8, 0);
442
+ heartParts.aorta.object.rotation.x = -Math.PI / 5;
443
+ heartGroup.add(heartParts.aorta.object);
444
+
445
+ updateLoadingProgress(62.5);
446
+
447
+ // Pulmonary Arteries (two tubes coming from the right ventricle)
448
+ const pulmonaryArteriesGeometry = new THREE.CylinderGeometry(0.3, 0.25, 1.2, 32);
449
+ pulmonaryArteriesGeometry.translate(0, 0.6, 0);
450
+ const pulmonaryArteriesMaterial = new THREE.MeshPhongMaterial({
451
+ color: heartParts.pulmonaryArteries.color,
452
+ shininess: 50,
453
+ transparent: true,
454
+ opacity: 0.9
455
+ });
456
+
457
+ heartParts.pulmonaryArteries.object = new THREE.Group();
458
+
459
+ const artery1 = new THREE.Mesh(pulmonaryArteriesGeometry, pulmonaryArteriesMaterial);
460
+ artery1.position.set(0.4, 0.5, 0);
461
+ artery1.rotation.x = -Math.PI / 4;
462
+ artery1.rotation.z = Math.PI / 6;
463
+
464
+ const artery2 = new THREE.Mesh(pulmonaryArteriesGeometry, pulmonaryArteriesMaterial);
465
+ artery2.position.set(0.7, 0.3, 0.2);
466
+ artery2.rotation.x = -Math.PI / 4;
467
+ artery2.rotation.z = -Math.PI / 6;
468
+
469
+ heartParts.pulmonaryArteries.object.add(artery1);
470
+ heartParts.pulmonaryArteries.object.add(artery2);
471
+ heartGroup.add(heartParts.pulmonaryArteries.object);
472
+
473
+ updateLoadingProgress(75);
474
+
475
+ // Pulmonary Veins (four tubes entering the left atrium)
476
+ const pulmonaryVeinsGeometry = new THREE.CylinderGeometry(0.2, 0.2, 0.8, 16);
477
+ const pulmonaryVeinsMaterial = new THREE.MeshPhongMaterial({
478
+ color: heartParts.pulmonaryVeins.color,
479
+ shininess: 50,
480
+ transparent: true,
481
+ opacity: 0.9
482
+ });
483
+
484
+ heartParts.pulmonaryVeins.object = new THREE.Group();
485
+
486
+ for (let i = 0; i < 4; i++) {
487
+ const vein = new THREE.Mesh(pulmonaryVeinsGeometry, pulmonaryVeinsMaterial);
488
+ vein.position.set(-0.8 - i * 0.15, 1.6 - i * 0.1, 0.15 - i * 0.1);
489
+ vein.rotation.x = -Math.PI / 4;
490
+ heartParts.pulmonaryVeins.object.add(vein);
491
+ }
492
+
493
+ heartGroup.add(heartParts.pulmonaryVeins.object);
494
+
495
+ updateLoadingProgress(87.5);
496
+
497
+ // Cardiac Fat (adipose tissue around the heart)
498
+ const fatGeometry = new THREE.SphereGeometry(1.5, 32, 32);
499
+ fatGeometry.scale(1, 0.8, 0.9);
500
+ const fatMaterial = new THREE.MeshPhongMaterial({
501
+ color: heartParts.fat.color,
502
+ shininess: 30,
503
+ transparent: true,
504
+ opacity: 0.7,
505
+ wireframe: false
506
+ });
507
+ heartParts.fat.object = new THREE.Mesh(fatGeometry, fatMaterial);
508
+ heartParts.fat.object.position.set(0, 0, 0);
509
+ heartGroup.add(heartParts.fat.object);
510
+
511
+ updateLoadingProgress(100);
512
+ }
513
+
514
+ // Set up UI event listeners
515
+ function setupEventListeners() {
516
+ // Toggle controls for each heart part
517
+ document.getElementById('leftVentricleToggle').addEventListener('change', function(e) {
518
+ heartParts.leftVentricle.visible = e.target.checked;
519
+ heartParts.leftVentricle.object.visible = e.target.checked;
520
+ });
521
+
522
+ document.getElementById('rightVentricleToggle').addEventListener('change', function(e) {
523
+ heartParts.rightVentricle.visible = e.target.checked;
524
+ heartParts.rightVentricle.object.visible = e.target.checked;
525
+ });
526
+
527
+ document.getElementById('leftAtriumToggle').addEventListener('change', function(e) {
528
+ heartParts.leftAtrium.visible = e.target.checked;
529
+ heartParts.leftAtrium.object.visible = e.target.checked;
530
+ });
531
+
532
+ document.getElementById('rightAtriumToggle').addEventListener('change', function(e) {
533
+ heartParts.rightAtrium.visible = e.target.checked;
534
+ heartParts.rightAtrium.object.visible = e.target.checked;
535
+ });
536
+
537
+ document.getElementById('aortaToggle').addEventListener('change', function(e) {
538
+ heartParts.aorta.visible = e.target.checked;
539
+ heartParts.aorta.object.visible = e.target.checked;
540
+ });
541
+
542
+ document.getElementById('pulmonaryArteriesToggle').addEventListener('change', function(e) {
543
+ heartParts.pulmonaryArteries.visible = e.target.checked;
544
+ heartParts.pulmonaryArteries.object.visible = e.target.checked;
545
+ });
546
+
547
+ document.getElementById('pulmonaryVeinsToggle').addEventListener('change', function(e) {
548
+ heartParts.pulmonaryVeins.visible = e.target.checked;
549
+ heartParts.pulmonaryVeins.object.visible = e.target.checked;
550
+ });
551
+
552
+ document.getElementById('fatToggle').addEventListener('change', function(e) {
553
+ heartParts.fat.visible = e.target.checked;
554
+ heartParts.fat.object.visible = e.target.checked;
555
+ });
556
+
557
+ // Reset view button
558
+ document.getElementById('resetView').addEventListener('click', function() {
559
+ controls.reset();
560
+ camera.position.z = 5;
561
+ });
562
+ }
563
+
564
+ // Loading progress simulation
565
+ function updateLoadingProgress(percent) {
566
+ document.getElementById('progress').style.width = percent + '%';
567
+
568
+ if (percent === 100) {
569
+ setTimeout(() => {
570
+ document.getElementById('loading').style.display = 'none';
571
+ }, 500);
572
+ }
573
+ }
574
+
575
+ // Handle window resize
576
+ function onWindowResize() {
577
+ const width = window.innerWidth - 300;
578
+ const height = window.innerHeight;
579
+
580
+ camera.aspect = width / height;
581
+ camera.updateProjectionMatrix();
582
+ renderer.setSize(width, height);
583
+ }
584
+
585
+ window.addEventListener('resize', onWindowResize);
586
+
587
+ // Animation loop
588
+ function animate() {
589
+ requestAnimationFrame(animate);
590
+ controls.update();
591
+ renderer.render(scene, camera);
592
+ }
593
+
594
+ // Initialize everything
595
+ function init() {
596
+ createHeartParts();
597
+ setupEventListeners();
598
+ animate();
599
+ }
600
+
601
+ init();
602
+ </script>
603
+ <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 <a href="https://enzostvs-deepsite.hf.space" style="color: #fff;" target="_blank" >DeepSite</a> <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;"></p></body>
604
+ </html>