JSFiddle - React, Tailwind, and code Playground

by brigand

HTML

<script src="https://unpkg.com/[email protected]/index.js"></script>
<div class="panel">
  <h2>Double Background Noise Generator</h2>
  <style id="css-out"></style>
</div>

CSS

html,
body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  background-color: transparent;
  font-family: Arial, sans;
}

html {
  background-color: #f9f9ff;
}

body {
  display: flex;
  justify-content: center;
  align-items: center;
}

.panel {
  width: 30em;
  max-width: 95vw;
  background: white;
  box-shadow: 0 0 3px #666;
  padding: 1em;
  border-radius: 1em;
  position: relative;
}

.panel::after {
  content: '';
  display: block;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  box-shadow: 0 0 3em rgba(0, 0, 0, 0.2);
  border-radius: 3.5em;
  z-index: -1;
  background: transparent;
}

#css-out {
  display: block;
  white-space: pre;
  overflow-y: visible;
  overflow-x: scroll;
  max-width: 100%;
  font-family: monospace;
  color: #992266;
}

JavaScript

const cssOut = document.querySelector('#css-out');

function main() {
  const first = makeNoise(64, 64);
  const second = makeNoise(139, 92);

  let css = [
    `html {`,
    `  background-image: url("${first}");`,
    `  background-size: 63px 67px;`,
    `}`,
    ``,
    `body {`,
    `  background-image: url("${second}");`,
    `  background-size: 139.3 90.3px;`,
    `}`,
  ].join('\n');
  cssOut.innerHTML = css;
}

function onCanvas(width, height, impl) {
  const canvas = document.createElement('canvas');
  canvas.width = width;
  canvas.height = height;
  const ctx = canvas.getContext('2d');
  impl(ctx);
  return canvas.toDataURL()
}

function makeNoise(width, height) {
  const SCALE = 3;
  const pixels = width * height;
  return onCanvas(width, height, (ctx) => {
    const imageData = ctx.getImageData(0, 0, width, height);
    const noise = new Noise();
    noise.seed(Math.random());

    const perlin3 = (x, y, z) => {
      const n = noise.perlin3(x, y, z);
      const positive = (n + 1) / 2
      return positive;
    }

    for (let x = 1; x < width; x += 1) {
      for (let y = 1; y < height; y += 1) {
        if (Math.random() < 1 / 33) {
          const px = x / width * SCALE;
          const py = y / height * SCALE;

          const hue = perlin3(px, py, 10);
          const saturation = perlin3(px, py, 2) * 0.17;
          const lightness = (perlin3(px, py, 1) * 0.6) + 0.2;
          const opacity = perlin3(px, py, 2) * 0.35 + 0.05;
          const alpha = Math.floor(opacity * 256)

          const [r, g, b] = hslToRgb(hue, saturation, lightness)
          const index = x * 4 + (y * width * 4)

          imageData.data[index] = r
          imageData.data[index + 1] = g
          imageData.data[index + 2] = b
          imageData.data[index + 3] = alpha;

        }
      }
    }

    ctx.putImageData(imageData, 0, 0)
  });
}

// all arguments in [0, 1]
function hslToRgb(h, s, l) {
  h = h * 360;

  let c = (1 - Math.abs(2 * l - 1)) * s,
    x = c * (1 -...