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>Spider in the night</title> </head> <body> <!-- Start your code here --> <div class="halloween"> <canvas id="horrorCanvas"></canvas> <div class="overlay"> <div class="eyebrow">ALL HALLOWS' EVE</div> <h1>THE WIDOW</h1> <p>Something is watching.</p> </div> <div class="actions"> <button id="motionBtn">Pause creature</button> <button id="eyesBtn">Eyes: ON</button> </div> </div> <!-- End your code here --> </body> </html>
* { box-sizing: border-box; } body { margin: 0; background: #05070b; font-family: Georgia, serif; } .halloween { position: relative; width: 100%; height: 620px; overflow: hidden; background: #080b12; } canvas { display: block; width: 100%; height: 100%; } .overlay { position: absolute; top: 35px; left: 0; width: 100%; text-align: center; pointer-events: none; color: #d7d1c9; text-shadow: 0 3px 20px #000; } .eyebrow { font: 10px Arial, sans-serif; letter-spacing: 5px; color: #bb7057; } h1 { font-size: clamp(32px, 6vw, 64px); letter-spacing: 10px; font-weight: normal; margin: 10px 0; } .overlay p { color: #9b9090; font-style: italic; font-size: 13px; letter-spacing: 2px; } .actions { position: absolute; bottom: 24px; left: 0; width: 100%; display: flex; justify-content: center; gap: 12px; } button { background: #12151bd9; border: 1px solid #65443e; color: #d7b5a6; padding: 12px 17px; border-radius: 4px; cursor: pointer; font: 12px Arial, sans-serif; letter-spacing: 1px; } button:hover { background: #39201e; }
const canvas = document.getElementById("horrorCanvas"); const ctx = canvas.getContext("2d"); const motionBtn = document.getElementById("motionBtn"); const eyesBtn = document.getElementById("eyesBtn"); let W = 0; let H = 0; let time = 0; let moving = true; let glowing = true; let lastFrame = 0; function resize() { const rect = canvas.getBoundingClientRect(); W = rect.width; H = rect.height; const dpr = Math.min(window.devicePixelRatio || 1, 2); canvas.width = Math.round(W * dpr); canvas.height = Math.round(H * dpr); ctx.setTransform(dpr, 0, 0, dpr, 0, 0); } window.addEventListener("resize", resize); resize(); function random(seed) { const n = Math.sin(seed * 127.1 + 78.233) * 43758.5453; return n - Math.floor(n); } function line(x1, y1, x2, y2, color, width) { ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.strokeStyle = color; ctx.lineWidth = width; ctx.stroke(); } function ellipse(x, y, rx, ry, c1, c2) { const g = ctx.createRadialGradient( x - rx * .35, y - ry * .4, 2, x, y, Math.max(rx, ry) * 1.4 ); g.addColorStop(0, c1); g.addColorStop(1, c2); ctx.fillStyle = g; ctx.beginPath(); ctx.ellipse(x, y, rx, ry, 0, 0, Math.PI * 2); ctx.fill(); } function background() { const g = ctx.createRadialGradient( W * .72, H * .24, 5, W * .5, H * .45, W ); g.addColorStop(0, "#28303c"); g.addColorStop(.45, "#111722"); g.addColorStop(1, "#030407"); ctx.fillStyle = g; ctx.fillRect(0, 0, W, H); const mx = W * .77; const my = H * .23; const r = Math.min(W, H) * .13; ctx.save(); ctx.shadowColor = "#c6ced9"; ctx.shadowBlur = 50; ellipse(mx, my, r, r, "#e0e0db", "#777f8b"); ctx.restore(); for (let i = 0; i < 16; i++) { const a = random(i + 12) * Math.PI * 2; const dist = random(i + 29) * r * .7; ellipse( mx + Math.cos(a) * dist, my + Math.sin(a) * dist, 3 + random(i + 3) * 9, 3 + random(i + 5) * 7, "#949ba5", "#adb0b3" ); } // Drifting mist for (let i = 0; i < 9; i++) { const fx = ((i * 173 + time * (3 + i)) % (W + 300)) - 150; const fy = H * (.45 + random(i + 7) * .5); const fog = ctx.createRadialGradient( fx, fy, 0, fx, fy, 180 ); fog.addColorStop(0, "rgba(120,135,155,.075)"); fog.addColorStop(1, "rgba(120,135,155,0)"); ctx.fillStyle = fog; ctx.fillRect(fx - 180, fy - 180, 360, 360); } } function drawWeb(cx, cy, radius) { ctx.save(); ctx.strokeStyle = "rgba(190,204,215,.22)"; ctx.lineWidth = .65; const spokes = 16; for (let i = 0; i < spokes; i++) { const a = i * Math.PI * 2 / spokes; line( cx, cy, cx + Math.cos(a) * radius, cy + Math.sin(a) * radius, "rgba(190,204,215,.24)", .7 ); } for (let ring = 1; ring <= 9; ring++) { const rr = radius * ring / 9; ctx.beginPath(); for (let i = 0; i <= spokes; i++) { const a = i * Math.PI * 2 / spokes; const sag = Math.sin(a * 8 + ring) * 3; const x = cx + Math.cos(a) * (rr + sag); const y = cy + Math.sin(a) * (rr + sag); if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y); } ctx.stroke(); } ctx.restore(); } function drawSegment(x1, y1, x2, y2, width) { ctx.lineCap = "round"; line(x1 + 2, y1 + 3, x2 + 2, y2 + 3, "#000", width + 3); line(x1, y1, x2, y2, "#211714", width); line(x1 - 1, y1 - 1, x2 - 1, y2 - 1, "#75503a", width * .28); const dx = x2 - x1; const dy = y2 - y1; const len = Math.hypot(dx, dy); if (len < 1) return; const nx = -dy / len; const ny = dx / len; for (let j = 1; j < 9; j++) { const f = j / 10; const px = x1 + dx * f; const py = y1 + dy * f; const hair = 3 + random(j + x1) * 6; line( px, py, px + nx * hair, py + ny * hair, "rgba(172,125,89,.48)", .65 ); line( px, py, px - nx * hair, py - ny * hair, "rgba(172,125,89,.35)", .55 ); } } function drawLeg(side, index, t, s) { const offsets = [-26, -10, 10, 27]; const sy = offsets[index] * s; const sx = side * 25 * s; const phase = t * 2.8 + index * 1.7 + (side === 1 ? Math.PI : 0); const step = Math.sin(phase) * 13 * s; const lift = Math.max(0, Math.cos(phase)) * 12 * s; const kneeX = side * (82 + index * 8) * s; const kneeY = (-85 + index * 39) * s - lift; const footX = side * (145 + index * 13) * s + step; const footY = (-105 + index * 70) * s - lift; drawSegment(sx, sy, kneeX, kneeY, 11 * s); drawSegment(kneeX, kneeY, footX, footY, 7 * s); // Hooked pointed claw line( footX, footY, footX + side * 13 * s, footY + 12 * s, "#1c1515", 3 * s ); ellipse(kneeX, kneeY, 6 * s, 6 * s, "#66402e", "#100c0d"); } function drawSpider() { const scale = Math.min(W / 720, H / 580, 1.2); const s = Math.max(.45, scale); const crawl = Math.sin(time * .55) * Math.min(W * .1, 65); const bob = Math.sin(time * 5) * 3; const x = W * .46 + crawl; const y = H * .51 + bob; // Silk strand line( x, 0, x, y - 75 * s, "rgba(205,215,225,.55)", 1 ); ctx.save(); ctx.translate(x, y); ctx.rotate(Math.sin(time * .5) * .07); // Back legs for (let i = 0; i < 4; i++) { drawLeg(-1, i, time, s); drawLeg(1, i, time, s); } // Large hairy abdomen ellipse( 0, -62 * s, 59 * s, 69 * s, "#5d3b31", "#08090d" ); // Fine bristles and rough body texture for (let i = 0; i < 420; i++) { const a = random(i + 50) * Math.PI * 2; const rr = Math.sqrt(random(i + 1000)); const px = Math.cos(a) * 54 * s * rr; const py = -62 * s + Math.sin(a) * 64 * s * rr; const alpha = .12 + random(i + 2000) * .35; line( px, py, px + Math.cos(a) * 5 * s, py + Math.sin(a) * 7 * s, "rgba(194,126,83," + alpha + ")", .6 * s ); } // Red hourglass-like marking ctx.fillStyle = "#8c241b"; ctx.beginPath(); ctx.moveTo(0, -94 * s); ctx.lineTo(-15 * s, -76 * s); ctx.lineTo(0, -59 * s); ctx.lineTo(15 * s, -76 * s); ctx.closePath(); ctx.fill(); ctx.beginPath(); ctx.moveTo(0, -59 * s); ctx.lineTo(-12 * s, -43 * s); ctx.lineTo(0, -29 * s); ctx.lineTo(12 * s, -43 * s); ctx.closePath(); ctx.fill(); // Cephalothorax ellipse( 0, 34 * s, 46 * s, 42 * s, "#654a3b", "#0b0a0e" ); // Small facial hairs for (let i = 0; i < 75; i++) { const a = random(i + 3000) * Math.PI * 2; const px = Math.cos(a) * 40 * s; const py = 34 * s + Math.sin(a) * 34 * s; line( px, py, px + Math.cos(a) * 7 * s, py + Math.sin(a) * 7 * s, "#76513c", .6 * s ); } // Eyes const eyePositions = [ [-19, 25], [-7, 19], [7, 19], [19, 25], [-22, 35], [-9, 32], [9, 32], [22, 35] ]; for (const pos of eyePositions) { const ex = pos[0] * s; const ey = pos[1] * s; if (glowing) { ctx.save(); ctx.shadowColor = "#ff1800"; ctx.shadowBlur = 17 * s; ellipse(ex, ey, 3.5 * s, 4 * s, "#ff6a25", "#7c0900"); ctx.restore(); } else { ellipse(ex, ey, 3 * s, 4 * s, "#4c3330", "#050505"); } } // Two sharp curved fangs for (const side of [-1, 1]) { ctx.beginPath(); ctx.moveTo(side * 13 * s, 57 * s); ctx.quadraticCurveTo( side * 24 * s, 83 * s, side * 6 * s, 93 * s ); ctx.quadraticCurveTo( side * 13 * s, 75 * s, side * 7 * s, 64 * s ); ctx.closePath(); ctx.fillStyle = "#c3aa89"; ctx.fill(); } ctx.restore(); } function drawBranches() { ctx.save(); ctx.strokeStyle = "#030405"; ctx.lineCap = "round"; function branch(x, y, length, angle, depth) { if (depth === 0) return; const nx = x + Math.cos(angle) * length; const ny = y + Math.sin(angle) * length; line(x, y, nx, ny, "#030405", depth * 3.4); branch(nx, ny, length * .72, angle - .5, depth - 1); branch(nx, ny, length * .68, angle + .6, depth - 1); } branch(-20, H * .8, 140, -.9, 6); branch(W + 20, H * .7, 130, -2.3, 6); ctx.restore(); } function frame(now) { if (!lastFrame) lastFrame = now; const dt = Math.min((now - lastFrame) / 1000, .05); lastFrame = now; if (moving) time += dt; ctx.clearRect(0, 0, W, H); background(); drawWeb(W * .1, H * .12, Math.min(W, H) * .35); drawWeb(W * .94, H * .88, Math.min(W, H) * .27); drawBranches(); drawSpider(); // Atmospheric vignette const v = ctx.createRadialGradient( W / 2, H / 2, H * .2, W / 2, H / 2, Math.max(W, H) * .75 ); v.addColorStop(0, "rgba(0,0,0,0)"); v.addColorStop(1, "rgba(0,0,0,.75)"); ctx.fillStyle = v; ctx.fillRect(0, 0, W, H); requestAnimationFrame(frame); } motionBtn.addEventListener("click", function () { moving = !moving; motionBtn.textContent = moving ? "Pause creature" : "Resume creature"; }); eyesBtn.addEventListener("click", function () { glowing = !glowing; eyesBtn.textContent = glowing ? "Eyes: ON" : "Eyes: OFF"; }); requestAnimationFrame(frame);
terminal
JavaScript Console
Preview
Clear
close
›
Run