Solids

Details

Description

The spacing on this one was a happy accident. I was trying to add padding where the overall field stayed the same time and the individual cells had padding (which really would have been a border), but I tried margin and really liked the effect.

I'm using bitty for the basic element connections. The code that does all the stuff is here below.

The HTML

<bitty-1-3 data-connect="PageContent" data-send="start">
  <div data-receive="status">NOT SOLID</div>
  <div data-receive="start"></div>
</bitty-1-3>

The CSS

[data-receive=start] {
  display: flex;
  flex-wrap: wrap;
}

[data-receive="shuffle|update"] {
  width: 10%;
  height: 3vh;
}

[data-color="0"] {
  background-color: var(--color-0);
}

[data-color="1"] {
  background-color: var(--color-1);
}

[data-color="2"] {
  background-color: var(--color-2);
}

[data-color="3"] {
  background-color: var(--color-3);
}

[data-color="4"] {
  background-color: var(--color-4);
}

.padded {
  margin: 1rem;
}

The JavaScript

const tmpl = `<div data-receive="shuffle|update"></div>`;

function randInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

class State {
  constructor() {
    this.matches = 0;
    this.max = 4;
    this.min = 0;
    this.sleep = 900;
  }
}
const s = new State();

window.PageContent = class {
  shuffle(_event, el) {
    const color = randInt(s.min, s.max);
    if (color !== 0) {
      el.classList.add("padded");
    }
    el.dataset.color = color;
  }

  async start(_event, el) {
    this.updateColors();
    for (let c = 0; c < 100; c += 1) {
      const cell = this.api.useTemplate(tmpl, {});
      await el.appendChild(cell);
    }
    this.api.forward(null, "shuffle");
    await sleep(2000);
    this.api.forward(null, "tickUpdate");
  }

  status(_event, el) {
    if (s.matches === 100) {
      el.innerHTML = "SOLID";
    } else {
      el.innerHTML = "NOT SOLID";
    }
  }

  async tickUpdate() {
    if (s.matches === 100) {
      await sleep(2000);
      this.api.forward(null, "shuffle");
      this.updateColors();
    }
    s.matches = 0;
    this.api.forward(null, "update");
    this.api.forward(null, "status");
    await sleep(s.sleep);
    this.tickUpdate();
  }

  async update(_event, el) {
    const checkColor = parseInt(el.dataset.color, 10);
    if (checkColor !== 0) {
      await sleep(randInt(0, s.sleep - 700));
      el.dataset.color = randInt(s.min, s.max);
    } else {
      el.classList.remove("padded");
      s.matches += 1;
    }
  }

  updateColors() {
    const c = randInt(0, 70) / 100;
    for (let color = 0; color < 4; color += 1) {
      const l = randInt(40, 80);
      const h = randInt(0, 360);
      document.documentElement.style.setProperty(
        `--color-${color}`,
        `oklch(${l}% ${c} ${h})`,
      );
    }
  }
};
NOT SOLID