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>Foggy evening</title> </head> <body> <!-- Start your code here --> <div class="rain-app" id="rainApp"> <div class="rain-scene" id="rainScene"> <!-- REAL CITY PHOTOGRAPH --> <div class="city-photo"></div> <!-- ATMOSPHERE --> <div class="city-shade"></div> <!-- FOGGED GLASS --> <div class="glass-fog"></div> <!-- CANVAS RAIN --> <canvas id="rainCanvas" aria-hidden="true"></canvas> <!-- MOVING WATER TRAILS --> <div class="rain-trails" id="rainTrails"></div> <!-- WINDOW REFLECTION --> <div class="glass-reflection"></div> <!-- WINDOW FRAME --> <div class="window-frame"> <div class="vertical-frame"></div> <div class="horizontal-frame"></div> <div class="window-sill"></div> </div> <!-- CONTENT --> <div class="scene-content"> <div class="eyebrow"> SOMEWHERE IN THE CITY </div> <h1> Foggy<br> <em>Evening.</em> </h1> <p> A quiet evening, a warm room,<br> and the city fading into the mist. </p> </div> </div> <!-- CONTROLS --> <div class="rain-controls"> <div class="control-title"> <span class="control-icon" aria-hidden="true"> ☁ </span> <div> <strong>Foggy Evening</strong> <small>A quiet city atmosphere</small> </div> </div> <div class="control-field"> <label for="rainAmount"> Rain density </label> <input type="range" id="rainAmount" min="10" max="100" value="75" > <output id="rainOutput" for="rainAmount"> 75% </output> </div> <div class="control-field"> <label for="fogAmount"> Window fog </label> <input type="range" id="fogAmount" min="0" max="100" value="35" > <output id="fogOutput" for="fogAmount"> 35% </output> </div> <button id="resetButton" class="reset-button" type="button" > Reset </button> </div> </div> <!-- End your code here --> </body> </html>
@import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=Playfair+Display:ital,wght@0,500;1,500&display=swap'); * { box-sizing: border-box; } body { margin: 0; background: #10151c; color: white; font-family: 'DM Sans', sans-serif; } button, input { font: inherit; } button:focus-visible, input:focus-visible { outline: 3px solid #ffd49b; outline-offset: 4px; } .rain-app { min-height: 100vh; padding: 20px; display: flex; flex-direction: column; gap: 16px; } /* SCENE */ .rain-scene { position: relative; isolation: isolate; overflow: hidden; height: 72vh; min-height: 500px; max-height: 760px; border-radius: 16px; background: #192635; --fog: .35; } /* REAL CITY PHOTO */ .city-photo { position: absolute; inset: -10px; background-image: url('https://images.unsplash.com/photo-1519501025264-65ba15a82390?w=1600&q=80'); background-size: cover; background-position: center; filter: blur(2px) brightness(.78); } /* DARK ATMOSPHERE */ .city-shade { position: absolute; inset: 0; background: linear-gradient( 90deg, rgba(5,12,23,.67), rgba(5,12,23,.15) 70% ), linear-gradient( 0deg, rgba(5,12,23,.5), transparent 45% ); } /* FOGGED GLASS */ .glass-fog { position: absolute; inset: 0; opacity: var(--fog); background: linear-gradient( 110deg, rgba(180,200,220,.38), rgba(180,200,220,.06) 50%, rgba(190,210,225,.3) ); pointer-events: none; } /* RAIN CANVAS */ #rainCanvas { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; } /* MOVING WATER */ .rain-trails { position: absolute; inset: 0; overflow: hidden; pointer-events: none; } .water-trail { position: absolute; top: -25%; width: 2px; height: var(--length); border-radius: 20px; background: linear-gradient( to bottom, transparent, rgba(230,245,255,.18) 40%, rgba(255,255,255,.7) ); box-shadow: 1px 0 1px rgba(0,0,0,.3); animation: waterSlide var(--duration) linear var(--delay) infinite; } .water-trail::after { content: ""; position: absolute; bottom: 0; left: -2px; width: 6px; height: 10px; border-radius: 50%; background: rgba(230,245,255,.65); } @keyframes waterSlide { from { transform: translateY(-100px); } to { transform: translateY(1100px); } } /* REFLECTION */ .glass-reflection { position: absolute; inset: 0; pointer-events: none; background: linear-gradient( 110deg, rgba(255,255,255,.09), transparent 28% ), radial-gradient( ellipse at 8% 45%, rgba(255,190,130,.1), transparent 35% ); } /* WINDOW FRAME */ .window-frame { position: absolute; inset: 0; border: 14px solid #17212d; box-shadow: inset 0 0 0 1px rgba(255,255,255,.2), inset 0 0 25px rgba(0,0,0,.4); pointer-events: none; } .vertical-frame { position: absolute; top: 0; bottom: 0; left: 70%; width: 17px; background: linear-gradient( 90deg, #101820, #3c4a59, #101820 ); } .horizontal-frame { position: absolute; top: 73%; left: 0; right: 0; height: 16px; background: linear-gradient( #3c4a59, #101820 ); } .window-sill { position: absolute; bottom: 0; left: 0; right: 0; height: 28px; background: linear-gradient( #3c4a59, #101820 ); } /* CONTENT */ .scene-content { position: absolute; z-index: 5; top: 48%; left: 8%; transform: translateY(-50%); } .eyebrow { color: #f4d6b2; font-size: 11px; font-weight: 700; letter-spacing: 3px; } .scene-content h1 { margin: 20px 0; font-family: 'Playfair Display', serif; font-size: clamp(65px, 9vw, 130px); font-weight: 500; line-height: 1.02; letter-spacing: -4px; text-shadow: 0 5px 25px #000a; } .scene-content h1 em { color: #f1d0aa; } .scene-content p { font-size: 17px; line-height: 1.7; color: #ffffff; text-shadow: 0 2px 10px #000; } /* RAIN BADGE */ .rain-badge { display: inline-flex; align-items: center; gap: 10px; margin-top: 22px; padding: 12px 17px; border: 1px solid rgba(255,255,255,.7); border-radius: 30px; background: rgba(10,20,32,.85); font-size: 10px; font-weight: 700; letter-spacing: 1px; } .badge-dot { width: 8px; height: 8px; border-radius: 50%; background: #9bd3ff; } /* FOOTER */ .scene-footer { position: absolute; z-index: 5; left: 5%; right: 5%; bottom: 40px; display: flex; justify-content: space-between; gap: 15px; font-size: 10px; font-weight: 600; letter-spacing: 1.5px; text-shadow: 0 2px 10px #000; } /* CONTROLS */ .rain-controls { display: flex; align-items: center; flex-wrap: wrap; gap: 25px; padding: 20px 25px; border: 1px solid #526174; border-radius: 12px; background: #1d2735; } .control-title { display: flex; align-items: center; gap: 13px; margin-right: auto; } .control-icon { display: grid; place-items: center; width: 45px; height: 45px; border-radius: 10px; background: #34475c; font-size: 24px; } .control-title strong { display: block; font-size: 15px; } .control-title small { display: block; margin-top: 4px; color: #d1dbe8; font-size: 12px; } .control-field { display: flex; align-items: center; gap: 12px; } .control-field label { font-size: 13px; font-weight: 600; white-space: nowrap; } .control-field input { width: 120px; accent-color: #f1d0a5; } .control-field output { min-width: 38px; color: #f1d0a5; font-size: 12px; font-weight: 700; } .reset-button { min-height: 44px; padding: 10px 20px; border: 1px solid #c5d2e0; border-radius: 8px; background: transparent; color: white; font-size: 13px; font-weight: 700; cursor: pointer; } .reset-button:hover { background: #34475c; } /* RESPONSIVE */ @media (max-width: 800px) { .rain-app { padding: 12px; } .rain-scene { height: 650px; } } @media (max-width: 520px) { .rain-scene { height: 600px; min-height: 600px; } .scene-content { left: 8%; right: 8%; } .scene-content h1 { font-size: 62px; letter-spacing: -2px; } .scene-content p { font-size: 14px; } .scene-footer { font-size: 8px; letter-spacing: .5px; } .control-title { width: 100%; } .control-field { width: 100%; } .control-field input { flex: 1; min-width: 0; } } /* REDUCED MOTION */ @media (prefers-reduced-motion: reduce) { .water-trail { animation: none !important; } }
(function () { var canvas = document.getElementById("rainCanvas"); var rainTrails = document.getElementById("rainTrails"); var rainAmount = document.getElementById("rainAmount"); var fogAmount = document.getElementById("fogAmount"); var rainOutput = document.getElementById("rainOutput"); var fogOutput = document.getElementById("fogOutput"); var rainScene = document.getElementById("rainScene"); var resetButton = document.getElementById("resetButton"); if (!canvas || !rainScene) return; var ctx = canvas.getContext("2d"); if (!ctx) return; var reducedMotion = window.matchMedia( "(prefers-reduced-motion: reduce)" ); var resizeTimer = null; var rainTimer = null; function random(min, max) { return Math.random() * (max - min) + min; } // DRAW WATER DROPLETS function drawDroplet(x, y, size) { ctx.save(); // DROP BODY ctx.beginPath(); ctx.ellipse( x, y, size * .65, size, 0, 0, Math.PI * 2 ); var gradient = ctx.createLinearGradient( x - size, y - size, x + size, y + size ); gradient.addColorStop( 0, "rgba(255,255,255,.65)" ); gradient.addColorStop( .45, "rgba(255,255,255,.06)" ); gradient.addColorStop( 1, "rgba(185,220,245,.45)" ); ctx.fillStyle = gradient; ctx.fill(); // DARK EDGE ctx.strokeStyle = "rgba(10,25,40,.35)"; ctx.lineWidth = .6; ctx.stroke(); // SMALL HIGHLIGHT if (size > 3) { ctx.beginPath(); ctx.ellipse( x - size * .2, y - size * .3, size * .12, size * .22, -.4, 0, Math.PI * 2 ); ctx.fillStyle = "rgba(255,255,255,.75)"; ctx.fill(); } ctx.restore(); } // DRAW STATIC RAIN function drawRain() { var rect = canvas.getBoundingClientRect(); var width = rect.width; var height = rect.height; if (width <= 0 || height <= 0) return; // CAP RESOLUTION FOR SLOWER COMPUTERS var scale = Math.min(window.devicePixelRatio || 1, 1.5); canvas.width = Math.floor(width * scale); canvas.height = Math.floor(height * scale); ctx.setTransform(scale, 0, 0, scale, 0, 0); ctx.clearRect(0, 0, width, height); var intensity = Number(rainAmount.value); // DENSE RAIN, BUT ONLY ONE CANVAS ELEMENT var count = Math.floor(intensity * 4); for (var i = 0; i < count; i++) { var x = random(0, width); var y = random(0, height); var size; if (Math.random() < .85) { size = random(1, 3.5); } else { size = random(4, 9); } drawDroplet(x, y, size); } } // CREATE A FEW ANIMATED TRAILS function createTrails() { var fragment = document.createDocumentFragment(); var intensity = Number(rainAmount.value); var count = Math.floor(intensity * .16); // NEVER MORE THAN 12 TRAILS count = Math.min(count, 12); for (var i = 0; i < count; i++) { var trail = document.createElement("span"); trail.className = "water-trail"; trail.style.left = random(0, 100) + "%"; trail.style.setProperty( "--length", random(60, 160) + "px" ); trail.style.setProperty( "--duration", random(9, 20) + "s" ); trail.style.setProperty( "--delay", random(-20, 0) + "s" ); fragment.appendChild(trail); } rainTrails.replaceChildren(fragment); } // UPDATE RAIN function updateRain() { rainOutput.textContent = rainAmount.value + "%"; drawRain(); createTrails(); } // THROTTLE UPDATES function scheduleRainUpdate() { rainOutput.textContent = rainAmount.value + "%"; clearTimeout(rainTimer); rainTimer = setTimeout(updateRain, 120); } // UPDATE FOG function updateFog() { var value = Number(fogAmount.value); fogOutput.textContent = value + "%"; rainScene.style.setProperty( "--fog", value / 100 ); } // RESIZE window.addEventListener("resize", function () { clearTimeout(resizeTimer); resizeTimer = setTimeout(drawRain, 180); }); // EVENTS rainAmount.addEventListener( "input", scheduleRainUpdate ); fogAmount.addEventListener( "input", updateFog ); resetButton.addEventListener("click", function () { clearTimeout(rainTimer); rainAmount.value = 75; fogAmount.value = 35; updateRain(); updateFog(); }); // INITIALIZE updateRain(); updateFog(); })();
terminal
JavaScript Console
Preview
Clear
close
›
Run