Particles, wall collision, wacky peer-collisions, particle-pursuit. Click anywhere to spawn a swarm :)
var w=a.width,h=a.height,M=Math,r=M.random,s=M.abs,p=[],n=Date.now,B=function(z){c.fillStyle="rgba(0,0,0,"+z;c.fillRect(0,0,w,h)},V=w/2,G=h/2,I=0;b.onclick=function(e){for(i=0;i<20;i++)p.push({X:80*(r()-r())+e.clientX,Y:80*(r()-r())+e.clientY,C:[99+r()*99|0,99+r()*99|0,99+r()*99|0],L:r()*4-2,K:r()*4-2})};B(1),function l(){B(.1);p.map(function($,i){G=h/2+M.sin(I+n()/2E3)*h/3+M.sin(n()/70)*7;V=w/2+M.cos(I+10+n()/3E3)*w/3;with($)s((Y+=K+=M.sin(n())/5)-h/2+K)>h/2&&(K/=-2),s((X+=L+=M.cos(n())/5)-w/2+L)>w/2&&(L/=-2),c.fillStyle="rgb("+C.join(","),c.fillRect(X,Y,7,7),s(G-Y)<100&&s(V-X)<100&&(Y+=(G-Y)/30)&&(X+=(V-X)/30),s(G-Y)<7&&s(V-X)<7&&(I=r()*80),c.fillRect(V,G,2,2);for(W=j=p.length-1;j>=0;j--){with(p[j])i!==j&&(X/50|0)==($.X/50|0)&&(Y/50|0)==($.Y/50|0)&&(P=L)&&(O=K)&&(L=$.L)&&($.L=P)&&(K=$.K)&&($.K=O)&&(W=0);if(!W)break}});requestAnimationFrame(l)}();
dmFyIHc9YS53aWR0aCxoPWEuaGVpZ2h0LE09TWF0aCxyPU0ucmFuZG9tLHM9TS5hYnMscD1bXSxuPURhdGUubm93LEI9ZnVuY3Rpb24oeil7Yy5maWxsU3R5bGU9InJnYmEoMCwwLDAsIit6O2MuZmlsbFJlY3QoMCwwLHcsaCl9LFY9dy8yLEc9aC8yLEk9MDtiLm9uY2xpY2s9ZnVuY3Rpb24oZSl7Zm9yKGk9MDtpPDIwO2krKylwLnB1c2goe1g6ODAqKHIoKS1yKCkpK2UuY2xpZW50WCxZOjgwKihyKCktcigpKStlLmNsaWVudFksQzpbOTkrcigpKjk5fDAsOTkrcigpKjk5fDAsOTkrcigpKjk5fDBdLEw6cigpKjQtMixLOnIoKSo0LTJ9KX07QigxKSxmdW5jdGlvbiBsKCl7QiguMSk7cC5tYXAoZnVuY3Rpb24oJCxpKXtHPWgvMitNLnNpbihJK24oKS8yRTMpKmgvMytNLnNpbihuKCkvNzApKjc7Vj13LzIrTS5jb3MoSSsxMCtuKCkvM0UzKSp3LzM7d2l0aCgkKXMoKFkrPUsrPU0uc2luKG4oKSkvNSktaC8yK0spPmgvMiYmKEsvPS0yKSxzKChYKz1MKz1NLmNvcyhuKCkpLzUpLXcvMitMKT53LzImJihMLz0tMiksYy5maWxsU3R5bGU9InJnYigiK0Muam9pbigiLCIpLGMuZmlsbFJlY3QoWCxZLDcsNykscyhHLVkpPDEwMCYmcyhWLVgpPDEwMCYmKFkrPShHLVkpLzMwKSYmKFgrPShWLVgpLzMwKSxzKEctWSk8NyYmcyhWLVgpPDcmJihJPXIoKSo4MCksYy5maWxsUmVjdChWLEcsMiwyKTtmb3IoVz1qPXAubGVuZ3RoLTE7aj49MDtqLS0pe3dpdGgocFtqXSlpIT09aiYmKFgvNTB8MCk9PSgkLlgvNTB8MCkmJihZLzUwfDApPT0oJC5ZLzUwfDApJiYoUD1MKSYmKE89SykmJihMPSQuTCkmJigkLkw9UCkmJihLPSQuSykmJigkLks9TykmJihXPTApO2lmKCFXKWJyZWFrfX0pO3JlcXVlc3RBbmltYXRpb25GcmFtZShsKX0oKTs=
var w=a.width,h=a.height,M=Math,r=M.random,s=M.abs,p=[],n=Date.now,
B=function(z){c.fillStyle="rgba(0,0,0,"+z;c.fillRect(0,0,w,h)}, V=w/2, G=h/2, I=0;
b.onclick= function(e){
for(i=0;i<20;i++)
//Generate Particles
//with L being the X-velocity, and K being Y-velocity
p.push({X:80*(r()-r())+e.clientX,Y:80*(r()-r())+e.clientY,C:[99+r()*99|0,99+r()*99|0,99+r()*99|0],L:r()*4-2,K:r()*4-2})};
//Blackens the canvas at first
B(1),
function l(){B(.1);
p.map(function($,i){
//Bait Position
G = h/2+ M.sin(I+ n()/2000 ) *h/3 + M.sin(n()/70) *7 ; V = w/2 + M.cos(I + 10+ n()/3000 )*w/3;
//wall bounce
with($)
s((Y+=K+=M.sin(n())/5)-h/2+K)>h/2 && (K/=-2),
s((X+=L+=M.cos(n())/5)-w/2+L)>w/2 && (L/=-2),
//Render Particles
c.fillStyle="rgb("+C.join(","),
c.fillRect(X,Y,7,7),
//Bait Chase
s(G-Y)<100 && (s(V-X)<100) && (Y += (G-Y)/30) && (X += (V-X)/30),
s(G-Y)<7 && (s(V-X)<7) && (I= r()*80),
//Render Bait
c.fillRect(V,G,2,2);
//Peer-Collission
for(W=j=p.length-1;j>=0;j--) {
with(p[j]) (i!==j) && ((X/50|0) == ($.X/50|0)) && ((Y/50|0) == ($.Y/50|0)) && (P=L) && (O=K) && (L=$.L) && ($.L=P) && (K=$.K) && ($.K=O) && (W=0);if(!W)break;
}
});
requestAnimationFrame(l)
}()