JSFiddle - React, Tailwind, and code Playground

by Katarn

HTML

<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
<div id="content">
  <h1 style="color: crimson;">Hola mundo</h1>
  <p style="color: lime">Esto es un ejemplo con pixelado y reducción de color.</p>
  <input type="text" placeholder="hola">
</div>

<div id="fxOverlay"></div>

CSS

body {
  margin: 0;
  font-family: sans-serif;
  font-weight: bold;
}

#content {
  padding: 2rem;
}

#fxOverlay {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9999;
  width: 100vw;
  height: 100vh;
  pointer-events: none;
}

JavaScript

const gbcPalette = [
  // Verde claro a oscuro (fondo típico)
  [224, 248, 208],
  [136, 192, 112],
  [52, 104, 86],
  [8, 24, 32],
  // Rojizos
  [255, 0, 0],
  [192, 0, 0],
  [128, 0, 0],
  [64, 0, 0],
  // Azulados
  [0, 0, 255],
  [0, 0, 192],
  [0, 0, 128],
  [0, 0, 64],
  // Amarillos
  [255, 255, 0],
  [192, 192, 0],
  [128, 128, 0],
  [64, 64, 0],
  // Morados
  [255, 0, 255],
  [192, 0, 192],
  [128, 0, 128],
  [64, 0, 64],
  // Grises
  [255, 255, 255],
  [192, 192, 192],
  [128, 128, 128],
  [64, 64, 64],
  [0, 0, 0],
  // Otros tonos comunes...
];

function getClosestColor(r, g, b) {
  let minDist = Infinity;
  let closest = [0, 0, 0];
  for (const [pr, pg, pb] of gbcPalette) {
    const dist = (r - pr) ** 2 + (g - pg) ** 2 + (b - pb) ** 2;
    if (dist < minDist) {
      minDist = dist;
      closest = [pr, pg, pb];
    }
  }
  return closest;
}

function renderPixelatedOverlay() {
  const overlay = document.getElementById('fxOverlay');
  overlay.style.display = 'none';

  requestAnimationFrame(() => {
    html2canvas(document.body).then(canvas => {
      overlay.style.display = '';

      const ctx = canvas.getContext('2d');
      const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
      const data = imgData.data;

      const step = 32;
for (let i = 0; i < data.length; i += 4) {
  const [r, g, b] = [data[i], data[i + 1], data[i + 2]];
  const [nr, ng, nb] = getClosestColor(r, g, b);
  data[i] = nr;
  data[i + 1] = ng;
  data[i + 2] = nb;
}
      ctx.putImageData(imgData, 0, 0);

      const scale = 0.2;
      const tmpCanvas = document.createElement('canvas');
      tmpCanvas.width = canvas.width * scale;
      tmpCanvas.height = canvas.height * scale;
      const tmpCtx = tmpCanvas.getContext('2d');
      tmpCtx.imageSmoothingEnabled = false;
      tmpCtx.drawImage(canvas, 0, 0, tmpCanvas.width, tmpCanvas.height);

      const finalCanvas = document.createElement('canvas');
      finalCanvas.width = canvas.width;
     ...