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
<!DOCTYPE html> <html> <head> <title>3D wireframe world</title> </head> <body> <!-- Start your code here --> <div id="world"> <canvas id="canvas"></canvas> <div class="hud hud-top"> <div class="brand">WIREFRAME <span>WORLD</span></div> <div class="meta">SYSTEM // 01</div> </div> <div class="hud hud-left"> <div class="readout"> <span>ALT</span> <strong id="altitude">084</strong> </div> <div class="readout"> <span>DEPTH</span> <strong id="depth">128</strong> </div> <div class="readout"> <span>MODE</span> <strong>SCAN</strong> </div> </div> <div class="hud hud-bottom"> <div>DRAG TO EXPLORE</div> <div>SCROLL TO ZOOM</div> </div> <div class="scan-label">LIVE TERRAIN SCAN</div> </div> <!-- End your code here --> </body> </html>
* { box-sizing: border-box; } html, body { margin: 0; width: 100%; height: 100%; overflow: hidden; background: #02050a; } body { font-family: Arial, Helvetica, sans-serif; } #world { position: relative; width: 100%; height: 100%; overflow: hidden; background: radial-gradient( ellipse at 50% 60%, rgba(8, 75, 90, .2), transparent 50% ), #02050a; } canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; cursor: grab; } canvas.dragging { cursor: grabbing; } /* ===================================== HUD ===================================== */ .hud { position: absolute; z-index: 10; color: rgba(175, 255, 250, .75); pointer-events: none; } .hud-top { top: 24px; left: 28px; right: 28px; display: flex; justify-content: space-between; align-items: center; } .brand { font-size: 14px; font-weight: 700; letter-spacing: 4px; color: rgba(220, 255, 252, .9); } .brand span { color: rgba(92, 239, 218, .6); } .meta { font-size: 8px; letter-spacing: 2px; color: rgba(100, 210, 205, .45); } /* ===================================== LEFT READOUT ===================================== */ .hud-left { left: 28px; top: 50%; transform: translateY(-50%); } .readout { margin-bottom: 22px; } .readout span { display: block; margin-bottom: 5px; font-size: 7px; letter-spacing: 2px; color: rgba(95, 205, 200, .4); } .readout strong { font-size: 17px; font-weight: 400; letter-spacing: 2px; color: rgba(205, 255, 249, .75); } /* ===================================== BOTTOM ===================================== */ .hud-bottom { left: 50%; bottom: 18px; transform: translateX(-50%); display: flex; gap: 28px; font-size: 8px; letter-spacing: 2px; color: rgba(115, 210, 205, .42); } .scan-label { position: absolute; right: 28px; bottom: 18px; z-index: 10; font-size: 8px; letter-spacing: 2px; color: rgba(95, 220, 210, .42); pointer-events: none; } /* ===================================== RESPONSIVE ===================================== */ @media (max-width: 700px) { .hud-left { display: none; } .meta { display: none; } .brand { font-size: 11px; letter-spacing: 3px; } .hud-bottom { font-size: 7px; gap: 15px; } .scan-label { display: none; } }
var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var altitudeEl = document.getElementById("altitude"); var depthEl = document.getElementById("depth"); /* ===================================== CANVAS ===================================== */ var W = 0; var H = 0; var DPR = 1; function resize() { DPR = Math.min( window.devicePixelRatio || 1, 2 ); W = window.innerWidth; H = window.innerHeight; canvas.width = W * DPR; canvas.height = H * DPR; canvas.style.width = W + "px"; canvas.style.height = H + "px"; ctx.setTransform( DPR, 0, 0, DPR, 0, 0 ); } window.addEventListener( "resize", resize ); resize(); /* ===================================== WORLD SETTINGS ===================================== */ var COLS = 34; var ROWS = 30; var spacing = 8; var cameraDistance = 470; var yaw = -0.15; var pitch = 0.72; var targetYaw = yaw; var targetPitch = pitch; var time = 0; var dragging = false; var lastX = 0; var lastY = 0; /* ===================================== TERRAIN ===================================== */ var terrain = []; function buildTerrain() { terrain = []; for (var z = 0; z <= ROWS; z++) { var row = []; for (var x = 0; x <= COLS; x++) { var wx = (x - COLS / 2) * spacing; var wz = (z - 5) * spacing; row.push({ x: wx, z: wz }); } terrain.push(row); } } buildTerrain(); /* ===================================== TERRAIN HEIGHT ===================================== */ function getHeight(x, z) { /* * Large mountains */ var large = Math.sin(x * 0.026 + 1.4) * Math.cos(z * 0.031) * 34; /* * Secondary forms */ var medium = Math.sin(x * 0.065 - z * 0.025) * 14; /* * Fine ridges */ var fine = Math.sin(x * 0.13) * Math.cos(z * 0.10) * 5; /* * Ridge formation */ var ridge = Math.pow( Math.abs( Math.sin( x * 0.021 + z * 0.015 ) ), 3 ) * 23; /* * Central valley */ var valley = Math.exp( -( x * x + z * z ) / 8500 ) * -18; /* * Animate a subtle wave */ var motion = Math.sin( time * 0.45 + z * 0.06 ) * 1.2; return ( large + medium + fine + ridge + valley + motion ); } /* ===================================== 3D ROTATION ===================================== */ function rotatePoint(x, y, z) { var cy = Math.cos(yaw); var sy = Math.sin(yaw); var cp = Math.cos(pitch); var sp = Math.sin(pitch); /* Y rotation */ var x1 = x * cy - z * sy; var z1 = x * sy + z * cy; /* X rotation */ var y2 = y * cp - z1 * sp; var z2 = y * sp + z1 * cp; return { x: x1, y: y2, z: z2 }; } /* ===================================== PROJECTION ===================================== */ function project(p) { var z = p.z + cameraDistance; if (z < 5) { return null; } var focal = 520; var scale = focal / z; return { x: W / 2 + p.x * scale, y: H * .59 - p.y * scale, depth: z }; } /* ===================================== HEIGHT COLOR ===================================== */ function terrainColor(y) { if (y < -10) { return { r: 25, g: 120, b: 118, a: .50 }; } if (y < 0) { return { r: 38, g: 170, b: 155, a: .58 }; } if (y < 12) { return { r: 56, g: 214, b: 187, a: .67 }; } if (y < 25) { return { r: 110, g: 239, b: 205, a: .78 }; } return { r: 205, g: 255, b: 230, a: .90 }; } /* ===================================== DRAW SKY ===================================== */ function drawSky() { var gradient = ctx.createLinearGradient( 0, 0, 0, H ); gradient.addColorStop( 0, "#02060c" ); gradient.addColorStop( .48, "#07131a" ); gradient.addColorStop( 1, "#02090d" ); ctx.fillStyle = gradient; ctx.fillRect( 0, 0, W, H ); } /* ===================================== STARS ===================================== */ var stars = []; for (var i = 0; i < 150; i++) { stars.push({ x: Math.random(), y: Math.random() * .52, size: Math.random() * 1.6 + .2, alpha: Math.random() * .7 + .15, phase: Math.random() * Math.PI * 2 }); } function drawStars() { for ( var i = 0; i < stars.length; i++ ) { var s = stars[i]; var flicker = .65 + Math.sin( time * 1.5 + s.phase ) * .35; ctx.fillStyle = "rgba(170,255,245," + ( s.alpha * flicker ) + ")"; ctx.beginPath(); ctx.arc( s.x * W, s.y * H, s.size, 0, Math.PI * 2 ); ctx.fill(); } } /* ===================================== HORIZON GLOW ===================================== */ function drawHorizon() { var y = H * .49; var gradient = ctx.createLinearGradient( 0, y - 80, 0, y + 100 ); gradient.addColorStop( 0, "rgba(30,220,190,0)" ); gradient.addColorStop( .5, "rgba(30,220,190,.12)" ); gradient.addColorStop( 1, "rgba(30,220,190,0)" ); ctx.fillStyle = gradient; ctx.fillRect( 0, y - 100, W, 200 ); } /* ===================================== PROJECT TERRAIN ===================================== */ function projectTerrain() { var projected = []; for ( var z = 0; z <= ROWS; z++ ) { var row = []; for ( var x = 0; x <= COLS; x++ ) { var p = terrain[z][x]; var y = getHeight( p.x, p.z ); var r = rotatePoint( p.x, y, p.z ); row.push( project(r) ); } projected.push(row); } return projected; } /* ===================================== DRAW TERRAIN FACES ===================================== */ function drawTerrain() { var projected = projectTerrain(); var faces = []; /* * Create all quads */ for ( var z = 0; z < ROWS; z++ ) { for ( var x = 0; x < COLS; x++ ) { var a = projected[z][x]; var b = projected[z][x + 1]; var c = projected[z + 1][x + 1]; var d = projected[z + 1][x]; if ( !a || !b || !c || !d ) { continue; } faces.push({ a: a, b: b, c: c, d: d, depth: ( a.depth + b.depth + c.depth + d.depth ) / 4, height: ( terrain[z][x].y + terrain[z][x + 1].y + terrain[z + 1][x + 1].y + terrain[z + 1][x].y ) / 4 }); } } /* * Painter's algorithm */ faces.sort( function(a, b) { return b.depth - a.depth; } ); /* * Draw faces */ for ( var i = 0; i < faces.length; i++ ) { var f = faces[i]; var c = terrainColor( f.height ); ctx.beginPath(); ctx.moveTo( f.a.x, f.a.y ); ctx.lineTo( f.b.x, f.b.y ); ctx.lineTo( f.c.x, f.c.y ); ctx.lineTo( f.d.x, f.d.y ); ctx.closePath(); /* * Fill */ ctx.fillStyle = "rgba(" + c.r + "," + c.g + "," + c.b + "," + (c.a * .12) + ")"; ctx.fill(); /* * Wireframe */ ctx.strokeStyle = "rgba(" + c.r + "," + c.g + "," + c.b + "," + ".58)"; ctx.lineWidth = .65; ctx.stroke(); } /* * Draw stronger ridge lines */ drawRidgeLines( projected ); } /* ===================================== RIDGE LINES ===================================== */ function drawRidgeLines(projected) { ctx.strokeStyle = "rgba(118,255,222,.20)"; ctx.lineWidth = 1; /* * Longitudinal lines */ for ( var x = 0; x <= COLS; x += 3 ) { ctx.beginPath(); var started = false; for ( var z = 0; z <= ROWS; z++ ) { var p = projected[z][x]; if (!p) { continue; } if (!started) { ctx.moveTo( p.x, p.y ); started = true; } else { ctx.lineTo( p.x, p.y ); } } ctx.stroke(); } } /* ===================================== GRID LINES ===================================== */ function drawGridLines() { /* * Subtle distant horizontal lines */ ctx.strokeStyle = "rgba(65,220,198,.13)"; ctx.lineWidth = .7; for ( var i = 0; i < 12; i++ ) { var depth = 35 + i * 35; var y = H * .55 + Math.pow( i / 11, 1.7 ) * H * .37; ctx.beginPath(); ctx.moveTo( W * .12, y ); ctx.lineTo( W * .88, y ); ctx.stroke(); } } /* ===================================== SCAN LINE ===================================== */ function drawScanLine() { var scan = ( Math.sin( time * .55 ) * .5 + .5 ); var y = H * .40 + scan * H * .46; var gradient = ctx.createLinearGradient( 0, y - 30, 0, y + 30 ); gradient.addColorStop( 0, "rgba(80,255,220,0)" ); gradient.addColorStop( .5, "rgba(80,255,220,.35)" ); gradient.addColorStop( 1, "rgba(80,255,220,0)" ); ctx.fillStyle = gradient; ctx.fillRect( 0, y - 30, W, 60 ); ctx.strokeStyle = "rgba(100,255,230,.38)"; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo( 0, y ); ctx.lineTo( W, y ); ctx.stroke(); } /* ===================================== FLOATING PARTICLES ===================================== */ var particles = []; for ( var i = 0; i < 35; i++ ) { particles.push({ x: Math.random() * W, y: H * .15 + Math.random() * H * .50, speed: .15 + Math.random() * .5, size: .5 + Math.random() * 1.5, phase: Math.random() * 10 }); } function drawParticles() { for ( var i = 0; i < particles.length; i++ ) { var p = particles[i]; p.y -= p.speed; if (p.y < H * .12) { p.y = H * .58; p.x = Math.random() * W; } var alpha = .2 + .15 * Math.sin( time * 2 + p.phase ); ctx.fillStyle = "rgba(110,255,225," + alpha + ")"; ctx.beginPath(); ctx.arc( p.x, p.y, p.size, 0, Math.PI * 2 ); ctx.fill(); } } /* ===================================== CENTER BEACON ===================================== */ function drawBeacon() { var x = W / 2; var y = H * .60; /* * Glow */ var gradient = ctx.createRadialGradient( x, y, 0, x, y, 80 ); gradient.addColorStop( 0, "rgba(95,255,225,.20)" ); gradient.addColorStop( 1, "rgba(95,255,225,0)" ); ctx.fillStyle = gradient; ctx.fillRect( x - 80, y - 80, 160, 160 ); /* * Pulse rings */ var pulse = ( Math.sin( time * 2 ) * .5 + .5 ); ctx.strokeStyle = "rgba(100,255,225," + (.28 - pulse * .15) + ")"; ctx.lineWidth = 1; ctx.beginPath(); ctx.arc( x, y, 10 + pulse * 18, 0, Math.PI * 2 ); ctx.stroke(); /* * Center point */ ctx.fillStyle = "#a9fff0"; ctx.shadowColor = "#54ffe0"; ctx.shadowBlur = 15; ctx.beginPath(); ctx.arc( x, y, 2.5, 0, Math.PI * 2 ); ctx.fill(); ctx.shadowBlur = 0; } /* ===================================== HUD VALUES ===================================== */ function updateHUD() { var scan = ( Math.sin( time * .55 ) * .5 + .5 ); altitudeEl.textContent = String( Math.round( 55 + scan * 80 ) ).padStart(3, "0"); depthEl.textContent = String( Math.round( 70 + cameraDistance * .18 ) ).padStart(3, "0"); } /* ===================================== MAIN RENDER ===================================== */ function render() { time += .016; /* * Smooth camera */ yaw += (targetYaw - yaw) * .08; pitch += (targetPitch - pitch) * .08; drawSky(); drawStars(); drawHorizon(); drawGridLines(); drawTerrain(); drawParticles(); drawBeacon(); drawScanLine(); updateHUD(); requestAnimationFrame( render ); } render(); /* ===================================== MOUSE CONTROLS ===================================== */ canvas.addEventListener( "mousedown", function(e) { dragging = true; canvas.classList.add( "dragging" ); lastX = e.clientX; lastY = e.clientY; } ); window.addEventListener( "mouseup", function() { dragging = false; canvas.classList.remove( "dragging" ); } ); window.addEventListener( "mousemove", function(e) { if (!dragging) { return; } var dx = e.clientX - lastX; var dy = e.clientY - lastY; lastX = e.clientX; lastY = e.clientY; targetYaw += dx * .006; targetPitch += dy * .003; targetPitch = Math.max( .30, Math.min( 1.18, targetPitch ) ); } ); /* ===================================== TOUCH ===================================== */ canvas.addEventListener( "touchstart", function(e) { var t = e.touches[0]; dragging = true; lastX = t.clientX; lastY = t.clientY; }, { passive: true } ); canvas.addEventListener( "touchmove", function(e) { if (!dragging) { return; } var t = e.touches[0]; var dx = t.clientX - lastX; var dy = t.clientY - lastY; lastX = t.clientX; lastY = t.clientY; targetYaw += dx * .006; targetPitch += dy * .003; targetPitch = Math.max( .30, Math.min( 1.18, targetPitch ) ); }, { passive: true } ); canvas.addEventListener( "touchend", function() { dragging = false; } ); /* ===================================== ZOOM ===================================== */ canvas.addEventListener( "wheel", function(e) { cameraDistance += e.deltaY * .45; cameraDistance = Math.max( 280, Math.min( 800, cameraDistance ) ); }, { passive: true } );
terminal
JavaScript Console
Preview
Clear
close
›
Run