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
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
<div id="controls"> <div class="controls-title">CONTROLS</div> <div class="keyboard"> <div class="key-row"> <span class="key">W</span> </div> <div class="key-row"> <span class="key">A</span> <span class="key">S</span> <span class="key">D</span> </div> </div> <div class="control-labels"> <div><b>W</b> Forward</div> <div><b>S</b> Back</div> <div><b>A</b> Left</div> <div><b>D</b> Right</div> </div> <div class="mouse-help"> ? Click + drag to look around </div> </div> <div id="crosshair"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>w
* { box-sizing: border-box; } html, body { margin: 0; width: 100%; height: 100%; overflow: hidden; background: #000; font-family: Arial, Helvetica, sans-serif; } /* CONTROLS */ #controls { position: fixed; left: 20px; bottom: 20px; z-index: 20; width: 185px; padding: 15px; color: white; background: rgba(0, 0, 0, 0.55); border: 1px solid rgba(255, 255, 255, 0.16); border-radius: 12px; backdrop-filter: blur(8px); user-select: none; pointer-events: none; } .controls-title { margin-bottom: 12px; font-size: 11px; font-weight: bold; letter-spacing: 2px; color: rgba(255, 255, 255, 0.65); } /* KEYBOARD */ .keyboard { margin-bottom: 12px; } .key-row { display: flex; justify-content: center; gap: 5px; margin-bottom: 5px; } .key { display: flex; align-items: center; justify-content: center; width: 34px; height: 34px; border: 1px solid rgba(255, 255, 255, 0.3); border-radius: 6px; background: rgba(255, 255, 255, 0.1); box-shadow: inset 0 -3px 0 rgba(0, 0, 0, 0.25); font-size: 12px; font-weight: bold; } /* CONTROL LABELS */ .control-labels { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 10px; font-size: 11px; color: rgba(255, 255, 255, 0.7); } .control-labels b { color: white; } /* MOUSE HELP */ .mouse-help { margin-top: 11px; padding-top: 10px; border-top: 1px solid rgba(255, 255, 255, 0.12); font-size: 11px; color: rgba(255, 255, 255, 0.55); } /* CROSSHAIR */ #crosshair { position: fixed; left: 50%; top: 50%; width: 18px; height: 18px; transform: translate(-50%, -50%); z-index: 20; pointer-events: none; } #crosshair::before, #crosshair::after { content: ""; position: absolute; background: rgba(255, 255, 255, 0.8); } #crosshair::before { width: 18px; height: 2px; left: 0; top: 8px; } #crosshair::after { width: 2px; height: 18px; left: 8px; top: 0; }
let scene; let camera; let renderer; let yawObject; let pitchObject; let keys = {}; let isDragging = false; let prevMouse = { x: 0, y: 0 }; init(); animate(); function init() { // SCENE scene = new THREE.Scene(); scene.background = new THREE.Color(0x111111); // CAMERA camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); // Controls vertical camera movement pitchObject = new THREE.Object3D(); pitchObject.add(camera); // Controls player position // and horizontal camera movement yawObject = new THREE.Object3D(); yawObject.position.set( 0, 2, 5 ); yawObject.add( pitchObject ); scene.add( yawObject ); // RENDERER renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setPixelRatio( Math.min( window.devicePixelRatio, 2 ) ); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); // KEYBOARD document.addEventListener( "keydown", function(event) { keys[event.code] = true; } ); document.addEventListener( "keyup", function(event) { keys[event.code] = false; } ); // MOUSE LOOK document.addEventListener( "mousedown", function(event) { isDragging = true; prevMouse.x = event.clientX; prevMouse.y = event.clientY; } ); document.addEventListener( "mouseup", function() { isDragging = false; } ); document.addEventListener( "mousemove", function(event) { if (!isDragging) { return; } const dx = event.clientX - prevMouse.x; const dy = event.clientY - prevMouse.y; prevMouse.x = event.clientX; prevMouse.y = event.clientY; // LEFT / RIGHT yawObject.rotation.y -= dx * 0.004; // UP / DOWN pitchObject.rotation.x -= dy * 0.004; // Prevent camera flipping pitchObject.rotation.x = Math.max( -Math.PI / 2, Math.min( Math.PI / 2, pitchObject.rotation.x ) ); } ); // TEXTURE LOADER const loader = new THREE.TextureLoader(); // FLOOR TEXTURE const floorTex = loader.load( "https://threejs.org/examples/textures/hardwood2_diffuse.jpg" ); floorTex.wrapS = THREE.RepeatWrapping; floorTex.wrapT = THREE.RepeatWrapping; floorTex.repeat.set( 40, 40 ); // CEILING TEXTURE const ceilTex = loader.load( "https://threejs.org/examples/textures/brick_diffuse.jpg" ); ceilTex.wrapS = THREE.RepeatWrapping; ceilTex.wrapT = THREE.RepeatWrapping; ceilTex.repeat.set( 40, 40 ); // FLOOR const floor = new THREE.Mesh( new THREE.PlaneGeometry( 300, 300 ), new THREE.MeshStandardMaterial({ map: floorTex, color: 0x666666 }) ); floor.rotation.x = -Math.PI / 2; scene.add(floor); // CEILING const ceiling = new THREE.Mesh( new THREE.PlaneGeometry( 300, 300 ), new THREE.MeshStandardMaterial({ map: ceilTex, color: 0x888888 }) ); ceiling.position.y = 10; ceiling.rotation.x = Math.PI / 2; scene.add(ceiling); // LIGHTING scene.add( new THREE.AmbientLight( 0x404040, 1.5 ) ); for ( let x = -100; x <= 100; x += 40 ) { for ( let z = -100; z <= 100; z += 40 ) { const light = new THREE.PointLight( 0xffffff, 1.2, 60 ); light.position.set( x, 9, z ); scene.add(light); } } // WALL CREATOR function wall( x, z, width, depth ) { const texture = loader.load( "https://threejs.org/examples/textures/stone.jpg" ); texture.wrapS = THREE.RepeatWrapping; texture.wrapT = THREE.RepeatWrapping; texture.repeat.set( Math.max( width / 5, 1 ), 5 ); const mesh = new THREE.Mesh( new THREE.BoxGeometry( width, 10, depth ), new THREE.MeshStandardMaterial({ map: texture }) ); mesh.position.set( x, 5, z ); scene.add(mesh); } // OUTSIDE WALLS wall( 0, -100, 200, 2 ); wall( 0, 100, 200, 2 ); wall( -100, 0, 2, 200 ); wall( 100, 0, 2, 200 ); // INTERIOR WALLS wall( 0, 0, 2, 80 ); wall( -40, 40, 80, 2 ); wall( 40, -40, 80, 2 ); // WINDOW RESIZE window.addEventListener( "resize", function() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight ); } ); } // GAME LOOP function animate() { requestAnimationFrame( animate ); const speed = 0.2; // FORWARD DIRECTION const forward = new THREE.Vector3( 0, 0, -1 ) .applyQuaternion( yawObject.quaternion ); // RIGHT DIRECTION const right = new THREE.Vector3( 1, 0, 0 ) .applyQuaternion( yawObject.quaternion ); forward.y = 0; right.y = 0; forward.normalize(); right.normalize(); // W = FORWARD if (keys["KeyW"]) { yawObject.position .addScaledVector( forward, speed ); } // S = BACKWARD if (keys["KeyS"]) { yawObject.position .addScaledVector( forward, -speed ); } // A = LEFT if (keys["KeyA"]) { yawObject.position .addScaledVector( right, -speed ); } // D = RIGHT if (keys["KeyD"]) { yawObject.position .addScaledVector( right, speed ); } renderer.render( scene, camera ); }
terminal
JavaScript Console
Preview
Clear
close
›
Run