Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Interactive 3D Solar System</title> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> | |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/controls/OrbitControls.min.js"></script> | |
<style> | |
body { | |
margin: 0; | |
overflow: hidden; | |
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
} | |
#canvas-container { | |
position: absolute; | |
width: 100%; | |
height: 100%; | |
} | |
.planet-info { | |
transition: all 0.3s ease; | |
transform: translateY(20px); | |
opacity: 0; | |
} | |
.planet-info.active { | |
transform: translateY(0); | |
opacity: 1; | |
} | |
.tooltip { | |
position: absolute; | |
background: rgba(0, 0, 0, 0.7); | |
color: white; | |
padding: 8px 12px; | |
border-radius: 4px; | |
pointer-events: none; | |
font-size: 14px; | |
z-index: 100; | |
transition: all 0.1s ease; | |
max-width: 200px; | |
} | |
.orbit { | |
position: absolute; | |
border: 1px solid rgba(255, 255, 255, 0.1); | |
border-radius: 50%; | |
transform-origin: center; | |
} | |
.star { | |
position: absolute; | |
background: white; | |
border-radius: 50%; | |
box-shadow: 0 0 5px white; | |
} | |
</style> | |
</head> | |
<body class="bg-gray-900 text-white"> | |
<div id="canvas-container"></div> | |
<!-- Main UI --> | |
<div class="fixed top-0 left-0 right-0 p-4 bg-black bg-opacity-50 z-10"> | |
<div class="flex justify-between items-center"> | |
<h1 class="text-2xl font-bold">Interactive Solar System</h1> | |
<div class="flex space-x-4"> | |
<button id="reset-view" class="px-4 py-2 bg-blue-600 rounded hover:bg-blue-700 transition">Reset View</button> | |
<button id="toggle-constellations" class="px-4 py-2 bg-purple-600 rounded hover:bg-purple-700 transition">Toggle Constellations</button> | |
<button id="toggle-orbits" class="px-4 py-2 bg-green-600 rounded hover:bg-green-700 transition">Toggle Orbits</button> | |
</div> | |
</div> | |
</div> | |
<!-- Planet Selector --> | |
<div class="fixed bottom-4 left-0 right-0 flex justify-center space-x-2 z-10"> | |
<button data-planet="sun" class="planet-btn w-10 h-10 rounded-full bg-yellow-500 hover:bg-yellow-400 transition"></button> | |
<button data-planet="mercury" class="planet-btn w-6 h-6 rounded-full bg-gray-400 hover:bg-gray-300 transition"></button> | |
<button data-planet="venus" class="planet-btn w-7 h-7 rounded-full bg-yellow-200 hover:bg-yellow-100 transition"></button> | |
<button data-planet="earth" class="planet-btn w-7 h-7 rounded-full bg-blue-500 hover:bg-blue-400 transition"></button> | |
<button data-planet="mars" class="planet-btn w-6 h-6 rounded-full bg-red-500 hover:bg-red-400 transition"></button> | |
<button data-planet="jupiter" class="planet-btn w-9 h-9 rounded-full bg-yellow-600 hover:bg-yellow-500 transition"></button> | |
<button data-planet="saturn" class="planet-btn w-8 h-8 rounded-full bg-yellow-300 hover:bg-yellow-200 transition"></button> | |
<button data-planet="uranus" class="planet-btn w-7 h-7 rounded-full bg-teal-300 hover:bg-teal-200 transition"></button> | |
<button data-planet="neptune" class="planet-btn w-7 h-7 rounded-full bg-blue-400 hover:bg-blue-300 transition"></button> | |
</div> | |
<!-- Planet Info Panel --> | |
<div class="fixed top-20 right-4 w-64 bg-black bg-opacity-70 rounded-lg p-4 z-10 planet-info"> | |
<h2 id="planet-name" class="text-xl font-bold mb-2">Solar System</h2> | |
<div id="planet-desc" class="text-sm"> | |
Click on a planet to view information about it. | |
</div> | |
<div class="mt-4 grid grid-cols-2 gap-2 text-xs"> | |
<div>Diameter: <span id="planet-diameter" class="font-bold">-</span></div> | |
<div>Distance from Sun: <span id="planet-distance" class="font-bold">-</span></div> | |
<div>Orbital Period: <span id="planet-orbit" class="font-bold">-</span></div> | |
<div>Rotation Period: <span id="planet-rotation" class="font-bold">-</span></div> | |
<div>Moons: <span id="planet-moons" class="font-bold">-</span></div> | |
<div>Surface Temp: <span id="planet-temp" class="font-bold">-</span></div> | |
</div> | |
</div> | |
<!-- Tooltip --> | |
<div id="tooltip" class="tooltip" style="display: none;"></div> | |
<script> | |
// Solar system data | |
const planets = { | |
sun: { | |
name: "Sun", | |
diameter: "1,392,700 km", | |
distance: "0 km", | |
orbit: "N/A", | |
rotation: "27 days", | |
moons: "0", | |
temp: "5,500°C", | |
desc: "The Sun is the star at the center of our solar system. It accounts for about 99.86% of the total mass of the Solar System.", | |
color: 0xFDB813, | |
radius: 10, | |
orbitRadius: 0, | |
rotationSpeed: 0.002, | |
orbitSpeed: 0 | |
}, | |
mercury: { | |
name: "Mercury", | |
diameter: "4,880 km", | |
distance: "57.9 million km", | |
orbit: "88 days", | |
rotation: "59 days", | |
moons: "0", | |
temp: "167°C", | |
desc: "Mercury is the smallest and innermost planet in the Solar System. It has no natural satellites and its surface is heavily cratered.", | |
color: 0xAAAAAA, | |
radius: 1.5, | |
orbitRadius: 30, | |
rotationSpeed: 0.004, | |
orbitSpeed: 0.04 | |
}, | |
venus: { | |
name: "Venus", | |
diameter: "12,104 km", | |
distance: "108.2 million km", | |
orbit: "225 days", | |
rotation: "243 days", | |
moons: "0", | |
temp: "464°C", | |
desc: "Venus is the second planet from the Sun and Earth's closest planetary neighbor. It has the densest atmosphere of the four terrestrial planets.", | |
color: 0xE6E6FA, | |
radius: 2.5, | |
orbitRadius: 50, | |
rotationSpeed: 0.002, | |
orbitSpeed: 0.015 | |
}, | |
earth: { | |
name: "Earth", | |
diameter: "12,742 km", | |
distance: "149.6 million km", | |
orbit: "365.25 days", | |
rotation: "1 day", | |
moons: "1", | |
temp: "15°C", | |
desc: "Earth is the third planet from the Sun and the only astronomical object known to harbor life. About 29% of Earth's surface is land consisting of continents and islands.", | |
color: 0x1E90FF, | |
radius: 2.6, | |
orbitRadius: 70, | |
rotationSpeed: 0.02, | |
orbitSpeed: 0.01 | |
}, | |
mars: { | |
name: "Mars", | |
diameter: "6,779 km", | |
distance: "227.9 million km", | |
orbit: "687 days", | |
rotation: "1.03 days", | |
moons: "2", | |
temp: "-65°C", | |
desc: "Mars is the fourth planet from the Sun and the second-smallest planet in the Solar System. It has a thin atmosphere and surface features reminiscent of impact craters.", | |
color: 0xFF4500, | |
radius: 1.8, | |
orbitRadius: 90, | |
rotationSpeed: 0.018, | |
orbitSpeed: 0.008 | |
}, | |
jupiter: { | |
name: "Jupiter", | |
diameter: "139,820 km", | |
distance: "778.3 million km", | |
orbit: "12 years", | |
rotation: "9.9 hours", | |
moons: "79", | |
temp: "-110°C", | |
desc: "Jupiter is the fifth planet from the Sun and the largest in the Solar System. It is a gas giant with a mass one-thousandth that of the Sun.", | |
color: 0xF5DEB3, | |
radius: 6, | |
orbitRadius: 120, | |
rotationSpeed: 0.04, | |
orbitSpeed: 0.002 | |
}, | |
saturn: { | |
name: "Saturn", | |
diameter: "116,460 km", | |
distance: "1.4 billion km", | |
orbit: "29.5 years", | |
rotation: "10.7 hours", | |
moons: "82", | |
temp: "-140°C", | |
desc: "Saturn is the sixth planet from the Sun and the second-largest in the Solar System, after Jupiter. It is a gas giant with an average radius about nine times that of Earth.", | |
color: 0xE5D9B6, | |
radius: 5, | |
orbitRadius: 150, | |
rotationSpeed: 0.038, | |
orbitSpeed: 0.0009 | |
}, | |
uranus: { | |
name: "Uranus", | |
diameter: "50,724 km", | |
distance: "2.9 billion km", | |
orbit: "84 years", | |
rotation: "17.2 hours", | |
moons: "27", | |
temp: "-195°C", | |
desc: "Uranus is the seventh planet from the Sun. It has the third-largest planetary radius and fourth-largest planetary mass in the Solar System.", | |
color: 0xAFEEEE, | |
radius: 3.5, | |
orbitRadius: 180, | |
rotationSpeed: 0.03, | |
orbitSpeed: 0.0004 | |
}, | |
neptune: { | |
name: "Neptune", | |
diameter: "49,244 km", | |
distance: "4.5 billion km", | |
orbit: "165 years", | |
rotation: "16.1 hours", | |
moons: "14", | |
temp: "-200°C", | |
desc: "Neptune is the eighth and farthest-known Solar planet from the Sun. It is the fourth-largest planet by diameter and the third-most-massive planet.", | |
color: 0x4682B4, | |
radius: 3.4, | |
orbitRadius: 210, | |
rotationSpeed: 0.032, | |
orbitSpeed: 0.0001 | |
} | |
}; | |
// Initialize Three.js scene | |
const container = document.getElementById('canvas-container'); | |
const scene = new THREE.Scene(); | |
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); | |
const renderer = new THREE.WebGLRenderer({ antialias: true }); | |
renderer.setSize(window.innerWidth, window.innerHeight); | |
renderer.setPixelRatio(window.devicePixelRatio); | |
renderer.shadowMap.enabled = true; | |
container.appendChild(renderer.domElement); | |
// Add controls | |
const controls = new THREE.OrbitControls(camera, renderer.domElement); | |
controls.enableDamping = true; | |
controls.dampingFactor = 0.05; | |
controls.minDistance = 5; | |
controls.maxDistance = 500; | |
// Set camera position | |
camera.position.set(0, 50, 100); | |
controls.update(); | |
// Add ambient light | |
const ambientLight = new THREE.AmbientLight(0x404040); | |
scene.add(ambientLight); | |
// Add directional light (sun) | |
const sunLight = new THREE.PointLight(0xffffff, 2, 500); | |
sunLight.castShadow = true; | |
sunLight.shadow.mapSize.width = 2048; | |
sunLight.shadow.mapSize.height = 2048; | |
scene.add(sunLight); | |
// Create solar system objects | |
const solarSystem = new THREE.Group(); | |
scene.add(solarSystem); | |
// Create sun | |
const sunGeometry = new THREE.SphereGeometry(planets.sun.radius, 32, 32); | |
const sunMaterial = new THREE.MeshPhongMaterial({ | |
color: planets.sun.color, | |
emissive: 0xFDB813, | |
emissiveIntensity: 1, | |
shininess: 10 | |
}); | |
const sun = new THREE.Mesh(sunGeometry, sunMaterial); | |
sun.castShadow = true; | |
sun.receiveShadow = true; | |
sun.name = "sun"; | |
solarSystem.add(sun); | |
sunLight.position.copy(sun.position); | |
// Create planets | |
const planetMeshes = {}; | |
const orbitLines = {}; | |
Object.keys(planets).forEach(planetKey => { | |
if (planetKey === "sun") return; | |
const planet = planets[planetKey]; | |
// Create orbit line | |
const orbitGeometry = new THREE.TorusGeometry(planet.orbitRadius, 0.05, 16, 100); | |
const orbitMaterial = new THREE.MeshBasicMaterial({ | |
color: 0x666666, | |
transparent: true, | |
opacity: 0.3 | |
}); | |
const orbit = new THREE.Mesh(orbitGeometry, orbitMaterial); | |
orbit.rotation.x = Math.PI / 2; | |
orbit.name = `${planetKey}-orbit`; | |
solarSystem.add(orbit); | |
orbitLines[planetKey] = orbit; | |
// Create planet | |
const planetGeometry = new THREE.SphereGeometry(planet.radius, 32, 32); | |
const planetMaterial = new THREE.MeshPhongMaterial({ | |
color: planet.color, | |
shininess: 10 | |
}); | |
const planetMesh = new THREE.Mesh(planetGeometry, planetMaterial); | |
planetMesh.castShadow = true; | |
planetMesh.receiveShadow = true; | |
planetMesh.position.x = planet.orbitRadius; | |
planetMesh.name = planetKey; | |
// Add ring for Saturn | |
if (planetKey === "saturn") { | |
const ringGeometry = new THREE.RingGeometry(planet.radius * 1.5, planet.radius * 2, 32); | |
const ringMaterial = new THREE.MeshPhongMaterial({ | |
color: 0xDAA520, | |
side: THREE.DoubleSide, | |
transparent: true, | |
opacity: 0.8 | |
}); | |
const ring = new THREE.Mesh(ringGeometry, ringMaterial); | |
ring.rotation.x = Math.PI / 2; | |
planetMesh.add(ring); | |
} | |
solarSystem.add(planetMesh); | |
planetMeshes[planetKey] = planetMesh; | |
}); | |
// Create stars background | |
const starsGeometry = new THREE.BufferGeometry(); | |
const starsMaterial = new THREE.PointsMaterial({ | |
color: 0xFFFFFF, | |
size: 0.1, | |
transparent: true | |
}); | |
const starsVertices = []; | |
for (let i = 0; i < 10000; i++) { | |
const x = (Math.random() - 0.5) * 2000; | |
const y = (Math.random() - 0.5) * 2000; | |
const z = (Math.random() - 0.5) * 2000; | |
starsVertices.push(x, y, z); | |
} | |
starsGeometry.setAttribute('position', new THREE.Float32BufferAttribute(starsVertices, 3)); | |
const stars = new THREE.Points(starsGeometry, starsMaterial); | |
scene.add(stars); | |
// Create constellations (simplified) | |
const constellations = new THREE.Group(); | |
scene.add(constellations); | |
// Add some simple constellation lines | |
const createConstellation = (points, name) => { | |
const lineGeometry = new THREE.BufferGeometry(); | |
lineGeometry.setFromPoints(points); | |
const lineMaterial = new THREE.LineBasicMaterial({ | |
color: 0x8888FF, | |
transparent: true, | |
opacity: 0.5 | |
}); | |
const line = new THREE.Line(lineGeometry, lineMaterial); | |
line.name = name; | |
constellations.add(line); | |
}; | |
// Example constellations (positions are arbitrary) | |
createConstellation([ | |
new THREE.Vector3(-100, 80, -50), | |
new THREE.Vector3(-90, 90, -40), | |
new THREE.Vector3(-80, 85, -30) | |
], "constellation-1"); | |
createConstellation([ | |
new THREE.Vector3(120, 70, -60), | |
new THREE.Vector3(130, 60, -70), | |
new THREE.Vector3(140, 80, -50) | |
], "constellation-2"); | |
createConstellation([ | |
new THREE.Vector3(-50, -30, 100), | |
new THREE.Vector3(-60, -20, 110), | |
new THREE.Vector3(-40, -10, 120) | |
], "constellation-3"); | |
// Animation variables | |
let showConstellations = true; | |
let showOrbits = true; | |
// Raycaster for planet selection | |
const raycaster = new THREE.Raycaster(); | |
const mouse = new THREE.Vector2(); | |
// UI Elements | |
const planetInfo = document.querySelector('.planet-info'); | |
const planetName = document.getElementById('planet-name'); | |
const planetDesc = document.getElementById('planet-desc'); | |
const planetDiameter = document.getElementById('planet-diameter'); | |
const planetDistance = document.getElementById('planet-distance'); | |
const planetOrbit = document.getElementById('planet-orbit'); | |
const planetRotation = document.getElementById('planet-rotation'); | |
const planetMoons = document.getElementById('planet-moons'); | |
const planetTemp = document.getElementById('planet-temp'); | |
const tooltip = document.getElementById('tooltip'); | |
// Event Listeners | |
document.addEventListener('mousemove', onMouseMove); | |
document.addEventListener('click', onClick); | |
window.addEventListener('resize', onWindowResize); | |
// Planet buttons | |
document.querySelectorAll('.planet-btn').forEach(btn => { | |
btn.addEventListener('click', () => { | |
const planet = btn.dataset.planet; | |
focusOnPlanet(planet); | |
}); | |
}); | |
// UI buttons | |
document.getElementById('reset-view').addEventListener('click', () => { | |
camera.position.set(0, 50, 100); | |
controls.target.set(0, 0, 0); | |
updatePlanetInfo(null); | |
}); | |
document.getElementById('toggle-constellations').addEventListener('click', () => { | |
showConstellations = !showConstellations; | |
constellations.visible = showConstellations; | |
}); | |
document.getElementById('toggle-orbits').addEventListener('click', () => { | |
showOrbits = !showOrbits; | |
Object.values(orbitLines).forEach(orbit => { | |
orbit.visible = showOrbits; | |
}); | |
}); | |
// Functions | |
function onMouseMove(event) { | |
// Calculate mouse position in normalized device coordinates | |
mouse.x = (event.clientX / window.innerWidth) * 2 - 1; | |
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; | |
// Update the raycaster | |
raycaster.setFromCamera(mouse, camera); | |
// Calculate objects intersecting the ray | |
const intersects = raycaster.intersectObjects(Object.values(planetMeshes)); | |
if (intersects.length > 0) { | |
const planet = intersects[0].object; | |
tooltip.style.display = 'block'; | |
tooltip.style.left = `${event.clientX + 10}px`; | |
tooltip.style.top = `${event.clientY + 10}px`; | |
tooltip.textContent = planets[planet.name].name; | |
} else { | |
tooltip.style.display = 'none'; | |
} | |
} | |
function onClick(event) { | |
// Calculate mouse position in normalized device coordinates | |
mouse.x = (event.clientX / window.innerWidth) * 2 - 1; | |
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; | |
// Update the raycaster | |
raycaster.setFromCamera(mouse, camera); | |
// Calculate objects intersecting the ray | |
const intersects = raycaster.intersectObjects(Object.values(planetMeshes)); | |
if (intersects.length > 0) { | |
const planet = intersects[0].object; | |
focusOnPlanet(planet.name); | |
updatePlanetInfo(planet.name); | |
} | |
} | |
function focusOnPlanet(planetName) { | |
if (planetName === 'sun') { | |
controls.target.copy(sun.position); | |
anime({ | |
targets: camera.position, | |
x: 0, | |
y: 20, | |
z: 50, | |
duration: 1000, | |
easing: 'easeInOutQuad' | |
}); | |
} else { | |
const planet = planetMeshes[planetName]; | |
controls.target.copy(planet.position); | |
// Calculate position to view the planet from a slight angle | |
const distance = planets[planetName].orbitRadius * 0.5; | |
const angle = Math.atan2(planet.position.z, planet.position.x); | |
anime({ | |
targets: camera.position, | |
x: planet.position.x + Math.cos(angle) * distance, | |
y: planet.position.y + distance * 0.3, | |
z: planet.position.z + Math.sin(angle) * distance, | |
duration: 1000, | |
easing: 'easeInOutQuad' | |
}); | |
} | |
} | |
function updatePlanetInfo(planetKey) { | |
if (!planetKey) { | |
planetName.textContent = "Solar System"; | |
planetDesc.textContent = "Click on a planet to view information about it."; | |
planetDiameter.textContent = "-"; | |
planetDistance.textContent = "-"; | |
planetOrbit.textContent = "-"; | |
planetRotation.textContent = "-"; | |
planetMoons.textContent = "-"; | |
planetTemp.textContent = "-"; | |
planetInfo.classList.remove('active'); | |
return; | |
} | |
const planet = planets[planetKey]; | |
planetName.textContent = planet.name; | |
planetDesc.textContent = planet.desc; | |
planetDiameter.textContent = planet.diameter; | |
planetDistance.textContent = planet.distance; | |
planetOrbit.textContent = planet.orbit; | |
planetRotation.textContent = planet.rotation; | |
planetMoons.textContent = planet.moons; | |
planetTemp.textContent = planet.temp; | |
planetInfo.classList.add('active'); | |
} | |
function onWindowResize() { | |
camera.aspect = window.innerWidth / window.innerHeight; | |
camera.updateProjectionMatrix(); | |
renderer.setSize(window.innerWidth, window.innerHeight); | |
} | |
// Animation loop | |
function animate() { | |
requestAnimationFrame(animate); | |
// Rotate sun | |
sun.rotation.y += planets.sun.rotationSpeed; | |
// Rotate and orbit planets | |
Object.keys(planetMeshes).forEach(planetKey => { | |
const planet = planetMeshes[planetKey]; | |
const planetData = planets[planetKey]; | |
// Rotate planet | |
planet.rotation.y += planetData.rotationSpeed; | |
// Orbit planet around sun | |
if (planetData.orbitSpeed > 0) { | |
planet.position.x = Math.cos(Date.now() * 0.001 * planetData.orbitSpeed) * planetData.orbitRadius; | |
planet.position.z = Math.sin(Date.now() * 0.001 * planetData.orbitSpeed) * planetData.orbitRadius; | |
} | |
}); | |
controls.update(); | |
renderer.render(scene, camera); | |
} | |
animate(); | |
</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=youjunhyeok/solar-system" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
</html> |