var svg = document.getElementById('svg');
var NS = 'http://www.w3.org/2000/svg';
function se(t){ return document.createElementNS(NS,t); }
function sa(e,o){ for (var k in o) e.setAttribute(k,o[k]); }
function R(a,b){ return a + Math.random()*(b-a); }
var W=300, H=200;
var CENTERS = [];
function hexPath(cx,cy,r){
var s=[];
for (var k=0;k<6;k++){
var a = Math.PI/180*(60*k-30);
s.push((cx+r*Math.cos(a)).toFixed(1)+','+(cy+r*Math.sin(a)).toFixed(1));
}
return 'M'+s.join('L')+'Z';
}
function rebuild(){
var pw=W-16, ph=H-16;
var hr = Math.max(6, Math.min(15, pw/15));
var w = hr*Math.sqrt(3);
var rows = Math.ceil(ph/(hr*1.5))+1;
var cols = Math.ceil(pw/w)+1;
var arr=[];
for (var row=0; row<rows; row++){
for (var col=0; col<cols; col++){
var x = col*w + (row%2? w/2:0);
var y = row*hr*1.5;
if (x<=pw+w*0.5 && y<=ph+hr*0.5) arr.push({ x:x, y:y, nx:x/pw, ny:y/ph, r:hr*0.95 });
}
}
CENTERS = arr;
}
function measure(){
var r = svg.getBoundingClientRect();
W = Math.max(r.width,10); H = Math.max(r.height,10);
sa(svg,{ viewBox: '0 0 ' + W + ' ' + H });
rebuild();
}
function fieldAt(x,y,blobs){
var v=0;
for (var i=0;i<blobs.length;i++){
var b=blobs[i], dx=x-b.x, dy=y-b.y;
v += b.amp*Math.exp(-(dx*dx+dy*dy)/(2*b.s*b.s));
}
return v;
}
var BLOBS_CUR = [ { x:0.35, y:0.4, amp:1, s:0.22 }, { x:0.65, y:0.6, amp:0.8, s:0.2 } ];
function draw(){
svg.innerHTML = '';
var padL=8, padT=8;
var vals = CENTERS.map(function(c){ return fieldAt(c.nx,c.ny,BLOBS_CUR); });
var maxV = Math.max.apply(null, vals.concat([0.4]));
CENTERS.forEach(function(c,i){
var v = vals[i]/maxV;
if (v<0.04) return;
var h = se('path');
sa(h,{ d: hexPath(padL+c.x, padT+c.y, c.r), fill:'var(--accent)', 'fill-opacity': 0.08+0.9*v });
svg.appendChild(h);
});
}
function animate(target){
var from = BLOBS_CUR.map(function(b){ return { x:b.x, y:b.y, amp:b.amp, s:b.s }; });
var t0 = performance.now();
function step(t){
var p = Math.min(1,(t-t0)/900);
var e = 1-Math.pow(1-p,3);
BLOBS_CUR = from.map(function(b,i){
return { x:b.x+(target[i].x-b.x)*e, y:b.y+(target[i].y-b.y)*e, amp:b.amp+(target[i].amp-b.amp)*e, s:b.s+(target[i].s-b.s)*e };
});
draw();
if (p<1) requestAnimationFrame(step);
}
requestAnimationFrame(step);
}
function nextBlobs(){
return [
{ x:R(0.2,0.45), y:R(0.2,0.55), amp:R(0.7,1.1), s:R(0.16,0.26) },
{ x:R(0.55,0.82), y:R(0.42,0.78), amp:R(0.55,1), s:R(0.14,0.24) }
];
}
new ResizeObserver(function(){ measure(); draw(); }).observe(svg);
measure();
draw();
animate(nextBlobs());
setInterval(function(){ animate(nextBlobs()); }, 3600);