| <!DOCTYPE html> |
| <html lang="fr"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Gravity Simulator - Comparaison interplanétaire</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| <style> |
| .planet { |
| transition: transform 0.3s ease, box-shadow 0.3s ease; |
| will-change: transform; |
| } |
| .planet:hover { |
| transform: scale(1.05); |
| box-shadow: 0 10px 25px rgba(0,0,0,0.2); |
| } |
| .gravity-well { |
| position: absolute; |
| border-radius: 50%; |
| opacity: 0.2; |
| transform: translate(-50%, -50%); |
| } |
| #simulationCanvas { |
| background: radial-gradient(circle at center, #1a202c 0%, #0f172a 100%); |
| border-radius: 12px; |
| box-shadow: inset 0 0 20px rgba(0,0,0,0.5); |
| } |
| .object { |
| position: absolute; |
| border-radius: 50%; |
| transform: translate(-50%, -50%); |
| } |
| @keyframes float { |
| 0%, 100% { transform: translateY(0); } |
| 50% { transform: translateY(-10px); } |
| } |
| .floating { |
| animation: float 3s ease-in-out infinite; |
| } |
| .planet-stats { |
| position: absolute; |
| background: rgba(30, 41, 59, 0.8); |
| border-radius: 8px; |
| padding: 8px; |
| font-size: 12px; |
| pointer-events: none; |
| transform: translateX(-50%); |
| } |
| .fall-data { |
| position: absolute; |
| bottom: 10px; |
| left: 50%; |
| transform: translateX(-50%); |
| background: rgba(30, 41, 59, 0.8); |
| border-radius: 8px; |
| padding: 8px; |
| font-size: 12px; |
| text-align: center; |
| min-width: 120px; |
| } |
| </style> |
| </head> |
| <body class="bg-gray-900 text-gray-100 min-h-screen"> |
| <div class="container mx-auto px-4 py-8"> |
| <header class="mb-10 text-center"> |
| <h1 class="text-4xl md:text-5xl font-bold mb-2 bg-gradient-to-r from-blue-400 to-purple-600 bg-clip-text text-transparent"> |
| Gravity Simulator |
| </h1> |
| <p class="text-xl text-gray-300 max-w-2xl mx-auto"> |
| Comparez les effets de la gravité sur différentes planètes en temps réel |
| </p> |
| </header> |
|
|
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-8 mb-10"> |
| |
| <div class="bg-gray-800 p-6 rounded-xl shadow-lg col-span-1"> |
| <h2 class="text-2xl font-semibold mb-4 flex items-center"> |
| <i class="fas fa-sliders-h mr-2 text-blue-400"></i> Paramètres |
| </h2> |
| |
| <div class="mb-6"> |
| <label class="block text-gray-300 mb-2">Planètes à comparer</label> |
| <div class="grid grid-cols-2 gap-2"> |
| <button id="earthBtn" class="planet-btn bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded flex items-center justify-center"> |
| <i class="fas fa-globe-americas mr-2"></i> Terre |
| </button> |
| <button id="moonBtn" class="planet-btn bg-gray-400 hover:bg-gray-500 text-gray-900 py-2 px-4 rounded flex items-center justify-center"> |
| <i class="fas fa-moon mr-2"></i> Lune |
| </button> |
| <button id="marsBtn" class="planet-btn bg-red-600 hover:bg-red-700 text-white py-2 px-4 rounded flex items-center justify-center"> |
| <i class="fas fa-globe mr-2"></i> Mars |
| </button> |
| <button id="jupiterBtn" class="planet-btn bg-yellow-600 hover:bg-yellow-700 text-white py-2 px-4 rounded flex items-center justify-center"> |
| <i class="fas fa-globe mr-2"></i> Jupiter |
| </button> |
| </div> |
| </div> |
| |
| <div class="mb-6"> |
| <label class="block text-gray-300 mb-2">Objet à lâcher</label> |
| <select id="objectType" class="w-full bg-gray-700 border border-gray-600 rounded py-2 px-3 text-white focus:outline-none focus:ring-2 focus:ring-blue-500"> |
| <option value="ball">Balle (1kg)</option> |
| <option value="feather">Plume (0.01kg)</option> |
| <option value="hammer">Marteau (5kg)</option> |
| <option value="car">Voiture (1000kg)</option> |
| </select> |
| </div> |
| |
| <div class="mb-6"> |
| <label class="block text-gray-300 mb-2">Hauteur de chute</label> |
| <input id="heightSlider" type="range" min="50" max="300" value="150" class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer"> |
| <div class="flex justify-between text-sm text-gray-400"> |
| <span>50m</span> |
| <span id="heightValue">150m</span> |
| <span>300m</span> |
| </div> |
| </div> |
| |
| <div class="flex space-x-3"> |
| <button id="startBtn" class="flex-1 bg-green-600 hover:bg-green-700 text-white py-2 px-4 rounded flex items-center justify-center"> |
| <i class="fas fa-play mr-2"></i> Démarrer |
| </button> |
| <button id="resetBtn" class="flex-1 bg-gray-600 hover:bg-gray-700 text-white py-2 px-4 rounded flex items-center justify-center"> |
| <i class="fas fa-redo mr-2"></i> Réinitialiser |
| </button> |
| </div> |
| </div> |
| |
| |
| <div class="bg-gray-800 p-6 rounded-xl shadow-lg col-span-2"> |
| <div class="flex justify-between items-center mb-4"> |
| <h2 class="text-2xl font-semibold flex items-center"> |
| <i class="fas fa-atom mr-2 text-purple-400"></i> Simulation |
| </h2> |
| <div class="text-sm bg-gray-700 px-3 py-1 rounded-full flex items-center"> |
| <i class="fas fa-info-circle mr-1 text-blue-400"></i> |
| <span id="timeScale">Temps réel</span> |
| </div> |
| </div> |
| |
| <div class="relative h-96 w-full" id="simulationContainer"> |
| <canvas id="simulationCanvas" class="w-full h-full"></canvas> |
| |
| |
| <div id="planetsContainer" class="absolute inset-0"></div> |
| |
| |
| <div id="resultsPanel" class="absolute bottom-4 left-4 bg-gray-900 bg-opacity-80 p-3 rounded-lg hidden"> |
| <div class="grid grid-cols-3 gap-4 text-sm"> |
| <div> |
| <div class="text-gray-400">Temps de chute:</div> |
| <div id="fallTime" class="font-mono">0.00s</div> |
| </div> |
| <div> |
| <div class="text-gray-400">Vitesse finale:</div> |
| <div id="finalSpeed" class="font-mono">0.00 m/s</div> |
| </div> |
| <div> |
| <div class="text-gray-400">Force gravitationnelle:</div> |
| <div id="gravForce" class="font-mono">0.00 N</div> |
| </div> |
| </div> |
| </div> |
| </div> |
| |
| <div class="mt-4 grid grid-cols-1 md:grid-cols-3 gap-4" id="planetStats"> |
| |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="bg-gray-800 p-6 rounded-xl shadow-lg mb-10"> |
| <h2 class="text-2xl font-semibold mb-4 flex items-center"> |
| <i class="fas fa-table mr-2 text-green-400"></i> Données planétaires |
| </h2> |
| |
| <div class="overflow-x-auto"> |
| <table class="w-full text-left"> |
| <thead class="bg-gray-700"> |
| <tr> |
| <th class="py-3 px-4">Planète</th> |
| <th class="py-3 px-4">Gravité (m/s²)</th> |
| <th class="py-3 px-4">Masse (×10²⁴ kg)</th> |
| <th class="py-3 px-4">Rayon (km)</th> |
| <th class="py-3 px-4">Temps de chute de 100m</th> |
| <th class="py-3 px-4">Vitesse finale (100m)</th> |
| </tr> |
| </thead> |
| <tbody id="planetData"> |
| |
| </tbody> |
| </table> |
| </div> |
| </div> |
| |
| |
| <div class="bg-gray-800 p-6 rounded-xl shadow-lg"> |
| <h2 class="text-2xl font-semibold mb-4 flex items-center"> |
| <i class="fas fa-book-open mr-2 text-yellow-400"></i> Science de la gravité |
| </h2> |
| |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> |
| <div class="bg-gray-700 p-4 rounded-lg"> |
| <h3 class="text-lg font-medium mb-2 text-blue-300">Loi de la gravitation universelle</h3> |
| <p class="text-gray-300 mb-3"> |
| La force gravitationnelle entre deux objets est donnée par la formule: |
| </p> |
| <div class="bg-gray-800 p-3 rounded font-mono text-center mb-3"> |
| F = G × (m₁ × m₂) / r² |
| </div> |
| <p class="text-gray-300"> |
| Où F est la force, G la constante gravitationnelle (6.674×10⁻¹¹ N·m²/kg²), |
| m₁ et m₂ les masses des objets, et r la distance entre leurs centres. |
| </p> |
| </div> |
| |
| <div class="bg-gray-700 p-4 rounded-lg"> |
| <h3 class="text-lg font-medium mb-2 text-purple-300">Mouvement des corps en chute libre</h3> |
| <p class="text-gray-300 mb-3"> |
| Pour un objet en chute libre près de la surface d'une planète: |
| </p> |
| <div class="bg-gray-800 p-3 rounded font-mono text-center mb-3"> |
| v = √(2 × g × h)<br> |
| t = √(2 × h / g) |
| </div> |
| <p class="text-gray-300"> |
| Où v est la vitesse finale, g l'accélération gravitationnelle, |
| h la hauteur de chute, et t le temps de chute. |
| </p> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| <script> |
| document.addEventListener('DOMContentLoaded', function() { |
| |
| const G = 6.67430e-11; |
| const PLANETS = { |
| earth: { name: "Terre", color: "#3b82f6", g: 9.81, mass: 5.972, radius: 6371, emoji: "🌍" }, |
| moon: { name: "Lune", color: "#9ca3af", g: 1.62, mass: 0.07346, radius: 1737, emoji: "🌕" }, |
| mars: { name: "Mars", color: "#ef4444", g: 3.71, mass: 0.64171, radius: 3389, emoji: "♂️" }, |
| jupiter: { name: "Jupiter", color: "#f59e0b", g: 24.79, mass: 1898.19, radius: 69911, emoji: "♃" } |
| }; |
| |
| const OBJECTS = { |
| ball: { name: "Balle", mass: 1, color: "#ffffff", radius: 10 }, |
| feather: { name: "Plume", mass: 0.01, color: "#f3f4f6", radius: 5 }, |
| hammer: { name: "Marteau", mass: 5, color: "#a1a1aa", radius: 12 }, |
| car: { name: "Voiture", mass: 1000, color: "#60a5fa", radius: 15 } |
| }; |
| |
| |
| let selectedPlanets = []; |
| let simulationRunning = false; |
| let animationId = null; |
| let startTime = null; |
| let objects = []; |
| let currentHeight = 150; |
| |
| |
| const simulationContainer = document.getElementById('simulationContainer'); |
| const simulationCanvas = document.getElementById('simulationCanvas'); |
| const planetsContainer = document.getElementById('planetsContainer'); |
| const planetStats = document.getElementById('planetStats'); |
| const planetData = document.getElementById('planetData'); |
| const heightSlider = document.getElementById('heightSlider'); |
| const heightValue = document.getElementById('heightValue'); |
| const objectType = document.getElementById('objectType'); |
| const startBtn = document.getElementById('startBtn'); |
| const resetBtn = document.getElementById('resetBtn'); |
| const resultsPanel = document.getElementById('resultsPanel'); |
| const fallTime = document.getElementById('fallTime'); |
| const finalSpeed = document.getElementById('finalSpeed'); |
| const gravForce = document.getElementById('gravForce'); |
| |
| |
| const ctx = simulationCanvas.getContext('2d'); |
| simulationCanvas.width = simulationContainer.clientWidth; |
| simulationCanvas.height = simulationContainer.clientHeight; |
| |
| |
| document.querySelectorAll('.planet-btn').forEach(btn => { |
| btn.addEventListener('click', function() { |
| const planetId = this.id.replace('Btn', ''); |
| togglePlanetSelection(planetId); |
| }); |
| }); |
| |
| heightSlider.addEventListener('input', function() { |
| currentHeight = parseInt(this.value); |
| heightValue.textContent = `${currentHeight}m`; |
| updateFallData(); |
| }); |
| |
| startBtn.addEventListener('click', startSimulation); |
| resetBtn.addEventListener('click', resetSimulation); |
| |
| |
| function togglePlanetSelection(planetId) { |
| const index = selectedPlanets.indexOf(planetId); |
| const btn = document.getElementById(`${planetId}Btn`); |
| |
| if (index === -1) { |
| if (selectedPlanets.length < 3) { |
| selectedPlanets.push(planetId); |
| btn.classList.add('ring-2', 'ring-blue-400'); |
| renderPlanetSelection(); |
| updatePlanetDataTable(); |
| updateFallData(); |
| } |
| } else { |
| selectedPlanets.splice(index, 1); |
| btn.classList.remove('ring-2', 'ring-blue-400'); |
| renderPlanetSelection(); |
| updatePlanetDataTable(); |
| updateFallData(); |
| } |
| } |
| |
| function renderPlanetSelection() { |
| planetsContainer.innerHTML = ''; |
| planetStats.innerHTML = ''; |
| |
| if (selectedPlanets.length === 0) { |
| planetsContainer.innerHTML = ` |
| <div class="absolute inset-0 flex items-center justify-center text-gray-500"> |
| <div class="text-center"> |
| <i class="fas fa-globe-europe text-5xl mb-4"></i> |
| <p>Sélectionnez au moins une planète pour commencer</p> |
| </div> |
| </div> |
| `; |
| return; |
| } |
| |
| const containerWidth = simulationContainer.clientWidth; |
| const planetWidth = containerWidth / selectedPlanets.length; |
| |
| selectedPlanets.forEach((planetId, index) => { |
| const planet = PLANETS[planetId]; |
| const left = (index * planetWidth) + (planetWidth / 2); |
| |
| |
| const planetEl = document.createElement('div'); |
| planetEl.className = `planet absolute top-1/2 flex flex-col items-center`; |
| planetEl.style.left = `${left}px`; |
| planetEl.style.transform = 'translate(-50%, -50%)'; |
| planetEl.innerHTML = ` |
| <div class="w-16 h-16 rounded-full shadow-lg mb-2" style="background-color: ${planet.color}"> |
| <div class="w-full h-full flex items-center justify-center text-2xl"> |
| ${planet.emoji} |
| </div> |
| </div> |
| <div class="text-sm font-medium">${planet.name}</div> |
| <div class="text-xs text-gray-400">${planet.g}m/s²</div> |
| `; |
| planetsContainer.appendChild(planetEl); |
| |
| |
| const gravityWell = document.createElement('div'); |
| gravityWell.className = 'gravity-well'; |
| gravityWell.style.width = `${planetWidth * 0.8}px`; |
| gravityWell.style.height = `${planetWidth * 0.8}px`; |
| gravityWell.style.left = `${left}px`; |
| gravityWell.style.top = '50%'; |
| gravityWell.style.backgroundColor = planet.color; |
| planetsContainer.appendChild(gravityWell); |
| |
| |
| const fallDataEl = document.createElement('div'); |
| fallDataEl.className = 'fall-data'; |
| fallDataEl.style.left = `${left}px`; |
| fallDataEl.style.color = planet.color; |
| fallDataEl.innerHTML = ` |
| <div>Hauteur: ${currentHeight}m</div> |
| <div>Temps: ${calculateFallTime(currentHeight, planet.g).toFixed(2)}s</div> |
| <div>Vitesse: ${calculateFinalSpeed(currentHeight, planet.g).toFixed(2)}m/s</div> |
| `; |
| fallDataEl.id = `fall-data-${planetId}`; |
| planetsContainer.appendChild(fallDataEl); |
| |
| |
| const statsEl = document.createElement('div'); |
| statsEl.className = 'bg-gray-700 p-4 rounded-lg'; |
| statsEl.innerHTML = ` |
| <div class="flex items-center mb-2"> |
| <div class="w-6 h-6 rounded-full mr-2" style="background-color: ${planet.color}"></div> |
| <h3 class="font-medium">${planet.name}</h3> |
| </div> |
| <div class="grid grid-cols-2 gap-2 text-sm"> |
| <div> |
| <div class="text-gray-400">Gravité:</div> |
| <div>${planet.g} m/s²</div> |
| </div> |
| <div> |
| <div class="text-gray-400">Masse:</div> |
| <div>${planet.mass} ×10²⁴ kg</div> |
| </div> |
| <div> |
| <div class="text-gray-400">Rayon:</div> |
| <div>${planet.radius} km</div> |
| </div> |
| <div> |
| <div class="text-gray-400">Poids de l'objet:</div> |
| <div id="weight-${planetId}">0 N</div> |
| </div> |
| </div> |
| `; |
| planetStats.appendChild(statsEl); |
| }); |
| } |
| |
| function calculateFallTime(height, gravity) { |
| return Math.sqrt(2 * height / gravity); |
| } |
| |
| function calculateFinalSpeed(height, gravity) { |
| return Math.sqrt(2 * gravity * height); |
| } |
| |
| function updateFallData() { |
| selectedPlanets.forEach(planetId => { |
| const planet = PLANETS[planetId]; |
| const fallDataEl = document.getElementById(`fall-data-${planetId}`); |
| if (fallDataEl) { |
| fallDataEl.innerHTML = ` |
| <div>Hauteur: ${currentHeight}m</div> |
| <div>Temps: ${calculateFallTime(currentHeight, planet.g).toFixed(2)}s</div> |
| <div>Vitesse: ${calculateFinalSpeed(currentHeight, planet.g).toFixed(2)}m/s</div> |
| `; |
| } |
| }); |
| } |
| |
| function updatePlanetDataTable() { |
| planetData.innerHTML = ''; |
| |
| Object.keys(PLANETS).forEach(planetId => { |
| const planet = PLANETS[planetId]; |
| const isSelected = selectedPlanets.includes(planetId); |
| const fallTime100m = calculateFallTime(100, planet.g); |
| const finalSpeed100m = calculateFinalSpeed(100, planet.g); |
| |
| const row = document.createElement('tr'); |
| row.className = isSelected ? 'bg-gray-700' : 'border-b border-gray-700'; |
| row.innerHTML = ` |
| <td class="py-3 px-4 flex items-center"> |
| ${isSelected ? `<span class="w-2 h-2 rounded-full mr-2" style="background-color: ${planet.color}"></span>` : ''} |
| ${planet.name} |
| </td> |
| <td class="py-3 px-4">${planet.g}</td> |
| <td class="py-3 px-4">${planet.mass}</td> |
| <td class="py-3 px-4">${planet.radius}</td> |
| <td class="py-3 px-4">${fallTime100m.toFixed(2)} s</td> |
| <td class="py-3 px-4">${finalSpeed100m.toFixed(2)} m/s</td> |
| `; |
| planetData.appendChild(row); |
| }); |
| } |
| |
| function startSimulation() { |
| if (selectedPlanets.length === 0 || simulationRunning) return; |
| |
| simulationRunning = true; |
| startBtn.disabled = true; |
| startTime = Date.now(); |
| objects = []; |
| |
| const height = currentHeight; |
| const object = OBJECTS[objectType.value]; |
| |
| |
| selectedPlanets.forEach((planetId, index) => { |
| const planet = PLANETS[planetId]; |
| const containerWidth = simulationContainer.clientWidth; |
| const planetWidth = containerWidth / selectedPlanets.length; |
| const planetX = (index * planetWidth) + (planetWidth / 2); |
| |
| const obj = { |
| planetId, |
| x: planetX, |
| y: 50, |
| vy: 0, |
| mass: object.mass, |
| radius: object.radius, |
| color: object.color, |
| planetX, |
| planetY: simulationContainer.clientHeight / 2, |
| g: planet.g, |
| height, |
| falling: false, |
| startTime: null, |
| fallDuration: null, |
| finalSpeed: null, |
| statsEl: null |
| }; |
| |
| |
| obj.statsEl = document.createElement('div'); |
| obj.statsEl.className = 'planet-stats'; |
| obj.statsEl.style.left = `${planetX}px`; |
| obj.statsEl.style.top = '20px'; |
| obj.statsEl.style.color = planet.color; |
| obj.statsEl.innerHTML = ` |
| <div>Temps: <span class="time-value">0.00</span>s</div> |
| <div>Vitesse: <span class="speed-value">0.00</span>m/s</div> |
| `; |
| planetsContainer.appendChild(obj.statsEl); |
| |
| objects.push(obj); |
| |
| |
| const weightEl = document.getElementById(`weight-${planetId}`); |
| if (weightEl) { |
| weightEl.textContent = `${(object.mass * planet.g).toFixed(2)} N`; |
| } |
| }); |
| |
| |
| animate(); |
| |
| |
| setTimeout(() => { |
| resultsPanel.classList.remove('hidden'); |
| }, 500); |
| } |
| |
| function animate() { |
| animationId = requestAnimationFrame(animate); |
| const now = Date.now(); |
| const elapsedTime = (now - startTime) / 1000; |
| |
| |
| ctx.clearRect(0, 0, simulationCanvas.width, simulationCanvas.height); |
| |
| |
| drawStars(); |
| |
| |
| objects.forEach(obj => { |
| if (!obj.falling && elapsedTime > 1) { |
| obj.falling = true; |
| obj.startTime = now; |
| } |
| |
| if (obj.falling) { |
| |
| const fallTime = (now - obj.startTime) / 1000; |
| |
| |
| |
| const scaleFactor = (simulationCanvas.height / 2 - 50) / obj.height; |
| obj.y = 50 + 0.5 * obj.g * fallTime * fallTime * scaleFactor; |
| |
| |
| obj.vy = obj.g * fallTime; |
| |
| |
| if (obj.statsEl) { |
| obj.statsEl.querySelector('.time-value').textContent = fallTime.toFixed(2); |
| obj.statsEl.querySelector('.speed-value').textContent = obj.vy.toFixed(2); |
| } |
| |
| |
| if (obj.y >= obj.planetY - 30) { |
| obj.y = obj.planetY - 30; |
| obj.falling = false; |
| obj.fallDuration = fallTime; |
| obj.finalSpeed = obj.vy; |
| |
| |
| updateResults(); |
| } |
| } |
| |
| |
| ctx.beginPath(); |
| ctx.arc(obj.x, obj.y, obj.radius, 0, Math.PI * 2); |
| ctx.fillStyle = obj.color; |
| ctx.fill(); |
| ctx.closePath(); |
| |
| |
| ctx.beginPath(); |
| ctx.ellipse(obj.x, obj.y + obj.radius + 2, obj.radius, obj.radius/3, 0, 0, Math.PI * 2); |
| ctx.fillStyle = 'rgba(0,0,0,0.3)'; |
| ctx.fill(); |
| ctx.closePath(); |
| }); |
| } |
| |
| function drawStars() { |
| ctx.fillStyle = 'white'; |
| |
| |
| for (let i = 0; i < 50; i++) { |
| const x = Math.random() * simulationCanvas.width; |
| const y = Math.random() * simulationCanvas.height; |
| const radius = Math.random() * 1.5; |
| |
| ctx.beginPath(); |
| ctx.arc(x, y, radius, 0, Math.PI * 2); |
| ctx.fill(); |
| } |
| } |
| |
| function updateResults() { |
| if (objects.length === 0) return; |
| |
| |
| const longestFall = objects.reduce((prev, current) => { |
| return (prev.fallDuration || 0) > (current.fallDuration || 0) ? prev : current; |
| }); |
| |
| if (longestFall.fallDuration) { |
| fallTime.textContent = `${longestFall.fallDuration.toFixed(2)}s`; |
| finalSpeed.textContent = `${longestFall.finalSpeed.toFixed(2)} m/s`; |
| |
| |
| const planet = PLANETS[longestFall.planetId]; |
| const object = OBJECTS[objectType.value]; |
| const force = object.mass * planet.g; |
| gravForce.textContent = `${force.toFixed(2)} N`; |
| } |
| } |
| |
| function resetSimulation() { |
| if (animationId) { |
| cancelAnimationFrame(animationId); |
| animationId = null; |
| } |
| |
| simulationRunning = false; |
| startBtn.disabled = false; |
| |
| |
| objects.forEach(obj => { |
| if (obj.statsEl && obj.statsEl.parentNode) { |
| obj.statsEl.parentNode.removeChild(obj.statsEl); |
| } |
| }); |
| |
| objects = []; |
| |
| |
| ctx.clearRect(0, 0, simulationCanvas.width, simulationCanvas.height); |
| |
| |
| resultsPanel.classList.add('hidden'); |
| |
| |
| fallTime.textContent = '0.00s'; |
| finalSpeed.textContent = '0.00 m/s'; |
| gravForce.textContent = '0.00 N'; |
| |
| |
| selectedPlanets.forEach(planetId => { |
| const weightEl = document.getElementById(`weight-${planetId}`); |
| if (weightEl) { |
| weightEl.textContent = '0 N'; |
| } |
| }); |
| } |
| |
| |
| updatePlanetDataTable(); |
| |
| |
| window.addEventListener('resize', function() { |
| simulationCanvas.width = simulationContainer.clientWidth; |
| simulationCanvas.height = simulationContainer.clientHeight; |
| renderPlanetSelection(); |
| }); |
| }); |
| </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=SaidAmchghal/simulation-de-gravit" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
| </html> |