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>Halloween theme flying bats</title> </head> <body> <!-- Start your code here --> <div class="bat-scene" id="batScene"> <div class="moon-glow"></div> <div class="moon"></div> <div class="cloud cloud-1"></div> <div class="cloud cloud-2"></div> <div class="cloud cloud-3"></div> <div class="bat-container" id="batContainer"></div> <div class="landscape"> <div class="hill hill-back"></div> <div class="hill hill-front"></div> </div> <div class="scene-info"> <span>AFTER DARK</span> <h1>NIGHT FLIGHT</h1> <p>Creatures of the night</p> </div> <div class="scene-controls"> <button id="addBats">+ More Bats</button> <button id="speedBats">Speed: Normal</button> <button id="pauseBats">Pause</button> </div> </div> <!-- End your code here --> </body> </html>
* { box-sizing: border-box; } body { margin: 0; background: #050811; font-family: Georgia, serif; } .bat-scene { position: relative; width: 100%; height: 650px; overflow: hidden; background: radial-gradient( ellipse at 65% 30%, #30445d 0%, #101d30 45%, #030710 100% ); isolation: isolate; } .moon { position: absolute; top: 90px; right: 20%; width: 150px; height: 150px; border-radius: 50%; background: radial-gradient( circle at 35% 30%, #f4f5e8, #bdcbd5 65%, #7f94a7 ); box-shadow: 0 0 35px #d9edff88, 0 0 100px #9abfe744; } .moon-glow { position: absolute; top: -15px; right: calc(20% - 105px); width: 360px; height: 360px; border-radius: 50%; background: radial-gradient( circle, #c9ddf51a, transparent 70% ); } .cloud { position: absolute; width: 450px; height: 110px; border-radius: 50%; background: #111c2bb0; filter: blur(25px); animation: cloudMove 30s linear infinite; } .cloud-1 { top: 100px; left: -500px; } .cloud-2 { top: 220px; left: -600px; animation-delay: -12s; animation-duration: 40s; } .cloud-3 { top: 60px; left: -450px; animation-delay: -22s; animation-duration: 35s; } .bat-container { position: absolute; inset: 0; z-index: 5; pointer-events: none; } .bat { position: absolute; width: 110px; height: 65px; transform-origin: center; will-change: transform; } .bat svg { width: 100%; height: 100%; overflow: visible; filter: drop-shadow(0 3px 3px #0006); } .bat .wing { fill: #030406; stroke: #141923; stroke-width: 1; } .bat .body { fill: #030406; } .bat .ear { fill: #030406; } .bat .left-wing { transform-origin: 50px 32px; animation: flapLeft .35s ease-in-out infinite alternate; } .bat .right-wing { transform-origin: 60px 32px; animation: flapRight .35s ease-in-out infinite alternate; } .bat .eye { fill: #b22222; } .landscape { position: absolute; inset: 0; pointer-events: none; } .hill { position: absolute; width: 140%; left: -20%; border-radius: 50% 50% 0 0; } .hill-back { bottom: -100px; height: 230px; background: #08131c; } .hill-front { bottom: -160px; height: 250px; background: #03080d; } .scene-info { position: absolute; top: 30px; width: 100%; text-align: center; color: #e3e8ed; pointer-events: none; z-index: 10; } .scene-info span { font: 10px Arial, sans-serif; letter-spacing: 5px; color: #9db2c6; } .scene-info h1 { font-size: clamp(32px, 6vw, 65px); font-weight: normal; letter-spacing: 7px; margin: 8px 0; } .scene-info p { font-size: 13px; font-style: italic; color: #aebac6; letter-spacing: 2px; } .scene-controls { position: absolute; bottom: 22px; width: 100%; display: flex; justify-content: center; gap: 10px; z-index: 15; } .scene-controls button { background: #0b1520dd; color: #d6e2ed; border: 1px solid #536c81; padding: 11px 17px; border-radius: 4px; cursor: pointer; font: 12px Arial, sans-serif; } .scene-controls button:hover { background: #23394c; } @keyframes flapLeft { from { transform: rotate(-35deg) scaleY(.65); } to { transform: rotate(25deg) scaleY(1.2); } } @keyframes flapRight { from { transform: rotate(35deg) scaleY(.65); } to { transform: rotate(-25deg) scaleY(1.2); } } @keyframes cloudMove { from { transform: translateX(0); } to { transform: translateX(160vw); } } @media (max-width: 600px) { .bat-scene { height: 550px; } .moon { width: 110px; height: 110px; right: 10%; } .moon-glow { right: calc(10% - 80px); width: 270px; height: 270px; } .scene-controls button { padding: 10px; font-size: 11px; } } @media (prefers-reduced-motion: reduce) { .bat-scene *, .bat-scene *::before, .bat-scene *::after { animation: none !important; } }
const container = document.getElementById("batContainer"); const scene = document.getElementById("batScene"); const addButton = document.getElementById("addBats"); const speedButton = document.getElementById("speedBats"); const pauseButton = document.getElementById("pauseBats"); let bats = []; let speedMultiplier = 1; let paused = false; let lastTime = 0; const NS = "http://www.w3.org/2000/svg"; function svgElement(tag, attributes) { const el = document.createElementNS(NS, tag); Object.keys(attributes).forEach(function(key) { el.setAttribute(key, attributes[key]); }); return el; } function createBat() { const bat = document.createElement("div"); bat.className = "bat"; const svg = svgElement("svg", { viewBox: "0 0 110 65" }); // Left wing const leftWing = svgElement("path", { class: "wing left-wing", d: "M52 32 Q35 5 10 15 Q20 20 5 33 Q20 29 25 42 Q35 30 52 32Z" }); // Right wing const rightWing = svgElement("path", { class: "wing right-wing", d: "M58 32 Q75 5 100 15 Q90 20 105 33 Q90 29 85 42 Q75 30 58 32Z" }); // Body const body = svgElement("ellipse", { class: "body", cx: "55", cy: "33", rx: "9", ry: "14" }); // Ears const earLeft = svgElement("path", { class: "ear", d: "M49 25 L46 13 L54 21Z" }); const earRight = svgElement("path", { class: "ear", d: "M61 25 L64 13 L56 21Z" }); // Eyes const eyeLeft = svgElement("circle", { class: "eye", cx: "52", cy: "29", r: "1.5" }); const eyeRight = svgElement("circle", { class: "eye", cx: "58", cy: "29", r: "1.5" }); svg.appendChild(leftWing); svg.appendChild(rightWing); svg.appendChild(body); svg.appendChild(earLeft); svg.appendChild(earRight); svg.appendChild(eyeLeft); svg.appendChild(eyeRight); bat.appendChild(svg); container.appendChild(bat); const rect = scene.getBoundingClientRect(); const scale = .3 + Math.random() * 1.1; const data = { element: bat, x: -150 - Math.random() * rect.width, y: 120 + Math.random() * (rect.height * .55), speed: 35 + Math.random() * 85, scale: scale, phase: Math.random() * Math.PI * 2, wave: 10 + Math.random() * 25, frequency: .6 + Math.random() * 1.5 }; bat.style.opacity = .35 + scale * .5; // Individual wing-flap speeds const duration = .22 + Math.random() * .25; leftWing.style.animationDuration = duration + "s"; rightWing.style.animationDuration = duration + "s"; bats.push(data); } function addColony(count) { for (let i = 0; i < count; i++) { createBat(); } } function animate(timestamp) { if (!lastTime) lastTime = timestamp; const dt = Math.min((timestamp - lastTime) / 1000, .05); lastTime = timestamp; if (!paused) { const rect = scene.getBoundingClientRect(); bats.forEach(function(bat) { bat.x += bat.speed * dt * speedMultiplier; bat.phase += dt * bat.frequency * speedMultiplier; const yOffset = Math.sin(bat.phase) * bat.wave; if (bat.x > rect.width + 150) { bat.x = -150 - Math.random() * 250; bat.y = 100 + Math.random() * (rect.height * .6); } bat.element.style.transform = "translate(" + bat.x + "px," + (bat.y + yOffset) + "px) scale(" + bat.scale + ")"; }); } requestAnimationFrame(animate); } addButton.addEventListener("click", function() { if (bats.length < 60) { addColony(Math.min(8, 60 - bats.length)); } }); speedButton.addEventListener("click", function() { speedMultiplier = speedMultiplier === 1 ? 2 : 1; speedButton.textContent = speedMultiplier === 1 ? "Speed: Normal" : "Speed: Fast"; bats.forEach(function(bat) { const wings = bat.element.querySelectorAll(".wing"); wings.forEach(function(wing) { wing.style.animationDuration = (speedMultiplier === 2 ? .16 : .32) + "s"; }); }); }); pauseButton.addEventListener("click", function() { paused = !paused; pauseButton.textContent = paused ? "Resume" : "Pause"; scene.style.setProperty( "--animation-state", paused ? "paused" : "running" ); document.querySelectorAll(".wing").forEach(function(wing) { wing.style.animationPlayState = paused ? "paused" : "running"; }); }); // Initial colony addColony(18); requestAnimationFrame(animate);
terminal
JavaScript Console
Preview
Clear
close
›
Run