Interaktiver 3D-Sonnensystem-Simulator
Von Wikiprompt, der freien Prompt-Enzyklopädie
Interaktiver 3D-Sonnensystem-Simulator Ein umfassender Prompt zum Erstellen eines ausgefeilten 3D-Sonnensystem-Simulators mit Three.js, einschließlich realistischer Umlaufbahnen, Steuerung, Benutzeroberfläche und visueller Verbesserungen.
Prompt-InhaltSpeichern
🌐
<!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 Simulator</title>
<style>
body {
margin: 0;
overflow: hidden;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: black;
color: white;
}
#info {
position: absolute;
top: 20px;
left: 20px;
background: rgba(20, 20, 30, 0.7);
backdrop-filter: blur(8px);
border: 1px solid rgba(255, 255, 255, 0.15);
border-radius: 12px;
padding: 12px 20px;
color: #ddd;
font-size: 14px;
pointer-events: none;
box-shadow: 0 4px 20px rgba(0,0,0,0.5);
z-index: 100;
letter-spacing: 0.5px;
}
#info span {
color: #ffaa00;
font-weight: 600;
}
#controls {
position: absolute;
bottom: 30px;
left: 0;
right: 0;
display: flex;
justify-content: center;
align-items: center;
gap: 30px;
background: rgba(15, 15, 25, 0.6);
backdrop-filter: blur(10px);
padding: 15px 30px;
border-radius: 50px;
margin: 0 auto;
width: fit-content;
border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: 0 8px 30px rgba(0,0,0,0.7);
z-index: 200;
pointer-events: auto;
}
#controls label {
display: flex;
align-items: center;
gap: 12px;
color: #ccc;
font-size: 15px;
font-weight: 400;
}
#controls input[type="range"] {
width: 180px;
cursor: pointer;
background: transparent;
accent-color: #ffaa00;
}
#controls button {
background: rgba(255, 170, 0, 0.2);
border: 1px solid #ffaa00;
color: #ffaa00;
padding: 8px 20px;
border-radius: 30px;
font-weight: 600;
font-size: 14px;
cursor: pointer;
transition: all 0.2s ease;
letter-spacing: 0.5px;
backdrop-filter: blur(4px);
}
#controls button:hover {
background: rgba(255, 170, 0, 0.4);
box-shadow: 0 0 15px rgba(255,170,0,0.3);
}
#controls button:active {
transform: scale(0.96);
}
#reset-btn {
background: rgba(100, 150, 255, 0.2);
border-color: #6a9fff;
color: #aacbff;
}
#reset-btn:hover {
background: rgba(100, 150, 255, 0.4);
}
#speed-value {
min-width: 50px;
text-align: center;
color: #ffaa00;
font-weight: 600;
}
#focus-info {
position: absolute;
bottom: 100px;
left: 20px;
background: rgba(0,0,0,0.5);
padding: 8px 16px;
border-radius: 20px;
font-size: 13px;
color: #aaa;
border-left: 3px solid #ffaa00;
pointer-events: none;
backdrop-filter: blur(4px);
}
@media (max-width: 700px) {
#controls {
flex-wrap: wrap;
width: 90%;
border-radius: 20px;
padding: 15px;
gap: 15px;
}
#controls input[type="range"] {
width: 120px;
}
}
</style>
</head>
<body>
<div id="info">
⏱️ Time scale: <span id="time-display">1.0x</span> | 🪐 <span id="focused-planet">None</span>
</div>
<div id="focus-info">🖱️ Click planet to focus</div>
<div id="controls">
<label>🚀 Speed
<input type="range" id="speed-slider" min="0" max="5" step="0.1" value="1.0">
<span id="speed-value">1.0x</span>
</label>
<button id="pause-btn">⏸️ Pause</button>
<button id="reset-btn">↺ Reset View</button>
</div>
<!-- Three.js from CDN -->
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@0.128.0/build/three.module.js",
"three/addons/": "https://unpkg.com/three@0.128.0/examples/jsm/"
}
}
</script>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// --- Setup Scene, Camera, Renderer ---
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x050510);
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 30, 60);
camera.lookAt(0, 0, 0);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = false; // not needed
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
document.body.appendChild(renderer.domElement);
// --- Controls ---
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
controls.autoRotate = false;
controls.enableZoom = true;
controls.zoomSpeed = 1.2;
controls.rotateSpeed = 0.8;
controls.target.set(0, 0, 0);
controls.maxDistance = 200;
controls.minDistance = 5;
// --- Lighting ---
// Ambient light for base visibility
const ambientLight = new THREE.AmbientLight(0x404060);
scene.add(ambientLight);
// Main directional light (simulating sun light)
const sunLight = new THREE.PointLight(0xffdd99, 2, 0, 0);
sunLight.position.set(0, 0, 0);
scene.add(sunLight);
// Additional fill lights
const fillLight = new THREE.DirectionalLight(0x4466ff, 0.3);
fillLight.position.set(-10, 10, 20);
scene.add(fillLight);
const backLight = new THREE.DirectionalLight(0xffaa66, 0.2);
backLight.position.set(5, -5, -15);
scene.add(backLight);
// --- Starfield Background (twinkling) ---
const starsGeometry = new THREE.BufferGeometry();
const starsCount = 6000;
const starPositions = new Float32Array(starsCount * 3);
const starColors = new Float32Array(starsCount * 3);
const starSizes = new Float32Array(starsCount);
for (let i = 0; i < starsCount; i++) {
// Random positions in a sphere shell
const r = 150 + Math.random() * 100;
const theta = Math.random() * Math.PI * 2;
const phi = Math.acos((Math.random() * 2) - 1);
starPositions[i*3] = r * Math.sin(phi) * Math.cos(theta);
starPositions[i*3+1] = r * Math.sin(phi) * Math.sin(theta);
starPositions[i*3+2] = r * Math.cos(phi);
// Color: white to blueish
const colorVal = 0.8 + Math.random() * 0.4;
starColors[i*3] = colorVal;
starColors[i*3+1] = colorVal * (0.8 + Math.random() * 0.3);
starColors[i*3+2] = 1.0;
starSizes[i] = 0.5 + Math.random() * 1.5;
}
starsGeometry.setAttribute('position', new THREE.BufferAttribute(starPositions, 3));
starsGeometry.setAttribute('color', new THREE.BufferAttribute(starColors, 3));
starsGeometry.setAttribute('size', new THREE.BufferAttribute(starSizes, 1));
const starsMaterial = new THREE.PointsMaterial({
size: 0.8,
vertexColors: true,
transparent: true,
opacity: 0.9,
blending: THREE.AdditiveBlending,
sizeAttenuation: true
});
const stars = new THREE.Points(starsGeometry, starsMaterial);
scene.add(stars);
// Twinkling effect: animate opacity/scale via custom shader? Simpler: rotate slowly and pulse size
// We'll animate in the loop
// --- Sun (with glow) ---
const sunGeometry = new THREE.SphereGeometry(3.5, 64, 64);
const sunMaterial = new THREE.MeshStandardMaterial({
color: 0xffaa33,
emissive: 0xff5500,
emissiveIntensity: 1.8,
roughness: 0.4,
metalness: 0.1
});
const sun = new THREE.Mesh(sunGeometry, sunMaterial);
scene.add(sun);
// Add a glow sprite (halo)
const glowTexture = createGlowTexture();
const glowMaterial = new THREE.SpriteMaterial({
map: glowTexture,
color: 0xffaa44,
transparent: true,
blending: THREE.AdditiveBlending,
depthWrite: false
});
const glowSprite = new THREE.Sprite(glowMaterial);
glowSprite.scale.set(12, 12, 1);
sun.add(glowSprite);
// --- Planet Data ---
// Approximate sizes and distances (scaled for visual appeal)
const planetsData = [
{ name: 'Mercury', radius: 0.6, distance: 6.5, color: 0xaaaaaa, speed: 0.02, emissive: 0x222222 },
{ name: 'Venus', radius: 0.9, distance: 9.5, color: 0xffcc88, speed: 0.015, emissive: 0x442200 },
{ name: 'Earth', radius: 1.0, distance: 12.5, color: 0x2299ff, speed: 0.012, emissive: 0x001122 },
{ name: 'Mars', radius: 0.8, distance: 15.5, color: 0xff6633, speed: 0.01, emissive: 0x331100 },
{ name: 'Jupiter', radius: 2.2, distance: 20.0, color: 0xddbb99, speed: 0.008, emissive: 0x332211 },
{ name: 'Saturn', radius: 1.9, distance: 25.0, color: 0xeeddbb, speed: 0.006, emissive: 0x332211 },
{ name: 'Uranus', radius: 1.5, distance: 30.0, color: 0x88ccff, speed: 0.005, emissive: 0x113344 },
{ name: 'Neptune', radius: 1.5, distance: 34.0, color: 0x3366ff, speed: 0.004, emissive: 0x001133 }
];
// Store planet meshes and their data for animation
const planets = [];
const orbitLines = [];
// Create planets and orbit rings
planetsData.forEach((data, index) => {
// Planet mesh
const geometry = new THREE.SphereGeometry(data.radius, 32, 32);
const material = new THREE.MeshStandardMaterial({
color: data.color,
emissive: data.emissive,
emissiveIntensity: 0.1,
roughness: 0.5,
metalness: 0.1
});
const planet = new THREE.Mesh(geometry, material);
// Initial position (on x-axis)
planet.position.x = data.distance;
// Store data
planet.userData = {
name: data.name,
distance: data.distance,
speed: data.speed,
angle: Math.random() * Math.PI * 2 // random start
};
scene.add(planet);
planets.push(planet);
// Add a small label sprite
const label = createLabelSprite(data.name);
label.position.y = data.radius + 0.8;
planet.add(label);
// Orbit ring (semi-transparent)
const orbitPoints = [];
const segments = 128;
for (let i = 0; i <= segments; i++) {
const angle = (i / segments) * Math.PI * 2;
const x = data.distance * Math.cos(angle);
const z = data.distance * Math.sin(angle);
orbitPoints.push(new THREE.Vector3(x, 0, z));
}
const orbitGeometry = new THREE.BufferGeometry().setFromPoints(orbitPoints);
const orbitMaterial = new THREE.LineBasicMaterial({
color: 0x88aaff,
transparent: true,
opacity: 0.15,
linewidth: 1 // not supported everywhere, but fine
});
const orbitLine = new THREE.Line(orbitGeometry, orbitMaterial);
scene.add(orbitLine);
orbitLines.push(orbitLine);
});
// --- Helper: Create a glowing texture for sun sprite ---
function createGlowTexture() {
const canvas = document.createElement('canvas');
canvas.width = 128;
canvas.height = 128;
const ctx = canvas.getContext('2d');
const gradient = ctx.createRadialGradient(64, 64, 0, 64, 64, 64);
gradient.addColorStop(0, 'rgba(255, 200, 100, 1)');
gradient.addColorStop(0.4, 'rgba(255, 150, 50, 0.8)');
gradient.addColorStop(0.7, 'rgba(255, 100, 0, 0.3)');
gradient.addColorStop(1, 'rgba(255, 50, 0, 0)');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 128, 128);
const texture = new THREE.CanvasTexture(canvas);
return texture;
}
// --- Helper to create a text label sprite ---
function createLabelSprite(text) {
const canvas = document.createElement('canvas');
canvas.width = 256;
canvas.height = 64;
const ctx = canvas.getContext('2d');
ctx.font = 'Bold 24px "Segoe UI", Arial, sans-serif';
ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';
ctx.shadowColor = 'rgba(0,0,0,0.8)';
ctx.shadowBlur = 8;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(text, 128, 32);
const texture = new THREE.CanvasTexture(canvas);
const material = new THREE.SpriteMaterial({
map: texture,
transparent: true,
depthTest: false,
depthWrite: false,
sizeAttenuation: true
});
const sprite = new THREE.Sprite(material);
sprite.scale.set(2.5, 0.8, 1);
return sprite;
}
// --- Raycaster for planet clicking ---
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
function onMouseClick(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(planets);
if (intersects.length > 0) {
const planet = intersects[0].object;
// Focus camera on planet
controls.target.copy(planet.position);
// Update info
document.getElementById('focused-planet').innerText = planet.userData.name;
// Optional: slight camera move? OrbitControls will handle
} else {
// If click empty space, reset focus to sun? maybe not
// document.getElementById('focused-planet').innerText = 'None';
}
}
window.addEventListener('click', onMouseClick);
// --- UI Elements ---
const speedSlider = document.getElementById('speed-slider');
const speedValue = document.getElementById('speed-value');
const pauseBtn = document.getElementById('pause-btn');
const resetBtn = document.getElementById('reset-btn');
const timeDisplay = document.getElementById('time-display');
let isPaused = false;
let speedMultiplier = 1.0;
speedSlider.addEventListener('input', (e) => {
speedMultiplier = parseFloat(e.target.value);
speedValue.textContent = speedMultiplier.toFixed(1) + 'x';
timeDisplay.textContent = speedMultiplier.toFixed(1) + 'x';
});
pauseBtn.addEventListener('click', () => {
isPaused = !isPaused;
pauseBtn.textContent = isPaused ? '▶️ Resume' : '⏸️ Pause';
});
resetBtn.addEventListener('click', () => {
// Reset camera
camera.position.set(0, 30, 60);
controls.target.set(0, 0, 0);
controls.update();
document.getElementById('focused-planet').innerText = 'None';
});
// Keyboard shortcut: Spacebar toggles pause
window.addEventListener('keydown', (e) => {
if (e.code === 'Space') {
e.preventDefault();
pauseBtn.click();
}
});
// --- Resize handler ---
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
// --- Animation Loop ---
let clock = new THREE.Clock();
function animate() {
const delta = clock.getDelta();
const elapsed = clock.getElapsedTime();
// Twinkling stars: subtle size variation
stars.material.size = 0.8 + Math.sin(elapsed * 2) * 0.1;
// Rotate stars slowly
stars.rotation.y += 0.0001;
// Update planet positions if not paused
if (!isPaused) {
planets.forEach(planet => {
const data = planet.userData;
data.angle += data.speed * speedMultiplier * delta * 2.5; // speed factor
// Keep angle within range
if (data.angle > Math.PI * 2) data.angle -= Math.PI * 2;
planet.position.x = data.distance * Math.cos(data.angle);
planet.position.z = data.distance * Math.sin(data.angle);
});
}
// Sun rotation
sun.rotation.y += 0.002;
// Update controls
controls.update();
// Render
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
// Start animation
animate();
// Initial focus info
document.getElementById('focused-planet').innerText = 'None';
// Add a subtle grid or something? Not needed, but maybe a faint ring for reference
// Optional: add a small axis helper? No, keep clean.
console.log('Solar System Simulator Loaded');
</script>
</body>
</html>
Melde dich an, um den vollständigen Prompt zu sehen
Weiter mit:
Mit der Anmeldung akzeptierst du unsere Nutzungsbedingungen und Datenschutz
Verwendung
Dieser Prompt ist für die Verwendung mit coding gedacht. Kopiere den Inhalt oben und füge ihn in dein bevorzugtes KI-Tool ein.
Für beste Ergebnisse passe die Platzhalter (eckige Klammern oder Großbuchstaben) an deine Anforderungen an.
Referenzen
- Kategorie: coding-Prompts
- Quelle: https://x.com/eyishazyer/status/2075849990367273241
Diskussion
0 Kommentare