Interesting, I solved it differently, by just randomly selecting the order in which belowLeft and belowRight are checked, inside the updatePixel function:
updatePixel(i) {
const below = i + this.width;
const belowLeft = below - 1;
const belowRight = below + 1;
// flag to indicate if we checked the left side already
let checkedLeft = false;
if (this.isEmpty(below)) {
swap(i, below);
// check the left side first with 50 % prob (ltr)
} else if (Math.random() <= 0.5 && this.isEmpty(belowLeft)) {
swap(i, belowLeft);
// indicate we checked the left side already
checkedLeft = true;
// check the right side first with 50 % prob
} else if (this.isEmpty(belowRight)) {
swap(i, belowRight);
// if we haven't checked the left side earlier, check it now (rtl)
} else if (!checkedLeft && window.sandgrid[belowLeft] == 1)
swap(i, belowLeft);
}
I may be testing wrong, but I believe that approach causes dropping a steady stream of sand on the right side of a cone to produce very strange falling behaviour as compared to the left, because the stream is more than one pixel wide. Looks like you changed some other bits around so you may have addressed this some other way.