Code snippet ported from the artist @KilledByAPixel. Check out his stuff
const c = document.querySelector("canvas") as HTMLCanvasElement;
const x = c.getContext("2d") as CanvasRenderingContext2D;
const S = Math.sin;
let t = 0;
// Cache style and dimensions
let color = getComputedStyle(c).color;
const { width, height } = c;
function draw() {
t += 0.01;
// Faster clear: reset transform and clear rect instead of resizing canvas
x.setTransform(1, 0, 0, 1, 0, 0);
x.clearRect(0, 0, width, height);
x.fillStyle = color;
let j = 47, T = 170, s = 1.02, i: number, h: number, w: number, X: number, y: number, r: number;
// Setup Initial State
x.translate(200, 400);
x.scale(0.5, 0.5);
for (; j--; x.scale(s, s)) {
// Hoist j-dependent math out of the nested loop
const j5 = j ** 5;
const j6 = j ** 6;
h = T + j6 % T;
for (i = h; (w = i / 3) > 0.1; i--) {
y = h - i;
X = j5 - t * T;
// Drawing the "structure"
x.fillRect(
(((X) + 500) % 2500) - 500 - (h * y) % w - T,
460 - y,
w,
3 / j ** 0.6
);
// Drawing the "particles" - cache r
r = (i % 5) + 2;
x.clearRect(
(((X + i * T) + 500) % 2500) - 500 + S(t * 3 + i) * 9,
(t * 99 + i ** 1.5) % 460,
r,
r
);
}
}
requestAnimationFrame(draw);
}
draw();