Gotta go fast
The approach I used last time isn’t very
efficient, since it repeatedly appends new SVG elements.
Here’s a speedier approach, via drawing on a canvas 2D context:
The code is shorter, too:
const CTX = document.getElementById("chaos").getContext("2d");
CTX.fillStyle = "#027f8d";
const [XS, YS] = ((b) => {
const w = CTX.canvas.width;
const s = 0.75 * w;
const h = (s * Math.sqrt(3)) / 2;
return [
[b + 0, b + s / 2, b + s],
[b + h, b + 0, b + h],
];
})(10);
let [X, Y, ON] = [0, 0, null];
const new_xy = () => {
const [u, v] = [Math.sqrt(Math.random()), Math.random()];
X = (1 - u) * XS[0] + u * (1 - v) * XS[1] + u * v * XS[2];
Y = (1 - u) * YS[0] + u * (1 - v) * YS[1] + u * v * YS[2];
};
const draw = (x, y, r = 2) => {
CTX.beginPath();
CTX.arc(x, y, r, 0, 2 * Math.PI, false);
CTX.fill();
};
XS.forEach((x, i) => draw(x, YS[i], 4));
document.getElementById("reset").addEventListener("click", () => {
ON = clearInterval(ON);
CTX.clearRect(0, 0, CTX.canvas.width, CTX.canvas.height);
XS.forEach((x, i) => draw(x, YS[i], 4));
});
document.getElementById("start_stop").addEventListener("click", () => {
if (!ON) {
new_xy();
ON = setInterval(() => {
const i = Math.floor(XS.length * Math.random());
X += 0.5 * (XS[i] - X);
Y += 0.5 * (YS[i] - Y);
draw(X, Y);
});
} else {
ON = clearInterval(ON);
}
});