Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>3D Solar System</title>
- <style>
- body { margin: 0; overflow: hidden; }
- #ui {
- position: absolute;
- top: 10px;
- left: 10px;
- background: rgba(255, 255, 255, 0.8);
- padding: 10px;
- font-family: sans-serif;
- z-index: 10;
- border-radius: 4px;
- }
- #ui label {
- margin-right: 5px;
- }
- #ui > div {
- margin-bottom: 10px;
- }
- </style>
- </head>
- <body>
- <!-- UI controls -->
- <div id="ui">
- <div>
- <label for="scaleSlider">Simulation Scale:</label>
- <input id="scaleSlider" type="range" min="0.5" max="2" step="0.01" value="1">
- <span id="scaleValue">1</span>
- </div>
- <div>
- <label for="rotationSpeedSlider">Self-Rotation Speed:</label>
- <input id="rotationSpeedSlider" type="range" min="0" max="0.1" step="0.001" value="0.02">
- <span id="rotationSpeedValue">0.02</span>
- </div>
- <div>
- <label for="orbitalSpeedSlider">Orbital Speed:</label>
- <input id="orbitalSpeedSlider" type="range" min="0" max="0.1" step="0.001" value="0.04">
- <span id="orbitalSpeedValue">0.04</span>
- </div>
- <div>
- <label for="zoomSlider">Zoom:</label>
- <input id="zoomSlider" type="range" min="50" max="300" step="1" value="150">
- <span id="zoomValue">150</span>
- </div>
- </div>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
- <script>
- // Create scene, camera, and renderer
- const scene = new THREE.Scene();
- const camera = new THREE.PerspectiveCamera(
- 75, window.innerWidth / window.innerHeight, 0.1, 2000
- );
- const renderer = new THREE.WebGLRenderer({ antialias: true });
- renderer.setSize(window.innerWidth, window.innerHeight);
- document.body.appendChild(renderer.domElement);
- // Create a group for the entire solar system (for scaling)
- const solarSystem = new THREE.Group();
- scene.add(solarSystem);
- // Add ambient light
- const ambientLight = new THREE.AmbientLight(0x404040);
- scene.add(ambientLight);
- // Add background stars
- function addStars() {
- const starsGeometry = new THREE.BufferGeometry();
- const starsCount = 10000;
- const positions = new Float32Array(starsCount * 3);
- for (let i = 0; i < starsCount; i++) {
- const x = (Math.random() - 0.5) * 2000;
- const y = (Math.random() - 0.5) * 2000;
- const z = (Math.random() - 0.5) * 2000;
- positions[i * 3] = x;
- positions[i * 3 + 1] = y;
- positions[i * 3 + 2] = z;
- }
- starsGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
- const starsMaterial = new THREE.PointsMaterial({ color: 0xffffff, size: 1 });
- const starField = new THREE.Points(starsGeometry, starsMaterial);
- scene.add(starField);
- }
- addStars();
- // Helper function to create a text sprite for labels
- function createTextSprite(message, parameters = {}) {
- const fontface = parameters.fontface || 'Arial';
- const fontsize = parameters.fontsize || 48;
- const borderThickness = parameters.borderThickness || 4;
- const borderColor = parameters.borderColor || { r: 0, g: 0, b: 0, a: 1.0 };
- const backgroundColor = parameters.backgroundColor || { r: 255, g: 255, b: 255, a: 1.0 };
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- context.font = fontsize + "px " + fontface;
- const metrics = context.measureText(message);
- const textWidth = metrics.width;
- canvas.width = textWidth + borderThickness * 2;
- canvas.height = fontsize + borderThickness * 2;
- context.font = fontsize + "px " + fontface;
- // Draw background and border
- context.fillStyle = `rgba(${backgroundColor.r}, ${backgroundColor.g}, ${backgroundColor.b}, ${backgroundColor.a})`;
- context.strokeStyle = `rgba(${borderColor.r}, ${borderColor.g}, ${borderColor.b}, ${borderColor.a})`;
- context.lineWidth = borderThickness;
- context.fillRect(0, 0, canvas.width, canvas.height);
- context.strokeRect(0, 0, canvas.width, canvas.height);
- // Draw text
- context.fillStyle = 'rgba(0, 0, 0, 1.0)';
- context.textAlign = "center";
- context.textBaseline = "middle";
- context.fillText(message, canvas.width / 2, canvas.height / 2);
- const texture = new THREE.CanvasTexture(canvas);
- texture.needsUpdate = true;
- const spriteMaterial = new THREE.SpriteMaterial({ map: texture });
- const sprite = new THREE.Sprite(spriteMaterial);
- sprite.scale.set(canvas.width * 0.02, canvas.height * 0.02, 1);
- return sprite;
- }
- // Create the Sun (central light source) with higher resolution geometry
- const sunGeometry = new THREE.SphereGeometry(5, 64, 64);
- const sunMaterial = new THREE.MeshBasicMaterial({ color: 0xffff00 });
- const sun = new THREE.Mesh(sunGeometry, sunMaterial);
- solarSystem.add(sun);
- // Add a point light inside the Sun
- const sunLight = new THREE.PointLight(0xffffff, 1.5, 1000);
- sun.add(sunLight);
- // Add Sun label
- const sunLabel = createTextSprite("Sun", { fontsize: 48 });
- sunLabel.position.set(0, 6.5, 0);
- sun.add(sunLabel);
- // Planetary data (all eight planets; values scaled for visualization)
- const planets = [
- { name: 'Mercury', radius: 0.4, distance: 10, speed: 0.08, color: 0x808080 },
- { name: 'Venus', radius: 0.9, distance: 15, speed: 0.06, color: 0xffa500 },
- { name: 'Earth', radius: 1, distance: 20, speed: 0.04, color: 0x0000ff },
- { name: 'Mars', radius: 0.5, distance: 25, speed: 0.03, color: 0xff0000 },
- { name: 'Jupiter', radius: 2.5, distance: 35, speed: 0.02, color: 0xffd700 },
- { name: 'Saturn', radius: 2, distance: 45, speed: 0.014, color: 0xffd700 },
- { name: 'Uranus', radius: 1.5, distance: 55, speed: 0.01, color: 0x00ffff },
- { name: 'Neptune', radius: 1.5, distance: 65, speed: 0.008, color: 0x00008b },
- ];
- // Array to hold planet objects for animation
- const planetMeshes = [];
- // Create planets, orbits, and labels with higher resolution geometry
- planets.forEach((planet, index) => {
- const geometry = new THREE.SphereGeometry(planet.radius, 64, 64);
- const material = new THREE.MeshPhongMaterial({ color: planet.color });
- const mesh = new THREE.Mesh(geometry, material);
- const angle = Math.random() * Math.PI * 2;
- mesh.position.set(
- Math.cos(angle) * planet.distance,
- 0,
- Math.sin(angle) * planet.distance
- );
- // Create orbit path
- const orbitGeometry = new THREE.BufferGeometry();
- const orbitPoints = [];
- const segments = 128;
- for (let i = 0; i <= segments; i++) {
- const a = (i / segments) * Math.PI * 2;
- orbitPoints.push(new THREE.Vector3(
- Math.cos(a) * planet.distance,
- 0,
- Math.sin(a) * planet.distance
- ));
- }
- orbitGeometry.setFromPoints(orbitPoints);
- const orbitLine = new THREE.Line(
- orbitGeometry,
- new THREE.LineBasicMaterial({ color: 0x444444 })
- );
- solarSystem.add(orbitLine);
- // Add planet label
- const label = createTextSprite(planet.name, { fontsize: 48 });
- label.position.set(0, planet.radius + 1, 0);
- mesh.add(label);
- // Optional inclination for a 3D effect.
- mesh.rotation.x = (Math.PI / 180) * (index * 5);
- solarSystem.add(mesh);
- planetMeshes.push({
- ...planet,
- mesh,
- angle
- });
- });
- // Position the camera and set initial zoom (z value)
- camera.position.set(0, 50, 150);
- camera.lookAt(0, 0, 0);
- // Mouse-drag rotation controls for the camera.
- let mouseDown = false;
- let mouseX = 0;
- let mouseY = 0;
- document.addEventListener('mousedown', (e) => {
- mouseDown = true;
- mouseX = e.clientX;
- mouseY = e.clientY;
- });
- document.addEventListener('mouseup', () => {
- mouseDown = false;
- });
- document.addEventListener('mousemove', (e) => {
- if (mouseDown) {
- const deltaX = e.clientX - mouseX;
- const deltaY = e.clientY - mouseY;
- camera.position.x += deltaX * 0.1;
- camera.position.y -= deltaY * 0.1;
- mouseX = e.clientX;
- mouseY = e.clientY;
- }
- });
- // UI Sliders for simulation scale, self-rotation speed, orbital speed, and zoom.
- const scaleSlider = document.getElementById('scaleSlider');
- const scaleValue = document.getElementById('scaleValue');
- scaleSlider.addEventListener('input', () => {
- const scale = parseFloat(scaleSlider.value);
- solarSystem.scale.set(scale, scale, scale);
- scaleValue.textContent = scale;
- });
- const rotationSpeedSlider = document.getElementById('rotationSpeedSlider');
- const rotationSpeedValue = document.getElementById('rotationSpeedValue');
- let rotationSpeed = parseFloat(rotationSpeedSlider.value);
- rotationSpeedSlider.addEventListener('input', () => {
- rotationSpeed = parseFloat(rotationSpeedSlider.value);
- rotationSpeedValue.textContent = rotationSpeed;
- });
- const orbitalSpeedSlider = document.getElementById('orbitalSpeedSlider');
- const orbitalSpeedValue = document.getElementById('orbitalSpeedValue');
- let orbitalSpeed = parseFloat(orbitalSpeedSlider.value);
- orbitalSpeedSlider.addEventListener('input', () => {
- orbitalSpeed = parseFloat(orbitalSpeedSlider.value);
- orbitalSpeedValue.textContent = orbitalSpeed;
- });
- const zoomSlider = document.getElementById('zoomSlider');
- const zoomValue = document.getElementById('zoomValue');
- zoomSlider.addEventListener('input', () => {
- const zoom = parseFloat(zoomSlider.value);
- camera.position.z = zoom;
- zoomValue.textContent = zoom;
- });
- // Animation loop
- function animate() {
- requestAnimationFrame(animate);
- // Update each planet's orbit and self-rotation.
- planetMeshes.forEach(planet => {
- planet.angle += planet.speed * orbitalSpeed;
- planet.mesh.position.x = Math.cos(planet.angle) * planet.distance;
- planet.mesh.position.z = Math.sin(planet.angle) * planet.distance;
- planet.mesh.rotation.y += rotationSpeed;
- });
- // Rotate the Sun using self-rotation speed (a fraction of orbital speed)
- sun.rotation.y += rotationSpeed * 0.1;
- // Ensure all label sprites face the camera.
- solarSystem.traverse(child => {
- if (child instanceof THREE.Sprite) {
- child.lookAt(camera.position);
- }
- });
- camera.lookAt(0, 0, 0);
- renderer.render(scene, camera);
- }
- window.addEventListener('resize', () => {
- camera.aspect = window.innerWidth / window.innerHeight;
- camera.updateProjectionMatrix();
- renderer.setSize(window.innerWidth, window.innerHeight);
- });
- animate();
- </script>
- </body>
- </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement