solar-system / index.html
youjunhyeok's picture
Add 2 files
69b2856 verified
<!DOCTYPE html>
<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>