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
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>Interactive Particle Galaxy</title> </head> <body> <!-- Start your code here --> <div class="galaxy-wrap"> <canvas id="galaxy"></canvas> <div class="galaxy-ui"> <div> <h1>Particle Galaxy</h1> <p>Move your mouse through the stars</p> </div> <button id="burstBtn">Create Supernova</button> </div> <div class="hint">Move • Click • Explore</div> </div> <!-- End your code here --> </body> </html>
* { box-sizing: border-box; } html, body { margin: 0; width: 100%; height: 100%; overflow: hidden; background: radial-gradient(circle at 50% 45%, #172344 0%, #080d20 38%, #02040d 75%); font-family: Arial, Helvetica, sans-serif; } .galaxy-wrap { position: relative; width: 100vw; height: 100vh; } canvas { position: absolute; inset: 0; width: 100%; height: 100%; } .galaxy-ui { position: absolute; top: 28px; left: 32px; right: 32px; display: flex; align-items: flex-start; justify-content: space-between; pointer-events: none; } .galaxy-ui h1 { margin: 0; color: white; font-size: 26px; font-weight: 600; letter-spacing: -0.5px; } .galaxy-ui p { margin: 7px 0 0; color: rgba(255, 255, 255, 0.55); font-size: 13px; } button { pointer-events: auto; padding: 10px 16px; border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 999px; background: rgba(255, 255, 255, 0.08); color: white; backdrop-filter: blur(12px); font-size: 12px; cursor: pointer; transition: background 0.25s ease, transform 0.25s ease; } button:hover { background: rgba(255, 255, 255, 0.16); transform: translateY(-2px); } .hint { position: absolute; bottom: 25px; left: 50%; transform: translateX(-50%); color: rgba(255, 255, 255, 0.35); font-size: 11px; letter-spacing: 3px; text-transform: uppercase; pointer-events: none; }
const canvas = document.getElementById("galaxy"); const ctx = canvas.getContext("2d"); let width; let height; let centerX; let centerY; const particles = []; const explosions = []; const mouse = { x: null, y: null, radius: 150 }; function resizeCanvas() { const ratio = window.devicePixelRatio || 1; width = window.innerWidth; height = window.innerHeight; canvas.width = width * ratio; canvas.height = height * ratio; canvas.style.width = width + "px"; canvas.style.height = height + "px"; ctx.setTransform(ratio, 0, 0, ratio, 0, 0); centerX = width / 2; centerY = height / 2; } resizeCanvas(); window.addEventListener("resize", resizeCanvas); class Particle { constructor() { this.reset(true); } reset(initial = false) { this.angle = Math.random() * Math.PI * 2; this.distance = Math.pow(Math.random(), 0.6) * Math.min(width, height) * 0.47; this.speed = 0.0004 + Math.random() * 0.0012; this.size = Math.random() * 1.8 + 0.3; this.depth = Math.random() * 0.7 + 0.3; this.offset = (Math.random() - 0.5) * this.distance * 0.45; this.opacity = Math.random() * 0.7 + 0.25; this.twinkle = Math.random() * Math.PI * 2; this.colorChoice = Math.random(); if (!initial) { this.angle = Math.random() * Math.PI * 2; } } update() { this.angle += this.speed * this.depth; this.twinkle += 0.03; let stretchX = 1.35; let stretchY = 0.48; let x = centerX + Math.cos(this.angle) * this.distance * stretchX; let y = centerY + Math.sin(this.angle) * this.distance * stretchY + this.offset; // Slight spiral curvature y += Math.sin( this.angle * 2 + this.distance * 0.01 ) * 8; // Mouse gravity if (mouse.x !== null) { const dx = mouse.x - x; const dy = mouse.y - y; const dist = Math.sqrt( dx * dx + dy * dy ); if (dist < mouse.radius) { const force = (mouse.radius - dist) / mouse.radius; x += dx * force * 0.14; y += dy * force * 0.14; } } this.x = x; this.y = y; } draw() { const glow = Math.sin(this.twinkle) * 0.15 + this.opacity; let color; if (this.colorChoice < 0.15) { color = "120, 170, 255"; } else if (this.colorChoice < 0.25) { color = "190, 150, 255"; } else if (this.colorChoice < 0.32) { color = "255, 180, 130"; } else { color = "220, 235, 255"; } ctx.beginPath(); ctx.arc( this.x, this.y, this.size * this.depth, 0, Math.PI * 2 ); ctx.fillStyle = `rgba(${color}, ${Math.max( 0.1, glow )})`; ctx.shadowBlur = this.size > 1.2 ? 10 : 0; ctx.shadowColor = `rgba(${color}, 0.8)`; ctx.fill(); } } class ExplosionParticle { constructor(x, y) { this.x = x; this.y = y; this.angle = Math.random() * Math.PI * 2; this.speed = Math.random() * 5 + 1; this.velocityX = Math.cos(this.angle) * this.speed; this.velocityY = Math.sin(this.angle) * this.speed; this.life = 1; this.decay = Math.random() * 0.015 + 0.008; this.size = Math.random() * 2 + 0.5; } update() { this.x += this.velocityX; this.y += this.velocityY; this.velocityX *= 0.985; this.velocityY *= 0.985; this.life -= this.decay; } draw() { ctx.beginPath(); ctx.arc( this.x, this.y, this.size, 0, Math.PI * 2 ); ctx.fillStyle = `rgba(180, 210, 255, ${this.life})`; ctx.shadowBlur = 15; ctx.shadowColor = "rgba(130, 170, 255, 0.8)"; ctx.fill(); } } function createGalaxy() { particles.length = 0; let amount = Math.min( 1200, Math.floor( (width * height) / 900 ) ); for (let i = 0; i < amount; i++) { particles.push( new Particle() ); } } createGalaxy(); function createSupernova(x, y) { for (let i = 0; i < 110; i++) { explosions.push( new ExplosionParticle(x, y) ); } } function drawGalaxyCore() { const gradient = ctx.createRadialGradient( centerX, centerY, 0, centerX, centerY, 180 ); gradient.addColorStop( 0, "rgba(255,255,255,0.65)" ); gradient.addColorStop( 0.08, "rgba(150,190,255,0.28)" ); gradient.addColorStop( 0.35, "rgba(90,80,220,0.08)" ); gradient.addColorStop( 1, "rgba(0,0,0,0)" ); ctx.beginPath(); ctx.arc( centerX, centerY, 180, 0, Math.PI * 2 ); ctx.fillStyle = gradient; ctx.fill(); } function animate() { requestAnimationFrame(animate); ctx.clearRect( 0, 0, width, height ); ctx.shadowBlur = 0; drawGalaxyCore(); for (const particle of particles) { particle.update(); particle.draw(); } for ( let i = explosions.length - 1; i >= 0; i-- ) { const particle = explosions[i]; particle.update(); particle.draw(); if (particle.life <= 0) { explosions.splice(i, 1); } } ctx.shadowBlur = 0; } animate(); window.addEventListener( "mousemove", (event) => { mouse.x = event.clientX; mouse.y = event.clientY; } ); window.addEventListener( "mouseleave", () => { mouse.x = null; mouse.y = null; } ); canvas.addEventListener( "click", (event) => { createSupernova( event.clientX, event.clientY ); } ); document .getElementById("burstBtn") .addEventListener( "click", () => { createSupernova( centerX, centerY ); } );
terminal
JavaScript Console
Preview
Clear
close
›
Run