Skip to content

Instantly share code, notes, and snippets.

@zzstoatzz
Last active December 14, 2024 08:35
Show Gist options
  • Save zzstoatzz/b8ec0f0b8c9b11457edd2d2dcdb49b86 to your computer and use it in GitHub Desktop.
Save zzstoatzz/b8ec0f0b8c9b11457edd2d2dcdb49b86 to your computer and use it in GitHub Desktop.
html particles impl
<html>
<body style="margin:0;overflow:hidden;background:#000;">
<canvas id="c"></canvas>
<div style="position:fixed;top:1em;right:1em;background:rgba(0,0,0,0.85);color:#fff;padding:1.5em;border-radius:8px;min-width:200px;box-shadow:0 2px 10px rgba(0,0,0,0.5);">
<h3 style="margin:0 0 1em 0;font-family:system-ui;font-weight:400;">Particle Controls</h3>
<label style="display:block;margin-bottom:0.5em;font-family:system-ui;">Count: <span id="v" style="color:#8FBC8F;"></span></label>
<input id="count" type="range" min="10" max="2000" value="500" step="10" style="width:100%;margin-bottom:1em;">
<label style="display:block;margin-bottom:0.5em;font-family:system-ui;">Attraction: <span id="fv" style="color:#87CEEB;"></span></label>
<input id="force" type="range" min="-10000" max="10000" value="0" step="10" style="width:100%;">
</div>
<script>
const can=document.getElementById('c'),ctx=can.getContext('2d');
let w,h,ps=[],cnt=500,force=0;
const colors=['#8FBC8F','#20B2AA','#87CEEB'];
function R(){w=can.width=innerWidth;h=can.height=innerHeight;init();}
onresize=R;R();
function init(){
ps=[];
for(let i=0;i<cnt;i++)ps.push({
x:Math.random()*w,
y:Math.random()*h,
vx:(Math.random()-0.5)*2,
vy:(Math.random()-0.5)*2,
r:Math.random()*0.8+0.4,
c:colors[i%3]
});
}
function anim(){
ctx.fillStyle='rgba(0,0,0,0.15)';
ctx.fillRect(0,0,w,h);
for(let i=0;i<ps.length;i++){
const p=ps[i];
for(let j=i+1;j<ps.length;j++){
const p2=ps[j];
const dx=p2.x-p.x,dy=p2.y-p.y;
const d=Math.sqrt(dx*dx+dy*dy);
if(d<100){
const f=force/(d*100);
p.vx+=dx*f;p.vy+=dy*f;
p2.vx-=dx*f;p2.vy-=dy*f;
}
}
p.x+=p.vx;p.y+=p.vy;
if(p.x<0||p.x>w)p.vx=-p.vx;
if(p.y<0||p.y>h)p.vy=-p.vy;
p.vx*=0.99;p.vy*=0.99;
ctx.beginPath();
ctx.arc(p.x,p.y,p.r,0,7);
ctx.fillStyle=p.c;
ctx.fill();
}
requestAnimationFrame(anim);
}
anim();
const rng=document.getElementById('count'),val=document.getElementById('v');
const forceInput=document.getElementById('force'),forceVal=document.getElementById('fv');
rng.oninput=()=>{cnt=rng.value;val.textContent=cnt;init();};
forceInput.oninput=()=>{force=forceInput.value/1000;forceVal.textContent=forceInput.value;};
val.textContent=cnt;
forceVal.textContent='0';
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment