Liveweave: Generative AI Web Editor & HTML/CSS/JS Playground
Initializing
Liveweave
Web
expand_more
home
Home
Palette
Color Explorer
arrow_outward
Polyline
Graphics Editor
arrow_outward
frame_source
Python Playground
arrow_outward
build
Tools
expand_more
restart_alt
Load "Hello Weaver!"
post_add
Generate Lorem ipsum...
code
Format HTML
code_blocks
Format CSS
data_object
Format JavaScript
library_add
Library
expand_more
A
Algolia JS
Animate CSS
Apex Charts JS
B
Bulma CSS
Bootstrap
C
Chart JS
Chartist
Create JS
D
D3
Dojo
F
Foundation
Fullpage JS
G
Granim JS
Google Charts
H
Halfmoon
J
jQuery
M
Materialize
Moment JS
Masonry JS
Milligram CSS
P
Pure CSS
Primer CSS
Popper JS
Pattern CSS
Picnic CSS
R
React JS
Raphael JS
Raisin CSS
S
Semantic UI
Skeleton CSS
Spectre CSS
Tachyons CSS
T
Tailwind
Three JS
U
UI Kit
Vis JS
W
Water CSS
download
Download
expand_more
developer_mode
Download as HTML
folder_zip
Download as .ZIP
cloud_upload
Fork
account_circle
Login
settings
Settings
expand_more
Editor font
14
px
A
A
Night mode
Line number
Mini map
Word wrap
sync_alt
Reset Settings
smart_display
Run
left_panel_close
AI Assistant
dashboard
All
HTML
CSS
JS
visibility
Preview
bolt
Live Preview
terminal
JS Console
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <div id="app"></div> <div class="header"> <div class="eyebrow">THREE.JS / SPACE EXPERIMENT</div> <h1>MINI SOLAR SYSTEM</h1> <p>Drag to explore · Click a planet · Scroll to zoom</p> </div> <div class="controls"> <div class="control-title"> ORBIT SPEED <span id="speedValue">50%</span> </div> <input id="speedSlider" type="range" min="0" max="100" value="50" > <button id="orbitButton"> HIDE ORBITS </button> <button id="resetButton"> RESET VIEW </button> </div> <div class="planet-info" id="planetInfo"> <div class="info-label"> SELECTED </div> <div class="info-name" id="planetName"> SOLAR SYSTEM </div> <div class="info-detail" id="planetDetail"> Click a planet to inspect it </div> </div> <div class="footer"> <span>DRAG = ROTATE</span> <span>SCROLL = ZOOM</span> <span>CLICK = FOCUS</span> </div>
* { box-sizing: border-box; } html, body { width: 100%; height: 100%; margin: 0; } body { overflow: hidden; background: radial-gradient( circle at 50% 45%, #111827 0%, #050912 45%, #010207 100% ); color: #fff; font-family: Arial, Helvetica, sans-serif; } /* ========================================= THREE.JS ========================================= */ #app { position: fixed; inset: 0; } #app canvas { width: 100%; height: 100%; display: block; cursor: grab; } #app canvas:active { cursor: grabbing; } /* ========================================= HEADER ========================================= */ .header { position: fixed; top: 28px; left: 30px; z-index: 10; pointer-events: none; } .eyebrow { font-size: 8px; letter-spacing: 3px; color: rgba(255,255,255,0.38); margin-bottom: 8px; } h1 { margin: 0; font-size: 36px; font-weight: 600; letter-spacing: -1.5px; } .header p { margin: 8px 0 0; font-size: 10px; color: rgba(255,255,255,0.36); } /* ========================================= CONTROLS ========================================= */ .controls { position: fixed; right: 28px; top: 28px; z-index: 10; width: 205px; padding: 16px; background: rgba(5,8,15,0.72); border: 1px solid rgba(255,255,255,0.12); border-radius: 12px; backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); } .control-title { font-size: 8px; letter-spacing: 1.5px; color: rgba(255,255,255,0.42); margin-bottom: 9px; } .control-title span { float: right; color: rgba(255,255,255,0.7); } #speedSlider { width: 100%; height: 4px; appearance: none; -webkit-appearance: none; background: rgba(255,255,255,0.18); border-radius: 10px; outline: none; margin-bottom: 16px; } #speedSlider::-webkit-slider-thumb { appearance: none; -webkit-appearance: none; width: 14px; height: 14px; border-radius: 50%; background: #fff; cursor: pointer; } #speedSlider::-moz-range-thumb { width: 14px; height: 14px; border: none; border-radius: 50%; background: #fff; cursor: pointer; } .controls button { display: block; width: 100%; margin-top: 7px; padding: 9px 11px; text-align: left; border: 1px solid rgba(255,255,255,0.12); border-radius: 7px; background: rgba(255,255,255,0.045); color: rgba(255,255,255,0.58); font-size: 8px; letter-spacing: 1px; cursor: pointer; transition: background 0.2s ease, color 0.2s ease; } .controls button:hover { background: rgba(255,255,255,0.09); color: #fff; } /* ========================================= PLANET INFO ========================================= */ .planet-info { position: fixed; right: 28px; bottom: 28px; z-index: 10; width: 205px; padding: 15px 16px; background: rgba(5,8,15,0.72); border: 1px solid rgba(255,255,255,0.12); border-left: 2px solid #ff9b48; border-radius: 8px; backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); pointer-events: none; } .info-label { font-size: 8px; letter-spacing: 1.5px; color: rgba(255,255,255,0.32); margin-bottom: 6px; } .info-name { font-size: 20px; font-weight: 600; letter-spacing: -0.5px; } .info-detail { margin-top: 5px; font-size: 9px; color: rgba(255,255,255,0.4); line-height: 1.4; } /* ========================================= FOOTER ========================================= */ .footer { position: fixed; left: 30px; bottom: 25px; z-index: 10; display: flex; gap: 18px; font-size: 8px; letter-spacing: 1px; color: rgba(255,255,255,0.28); pointer-events: none; } /* ========================================= PLANET LABEL ========================================= */ .planet-label { position: fixed; z-index: 5; transform: translate(-50%, -100%); padding: 4px 7px; background: rgba(0,0,0,0.65); border: 1px solid rgba(255,255,255,0.12); border-radius: 4px; font-size: 8px; letter-spacing: 1px; color: rgba(255,255,255,0.72); pointer-events: none; opacity: 0; transition: opacity 0.2s ease; } /* ========================================= MOBILE ========================================= */ @media (max-width: 600px) { .header { top: 18px; left: 18px; } h1 { font-size: 28px; } .controls { top: 18px; right: 18px; width: 155px; } .planet-info { right: 15px; bottom: 15px; width: 170px; } .footer { left: 18px; bottom: 18px; gap: 10px; } }
/* ===================================================== MINI SOLAR SYSTEM Three.js r128 ===================================================== */ /* ===================================================== CHECK THREE.JS ===================================================== */ if (typeof THREE === "undefined") { document.body.innerHTML = "<div style='" + "color:white;" + "font-family:Arial;" + "padding:40px;" + "'>Three.js did not load.</div>"; throw new Error( "Three.js not loaded." ); } /* ===================================================== CONTAINER ===================================================== */ const app = document.getElementById( "app" ); /* ===================================================== SCENE ===================================================== */ const scene = new THREE.Scene(); /* ===================================================== CAMERA ===================================================== */ const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 1000 ); camera.position.set( 0, 10, 32 ); /* ===================================================== RENDERER ===================================================== */ const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); renderer.setSize( window.innerWidth, window.innerHeight ); renderer.setPixelRatio( Math.min( window.devicePixelRatio, 2 ) ); renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap; app.appendChild( renderer.domElement ); /* ===================================================== LIGHTING ===================================================== */ const ambient = new THREE.AmbientLight( 0xffffff, 0.18 ); scene.add( ambient ); /* ===================================================== STAR LIGHT ===================================================== */ const sunLight = new THREE.PointLight( 0xffffff, 3.0, 150 ); sunLight.position.set( 0, 0, 0 ); sunLight.castShadow = true; scene.add( sunLight ); /* ===================================================== STAR FIELD ===================================================== */ const starGeometry = new THREE.BufferGeometry(); const starPositions = []; for ( let i = 0; i < 2500; i++ ) { const radius = 55 + Math.random() * 70; const theta = Math.random() * Math.PI * 2; const phi = Math.acos( 2 * Math.random() - 1 ); starPositions.push( radius * Math.sin(phi) * Math.cos(theta), radius * Math.cos(phi), radius * Math.sin(phi) * Math.sin(theta) ); } starGeometry.setAttribute( "position", new THREE.Float32BufferAttribute( starPositions, 3 ) ); const starMaterial = new THREE.PointsMaterial({ color: 0xffffff, size: 0.08, transparent: true, opacity: 0.9 }); const stars = new THREE.Points( starGeometry, starMaterial ); scene.add( stars ); /* ===================================================== SUN ===================================================== */ const sun = new THREE.Mesh( new THREE.SphereGeometry( 1.7, 48, 48 ), new THREE.MeshBasicMaterial({ color: 0xffb347 }) ); scene.add( sun ); /* ===================================================== SUN GLOW ===================================================== */ const glow = new THREE.Mesh( new THREE.SphereGeometry( 2.2, 48, 48 ), new THREE.MeshBasicMaterial({ color: 0xff8c32, transparent: true, opacity: 0.16, depthWrite: false }) ); scene.add( glow ); /* ===================================================== PLANET GROUPS ===================================================== */ const system = new THREE.Group(); scene.add( system ); /* ===================================================== ORBIT GROUP ===================================================== */ const orbitGroup = new THREE.Group(); system.add( orbitGroup ); /* ===================================================== PLANET DATA ===================================================== */ const planets = [ { name: "Mercury", color: 0x99958f, size: 0.28, distance: 3.2, speed: 1.9, description: "Closest planet to the Sun" }, { name: "Venus", color: 0xd7a86e, size: 0.42, distance: 4.6, speed: 1.35, description: "A dense world wrapped in clouds" }, { name: "Earth", color: 0x397bbf, size: 0.48, distance: 6.1, speed: 1.0, description: "Our home planet" }, { name: "Mars", color: 0xc45f48, size: 0.37, distance: 7.5, speed: 0.82, description: "The red planet" }, { name: "Jupiter", color: 0xd2a36e, size: 0.95, distance: 10.0, speed: 0.43, description: "The largest planet" }, { name: "Saturn", color: 0xd8c08c, size: 0.80, distance: 13.0, speed: 0.32, description: "Famous for its rings" }, { name: "Uranus", color: 0x77c6d0, size: 0.62, distance: 15.7, speed: 0.22, description: "A cold ice giant" }, { name: "Neptune", color: 0x416bca, size: 0.60, distance: 18.2, speed: 0.17, description: "The distant blue world" } ]; /* ===================================================== ORBIT CREATOR ===================================================== */ function createOrbit( radius ) { const points = []; for ( let i = 0; i <= 128; i++ ) { const angle = ( i / 128 ) * Math.PI * 2; points.push( new THREE.Vector3( Math.cos(angle) * radius, 0, Math.sin(angle) * radius ) ); } const geometry = new THREE.BufferGeometry() .setFromPoints( points ); const material = new THREE.LineBasicMaterial({ color: 0x596171, transparent: true, opacity: 0.24 }); return new THREE.Line( geometry, material ); } /* ===================================================== CREATE PLANETS ===================================================== */ const planetObjects = []; planets.forEach( function(data) { /* ----------------------------------------------- Planet orbit ------------------------------------------------ */ const orbit = createOrbit( data.distance ); orbitGroup.add( orbit ); /* ----------------------------------------------- Planet pivot ------------------------------------------------ */ const pivot = new THREE.Group(); system.add( pivot ); /* ----------------------------------------------- Planet ------------------------------------------------ */ const planet = new THREE.Mesh( new THREE.SphereGeometry( data.size, 32, 32 ), new THREE.MeshStandardMaterial({ color: data.color, roughness: 0.75, metalness: 0.02 }) ); planet.position.x = data.distance; planet.castShadow = true; planet.receiveShadow = true; pivot.add( planet ); /* ----------------------------------------------- Rings ------------------------------------------------ */ if ( data.name === "Saturn" ) { const ring = new THREE.Mesh( new THREE.RingGeometry( 1.05, 1.55, 64 ), new THREE.MeshBasicMaterial({ color: 0xc7b78d, side: THREE.DoubleSide, transparent: true, opacity: 0.72 }) ); ring.rotation.x = Math.PI / 2; planet.add( ring ); } /* ----------------------------------------------- Earth moon ------------------------------------------------ */ if ( data.name === "Earth" ) { const moonPivot = new THREE.Group(); planet.add( moonPivot ); const moon = new THREE.Mesh( new THREE.SphereGeometry( 0.12, 20, 20 ), new THREE.MeshStandardMaterial({ color: 0xbab8b2, roughness: 0.9 }) ); moon.position.x = 0.85; moonPivot.add( moon ); planetObjects.push({ object: moonPivot, moon: true }); } /* ----------------------------------------------- Store ------------------------------------------------ */ planetObjects.push({ object: planet, pivot: pivot, data: data, angle: Math.random() * Math.PI * 2, originalScale: 1 }); } ); /* ===================================================== CLICK DETECTION ===================================================== */ const raycaster = new THREE.Raycaster(); const mouse = new THREE.Vector2(); let selectedPlanet = null; renderer.domElement.addEventListener( "pointerdown", function(event) { /* Store pointer location. */ mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1; mouse.y = -( event.clientY / window.innerHeight ) * 2 + 1; raycaster.setFromCamera( mouse, camera ); const objects = planetObjects .filter( item => item.object && item.object.isMesh ) .map( item => item.object ); const hits = raycaster.intersectObjects( objects, false ); if ( hits.length === 0 ) { return; } const hit = hits[0].object; const found = planetObjects.find( item => item.object === hit ); if ( found && found.data ) { selectPlanet( found ); } } ); /* ===================================================== PLANET SELECTION ===================================================== */ function selectPlanet( item ) { selectedPlanet = item; document.getElementById( "planetName" ).textContent = item.data.name; document.getElementById( "planetDetail" ).textContent = item.data.description; /* Highlight selected planet. */ planetObjects.forEach( function(planet) { if (!planet.data) { return; } planet.object.scale.setScalar( planet === item ? 1.18 : 1 ); } ); } /* ===================================================== SPEED CONTROL ===================================================== */ const speedSlider = document.getElementById( "speedSlider" ); const speedValue = document.getElementById( "speedValue" ); let speed = 0.5; speedSlider.addEventListener( "input", function() { speed = Number( this.value ) / 100; speedValue.textContent = this.value + "%"; } ); /* ===================================================== ORBIT VISIBILITY ===================================================== */ let orbitVisible = true; document .getElementById( "orbitButton" ) .addEventListener( "click", function() { orbitVisible = !orbitVisible; orbitGroup.visible = orbitVisible; this.textContent = orbitVisible ? "HIDE ORBITS" : "SHOW ORBITS"; } ); /* ===================================================== RESET VIEW ===================================================== */ document .getElementById( "resetButton" ) .addEventListener( "click", function() { cameraAngle = 0; cameraHeight = 0.2; cameraDistance = 32; selectedPlanet = null; document.getElementById( "planetName" ).textContent = "SOLAR SYSTEM"; document.getElementById( "planetDetail" ).textContent = "Click a planet to inspect it"; planetObjects.forEach( function(planet) { if ( planet.data ) { planet.object.scale.setScalar( 1 ); } } ); } ); /* ===================================================== CAMERA ORBIT ===================================================== */ let dragging = false; let cameraAngle = 0; let cameraHeight = 0.2; let cameraDistance = 32; let lastX = 0; let lastY = 0; renderer.domElement.addEventListener( "pointerdown", function(event) { dragging = true; lastX = event.clientX; lastY = event.clientY; } ); window.addEventListener( "pointermove", function(event) { if (!dragging) { return; } const dx = event.clientX - lastX; const dy = event.clientY - lastY; cameraAngle += dx * 0.005; cameraHeight += dy * 0.003; cameraHeight = Math.max( -0.7, Math.min( 0.9, cameraHeight ) ); lastX = event.clientX; lastY = event.clientY; } ); window.addEventListener( "pointerup", function() { dragging = false; } ); /* ===================================================== ZOOM ===================================================== */ renderer.domElement.addEventListener( "wheel", function(event) { cameraDistance += event.deltaY * 0.02; cameraDistance = Math.max( 12, Math.min( 52, cameraDistance ) ); }, { passive: true } ); /* ===================================================== ANIMATION ===================================================== */ let time = 0; function animate() { requestAnimationFrame( animate ); time += 0.016; /* ----------------------------------------------- Solar system rotation ------------------------------------------------ */ planetObjects.forEach( function(item) { /* Moon */ if ( item.moon ) { item.object.rotation.y += 0.035 * speed; return; } /* Planet rotation */ item.object.rotation.y += 0.008 * speed; /* Orbital movement */ item.angle += 0.003 * item.data.speed * speed; item.pivot.rotation.y = item.angle; } ); /* ----------------------------------------------- Sun pulse ------------------------------------------------ */ const pulse = 1 + Math.sin( time * 2 ) * 0.018; sun.scale.setScalar( pulse ); glow.scale.setScalar( pulse * 1.02 ); /* ----------------------------------------------- Stars ------------------------------------------------ */ stars.rotation.y += 0.00006; /* ----------------------------------------------- Light motion ------------------------------------------------ */ sunLight.intensity = 3.0 + Math.sin( time * 2 ) * 0.15; /* ----------------------------------------------- Camera ------------------------------------------------ */ camera.position.x = Math.sin( cameraAngle ) * cameraDistance; camera.position.z = Math.cos( cameraAngle ) * cameraDistance; camera.position.y = cameraHeight * 20; camera.lookAt( 0, 0, 0 ); /* ----------------------------------------------- Render ------------------------------------------------ */ renderer.render( scene, camera ); } /* ===================================================== RESIZE ===================================================== */ window.addEventListener( "resize", function() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight ); } ); /* ===================================================== START ===================================================== */ animate();
terminal
JavaScript Console
Preview
Clear
close
›
Run