render = {
const particleContext = DOM.context2d(width, height);
const randomWalkParticles = Array.from({length: activeParticles},
() => [Math.random() * width,
Math.random() * height,
(Math.random() - 0.5),
(Math.random() - 0.5)]);
const minDistance2 = minDistance * minDistance;
const maxDistance2 = maxDistance * maxDistance;
let iterationCountBeforeFade = 0;
while(true){
iterationCountBeforeFade++;
if (iterationCountBeforeFade===3) {
iterationCountBeforeFade = 0;
particleContext.globalCompositeOperation = "destination-out";
particleContext.fillStyle = "rgba(255,255,255,0.2)";
particleContext.fillRect(0,0,width,height);
particleContext.globalCompositeOperation = "source-over";
}
for (let i = 0; i < activeParticles; ++i) {
for (let j = i + 1; j < activeParticles; ++j) {
const pi = randomWalkParticles[i];
const pj = randomWalkParticles[j];
const dx = pi[0] - pj[0];
const dy = pi[1] - pj[1];
const d2 = dx * dx + dy * dy;
if (d2 < maxDistance2) {
let alpha = d2 > minDistance2 ? (maxDistance2 - d2) / (maxDistance2 - minDistance2) : 1;
particleContext.strokeStyle= `hsla(220, 53%, 28%, ${alpha})`;
particleContext.beginPath();
particleContext.moveTo(pi[0], pi[1]);
particleContext.lineTo(pj[0], pj[1]);
particleContext.stroke();
particleContext.closePath();
}
}
}
yield particleContext.canvas;
for (const p of randomWalkParticles) {
p[0] += p[2];
p[1] += p[3];
if (p[0] < (0 - maxDistance)) p[0] = width + maxDistance;
else if (p[0] > (width + maxDistance)) p[0] = 0 - maxDistance;
if (p[1] < (0 - maxDistance)) p[1] = height + maxDistance;
else if (p[1] > (height + maxDistance)) p[1] = 0 - maxDistance;
p[2] += 0.3 * (Math.random() - 0.5) - .01 * p[2];
p[3] += 0.3 * (Math.random() - 0.5) - .01 * p[3];
}
}
}