{
const canvas = DOM.canvas(width, width);
const gl = canvas.getContext("webgl");
const program = initShaderProgram(gl, vertexShader, fragShader);
const positionAttribLoc = gl.getAttribLocation(program, "a_position");
const resolutionUniformLoc = gl.getUniformLocation(program, "u_resolution");
gl.viewport(0, 0, width, width);
gl.useProgram(program);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
gl.enable(gl.BLEND);
gl.disable(gl.DEPTH_TEST);
gl.uniform2f(resolutionUniformLoc, width, width);
let particles = createParticles(1000);
const start = Date.now();
while (true) {
const elapsed = Date.now() - start;
const positions = [];
particles = _.chain(particles)
.union(createParticles(300))
.filter((d) => d.life)
.value();
console.log(particles.length);
const gravity = vec2.fromValues(0, -5);
_.each(particles, (d, i) => {
const { position, velocity, acceleration } = d;
const [x, y] = position;
const radius = 5;
const angle = d3.scaleLinear(
[0, 1],
[Math.PI * -3, 3 * Math.PI]
)(noise(x / 50, y / 50, elapsed / 10000));
vec2.add(
velocity,
velocity,
vec2.fromValues(radius * Math.cos(angle), radius * Math.sin(angle))
);
vec2.add(velocity, velocity, gravity);
vec2.add(position, position, velocity);
vec2.scale(velocity, velocity, 0.5);
positions.push(position[0]);
positions.push(position[1]);
d.life -= 1;
});
const positionBuffer = initPositionBuffer(gl, positions);
setPositionAttribute(gl, positionBuffer, positionAttribLoc);
gl.drawArrays(gl.POINTS, 0, particles.length);
yield Promises.delay(60, canvas);
}
}