flowVis = {
const size = Math.min(width, 350);
const ctx = DOM.context2d(size, size);
ctx.canvas.style.border = "solid 1px black";
ctx.shadowColor = "#fff";
ctx.shadowBlur = 5;
const particleCtx = DOM.context2d(size, size);
let time = performance.now();
while (true) {
const now = performance.now();
const dt = (now - time) / 1000;
time = now;
const t = Math.sin(0.5 * now / 1000);
const field = (x, y) => {
const v0 = fieldProps.fieldA(x, y);
const v1 = fieldProps.fieldB(x, y);
return interpolateVector(v0, v1, fieldProps.interpolate === "yes" ? t : 0);
};
const fadeOut = Math.max(1, particleProps.fadeOut * Math.floor(100 * dt));
reduceOpacity(particleCtx, fadeOut);
particles.forEach((particle) => {
updateParticle(particle, field, dt, particleProps.speed * 100 / size);
drawParticle(particleCtx, particle);
});
const image = await createImage(ctx, size * 0.5, size * 0.5, field, fieldProps.alphaScale);
ctx.clearRect(0, 0, size, size);
ctx.drawImage(image, 0, 0, size, size);
ctx.shadowBlur = 5;
drawArrowGrid(ctx, field, arrowProps.gridSize, arrowProps.size);
ctx.shadowBlur = 0;
ctx.drawImage(particleCtx.canvas, 0, 0, size, size);
yield ctx.canvas;
}
}