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
<div class="game-shell"> <div class="game-header"> <div> <span class="eyebrow">ARCADE GAME</span> <h1>Neon Racer</h1> </div> <div class="score-panel"> <div> <small>SCORE</small> <strong id="score">0</strong> </div> <div> <small>SPEED</small> <strong id="speed">1</strong> </div> </div> </div> <div class="game-area"> <canvas id="gameCanvas"></canvas> <div class="start-screen" id="startScreen"> <div class="start-card"> <span class="game-badge">NEON RACER</span> <h2>Ready to race?</h2> <p> Avoid traffic and survive as long as you can. </p> <div class="controls-help"> <span>← / A</span> <small>Steer left</small> <span>→ / D</span> <small>Steer right</small> </div> <button id="startButton"> Start Race </button> </div> </div> <div class="game-over" id="gameOver"> <div class="game-over-card"> <span>RACE OVER</span> <h2 id="finalScore"> Score 0 </h2> <button id="restartButton"> Race Again </button> </div> </div> </div> </div>
* { box-sizing: border-box; } html, body { margin: 0; min-height: 100%; font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background: radial-gradient( circle at 50% 10%, #1d2440, #0b0e18 50%, #05070c ); color: white; } body { min-height: 100vh; } /* SHELL */ .game-shell { min-height: 100vh; display: flex; flex-direction: column; align-items: center; padding: 24px; } /* HEADER */ .game-header { width: min(560px, 96vw); display: flex; justify-content: space-between; align-items: flex-end; margin-bottom: 14px; } .eyebrow { display: block; margin-bottom: 5px; color: rgba(255,255,255,.35); font-size: 8px; font-weight: 700; letter-spacing: 2px; } .game-header h1 { margin: 0; font-size: 24px; letter-spacing: -1px; } .score-panel { display: flex; gap: 9px; } .score-panel div { min-width: 72px; padding: 8px 12px; border: 1px solid rgba(255,255,255,.08); border-radius: 10px; background: rgba(255,255,255,.04); text-align: right; } .score-panel small { display: block; color: rgba(255,255,255,.3); font-size: 7px; letter-spacing: 1px; } .score-panel strong { display: block; margin-top: 3px; font-size: 16px; } /* GAME */ .game-area { position: relative; width: min(560px, 96vw); height: min(760px, 78vh); min-height: 540px; overflow: hidden; border: 1px solid rgba(255,255,255,.09); border-radius: 24px; background: #10131a; box-shadow: 0 35px 90px rgba(0,0,0,.48); } canvas { width: 100%; height: 100%; display: block; } /* OVERLAYS */ .start-screen, .game-over { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; padding: 20px; background: rgba(4,6,10,.68); backdrop-filter: blur(7px); z-index: 5; } .game-over { display: none; } .start-card, .game-over-card { width: min(340px, 100%); padding: 28px; border: 1px solid rgba(255,255,255,.1); border-radius: 20px; background: rgba(18,22,31,.9); box-shadow: 0 20px 50px rgba(0,0,0,.4); text-align: center; } .game-badge, .game-over-card > span { color: #7d8cff; font-size: 8px; font-weight: 800; letter-spacing: 2.2px; } .start-card h2, .game-over-card h2 { margin: 10px 0 8px; font-size: 27px; letter-spacing: -1px; } .start-card p { margin: 0; color: rgba(255,255,255,.42); font-size: 11px; line-height: 1.6; } /* CONTROLS */ .controls-help { display: grid; grid-template-columns: 80px 1fr; gap: 8px 12px; align-items: center; margin: 22px 0; } .controls-help span { padding: 8px; border: 1px solid rgba(255,255,255,.1); border-radius: 8px; background: rgba(255,255,255,.04); font-size: 10px; font-weight: 700; } .controls-help small { color: rgba(255,255,255,.4); text-align: left; font-size: 9px; } .start-card button, .game-over-card button { width: 100%; height: 42px; border: 0; border-radius: 10px; background: linear-gradient( 135deg, #786bff, #4ba8ff ); color: white; font-size: 11px; font-weight: 700; cursor: pointer; box-shadow: 0 10px 30px rgba(90,100,255,.25); transition: transform .18s, filter .18s; } .start-card button:hover, .game-over-card button:hover { transform: translateY(-2px); filter: brightness(1.08); } /* MOBILE */ @media ( max-width: 600px ) { .game-shell { padding: 14px; } .game-header { align-items: flex-start; } .score-panel { gap: 5px; } .score-panel div { min-width: 58px; padding: 7px 8px; } .game-area { min-height: 500px; } }
const canvas = document.getElementById( "gameCanvas" ); const ctx = canvas.getContext("2d"); const startScreen = document.getElementById( "startScreen" ); const gameOverScreen = document.getElementById( "gameOver" ); const startButton = document.getElementById( "startButton" ); const restartButton = document.getElementById( "restartButton" ); const scoreDisplay = document.getElementById( "score" ); const speedDisplay = document.getElementById( "speed" ); const finalScore = document.getElementById( "finalScore" ); let width; let height; let gameRunning = false; let score = 0; let speed = 6; let roadOffset = 0; let spawnTimer = 0; let animationFrame; /* PLAYER */ const player = { x: 0, y: 0, width: 42, height: 78, speed: 7 }; const keys = { left: false, right: false }; const enemies = []; /* ----------------------------- RESIZE ------------------------------ */ function resizeCanvas() { const rect = canvas .parentElement .getBoundingClientRect(); width = rect.width; height = rect.height; const ratio = window.devicePixelRatio || 1; canvas.width = width * ratio; canvas.height = height * ratio; ctx.setTransform( ratio, 0, 0, ratio, 0, 0 ); resetPlayer(); } window.addEventListener( "resize", resizeCanvas ); resizeCanvas(); /* ----------------------------- PLAYER RESET ------------------------------ */ function resetPlayer() { player.x = width / 2 - player.width / 2; player.y = height - player.height - 45; } /* ----------------------------- INPUT ------------------------------ */ document.addEventListener( "keydown", function(event) { if ( event.code === "ArrowLeft" || event.code === "KeyA" ) { keys.left = true; event.preventDefault(); } if ( event.code === "ArrowRight" || event.code === "KeyD" ) { keys.right = true; event.preventDefault(); } } ); document.addEventListener( "keyup", function(event) { if ( event.code === "ArrowLeft" || event.code === "KeyA" ) { keys.left = false; } if ( event.code === "ArrowRight" || event.code === "KeyD" ) { keys.right = false; } } ); /* ----------------------------- ROAD ------------------------------ */ function drawRoad() { ctx.fillStyle = "#151921"; ctx.fillRect( 0, 0, width, height ); const roadWidth = width * .68; const roadX = ( width - roadWidth ) / 2; /* GRASS / SIDE AREAS */ ctx.fillStyle = "#101c18"; ctx.fillRect( 0, 0, roadX, height ); ctx.fillRect( roadX + roadWidth, 0, roadX, height ); /* ROAD */ ctx.fillStyle = "#232831"; ctx.fillRect( roadX, 0, roadWidth, height ); /* ROAD EDGE */ ctx.fillStyle = "#dce0e8"; ctx.fillRect( roadX, 0, 4, height ); ctx.fillRect( roadX + roadWidth - 4, 0, 4, height ); /* NEON SIDE GLOW */ ctx.fillStyle = "rgba(80,120,255,.12)"; ctx.fillRect( roadX + 5, 0, 7, height ); ctx.fillRect( roadX + roadWidth - 12, 0, 7, height ); /* LANE DASHES */ const laneWidth = roadWidth / 3; roadOffset += speed; if ( roadOffset > 60 ) { roadOffset = 0; } for ( let lane = 1; lane <= 2; lane++ ) { const x = roadX + laneWidth * lane; for ( let y = -60 + roadOffset; y < height; y += 60 ) { ctx.fillStyle = "rgba(255,255,255,.45)"; ctx.fillRect( x - 2, y, 4, 32 ); } } } /* ----------------------------- CAR ------------------------------ */ function drawCar( x, y, w, h, color, enemy = false ) { ctx.save(); ctx.translate( x, y ); /* SHADOW */ ctx.fillStyle = "rgba(0,0,0,.35)"; roundRect( ctx, 4, 7, w, h, 11 ); ctx.fill(); /* BODY */ const gradient = ctx.createLinearGradient( 0, 0, w, h ); gradient.addColorStop( 0, color ); gradient.addColorStop( 1, enemy ? "#292d36" : "#3247d6" ); ctx.fillStyle = gradient; roundRect( ctx, 0, 0, w, h, 11 ); ctx.fill(); /* WINDSHIELD */ ctx.fillStyle = "#182536"; roundRect( ctx, 8, 14, w - 16, 22, 6 ); ctx.fill(); /* REAR WINDOW */ ctx.fillStyle = "#121d2a"; roundRect( ctx, 9, 45, w - 18, 17, 5 ); ctx.fill(); /* LIGHTS */ ctx.fillStyle = enemy ? "#ff4f5f" : "#eaf1ff"; ctx.fillRect( 5, 5, 8, 4 ); ctx.fillRect( w - 13, 5, 8, 4 ); /* PLAYER NEON */ if (!enemy) { ctx.shadowBlur = 18; ctx.shadowColor = "#536dff"; ctx.strokeStyle = "rgba(100,130,255,.9)"; ctx.lineWidth = 2; roundRect( ctx, 1, 1, w - 2, h - 2, 10 ); ctx.stroke(); } ctx.restore(); } /* ----------------------------- ROUND RECT ------------------------------ */ function roundRect( ctx, x, y, width, height, radius ) { radius = Math.min( radius, width / 2, height / 2 ); ctx.beginPath(); ctx.moveTo( x + radius, y ); ctx.arcTo( x + width, y, x + width, y + height, radius ); ctx.arcTo( x + width, y + height, x, y + height, radius ); ctx.arcTo( x, y + height, x, y, radius ); ctx.arcTo( x, y, x + width, y, radius ); ctx.closePath(); } /* ----------------------------- ENEMY SPAWN ------------------------------ */ function spawnEnemy() { const roadWidth = width * .68; const roadX = ( width - roadWidth ) / 2; const laneWidth = roadWidth / 3; const lane = Math.floor( Math.random() * 3 ); const carWidth = 40; const carHeight = 75; const x = roadX + lane * laneWidth + laneWidth / 2 - carWidth / 2; const colors = [ "#f05b68", "#ef9b3d", "#38bca8", "#a269ff", "#eeeeee" ]; enemies.push({ x: x, y: -100, width: carWidth, height: carHeight, speed: speed + Math.random() * 2, color: colors[ Math.floor( Math.random() * colors.length ) ] }); } /* ----------------------------- ENEMY UPDATE ------------------------------ */ function updateEnemies() { spawnTimer++; const spawnRate = Math.max( 36, 85 - speed * 4 ); if ( spawnTimer > spawnRate ) { spawnEnemy(); spawnTimer = 0; } for ( let i = enemies.length - 1; i >= 0; i-- ) { const enemy = enemies[i]; enemy.y += enemy.speed; if ( enemy.y > height + 100 ) { enemies.splice( i, 1 ); score += 10; continue; } if ( collision( player, enemy ) ) { endGame(); return; } } } /* ----------------------------- COLLISION ------------------------------ */ function collision( a, b ) { const padding = 7; return ( a.x + padding < b.x + b.width - padding && a.x + a.width - padding > b.x + padding && a.y + padding < b.y + b.height - padding && a.y + a.height - padding > b.y + padding ); } /* ----------------------------- PLAYER MOVEMENT ------------------------------ */ function updatePlayer() { const roadWidth = width * .68; const roadX = ( width - roadWidth ) / 2; const leftBound = roadX + 10; const rightBound = roadX + roadWidth - player.width - 10; if ( keys.left ) { player.x -= player.speed; } if ( keys.right ) { player.x += player.speed; } player.x = Math.max( leftBound, Math.min( rightBound, player.x ) ); } /* ----------------------------- DRAW ENEMIES ------------------------------ */ function drawEnemies() { enemies.forEach( function(enemy) { drawCar( enemy.x, enemy.y, enemy.width, enemy.height, enemy.color, true ); } ); } /* ----------------------------- GAME LOOP ------------------------------ */ function gameLoop() { if ( !gameRunning ) { return; } animationFrame = requestAnimationFrame( gameLoop ); ctx.clearRect( 0, 0, width, height ); drawRoad(); updatePlayer(); updateEnemies(); drawEnemies(); drawCar( player.x, player.y, player.width, player.height, "#667cff" ); score += .08; speed = Math.min( 13, 6 + score / 650 ); scoreDisplay.textContent = Math.floor( score ); speedDisplay.textContent = ( speed / 6 ).toFixed( 1 ) + "x"; } /* ----------------------------- START GAME ------------------------------ */ function startGame() { cancelAnimationFrame( animationFrame ); gameRunning = true; score = 0; speed = 6; roadOffset = 0; spawnTimer = 0; enemies.length = 0; keys.left = false; keys.right = false; resetPlayer(); scoreDisplay.textContent = "0"; speedDisplay.textContent = "1.0x"; startScreen.style.display = "none"; gameOverScreen.style.display = "none"; gameLoop(); } /* ----------------------------- END ------------------------------ */ function endGame() { gameRunning = false; cancelAnimationFrame( animationFrame ); finalScore.textContent = "Score " + Math.floor( score ); gameOverScreen.style.display = "flex"; } /* ----------------------------- BUTTONS ------------------------------ */ startButton.addEventListener( "click", startGame ); restartButton.addEventListener( "click", startGame );
terminal
JavaScript Console
Preview
Clear
close
›
Run