<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Solar System Element</title>
   <style>
       body { margin: 0; background-color: #000; }
       /* This is the container for the custom element. You can change its size and position. */
       #solar-system-container {
           width: 1000px;
           height: 1000px;
       }
   </style>
</head>
<body>
   <div id="solar-system-container">
       <solar-system-animation></solar-system-animation>
   </div>
   
   <script>
       class SolarSystemAnimation extends HTMLElement {
           constructor() {
               super();
               this.attachShadow({ mode: 'open' });
               
               // Define the styles for the component's container and canvas
               const style = document.createElement('style');
               style.textContent = `
                   :host {
                       display: block;
                       width: 100%;
                       height: 100%;
                       overflow: hidden;
                   }
                   canvas {
                       display: block;
                       width: 100%;
                       height: 100%;
                       background-color: #000;
                   }
               `;
               this.shadowRoot.appendChild(style);
               
               // Load the three.js library dynamically. The animation will start once it's loaded.
               const threeScript = document.createElement('script');
               threeScript.src = 'https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js';
               threeScript.onload = () => this.initAnimation();
               this.shadowRoot.appendChild(threeScript);
           }
       
           initAnimation() {
               // --- SCENE SETUP ---
               const scene = new THREE.Scene();
               const camera = new THREE.PerspectiveCamera(45, this.clientWidth / this.clientHeight, 0.1, 5000);
               const renderer = new THREE.WebGLRenderer({ antialias: true });
               renderer.setSize(this.clientWidth, this.clientHeight);
               this.shadowRoot.appendChild(renderer.domElement);
               
               // Create a group for the camera to control its orbit
               const cameraGroup = new THREE.Group();
               scene.add(cameraGroup);
               cameraGroup.add(camera);
               
               // Set initial camera position and tilt
               camera.position.z = 500;
               camera.position.y = 100;
               cameraGroup.rotation.x = 15 * (Math.PI / 180);
               camera.lookAt(new THREE.Vector3(0, 0, 0));
       
               // --- LIGHTING ---
               // A strong light at the center to represent the Sun
               const sunLight = new THREE.PointLight(0xffffff, 2, 0, 2);
               scene.add(sunLight);
               const ambientLight = new THREE.AmbientLight(0x404040); // Soft white light
               scene.add(ambientLight);
       
               // --- PLANET DATA (scaled for a better fit) ---
               const planets = [
                   { name: 'Mercury', size: 0.45, distance: 15, color: 0x8A8A8A, speed: 0.005, moons: [] },
                   { name: 'Venus', size: 1.35, distance: 20, color: 0xC19A6B, speed: 0.004, moons: [] },
                   { 
                       name: 'Earth', 
                       size: 1.5, 
                       distance: 25, 
                       color: 0x228B22, 
                       speed: 0.003, 
                       moons: [
                           { name: 'Moon', size: 0.375, distance: 4.5, color: 0xC0C0C0, speed: 0.02 }
                       ]
                   },
                   { 
                       name: 'Mars', 
                       size: 0.75, 
                       distance: 30, 
                       color: 0x800000, 
                       speed: 0.002,
                       moons: [
                           { name: 'Phobos', size: 0.15, distance: 2.25, color: 0x696969, speed: 0.03 },
                           { name: 'Deimos', size: 0.12, distance: 3.75, color: 0xA9A9A9, speed: 0.025 }
                       ]
                   },
                   { 
                       name: 'Jupiter', 
                       size: 7.5, 
                       distance: 75, 
                       color: 0xBD8948, 
                       speed: 0.001,
                       moons: [
                           { name: 'Io', size: 0.6, distance: 10.5, color: 0xFFD700, speed: 0.02 },
                           { name: 'Europa', size: 0.525, distance: 13.5, color: 0xADD8E6, speed: 0.018 },
                           { name: 'Ganymede', size: 0.825, distance: 18, color: 0x778899, speed: 0.015 },
                           { name: 'Callisto', size: 0.75, distance: 24, color: 0x696969, speed: 0.012 },
                           { name: 'Amalthea', size: 0.2, distance: 8, color: 0xAAAAAA, speed: 0.025 }
                       ]
                   },
                   { 
                       name: 'Saturn', 
                       size: 6.75, 
                       distance: 125, 
                       color: 0xBDAF80, 
                       speed: 0.0008,
                       moons: [
                           { name: 'Titan', size: 0.75, distance: 12, color: 0xD2B48C, speed: 0.01 },
                           { name: 'Rhea', size: 0.45, distance: 16, color: 0xD2B48C, speed: 0.012 },
                       ]
                   },
                   { name: 'Uranus', size: 3.0, distance: 175, color: 0xACE5EE, speed: 0.0006, moons: [{ name: 'Titania', size: 0.4, distance: 8, color: 0xD3D3D3, speed: 0.015 }] },
                   { name: 'Neptune', size: 2.85, distance: 250, color: 0x4169E1, speed: 0.0005, moons: [{ name: 'Triton', size: 0.45, distance: 9, color: 0xA9A9A9, speed: 0.012 }] }
               ];
       
               // --- OBJECT CREATION ---
               // Create the Sun
               const sunGeometry = new THREE.SphereGeometry(15, 32, 32);
               const sunMaterial = new THREE.MeshBasicMaterial({ color: 0xFFFF00 });
               const sun = new THREE.Mesh(sunGeometry, sunMaterial);
               scene.add(sun);
       
               // Create each planet, its moons, and a trail
               const planetGroups = [];
               const maxTrailPoints = 10000;
       
               planets.forEach(p => {
                   const planetGroup = new THREE.Group();
                   scene.add(planetGroup);
       
                   // Planet Mesh
                   const planetGeometry = new THREE.SphereGeometry(p.size, 16, 16);
                   const planetMaterial = new THREE.MeshPhongMaterial({ color: p.color });
                   const planetMesh = new THREE.Mesh(planetGeometry, planetMaterial);
                   planetMesh.position.x = p.distance;
                   planetGroup.add(planetMesh);
                   
                   // Saturn's Rings
                   if (p.name === 'Saturn') {
                       const ringGeometry = new THREE.RingGeometry(p.size * 1.2, p.size * 1.8, 64);
                       const ringMaterial = new THREE.MeshBasicMaterial({ color: 0x8B7355, side: THREE.DoubleSide });
                       const rings = new THREE.Mesh(ringGeometry, ringMaterial);
                       rings.rotation.x = -Math.PI / 2;
                       planetMesh.add(rings);
                   }
       
                   // Moons
                   const moonGroup = new THREE.Group();
                   planetMesh.add(moonGroup);
                   p.moons.forEach((m, moonIndex) => {
                       const moonGeometry = new THREE.SphereGeometry(m.size, 16, 16);
                       const moonMaterial = new THREE.MeshPhongMaterial({ color: m.color });
                       const moonMesh = new THREE.Mesh(moonGeometry, moonMaterial);
                       
                       // Stagger the moon positions
                       const angle = (2 * Math.PI / p.moons.length) * moonIndex;
                       moonMesh.position.x = m.distance * Math.cos(angle);
                       moonMesh.position.z = m.distance * Math.sin(angle);
       
                       moonGroup.add(moonMesh);
                       moonMesh.userData.speed = m.speed;
                   });
                   planetMesh.userData.moonGroup = moonGroup;
       
                   // Particle Trail
                   const trailGeometry = new THREE.BufferGeometry();
                   const positions = new Float32Array(maxTrailPoints * 3);
                   trailGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
                   const trailMaterial = new THREE.PointsMaterial({ color: p.color, size: 0.1 });
                   const trail = new THREE.Points(trailGeometry, trailMaterial);
                   scene.add(trail);
                   trail.geometry.setDrawRange(0, 0);
       
                   planetGroups.push({ 
                       group: planetGroup, 
                       speed: p.speed, 
                       mesh: planetMesh, 
                       trail: trail, 
                       trailGeometry: trailGeometry,
                       trailIndex: 0
                   });
               });
       
               // --- ANIMATION LOOP ---
               const cameraOrbitSpeed = 0.001;
               function animate() {
                   requestAnimationFrame(animate);
       
                   // Orbit the camera
                   cameraGroup.rotation.y += cameraOrbitSpeed;
       
                   // Rotate planets and their orbits
                   planetGroups.forEach(p => {
                       p.group.rotation.y += p.speed;
                       p.mesh.rotation.y += p.speed * 5; // Axial rotation
                       
                       // Moon orbits
                       if (p.mesh.userData.moonGroup) {
                           p.mesh.userData.moonGroup.children.forEach(moon => {
                               moon.rotation.y += moon.userData.speed;
                           });
                       }
       
                       // Update particle trail
                       const positions = p.trailGeometry.attributes.position.array;
                       const index = p.trailIndex;
                       const planetPosition = new THREE.Vector3();
                       p.mesh.getWorldPosition(planetPosition);
                       
                       positions[index * 3] = planetPosition.x;
                       positions[index * 3 + 1] = planetPosition.y;
                       positions[index * 3 + 2] = planetPosition.z;
       
                       p.trailIndex = (p.trailIndex + 1) % maxTrailPoints;
                       p.trailGeometry.attributes.position.needsUpdate = true;
                       p.trailGeometry.setDrawRange(0, Math.min(p.trailIndex, maxTrailPoints));
                   });
       
                   renderer.render(scene, camera);
               }
       
               // --- RESIZE HANDLING ---
               const resizeObserver = new ResizeObserver(entries => {
                   const entry = entries[0];
                   const { width, height } = entry.contentRect;
                   camera.aspect = width / height;
                   camera.updateProjectionMatrix();
                   renderer.setSize(width, height);
               });
               resizeObserver.observe(this);
       
               animate();
           }
       }
       
       customElements.define('solar-system-animation', SolarSystemAnimation);
   </script>
</body>
</html>
 

We need your consent to load the translations

We use a third-party service to translate the website content that may collect data about your activity. Please review the details in the privacy policy and accept the service to view the translations.