Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>3D Solar System Explorer with Textures</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> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css"> | |
| <style> | |
| .planet-info-card { | |
| backdrop-filter: blur(10px); | |
| background-color: rgba(15, 23, 42, 0.7); | |
| border: 1px solid rgba(255, 255, 255, 0.1); | |
| } | |
| .ring { | |
| position: absolute; | |
| border: 2px solid rgba(255, 255, 255, 0.4); | |
| border-radius: 50%; | |
| transform: rotateX(75deg); | |
| pointer-events: none; | |
| } | |
| #loading-screen { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background: #0f172a; | |
| display: flex; | |
| flex-direction: column; | |
| justify-content: center; | |
| align-items: center; | |
| z-index: 9999; | |
| transition: opacity 0.5s ease-out; | |
| } | |
| .loading-spinner { | |
| width: 50px; | |
| height: 50px; | |
| border: 5px solid rgba(255, 255, 255, 0.3); | |
| border-radius: 50%; | |
| border-top-color: #3b82f6; | |
| animation: spin 1s ease-in-out infinite; | |
| } | |
| @keyframes spin { | |
| to { transform: rotate(360deg); } | |
| } | |
| #canvas-container { | |
| transition: filter 0.3s ease; | |
| } | |
| .blur-effect { | |
| filter: blur(4px); | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-slate-900 text-slate-100 overflow-hidden"> | |
| <!-- Loading Screen --> | |
| <div id="loading-screen"> | |
| <div class="loading-spinner mb-4"></div> | |
| <p class="text-xl font-semibold">Loading the cosmos...</p> | |
| <p class="text-slate-400 mt-2">Preparing your interstellar journey</p> | |
| </div> | |
| <div class="flex h-screen"> | |
| <!-- Sidebar --> | |
| <div class="w-80 bg-slate-800/50 border-r border-slate-700/50 flex flex-col"> | |
| <div class="p-4 border-b border-slate-700/50"> | |
| <h1 class="text-2xl font-bold text-blue-400 flex items-center"> | |
| <i class="fas fa-globe-europe mr-2"></i> | |
| Solar System Explorer | |
| </h1> | |
| <p class="text-slate-400 text-sm mt-1">Explore our cosmic neighborhood in 3D</p> | |
| </div> | |
| <div class="flex-1 overflow-y-auto p-4 space-y-4"> | |
| <div class="space-y-2"> | |
| <h2 class="text-lg font-semibold text-slate-300 flex items-center"> | |
| <i class="fas fa-sun mr-2 text-yellow-400"></i> | |
| The Sun | |
| </h2> | |
| <button onclick="focusOnPlanet('sun')" class="w-full p-2 bg-slate-700/50 hover:bg-slate-700 rounded-lg text-left flex items-center"> | |
| <div class="w-6 h-6 rounded-full bg-yellow-500 mr-3"></div> | |
| View the Sun | |
| </button> | |
| </div> | |
| <div class="space-y-2"> | |
| <h2 class="text-lg font-semibold text-slate-300 flex items-center"> | |
| <i class="fas fa-globe-americas mr-2 text-blue-400"></i> | |
| Rocky Planets | |
| </h2> | |
| <button onclick="focusOnPlanet('mercury')" class="w-full p-2 bg-slate-700/50 hover:bg-slate-700 rounded-lg text-left flex items-center"> | |
| <div class="w-6 h-6 rounded-full bg-gray-400 mr-3"></div> | |
| Mercury | |
| </button> | |
| <button onclick="focusOnPlanet('venus')" class="w-full p-2 bg-slate-700/50 hover:bg-slate-700 rounded-lg text-left flex items-center"> | |
| <div class="w-6 h-6 rounded-full bg-yellow-200 mr-3"></div> | |
| Venus | |
| </button> | |
| <button onclick="focusOnPlanet('earth')" class="w-full p-2 bg-slate-700/50 hover:bg-slate-700 rounded-lg text-left flex items-center"> | |
| <div class="w-6 h-6 rounded-full bg-blue-500 mr-3"></div> | |
| Earth | |
| </button> | |
| <button onclick="focusOnPlanet('mars')" class="w-full p-2 bg-slate-700/50 hover:bg-slate-700 rounded-lg text-left flex items-center"> | |
| <div class="w-6 h-6 rounded-full bg-red-500 mr-3"></div> | |
| Mars | |
| </button> | |
| </div> | |
| <div class="space-y-2"> | |
| <h2 class="text-lg font-semibold text-slate-300 flex items-center"> | |
| <i class="fas fa-ring mr-2 text-purple-400"></i> | |
| Gas Giants | |
| </h2> | |
| <button onclick="focusOnPlanet('jupiter')" class="w-full p-2 bg-slate-700/50 hover:bg-slate-700 rounded-lg text-left flex items-center"> | |
| <div class="w-6 h-6 rounded-full bg-yellow-300 mr-3"></div> | |
| Jupiter | |
| </button> | |
| <button onclick="focusOnPlanet('saturn')" class="w-full p-2 bg-slate-700/50 hover:bg-slate-700 rounded-lg text-left flex items-center"> | |
| <div class="w-6 h-6 rounded-full bg-yellow-200 mr-3 relative"> | |
| <div class="ring" style="width: 16px; height: 16px; top: -3px; left: -3px;"></div> | |
| </div> | |
| Saturn | |
| </button> | |
| <button onclick="focusOnPlanet('uranus')" class="w-full p-2 bg-slate-700/50 hover:bg-slate-700 rounded-lg text-left flex items-center"> | |
| <div class="w-6 h-6 rounded-full bg-teal-300 mr-3"></div> | |
| Uranus | |
| </button> | |
| <button onclick="focusOnPlanet('neptune')" class="w-full p-2 bg-slate-700/50 hover:bg-slate-700 rounded-lg text-left flex items-center"> | |
| <div class="w-6 h-6 rounded-full bg-blue-400 mr-3"></div> | |
| Neptune | |
| </button> | |
| </div> | |
| <div class="space-y-2"> | |
| <h2 class="text-lg font-semibold text-slate-300 flex items-center"> | |
| <i class="fas fa-star mr-2 text-slate-400"></i> | |
| Dwarf Planets | |
| </h2> | |
| <button onclick="focusOnPlanet('pluto')" class="w-full p-2 bg-slate-700/50 hover:bg-slate-700 rounded-lg text-left flex items-center"> | |
| <div class="w-6 h-6 rounded-full bg-gray-300 mr-3"></div> | |
| Pluto | |
| </button> | |
| </div> | |
| </div> | |
| <div class="p-4 border-t border-slate-700/50 text-sm text-slate-400"> | |
| <p>Use mouse to rotate, scroll to zoom</p> | |
| <p class="mt-1">Hold right click to pan</p> | |
| </div> | |
| </div> | |
| <!-- Main Content --> | |
| <div class="flex-1 relative"> | |
| <div id="canvas-container" class="h-full w-full"> | |
| <!-- Three.js canvas will be inserted here --> | |
| </div> | |
| <!-- Planet Info Card --> | |
| <div id="planet-info" class="planet-info-card absolute top-4 right-4 p-4 rounded-lg shadow-lg w-64 hidden"> | |
| <div class="flex justify-between items-start"> | |
| <div> | |
| <h2 id="planet-name" class="text-xl font-bold"></h2> | |
| <p id="planet-type" class="text-sm text-slate-300"></p> | |
| </div> | |
| <button onclick="hidePlanetInfo()" class="text-slate-400 hover:text-white"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <div class="mt-4 space-y-3"> | |
| <div> | |
| <p class="text-xs text-slate-400">Distance from Sun</p> | |
| <p id="planet-distance" class="text-sm"></p> | |
| </div> | |
| <div> | |
| <p class="text-xs text-slate-400">Diameter</p> | |
| <p id="planet-diameter" class="text-sm"></p> | |
| </div> | |
| <div> | |
| <p class="text-xs text-slate-400">Orbital Period</p> | |
| <p id="planet-period" class="text-sm"></p> | |
| </div> | |
| <div> | |
| <p class="text-xs text-slate-400">Surface Temperature</p> | |
| <p id="planet-temperature" class="text-sm"></p> | |
| </div> | |
| </div> | |
| <div class="mt-4 pt-3 border-t border-slate-700/50"> | |
| <p id="planet-fact" class="text-sm italic text-slate-300"></p> | |
| </div> | |
| </div> | |
| <!-- Controls --> | |
| <div class="absolute bottom-4 left-1/2 transform -translate-x-1/2 flex space-x-2"> | |
| <button onclick="toggleAutoRotate()" id="auto-rotate-btn" class="bg-slate-800/70 hover:bg-slate-700/70 p-2 rounded-full"> | |
| <i class="fas fa-sync-alt"></i> | |
| </button> | |
| <button onclick="resetCamera()" class="bg-slate-800/70 hover:bg-slate-700/70 p-2 rounded-full"> | |
| <i class="fas fa-home"></i> | |
| </button> | |
| <button onclick="toggleFullscreen()" class="bg-slate-800/70 hover:bg-slate-700/70 p-2 rounded-full"> | |
| <i class="fas fa-expand"></i> | |
| </button> | |
| </div> | |
| <!-- Current Planet Indicator --> | |
| <div id="current-planet-indicator" class="absolute top-4 left-4 bg-slate-800/70 px-3 py-1 rounded-full text-sm hidden"> | |
| Viewing: <span id="current-planet-name" class="font-semibold"></span> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Three.js variables | |
| let scene, camera, renderer, controls; | |
| let planets = {}; | |
| let currentPlanet = null; | |
| let autoRotate = true; | |
| let planetMeshes = {}; | |
| let textureLoader = new THREE.TextureLoader(); | |
| let loadingManager = new THREE.LoadingManager(); | |
| // Planet data with texture URLs | |
| const planetInfo = { | |
| sun: { | |
| name: "The Sun", | |
| type: "Yellow Dwarf Star", | |
| distance: "0 km (Center of Solar System)", | |
| diameter: "1,392,700 km", | |
| period: "N/A", | |
| temperature: "5,500°C (Surface)", | |
| fact: "The Sun contains 99.86% of the mass in the Solar System.", | |
| textureUrl: "https://www.solarsystemscope.com/textures/download/2k_sun.jpg", | |
| size: 10, | |
| position: { x: 0, y: 0, z: 0 } | |
| }, | |
| mercury: { | |
| name: "Mercury", | |
| type: "Terrestrial Planet", | |
| distance: "57.9 million km", | |
| diameter: "4,880 km", | |
| period: "88 Earth days", | |
| temperature: "-173°C to 427°C", | |
| fact: "A day on Mercury (sunrise to sunrise) lasts 176 Earth days.", | |
| textureUrl: "https://www.solarsystemscope.com/textures/download/2k_mercury.jpg", | |
| size: 0.8, | |
| position: { x: 20, y: 0, z: 0 } | |
| }, | |
| venus: { | |
| name: "Venus", | |
| type: "Terrestrial Planet", | |
| distance: "108.2 million km", | |
| diameter: "12,104 km", | |
| period: "225 Earth days", | |
| temperature: "462°C (Average)", | |
| fact: "Venus rotates in the opposite direction to most planets.", | |
| textureUrl: "https://www.solarsystemscope.com/textures/download/2k_venus_surface.jpg", | |
| size: 0.95, | |
| position: { x: 30, y: 0, z: 0 } | |
| }, | |
| earth: { | |
| name: "Earth", | |
| type: "Terrestrial Planet", | |
| distance: "149.6 million km", | |
| diameter: "12,742 km", | |
| period: "365.25 days", | |
| temperature: "-88°C to 58°C", | |
| fact: "Earth is the only known planet to support life.", | |
| textureUrl: "https://www.solarsystemscope.com/textures/download/2k_earth_daymap.jpg", | |
| size: 1, | |
| position: { x: 40, y: 0, z: 0 } | |
| }, | |
| mars: { | |
| name: "Mars", | |
| type: "Terrestrial Planet", | |
| distance: "227.9 million km", | |
| diameter: "6,779 km", | |
| period: "687 Earth days", | |
| temperature: "-140°C to 20°C", | |
| fact: "Mars has the largest volcano in the solar system - Olympus Mons.", | |
| textureUrl: "https://www.solarsystemscope.com/textures/download/2k_mars.jpg", | |
| size: 0.53, | |
| position: { x: 50, y: 0, z: 0 } | |
| }, | |
| jupiter: { | |
| name: "Jupiter", | |
| type: "Gas Giant", | |
| distance: "778.5 million km", | |
| diameter: "139,820 km", | |
| period: "11.86 Earth years", | |
| temperature: "-145°C (Cloud tops)", | |
| fact: "Jupiter's Great Red Spot is a storm that has raged for at least 400 years.", | |
| textureUrl: "https://www.solarsystemscope.com/textures/download/2k_jupiter.jpg", | |
| size: 2.5, | |
| position: { x: 70, y: 0, z: 0 } | |
| }, | |
| saturn: { | |
| name: "Saturn", | |
| type: "Gas Giant", | |
| distance: "1.43 billion km", | |
| diameter: "116,460 km", | |
| period: "29.46 Earth years", | |
| temperature: "-178°C (Cloud tops)", | |
| fact: "Saturn's rings are made mostly of chunks of ice and rock.", | |
| textureUrl: "https://www.solarsystemscope.com/textures/download/2k_saturn.jpg", | |
| ringTextureUrl: "https://www.solarsystemscope.com/textures/download/2k_saturn_ring_alpha.png", | |
| size: 2, | |
| position: { x: 90, y: 0, z: 0 } | |
| }, | |
| uranus: { | |
| name: "Uranus", | |
| type: "Ice Giant", | |
| distance: "2.87 billion km", | |
| diameter: "50,724 km", | |
| period: "84 Earth years", | |
| temperature: "-216°C (Cloud tops)", | |
| fact: "Uranus rotates on its side, with an axial tilt of 98 degrees.", | |
| textureUrl: "https://www.solarsystemscope.com/textures/download/2k_uranus.jpg", | |
| ringTextureUrl: "https://www.solarsystemscope.com/textures/download/2k_uranus_ring.png", | |
| size: 1.5, | |
| position: { x: 110, y: 0, z: 0 } | |
| }, | |
| neptune: { | |
| name: "Neptune", | |
| type: "Ice Giant", | |
| distance: "4.5 billion km", | |
| diameter: "49,244 km", | |
| period: "164.8 Earth years", | |
| temperature: "-214°C (Cloud tops)", | |
| fact: "Neptune has the strongest winds in the solar system, up to 2,100 km/h.", | |
| textureUrl: "https://www.solarsystemscope.com/textures/download/2k_neptune.jpg", | |
| size: 1.5, | |
| position: { x: 130, y: 0, z: 0 } | |
| }, | |
| pluto: { | |
| name: "Pluto", | |
| type: "Dwarf Planet", | |
| distance: "5.9 billion km", | |
| diameter: "2,377 km", | |
| period: "248 Earth years", | |
| temperature: "-233°C to -223°C", | |
| fact: "Pluto was reclassified as a dwarf planet in 2006.", | |
| textureUrl: "https://www.solarsystemscope.com/textures/download/2k_pluto.jpg", | |
| size: 0.3, | |
| position: { x: 150, y: 0, z: 0 } | |
| } | |
| }; | |
| // Initialize Three.js scene | |
| function init() { | |
| // Create scene | |
| scene = new THREE.Scene(); | |
| scene.background = new THREE.Color(0x0f172a); | |
| // Add ambient light | |
| const ambientLight = new THREE.AmbientLight(0x404040); | |
| scene.add(ambientLight); | |
| // Add directional light (sun) | |
| const directionalLight = new THREE.DirectionalLight(0xffffff, 1); | |
| directionalLight.position.set(0, 0, 0); | |
| scene.add(directionalLight); | |
| // Create camera | |
| camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); | |
| camera.position.set(0, 20, 50); | |
| // Create renderer | |
| renderer = new THREE.WebGLRenderer({ antialias: true }); | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| document.getElementById('canvas-container').appendChild(renderer.domElement); | |
| // Add orbit controls | |
| controls = new THREE.OrbitControls(camera, renderer.domElement); | |
| controls.enableDamping = true; | |
| controls.dampingFactor = 0.05; | |
| controls.autoRotate = autoRotate; | |
| controls.autoRotateSpeed = 0.5; | |
| // Create planets with textures | |
| createPlanetsWithTextures(); | |
| // Add stars background | |
| addStars(); | |
| // Start with Earth focused | |
| setTimeout(() => { | |
| focusOnPlanet('earth'); | |
| hideLoadingScreen(); | |
| }, 1500); | |
| // Handle window resize | |
| window.addEventListener('resize', onWindowResize); | |
| // Start animation loop | |
| animate(); | |
| } | |
| // Create all planets with textures | |
| function createPlanetsWithTextures() { | |
| // Create the Sun with texture | |
| const sunGeometry = new THREE.SphereGeometry(planetInfo.sun.size, 64, 64); | |
| const sunMaterial = new THREE.MeshBasicMaterial({ | |
| color: 0xffff00, | |
| emissive: 0xffffbb, | |
| emissiveIntensity: 1 | |
| }); | |
| const sun = new THREE.Mesh(sunGeometry, sunMaterial); | |
| sun.position.set(0, 0, 0); | |
| scene.add(sun); | |
| planetMeshes.sun = sun; | |
| // Load sun texture | |
| textureLoader.load(planetInfo.sun.textureUrl, function(texture) { | |
| sunMaterial.map = texture; | |
| sunMaterial.needsUpdate = true; | |
| }); | |
| // Create other planets with placeholder colors first | |
| for (const planet in planetInfo) { | |
| if (planet === 'sun') continue; | |
| const geometry = new THREE.SphereGeometry(planetInfo[planet].size, 64, 64); | |
| let material; | |
| // Set placeholder colors based on planet type | |
| if (planet === 'mercury') material = new THREE.MeshPhongMaterial({ color: 0xaaaaaa }); | |
| else if (planet === 'venus') material = new THREE.MeshPhongMaterial({ color: 0xffccaa }); | |
| else if (planet === 'earth') material = new THREE.MeshPhongMaterial({ color: 0x1a66ff }); | |
| else if (planet === 'mars') material = new THREE.MeshPhongMaterial({ color: 0xff3300 }); | |
| else if (planet === 'jupiter') material = new THREE.MeshPhongMaterial({ color: 0xffcc99 }); | |
| else if (planet === 'saturn') material = new THREE.MeshPhongMaterial({ color: 0xffdd99 }); | |
| else if (planet === 'uranus') material = new THREE.MeshPhongMaterial({ color: 0x99ffff }); | |
| else if (planet === 'neptune') material = new THREE.MeshPhongMaterial({ color: 0x3399ff }); | |
| else if (planet === 'pluto') material = new THREE.MeshPhongMaterial({ color: 0xcccccc }); | |
| const planetMesh = new THREE.Mesh(geometry, material); | |
| // Position the planet | |
| planetMesh.position.set( | |
| planetInfo[planet].position.x, | |
| planetInfo[planet].position.y, | |
| planetInfo[planet].position.z | |
| ); | |
| scene.add(planetMesh); | |
| planetMeshes[planet] = planetMesh; | |
| // Load actual textures | |
| textureLoader.load(planetInfo[planet].textureUrl, function(texture) { | |
| material.map = texture; | |
| material.needsUpdate = true; | |
| // Add rings to Saturn | |
| if (planet === 'saturn') { | |
| textureLoader.load(planetInfo.saturn.ringTextureUrl, function(ringTexture) { | |
| const ringGeometry = new THREE.RingGeometry(2.2, 3.5, 64); | |
| const ringMaterial = new THREE.MeshPhongMaterial({ | |
| map: ringTexture, | |
| side: THREE.DoubleSide, | |
| transparent: true, | |
| opacity: 0.8 | |
| }); | |
| const ring = new THREE.Mesh(ringGeometry, ringMaterial); | |
| ring.rotation.x = Math.PI / 2; | |
| planetMesh.add(ring); | |
| }); | |
| } | |
| // Add rings to Uranus | |
| if (planet === 'uranus') { | |
| textureLoader.load(planetInfo.uranus.ringTextureUrl, function(ringTexture) { | |
| const ringGeometry = new THREE.RingGeometry(1.8, 2.5, 64); | |
| const ringMaterial = new THREE.MeshPhongMaterial({ | |
| map: ringTexture, | |
| side: THREE.DoubleSide, | |
| transparent: true, | |
| opacity: 0.6 | |
| }); | |
| const ring = new THREE.Mesh(ringGeometry, ringMaterial); | |
| ring.rotation.x = Math.PI / 2; | |
| planetMesh.add(ring); | |
| }); | |
| } | |
| }); | |
| } | |
| } | |
| // Add stars background | |
| function addStars() { | |
| const starsGeometry = new THREE.BufferGeometry(); | |
| const starCount = 5000; | |
| const positions = new Float32Array(starCount * 3); | |
| for (let i = 0; i < starCount; i++) { | |
| const i3 = i * 3; | |
| positions[i3] = (Math.random() - 0.5) * 2000; | |
| positions[i3 + 1] = (Math.random() - 0.5) * 2000; | |
| positions[i3 + 2] = (Math.random() - 0.5) * 2000; | |
| } | |
| starsGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); | |
| const starsMaterial = new THREE.PointsMaterial({ | |
| color: 0xffffff, | |
| size: 0.5, | |
| transparent: true, | |
| opacity: 0.8 | |
| }); | |
| const stars = new THREE.Points(starsGeometry, starsMaterial); | |
| scene.add(stars); | |
| } | |
| // Focus camera on a specific planet | |
| function focusOnPlanet(planetName) { | |
| if (!planetMeshes[planetName]) return; | |
| currentPlanet = planetName; | |
| const planet = planetMeshes[planetName]; | |
| const planetData = planetInfo[planetName]; | |
| // Calculate target position (slightly above the planet) | |
| const targetPosition = new THREE.Vector3( | |
| planet.position.x, | |
| planet.position.y + planetData.size * 0.5, | |
| planet.position.z | |
| ); | |
| // Calculate camera position based on planet size | |
| const distance = planetData.size * 5; | |
| const cameraPosition = new THREE.Vector3( | |
| planet.position.x, | |
| planet.position.y + planetData.size * 0.5, | |
| planet.position.z + distance | |
| ); | |
| // Animate camera movement | |
| const duration = 1000; | |
| const startTime = Date.now(); | |
| const animateCamera = () => { | |
| const elapsed = Date.now() - startTime; | |
| const progress = Math.min(elapsed / duration, 1); | |
| // Ease in-out function | |
| const easeProgress = progress < 0.5 | |
| ? 2 * progress * progress | |
| : 1 - Math.pow(-2 * progress + 2, 2) / 2; | |
| // Interpolate positions | |
| camera.position.lerpVectors( | |
| camera.position, | |
| cameraPosition, | |
| easeProgress | |
| ); | |
| controls.target.lerpVectors( | |
| controls.target, | |
| targetPosition, | |
| easeProgress | |
| ); | |
| if (progress < 1) { | |
| requestAnimationFrame(animateCamera); | |
| } else { | |
| // Update UI after animation completes | |
| updatePlanetUI(planetName); | |
| } | |
| }; | |
| animateCamera(); | |
| } | |
| // Update planet information UI | |
| function updatePlanetUI(planetName) { | |
| const planetData = planetInfo[planetName]; | |
| document.getElementById('planet-name').textContent = planetData.name; | |
| document.getElementById('planet-type').textContent = planetData.type; | |
| document.getElementById('planet-distance').textContent = planetData.distance; | |
| document.getElementById('planet-diameter').textContent = planetData.diameter; | |
| document.getElementById('planet-period').textContent = planetData.period; | |
| document.getElementById('planet-temperature').textContent = planetData.temperature; | |
| document.getElementById('planet-fact').textContent = planetData.fact; | |
| // Show planet info card | |
| document.getElementById('planet-info').classList.remove('hidden'); | |
| // Update current planet indicator | |
| document.getElementById('current-planet-name').textContent = planetData.name; | |
| document.getElementById('current-planet-indicator').classList.remove('hidden'); | |
| // Add blur effect to canvas | |
| document.getElementById('canvas-container').classList.add('blur-effect'); | |
| } | |
| // Hide planet information UI | |
| function hidePlanetInfo() { | |
| document.getElementById('planet-info').classList.add('hidden'); | |
| document.getElementById('canvas-container').classList.remove('blur-effect'); | |
| } | |
| // Toggle auto-rotation | |
| function toggleAutoRotate() { | |
| autoRotate = !autoRotate; | |
| controls.autoRotate = autoRotate; | |
| const btn = document.getElementById('auto-rotate-btn'); | |
| if (autoRotate) { | |
| btn.classList.remove('bg-slate-700/70'); | |
| btn.classList.add('bg-blue-600/70'); | |
| } else { | |
| btn.classList.remove('bg-blue-600/70'); | |
| btn.classList.add('bg-slate-700/70'); | |
| } | |
| } | |
| // Reset camera to default position | |
| function resetCamera() { | |
| camera.position.set(0, 20, 50); | |
| controls.target.set(0, 0, 0); | |
| currentPlanet = null; | |
| // Hide planet info | |
| document.getElementById('planet-info').classList.add('hidden'); | |
| document.getElementById('current-planet-indicator').classList.add('hidden'); | |
| document.getElementById('canvas-container').classList.remove('blur-effect'); | |
| } | |
| // Toggle fullscreen mode | |
| function toggleFullscreen() { | |
| if (!document.fullscreenElement) { | |
| document.documentElement.requestFullscreen(); | |
| } else { | |
| if (document.exitFullscreen) { | |
| document.exitFullscreen(); | |
| } | |
| } | |
| } | |
| // Hide loading screen | |
| function hideLoadingScreen() { | |
| const loadingScreen = document.getElementById('loading-screen'); | |
| loadingScreen.style.opacity = '0'; | |
| setTimeout(() => { | |
| loadingScreen.style.display = 'none'; | |
| }, 500); | |
| } | |
| // Handle window resize | |
| function onWindowResize() { | |
| camera.aspect = window.innerWidth / window.innerHeight; | |
| camera.updateProjectionMatrix(); | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| } | |
| // Animation loop | |
| function animate() { | |
| requestAnimationFrame(animate); | |
| // Rotate planets | |
| for (const planet in planetMeshes) { | |
| if (planet === 'sun') continue; | |
| // Each planet rotates at a different speed | |
| let rotationSpeed = 0.005; | |
| if (planet === 'mercury') rotationSpeed = 0.01; | |
| if (planet === 'venus') rotationSpeed = -0.003; // Venus rotates backwards | |
| if (planet === 'earth') rotationSpeed = 0.01; | |
| if (planet === 'mars') rotationSpeed = 0.008; | |
| if (planet === 'jupiter') rotationSpeed = 0.02; | |
| if (planet === 'saturn') rotationSpeed = 0.015; | |
| if (planet === 'uranus') rotationSpeed = -0.01; // Uranus rotates on its side | |
| if (planet === 'neptune') rotationSpeed = 0.01; | |
| if (planet === 'pluto') rotationSpeed = 0.005; | |
| planetMeshes[planet].rotation.y += rotationSpeed; | |
| } | |
| // Required for damping | |
| controls.update(); | |
| renderer.render(scene, camera); | |
| } | |
| // Initialize the app when the page loads | |
| window.onload = init; | |
| </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/solor-system-explorer" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |