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>Claw machine game</title> </head> <body> <!-- Start your code here --> <div class="arcade"> <header class="topbar"> <div> <div class="eyebrow">THE LITTLE ARCADE</div> <h1>Plushie Paradise</h1> <p>A tiny claw machine adventure</p> </div> <div class="stats"> <div class="stat"> <span>PRIZES</span> <strong id="score">0</strong> </div> <div class="stat"> <span>TRIES LEFT</span> <strong id="tries">8</strong> </div> </div> </header> <div class="machine"> <div class="marquee"> <span class="sparkle">✦</span> PLUSHIE PARADISE <span class="sparkle">✦</span> </div> <div class="glass"> <canvas id="game" width="480" height="390"></canvas> </div> <div class="control-panel"> <div class="direction-controls"> <button id="left" class="move-btn" type="button"> ◀ </button> <button id="right" class="move-btn" type="button"> ▶ </button> </div> <div class="status" id="status"> Position the claw! </div> <button id="grab" class="grab-btn" type="button"> GRAB! </button> </div> <div class="prize-area"> <div class="prize-label">YOUR PRIZES</div> <div id="collection" class="collection"></div> </div> </div> <div class="bottom"> <span>Use arrow keys or buttons to move</span> <button id="restart" type="button">New Game</button> </div> </div> <!-- End your code here --> </body> </html>
* { box-sizing: border-box; } body { margin: 0; min-height: 100vh; display: grid; place-items: center; padding: 24px; background: #fff5f7; font-family: "Trebuchet MS", Arial, sans-serif; color: #654b68; } .arcade { width: min(560px, 100%); } .topbar { display: flex; justify-content: space-between; align-items: center; gap: 15px; margin-bottom: 20px; } .eyebrow { font-size: 10px; letter-spacing: 2px; color: #cc8caa; font-weight: 900; } h1 { margin: 5px 0; font-size: clamp(25px, 5vw, 34px); letter-spacing: -1px; } .topbar p { margin: 0; font-size: 12px; color: #aa91a7; } .stats { display: flex; gap: 8px; } .stat { min-width: 75px; background: white; border-radius: 13px; padding: 10px; text-align: center; box-shadow: 0 4px 15px #c88ca21c; } .stat span { display: block; font-size: 9px; color: #b19bb0; font-weight: bold; letter-spacing: 1px; } .stat strong { display: block; font-size: 23px; color: #b66a9a; margin-top: 4px; } .machine { background: #f4a9c7; padding: 15px; border: 5px solid #e58fb5; border-radius: 26px; box-shadow: 0 15px 0 #d884aa, 0 30px 50px #b77b9c40; } .marquee { background: #fff0b8; border: 4px solid #fff8dc; border-radius: 15px; text-align: center; padding: 13px 5px; font-weight: 900; font-size: clamp(15px, 4vw, 23px); letter-spacing: 2px; color: #bd6a94; margin-bottom: 13px; box-shadow: inset 0 -4px #f8dfa0; } .sparkle { color: #e9a447; margin: 0 6px; } .glass { border: 7px solid #fff4f8; border-radius: 14px; overflow: hidden; background: #e1f6f6; box-shadow: inset 0 0 20px #8bbdbd40; } canvas { width: 100%; height: auto; display: block; touch-action: none; } .control-panel { display: flex; align-items: center; justify-content: space-between; gap: 10px; background: #ffd3e3; border-radius: 14px; margin-top: 13px; padding: 15px; } .direction-controls { display: flex; gap: 8px; } button { border: none; font-family: inherit; cursor: pointer; font-weight: 900; touch-action: none; user-select: none; } .move-btn { width: 48px; height: 48px; border-radius: 13px; background: #fff; color: #b875a5; font-size: 20px; box-shadow: 0 4px 0 #e9b6cf; } .move-btn:active { transform: translateY(3px); box-shadow: 0 1px 0 #e9b6cf; } .status { flex: 1; text-align: center; font-size: 12px; font-weight: bold; color: #a26f90; } .grab-btn { padding: 16px 22px; border-radius: 13px; background: #ffe795; color: #a66e46; box-shadow: 0 4px 0 #e9c36e; font-size: 13px; } .grab-btn:active { transform: translateY(3px); } .prize-area { background: #d981a8; margin-top: 13px; padding: 12px; border-radius: 12px; } .prize-label { color: #fff4fa; font-size: 10px; letter-spacing: 2px; font-weight: 900; text-align: center; margin-bottom: 8px; } .collection { min-height: 45px; display: flex; justify-content: center; align-items: center; flex-wrap: wrap; gap: 8px; background: #fff0f5; border-radius: 9px; padding: 8px; } .prize { font-size: 26px; animation: pop .3s ease-out; } .empty { font-size: 11px; color: #b9a0b0; } .bottom { display: flex; justify-content: space-between; align-items: center; margin-top: 28px; gap: 12px; font-size: 11px; color: #a88da1; } #restart { background: white; color: #ae729a; border: 1px solid #edd7e4; border-radius: 9px; padding: 10px 15px; } @keyframes pop { from { transform: scale(0); } to { transform: scale(1); } } @media (max-width: 500px) { body { padding: 12px; } .topbar { flex-direction: column; align-items: flex-start; } .status { font-size: 10px; } .move-btn { width: 40px; height: 43px; } .grab-btn { padding: 14px; } .machine { padding: 9px; } }
const canvas = document.getElementById("game"); const ctx = canvas.getContext("2d"); const scoreEl = document.getElementById("score"); const triesEl = document.getElementById("tries"); const statusEl = document.getElementById("status"); const collection = document.getElementById("collection"); const W = canvas.width; const H = canvas.height; const claw = { x: 240, y: 48, homeY: 48, speed: 210, state: "idle", held: null, grip: 0, timer: 0 }; let toys = []; let prizes = 0; let tries = 8; let keys = {}; let lastTime = 0; let frameId = null; let finished = false; const toyTypes = [ { name: "Bear", color: "#c9a1ed", icon: "\uD83E\uDDF8" }, { name: "Bunny", color: "#ffc4d8", icon: "\uD83D\uDC30" }, { name: "Frog", color: "#a7dfaa", icon: "\uD83D\uDC38" }, { name: "Cat", color: "#ffdaa0", icon: "\uD83D\uDC31" }, { name: "Panda", color: "#e8e8ef", icon: "\uD83D\uDC3C" } ]; function createToys() { toys = []; const positions = [ [65, 325], [140, 330], [215, 325], [290, 330], [365, 325], [425, 330], [100, 277], [185, 280], [270, 278], [350, 280] ]; positions.forEach(function(pos, i) { const type = toyTypes[i % toyTypes.length]; toys.push({ x: pos[0], y: pos[1], baseY: pos[1], size: 25, type: type, caught: false, wobble: Math.random() * 6 }); }); } function roundedRect(x, y, w, h, r, color) { ctx.fillStyle = color; ctx.beginPath(); ctx.roundRect(x, y, w, h, r); ctx.fill(); } function circle(x, y, r, color) { ctx.fillStyle = color; ctx.beginPath(); ctx.arc(x, y, r, 0, Math.PI * 2); ctx.fill(); } function drawBackground() { const gradient = ctx.createLinearGradient(0, 0, 0, H); gradient.addColorStop(0, "#e5f9fa"); gradient.addColorStop(1, "#c8ebdf"); ctx.fillStyle = gradient; ctx.fillRect(0, 0, W, H); for (let i = 0; i < 8; i++) { circle( 35 + i * 65, 65 + Math.sin(i * 2) * 25, 5, "#ffffff88" ); } roundedRect(0, 350, W, 40, 0, "#e8b7c9"); roundedRect(0, 350, W, 7, 0, "#fff1f5"); roundedRect(8, 355, 72, 35, 7, "#bc7198"); roundedRect(15, 359, 58, 24, 5, "#75486f"); ctx.fillStyle = "#ffffff55"; ctx.beginPath(); ctx.moveTo(20, 0); ctx.lineTo(70, 0); ctx.lineTo(160, 350); ctx.lineTo(120, 350); ctx.closePath(); ctx.fill(); } function drawToy(toy, now) { if (toy.caught && claw.held !== toy) { return; } let x = toy.x; let y = toy.y; if (claw.held === toy) { x = claw.x; y = claw.y + 45; } const bob = claw.held === toy ? 0 : Math.sin(now * 0.002 + toy.wobble) * 2; y += bob; const c = toy.type.color; ctx.save(); ctx.translate(x, y); circle(-17, -18, 12, c); circle(17, -18, 12, c); circle(0, 9, 25, c); circle(0, -13, 23, c); circle(-8, -17, 3, "#51425b"); circle(8, -17, 3, "#51425b"); circle(0, -7, 4, "#e78fa5"); circle(-15, 27, 10, c); circle(15, 27, 10, c); circle(-16, -7, 5, "#f6a6ba88"); circle(16, -7, 5, "#f6a6ba88"); ctx.restore(); } function drawClaw() { ctx.strokeStyle = "#9e95b3"; ctx.lineWidth = 5; ctx.beginPath(); ctx.moveTo(claw.x, 0); ctx.lineTo(claw.x, claw.y); ctx.stroke(); roundedRect( claw.x - 24, 10, 48, 17, 7, "#b5a5ca" ); circle(claw.x, claw.y, 13, "#d9c9e7"); circle(claw.x, claw.y, 6, "#a898c0"); const open = claw.state === "closing" || claw.held !== null ? 12 : 24; ctx.strokeStyle = "#a39ab6"; ctx.lineWidth = 7; ctx.lineCap = "round"; ctx.beginPath(); ctx.moveTo(claw.x - 8, claw.y + 7); ctx.lineTo(claw.x - open, claw.y + 31); ctx.lineTo(claw.x - open + 8, claw.y + 43); ctx.moveTo(claw.x + 8, claw.y + 7); ctx.lineTo(claw.x + open, claw.y + 31); ctx.lineTo(claw.x + open - 8, claw.y + 43); ctx.stroke(); } function draw(now) { drawBackground(); toys.forEach(function(toy) { drawToy(toy, now); }); drawClaw(); } function startGrab() { if (finished || claw.state !== "idle") { return; } if (tries <= 0) { return; } tries--; triesEl.textContent = String(tries); claw.state = "down"; claw.held = null; statusEl.textContent = "Dropping..."; } function findTarget() { let nearest = null; let distance = Infinity; toys.forEach(function(toy) { if (toy.caught) return; const dx = Math.abs(toy.x - claw.x); if (dx < distance) { distance = dx; nearest = toy; } }); if (nearest && distance < 32) { return { toy: nearest, distance: distance }; } return null; } function resolveGrab() { const target = findTarget(); if (!target) { statusEl.textContent = "Oops! Missed!"; claw.state = "up"; return; } const accuracy = 1 - target.distance / 32; const chance = 0.15 + accuracy * 0.8; if (Math.random() < chance) { claw.held = target.toy; claw.grip = accuracy; target.toy.caught = true; statusEl.textContent = "Got one!"; } else { statusEl.textContent = "It slipped!"; } claw.state = "up"; } function addPrize(toy) { const empty = collection.querySelector(".empty"); if (empty) { empty.remove(); } const item = document.createElement("span"); item.className = "prize"; item.textContent = toy.type.icon; item.title = toy.type.name; collection.appendChild(item); prizes++; scoreEl.textContent = String(prizes); } function finishGame() { finished = true; statusEl.textContent = "Finished! " + prizes + " prizes won!"; } function update(dt) { if (claw.state === "idle") { if (keys.ArrowLeft || keys.a) { claw.x -= claw.speed * dt; } if (keys.ArrowRight || keys.d) { claw.x += claw.speed * dt; } claw.x = Math.max(35, Math.min(W - 35, claw.x)); } if (claw.state === "down") { claw.y += 220 * dt; if (claw.y >= 275) { claw.y = 275; claw.state = "closing"; claw.timer = 0; } } if (claw.state === "closing") { claw.timer += dt; if (claw.timer >= 0.35) { resolveGrab(); } } if (claw.state === "up") { claw.y -= 170 * dt; if (claw.held && claw.y > 100) { const slipChance = (1 - claw.grip) * 0.35 * dt; if (Math.random() < slipChance) { claw.held.caught = false; claw.held = null; statusEl.textContent = "Oh no! It slipped!"; } } if (claw.y <= claw.homeY) { claw.y = claw.homeY; if (claw.held) { claw.state = "deliver"; statusEl.textContent = "Delivering prize!"; } else { claw.state = "idle"; if (tries <= 0) { finishGame(); } } } } if (claw.state === "deliver") { claw.x -= 230 * dt; if (claw.x <= 45) { claw.x = 45; if (claw.held) { addPrize(claw.held); claw.held = null; } claw.state = "return"; } } if (claw.state === "return") { claw.x += 230 * dt; if (claw.x >= 240) { claw.x = 240; claw.state = "idle"; statusEl.textContent = "Ready for another grab!"; if (tries <= 0) { finishGame(); } } } } function loop(now) { const dt = Math.min((now - lastTime) / 1000, 0.04); lastTime = now; update(dt); draw(now); frameId = requestAnimationFrame(loop); } function newGame() { tries = 8; prizes = 0; finished = false; claw.x = 240; claw.y = claw.homeY; claw.state = "idle"; claw.held = null; keys = {}; triesEl.textContent = "8"; scoreEl.textContent = "0"; statusEl.textContent = "Position the claw!"; collection.replaceChildren(); const empty = document.createElement("span"); empty.className = "empty"; empty.textContent = "Your plushies will appear here"; collection.appendChild(empty); createToys(); } document.addEventListener("keydown", function(e) { if ( e.key === "ArrowLeft" || e.key === "ArrowRight" || e.code === "Space" ) { e.preventDefault(); } keys[e.key] = true; if (e.code === "Space" && !e.repeat) { startGrab(); } }); document.addEventListener("keyup", function(e) { keys[e.key] = false; }); function bindMove(id, key) { const btn = document.getElementById(id); btn.addEventListener("pointerdown", function(e) { e.preventDefault(); keys[key] = true; btn.setPointerCapture(e.pointerId); }); btn.addEventListener("pointerup", function() { keys[key] = false; }); btn.addEventListener("pointercancel", function() { keys[key] = false; }); btn.addEventListener("lostpointercapture", function() { keys[key] = false; }); } bindMove("left", "ArrowLeft"); bindMove("right", "ArrowRight"); document.getElementById("grab") .addEventListener("click", startGrab); document.getElementById("restart") .addEventListener("click", newGame); newGame(); lastTime = performance.now(); frameId = requestAnimationFrame(loop);
terminal
JavaScript Console
Preview
Clear
close
›
Run