Transparency

Kicking off Weird Web October with a spin.

Details

Day 1's theme is Transparency. I'm going with semi-transparent.

This is ten copies of the same image. Each made to be semi-transparent and rotateted at a random angle to start with. Every few seconds they align themselves. The result is a non-transparent version of the image. A few seconds later, they spin to random angles again.

I'm using bitty for the basic set up. This is the rest of the code.

The HTML

<bitty-2-0 data-connect="TransparentSpinner" data-send="init">
  <div class="selfie-wrapper" data-receive="init"></div>
</bitty-2-0>

The CSS

.selfie-wrapper {
  position: relative;
  max-width: 72%;
  margin-top: 8%;
  margin-inline: auto;
}

.placeholder {
  opacity: 0;
}

.selfie {
  opacity: 20%;
  position: absolute;
  top: 0;
  left: 0;
}

.headsup {
  color: var(--warning);
  background-color: var(--link);
  position: absolute;
  top: 30%;
  left: 0;
}

main {
  margin-block: 2.2rem;
}

The JavaScript

const s = {
  rotated: true
};

function addStyles() {
  const sheet = new CSSStyleSheet();
  const lines = [...Array(10)].map((_, index) => {
    return `
:root { --layer-${index}-rotation: ${randomInt(-360, 360)}deg }
.layer-${index} {
  transform: rotate(var(--layer-${index}-rotation));
  transition:
    transform 3000ms;
}`;
  });
  const output = lines.join("\n");
  sheet.replaceSync(output);
  document.adoptedStyleSheets.push(sheet);
}

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


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

window.TransparentSpinner = class {
  bittyInit() {
    this.api.setProp("--page-visibility", "visible");
    addStyles()
  }

  async init(_event, el) {
    const images = [...Array(10)].map((_, index) => {
      return `<img src="/images/selfie-1.png" class="selfie layer-${index}" />`
    });
    images.push(
      `<img src="/images/selfie-1.png" class="placeholder" />`
    );
    images.push(
      `<div class="headsup" data-receive="rotate">Head's up - this image moves a lot.
        <br />
        <button data-send="rotate">Click here if you're okay with that</button>
      </div>`
    );
    el.innerHTML = images.join("\n");
  }

  async rotate(_event, el) {
    if (el) {
      el.hidden = true;
    }
    await sleep(300);
    if (s.rotated) {
      for (let index = 0; index < 10; index += 1) {
        document.documentElement.style.setProperty(
          `--layer-${index}-rotation`,
          `0deg`
        );
      }
      await sleep(3700);
      s.rotated = false;
      this.rotate();
    } else {
      for (let index = 0; index < 10; index += 1) {
        document.documentElement.style.setProperty(
          `--layer-${index}-rotation`,
          `${randomInt(-360, 360)}deg`
        );
      }
      await sleep(3700);
      s.rotated = true;
      this.rotate();
    }
  }
}