<!doctype html>
<title>Particle Background</title>
<style>
html,body{height:100%;margin:0;background:#000;overflow:hidden}
#canvas{display:block;position:fixed;inset:0;z-index:0}
.controls{position:fixed;left:12px;bottom:12px;z-index:10;background:rgba(255,255,255,0.06);backdrop-filter:blur(6px);padding:8px;border-radius:10px;color:#fff;font-family:system-ui;font-size:13px}
.btn{background:rgba(255,255,255,0.08);border:0;padding:6px 10px;border-radius:8px;color:#fff;cursor:pointer}
.btn:active{transform:scale(0.98)}
</style>
Pause
Density
<script>
(() => {
const c = document.getElementById('canvas');
const ctx = c.getContext('2d', { alpha: true });
let DPR = Math.max(1, window.devicePixelRatio || 1);
function resize() {
DPR = Math.max(1, window.devicePixelRatio || 1);
c.width = Math.floor(innerWidth * DPR);
c.height = Math.floor(innerHeight * DPR);
c.style.width = innerWidth + 'px';
c.style.height = innerHeight + 'px';
ctx.setTransform(DPR,0,0,DPR,0,0);
}
addEventListener('resize', resize);
resize();
// Config
const palette = ['#FFD54A','#FF6B6B','#9FA8DA','#B39DDB','#90CAF9']; // yellow, red, blue, purple...
let PARTICLE_COUNT = 900; // adjustable by slider
const MAX_SPEED = 0.35;
const GRAVITY = 0.0005;
const FRICTION = 0.9999;
// helper: gaussian random for cluster
function gaussian(mean=0, std=1){
// Box-Muller
let u=0,v=0;
while(u===0) u=Math.random();
while(v===0) v
<!doctype html>
<title>Particle Background</title> <style> html,body{height:100%;margin:0;background:#000;overflow:hidden} #canvas{display:block;position:fixed;inset:0;z-index:0} .controls{position:fixed;left:12px;bottom:12px;z-index:10;background:rgba(255,255,255,0.06);backdrop-filter:blur(6px);padding:8px;border-radius:10px;color:#fff;font-family:system-ui;font-size:13px} .btn{background:rgba(255,255,255,0.08);border:0;padding:6px 10px;border-radius:8px;color:#fff;cursor:pointer} .btn:active{transform:scale(0.98)} </style>