Spaces:
Running
Running
Add 1 files
Browse files- index.html +131 -1
index.html
CHANGED
|
@@ -3,7 +3,7 @@
|
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8">
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
-
<title>Système Solaire 3D</title>
|
| 7 |
<script src="https://cdn.tailwindcss.com"></script>
|
| 8 |
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/build/three.min.js"></script>
|
| 9 |
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.js"></script>
|
|
@@ -79,6 +79,15 @@
|
|
| 79 |
backdrop-filter: blur(5px);
|
| 80 |
display: none;
|
| 81 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 82 |
</style>
|
| 83 |
</head>
|
| 84 |
<body>
|
|
@@ -102,6 +111,9 @@
|
|
| 102 |
<button id="toggleLabels" class="bg-purple-600 hover:bg-purple-700 text-white py-1 px-3 rounded text-sm transition">
|
| 103 |
Masquer les labels
|
| 104 |
</button>
|
|
|
|
|
|
|
|
|
|
| 105 |
</div>
|
| 106 |
</div>
|
| 107 |
|
|
@@ -377,11 +389,77 @@
|
|
| 377 |
labels.push({ element: label, planet: planet });
|
| 378 |
});
|
| 379 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 380 |
// Contrôles UI
|
| 381 |
const speedControl = document.getElementById('speedControl');
|
| 382 |
const speedValue = document.getElementById('speedValue');
|
| 383 |
const toggleOrbits = document.getElementById('toggleOrbits');
|
| 384 |
const toggleLabels = document.getElementById('toggleLabels');
|
|
|
|
| 385 |
const planetInfo = document.getElementById('planetInfo');
|
| 386 |
const planetName = document.getElementById('planetName');
|
| 387 |
const planetDistance = document.getElementById('planetDistance');
|
|
@@ -390,6 +468,7 @@
|
|
| 390 |
|
| 391 |
let showOrbits = true;
|
| 392 |
let showLabels = true;
|
|
|
|
| 393 |
let speedFactor = 1;
|
| 394 |
|
| 395 |
speedControl.addEventListener('input', (e) => {
|
|
@@ -408,11 +487,21 @@
|
|
| 408 |
toggleLabels.addEventListener('click', () => {
|
| 409 |
showLabels = !showLabels;
|
| 410 |
labels.forEach(label => label.element.style.display = showLabels ? 'block' : 'none');
|
|
|
|
| 411 |
toggleLabels.textContent = showLabels ? 'Masquer les labels' : 'Afficher les labels';
|
| 412 |
toggleLabels.classList.toggle('bg-purple-600');
|
| 413 |
toggleLabels.classList.toggle('bg-gray-600');
|
| 414 |
});
|
| 415 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 416 |
// Gestion des clics sur les planètes
|
| 417 |
window.addEventListener('click', (event) => {
|
| 418 |
// Calcul de la position de la souris en coordonnées normalisées
|
|
@@ -468,6 +557,12 @@
|
|
| 468 |
const y = (-(screenPosition.y * 0.5 + 0.5) + 1) * window.innerHeight;
|
| 469 |
label.element.style.transform = `translate(-50%, -50%) translate(${x}px,${y}px)`;
|
| 470 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 471 |
|
| 472 |
// Animation du soleil
|
| 473 |
sun.rotation.y += 0.002 * speedFactor;
|
|
@@ -486,6 +581,41 @@
|
|
| 486 |
particle.position.normalize().multiplyScalar(5 + Math.random() * 2);
|
| 487 |
}
|
| 488 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 489 |
|
| 490 |
controls.update();
|
| 491 |
renderer.render(scene, camera);
|
|
|
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8">
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>Système Solaire 3D avec Comète</title>
|
| 7 |
<script src="https://cdn.tailwindcss.com"></script>
|
| 8 |
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/build/three.min.js"></script>
|
| 9 |
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.js"></script>
|
|
|
|
| 79 |
backdrop-filter: blur(5px);
|
| 80 |
display: none;
|
| 81 |
}
|
| 82 |
+
.comet-label {
|
| 83 |
+
position: absolute;
|
| 84 |
+
color: #aaf;
|
| 85 |
+
font-size: 12px;
|
| 86 |
+
pointer-events: none;
|
| 87 |
+
text-shadow: 0 0 3px black;
|
| 88 |
+
white-space: nowrap;
|
| 89 |
+
transform: translate(-50%, -50%);
|
| 90 |
+
}
|
| 91 |
</style>
|
| 92 |
</head>
|
| 93 |
<body>
|
|
|
|
| 111 |
<button id="toggleLabels" class="bg-purple-600 hover:bg-purple-700 text-white py-1 px-3 rounded text-sm transition">
|
| 112 |
Masquer les labels
|
| 113 |
</button>
|
| 114 |
+
<button id="toggleComet" class="bg-green-600 hover:bg-green-700 text-white py-1 px-3 rounded text-sm transition">
|
| 115 |
+
Masquer la comète
|
| 116 |
+
</button>
|
| 117 |
</div>
|
| 118 |
</div>
|
| 119 |
|
|
|
|
| 389 |
labels.push({ element: label, planet: planet });
|
| 390 |
});
|
| 391 |
|
| 392 |
+
// Création de la comète
|
| 393 |
+
function createComet() {
|
| 394 |
+
// Noyau de la comète
|
| 395 |
+
const cometGeometry = new THREE.SphereGeometry(0.3, 16, 16);
|
| 396 |
+
const cometMaterial = new THREE.MeshPhongMaterial({
|
| 397 |
+
color: 0x88ccff,
|
| 398 |
+
emissive: 0x88ccff,
|
| 399 |
+
emissiveIntensity: 0.5
|
| 400 |
+
});
|
| 401 |
+
const comet = new THREE.Mesh(cometGeometry, cometMaterial);
|
| 402 |
+
|
| 403 |
+
// Queue de la comète (particules)
|
| 404 |
+
const tailParticles = new THREE.BufferGeometry();
|
| 405 |
+
const tailMaterial = new THREE.PointsMaterial({
|
| 406 |
+
color: 0x88ffff,
|
| 407 |
+
size: 0.1,
|
| 408 |
+
transparent: true,
|
| 409 |
+
opacity: 0.8,
|
| 410 |
+
blending: THREE.AdditiveBlending
|
| 411 |
+
});
|
| 412 |
+
|
| 413 |
+
const tailVertices = [];
|
| 414 |
+
for (let i = 0; i < 100; i++) {
|
| 415 |
+
// Position aléatoire derrière la comète
|
| 416 |
+
const x = -Math.random() * 5;
|
| 417 |
+
const y = (Math.random() - 0.5) * 0.5;
|
| 418 |
+
const z = (Math.random() - 0.5) * 0.5;
|
| 419 |
+
tailVertices.push(x, y, z);
|
| 420 |
+
}
|
| 421 |
+
|
| 422 |
+
tailParticles.setAttribute('position', new THREE.Float32BufferAttribute(tailVertices, 3));
|
| 423 |
+
const tail = new THREE.Points(tailParticles, tailMaterial);
|
| 424 |
+
comet.add(tail);
|
| 425 |
+
|
| 426 |
+
// Position initiale aléatoire
|
| 427 |
+
const angle = Math.random() * Math.PI * 2;
|
| 428 |
+
const distance = 150 + Math.random() * 50;
|
| 429 |
+
comet.position.x = Math.cos(angle) * distance;
|
| 430 |
+
comet.position.z = Math.sin(angle) * distance;
|
| 431 |
+
comet.position.y = (Math.random() - 0.5) * 30;
|
| 432 |
+
|
| 433 |
+
// Vitesse et direction aléatoires
|
| 434 |
+
const velocity = new THREE.Vector3(
|
| 435 |
+
(Math.random() - 0.5) * 0.5,
|
| 436 |
+
(Math.random() - 0.5) * 0.2,
|
| 437 |
+
(Math.random() - 0.5) * 0.5
|
| 438 |
+
);
|
| 439 |
+
|
| 440 |
+
// Label pour la comète
|
| 441 |
+
const label = document.createElement('div');
|
| 442 |
+
label.className = 'comet-label';
|
| 443 |
+
label.textContent = 'Comète';
|
| 444 |
+
document.body.appendChild(label);
|
| 445 |
+
|
| 446 |
+
return {
|
| 447 |
+
mesh: comet,
|
| 448 |
+
velocity: velocity,
|
| 449 |
+
label: label,
|
| 450 |
+
tail: tail
|
| 451 |
+
};
|
| 452 |
+
}
|
| 453 |
+
|
| 454 |
+
const comet = createComet();
|
| 455 |
+
scene.add(comet.mesh);
|
| 456 |
+
|
| 457 |
// Contrôles UI
|
| 458 |
const speedControl = document.getElementById('speedControl');
|
| 459 |
const speedValue = document.getElementById('speedValue');
|
| 460 |
const toggleOrbits = document.getElementById('toggleOrbits');
|
| 461 |
const toggleLabels = document.getElementById('toggleLabels');
|
| 462 |
+
const toggleComet = document.getElementById('toggleComet');
|
| 463 |
const planetInfo = document.getElementById('planetInfo');
|
| 464 |
const planetName = document.getElementById('planetName');
|
| 465 |
const planetDistance = document.getElementById('planetDistance');
|
|
|
|
| 468 |
|
| 469 |
let showOrbits = true;
|
| 470 |
let showLabels = true;
|
| 471 |
+
let showComet = true;
|
| 472 |
let speedFactor = 1;
|
| 473 |
|
| 474 |
speedControl.addEventListener('input', (e) => {
|
|
|
|
| 487 |
toggleLabels.addEventListener('click', () => {
|
| 488 |
showLabels = !showLabels;
|
| 489 |
labels.forEach(label => label.element.style.display = showLabels ? 'block' : 'none');
|
| 490 |
+
comet.label.style.display = showLabels ? 'block' : 'none';
|
| 491 |
toggleLabels.textContent = showLabels ? 'Masquer les labels' : 'Afficher les labels';
|
| 492 |
toggleLabels.classList.toggle('bg-purple-600');
|
| 493 |
toggleLabels.classList.toggle('bg-gray-600');
|
| 494 |
});
|
| 495 |
|
| 496 |
+
toggleComet.addEventListener('click', () => {
|
| 497 |
+
showComet = !showComet;
|
| 498 |
+
comet.mesh.visible = showComet;
|
| 499 |
+
comet.label.style.display = showComet && showLabels ? 'block' : 'none';
|
| 500 |
+
toggleComet.textContent = showComet ? 'Masquer la comète' : 'Afficher la comète';
|
| 501 |
+
toggleComet.classList.toggle('bg-green-600');
|
| 502 |
+
toggleComet.classList.toggle('bg-gray-600');
|
| 503 |
+
});
|
| 504 |
+
|
| 505 |
// Gestion des clics sur les planètes
|
| 506 |
window.addEventListener('click', (event) => {
|
| 507 |
// Calcul de la position de la souris en coordonnées normalisées
|
|
|
|
| 557 |
const y = (-(screenPosition.y * 0.5 + 0.5) + 1) * window.innerHeight;
|
| 558 |
label.element.style.transform = `translate(-50%, -50%) translate(${x}px,${y}px)`;
|
| 559 |
});
|
| 560 |
+
|
| 561 |
+
// Mise à jour du label de la comète
|
| 562 |
+
const cometScreenPos = comet.mesh.position.clone().project(camera);
|
| 563 |
+
const cometX = (cometScreenPos.x * 0.5 + 0.5) * window.innerWidth;
|
| 564 |
+
const cometY = (-(cometScreenPos.y * 0.5 + 0.5) + 1) * window.innerHeight;
|
| 565 |
+
comet.label.style.transform = `translate(-50%, -50%) translate(${cometX}px,${cometY}px)`;
|
| 566 |
|
| 567 |
// Animation du soleil
|
| 568 |
sun.rotation.y += 0.002 * speedFactor;
|
|
|
|
| 581 |
particle.position.normalize().multiplyScalar(5 + Math.random() * 2);
|
| 582 |
}
|
| 583 |
});
|
| 584 |
+
|
| 585 |
+
// Animation de la comète
|
| 586 |
+
comet.mesh.position.x += comet.velocity.x * speedFactor;
|
| 587 |
+
comet.mesh.position.y += comet.velocity.y * speedFactor;
|
| 588 |
+
comet.mesh.position.z += comet.velocity.z * speedFactor;
|
| 589 |
+
|
| 590 |
+
// Faire tourner la queue de la comète
|
| 591 |
+
comet.tail.rotation.y += 0.01 * speedFactor;
|
| 592 |
+
|
| 593 |
+
// Si la comète sort de la scène, la repositionner de l'autre côté
|
| 594 |
+
if (Math.abs(comet.mesh.position.x) > 200 ||
|
| 595 |
+
Math.abs(comet.mesh.position.y) > 100 ||
|
| 596 |
+
Math.abs(comet.mesh.position.z) > 200) {
|
| 597 |
+
|
| 598 |
+
// Nouvelle position aléatoire
|
| 599 |
+
const angle = Math.random() * Math.PI * 2;
|
| 600 |
+
const distance = 150 + Math.random() * 50;
|
| 601 |
+
comet.mesh.position.x = Math.cos(angle) * distance;
|
| 602 |
+
comet.mesh.position.z = Math.sin(angle) * distance;
|
| 603 |
+
comet.mesh.position.y = (Math.random() - 0.5) * 30;
|
| 604 |
+
|
| 605 |
+
// Nouvelle direction
|
| 606 |
+
comet.velocity.set(
|
| 607 |
+
(Math.random() - 0.5) * 0.5,
|
| 608 |
+
(Math.random() - 0.5) * 0.2,
|
| 609 |
+
(Math.random() - 0.5) * 0.5
|
| 610 |
+
);
|
| 611 |
+
}
|
| 612 |
+
|
| 613 |
+
// Orientation de la comète vers sa direction de mouvement
|
| 614 |
+
comet.mesh.lookAt(
|
| 615 |
+
comet.mesh.position.x + comet.velocity.x,
|
| 616 |
+
comet.mesh.position.y + comet.velocity.y,
|
| 617 |
+
comet.mesh.position.z + comet.velocity.z
|
| 618 |
+
);
|
| 619 |
|
| 620 |
controls.update();
|
| 621 |
renderer.render(scene, camera);
|