sam-s-space / index.html
ayokings's picture
Add 2 files
7c186eb verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D Solar System Model</title>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/controls/OrbitControls.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Arial', sans-serif;
}
body {
background: linear-gradient(135deg, #000428, #004e92);
color: white;
overflow: hidden;
height: 100vh;
}
#container {
position: absolute;
width: 100%;
height: 100%;
}
#info {
position: absolute;
bottom: 20px;
left: 20px;
background: rgba(0, 0, 0, 0.7);
padding: 15px;
border-radius: 10px;
max-width: 300px;
}
#info h2 {
margin-bottom: 10px;
color: #ff9d00;
}
#controls {
position: absolute;
top: 20px;
right: 20px;
background: rgba(0, 0, 0, 0.7);
padding: 15px;
border-radius: 10px;
display: flex;
flex-direction: column;
gap: 10px;
}
.control-group {
display: flex;
align-items: center;
gap: 10px;
}
button {
background: #ff9d00;
color: #000;
border: none;
padding: 8px 12px;
border-radius: 5px;
cursor: pointer;
font-weight: bold;
transition: all 0.3s;
}
button:hover {
background: #ffc107;
transform: translateY(-2px);
}
.planet-info {
display: none;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0, 0, 0, 0.9);
padding: 20px;
border-radius: 10px;
width: 300px;
z-index: 100;
border: 2px solid #ff9d00;
}
.planet-info h3 {
color: #ff9d00;
margin-bottom: 10px;
text-align: center;
}
.planet-info p {
margin-bottom: 8px;
}
.close-btn {
position: absolute;
top: 10px;
right: 10px;
background: #ff9d00;
color: #000;
border: none;
width: 25px;
height: 25px;
border-radius: 50%;
cursor: pointer;
font-weight: bold;
}
#loading {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #000;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
z-index: 1000;
}
.loader {
border: 5px solid #f3f3f3;
border-top: 5px solid #ff9d00;
border-radius: 50%;
width: 50px;
height: 50px;
animation: spin 1s linear infinite;
margin-bottom: 20px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
#title {
position: absolute;
top: 20px;
left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.7);
padding: 10px 20px;
border-radius: 10px;
font-size: 24px;
color: #ff9d00;
}
</style>
</head>
<body>
<div id="loading">
<div class="loader"></div>
<p>Loading Solar System...</p>
</div>
<div id="container"></div>
<div id="title">3D Solar System Explorer</div>
<div id="info">
<h2>Solar System Facts</h2>
<p>Click on any planet to learn more about it. Use your mouse to rotate the view and scroll to zoom in/out.</p>
</div>
<div id="controls">
<div class="control-group">
<button id="speedUp">Speed Up Orbits</button>
<button id="speedDown">Slow Down Orbits</button>
</div>
<div class="control-group">
<button id="zoomIn">Zoom In</button>
<button id="zoomOut">Zoom Out</button>
</div>
<button id="resetView">Reset View</button>
</div>
<div id="planetInfo" class="planet-info">
<button class="close-btn">X</button>
<h3 id="planetName">Planet Name</h3>
<p>Type: <span id="planetType"></span></p>
<p>Diameter: <span id="planetDiameter"></span></p>
<p>Distance from Sun: <span id="planetDistance"></span></p>
<p>Orbital Period: <span id="planetPeriod"></span></p>
<p>Moons: <span id="planetMoons"></span></p>
<p>Fun Fact: <span id="planetFact"></span></p>
</div>
<script>
// Wait for the DOM to load
document.addEventListener('DOMContentLoaded', function() {
// Hide loading screen after a short delay
setTimeout(() => {
document.getElementById('loading').style.display = 'none';
initSolarSystem();
}, 1500);
// Close planet info
document.querySelector('.close-btn').addEventListener('click', function() {
document.getElementById('planetInfo').style.display = 'none';
});
});
function initSolarSystem() {
// Scene setup
const scene = new THREE.Scene();
const container = document.getElementById('container');
const width = container.clientWidth;
const height = container.clientHeight;
// Camera setup
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
camera.position.z = 30;
// Renderer setup
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(width, height);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setClearColor(0x000000);
container.appendChild(renderer.domElement);
// Controls
const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
controls.minDistance = 10;
controls.maxDistance = 100;
// Lighting
const ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);
const sunLight = new THREE.PointLight(0xffd700, 1.5, 300);
sunLight.position.set(0, 0, 0);
scene.add(sunLight);
// Planets data
const planetsData = [
{
name: 'Mercury',
radius: 0.4,
distance: 5,
color: 0xA9A9A9,
speed: 0.04,
type: 'Terrestrial',
diameter: '4,879 km',
orbitalPeriod: '88 Earth days',
moons: '0',
fact: 'Mercury has no atmosphere to retain heat, so temperatures swing between 430°C day and -180°C night.'
},
{
name: 'Venus',
radius: 0.6,
distance: 7,
color: 0xf5f5dc,
speed: 0.015,
type: 'Terrestrial',
diameter: '12,104 km',
orbitalPeriod: '225 Earth days',
moons: '0',
fact: 'Venus rotates in the opposite direction to most planets and has days longer than its years!'
},
{
name: 'Earth',
radius: 0.6,
distance: 10,
color: 0x1E88E5,
speed: 0.01,
type: 'Terrestrial',
diameter: '12,742 km',
orbitalPeriod: '365 Earth days',
moons: '1 (Moon)',
fact: 'Earth is the only known planet with liquid water on its surface and life as we know it.'
},
{
name: 'Mars',
radius: 0.5,
distance: 15,
color: 0xff4500,
speed: 0.008,
type: 'Terrestrial',
diameter: '6,779 km',
orbitalPeriod: '687 Earth days',
moons: '2 (Phobos & Deimos)',
fact: 'Mars has the largest volcano in the solar system (Olympus Mons) and might have had oceans in the past.'
},
{
name: 'Jupiter',
radius: 1.4,
distance: 20,
color: 0xff8c00,
speed: 0.002,
type: 'Gas Giant',
diameter: '139,820 km',
orbitalPeriod: '4,333 Earth days',
moons: '79+',
fact: "Jupiter's Great Red Spot is a storm that has raged for at least 350 years and could fit 3 Earths inside it."
},
{
name: 'Saturn',
radius: 1.2,
distance: 25,
color: 0xffd700,
speed: 0.0009,
type: 'Gas Giant',
diameter: '116,460 km',
orbitalPeriod: '10,756 Earth days',
moons: '82+',
fact: "Saturn's rings are made of billions of ice particles ranging from dust-sized to mountain-sized."
},
{
name: 'Uranus',
radius: 0.9,
distance: 30,
color: 0x87CEFA,
speed: 0.0004,
type: 'Ice Giant',
diameter: '50,724 km',
orbitalPeriod: '30,687 Earth days',
moons: '27+',
fact: 'Uranus rotates on its side (almost 90° tilt), likely due to a massive collision early in its history.'
},
{
name: 'Neptune',
radius: 0.9,
distance: 35,
color: 0x4169E1,
speed: 0.0001,
type: 'Ice Giant',
diameter: '49,244 km',
orbitalPeriod: '60,190 Earth days',
moons: '14+',
fact: 'Neptune has the strongest winds in the solar system (over 2,100 km/h) despite being the coldest planet.'
}
];
// Stars
function addStars() {
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);
}
addStars();
// Sun
const sunGeometry = new THREE.SphereGeometry(1.8, 32, 32);
const sunMaterial = new THREE.MeshBasicMaterial({
color: 0xffd700,
emissive: 0xffd700,
emissiveIntensity: 1
});
const sun = new THREE.Mesh(sunGeometry, sunMaterial);
scene.add(sun);
// Sun glow effect
const sunGlowGeometry = new THREE.SphereGeometry(2.1, 32, 32);
const sunGlowMaterial = new THREE.MeshBasicMaterial({
color: 0xffd700,
transparent: true,
opacity: 0.3,
blending: THREE.AdditiveBlending
});
const sunGlow = new THREE.Mesh(sunGlowGeometry, sunGlowMaterial);
scene.add(sunGlow);
// Create planets
const planets = [];
let planetMeshes = [];
planetsData.forEach((planet, index) => {
const geometry = new THREE.SphereGeometry(planet.radius, 32, 32);
const material = new THREE.MeshPhongMaterial({
color: planet.color,
shininess: 5
});
const planetMesh = new THREE.Mesh(geometry, material);
// Position planet in orbit
const angle = (index / planetsData.length) * Math.PI * 2;
planetMesh.position.x = planet.distance * Math.cos(angle);
planetMesh.position.z = planet.distance * Math.sin(angle);
// Store additional properties
planetMesh.userData = {
...planet,
originalDistance: planet.distance,
originalSpeed: planet.speed,
currentAngle: angle
};
scene.add(planetMesh);
planetMeshes.push(planetMesh);
// Add orbital path
const orbitGeometry = new THREE.BufferGeometry();
const orbitMaterial = new THREE.LineBasicMaterial({
color: 0x666666,
transparent: true,
opacity: 0.3
});
const orbitPoints = [];
for (let i = 0; i <= 64; i++) {
const theta = (i / 64) * Math.PI * 2;
orbitPoints.push(new THREE.Vector3(
planet.distance * Math.cos(theta),
0,
planet.distance * Math.sin(theta)
));
}
orbitGeometry.setFromPoints(orbitPoints);
const orbit = new THREE.Line(orbitGeometry, orbitMaterial);
scene.add(orbit);
});
// Variables for animation control
let speedFactor = 1;
let animationId = null;
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
let currentPlanet = null;
// Handle planet clicks
window.addEventListener('click', (event) => {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(planetMeshes);
if (intersects.length > 0) {
const planet = intersects[0].object;
currentPlanet = planet;
// Show planet info
document.getElementById('planetName').textContent = planet.userData.name;
document.getElementById('planetType').textContent = planet.userData.type;
document.getElementById('planetDiameter').textContent = planet.userData.diameter;
document.getElementById('planetDistance').textContent = planet.userData.originalDistance.toFixed(1) + ' AU';
document.getElementById('planetPeriod').textContent = planet.userData.orbitalPeriod;
document.getElementById('planetMoons').textContent = planet.userData.moons;
document.getElementById('planetFact').textContent = planet.userData.fact;
document.getElementById('planetInfo').style.display = 'block';
// Move camera to focus on planet
const distanceToPlanet = planet.position.distanceTo(camera.position);
controls.target.copy(planet.position);
camera.position
.copy(planet.position)
.add(new THREE.Vector3(0, distanceToPlanet * 0.3, distanceToPlanet * 1.5));
}
});
// Control buttons
document.getElementById('speedUp').addEventListener('click', () => {
speedFactor *= 1.5;
});
document.getElementById('speedDown').addEventListener('click', () => {
speedFactor /= 1.5;
});
document.getElementById('zoomIn').addEventListener('click', () => {
camera.position.multiplyScalar(0.9);
});
document.getElementById('zoomOut').addEventListener('click', () => {
camera.position.multiplyScalar(1.1);
});
document.getElementById('resetView').addEventListener('click', () => {
camera.position.set(0, 0, 30);
controls.target.set(0, 0, 0);
speedFactor = 1;
});
// Handle window resize
window.addEventListener('resize', () => {
camera.aspect = container.clientWidth / container.clientHeight;
camera.updateProjectionMatrix();
renderer.setSize(container.clientWidth, container.clientHeight);
});
// Animation loop
function animate() {
animationId = requestAnimationFrame(animate);
// Update sun glow animation
sunGlow.scale.x = 1 + Math.sin(Date.now() * 0.001) * 0.05;
sunGlow.scale.y = 1 + Math.cos(Date.now() * 0.001 + 0.5) * 0.05;
sunGlow.scale.z = 1 + Math.sin(Date.now() * 0.001 + 1) * 0.05;
// Rotate sun
sun.rotation.y += 0.002;
// Update planet positions
planetMeshes.forEach(planet => {
const data = planet.userData;
data.currentAngle += data.speed * speedFactor;
planet.position.x = data.originalDistance * Math.cos(data.currentAngle);
planet.position.z = data.originalDistance * Math.sin(data.currentAngle);
// Rotate planet
planet.rotation.y += 0.01;
});
controls.update();
renderer.render(scene, camera);
}
animate();
// Clean up on unmount
window.addEventListener('beforeunload', () => {
if (animationId) {
cancelAnimationFrame(animationId);
}
renderer.dispose();
});
}
</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 <a href="https://enzostvs-deepsite.hf.space" style="color: #fff;" target="_blank" >DeepSite</a> <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;"></p></body>
</html>