Advertisement
here2share

Color Gradient Animation

Aug 11th, 2024
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>Color Gradient Animation</title>
  7.     <style>
  8.         body {
  9.             margin: 0;
  10.             overflow: hidden;
  11.             display: flex;
  12.             justify-content: center;
  13.             align-items: center;
  14.             height: 100vh;
  15.             background-color: #f0f0f0;
  16.         }
  17.         canvas {
  18.             border: 1px solid #000;
  19.         }
  20.     </style>
  21. </head>
  22. <body>
  23.     <canvas id="colorCanvas"></canvas>
  24.     <script>
  25.         const canvas = document.getElementById('colorCanvas');
  26.         const ctx = canvas.getContext('2d');
  27.  
  28.         const ww = 1200;
  29.         const hh = 600;
  30.         const zz = 10;
  31.         const w0 = Math.floor(ww / zz);
  32.         const h0 = Math.floor(hh / zz);
  33.  
  34.         canvas.width = ww;
  35.         canvas.height = hh;
  36.  
  37.         const colors = [
  38.             [0, 0, 0], [255, 0, 0], [255, 165, 0], [255, 255, 0],
  39.             [75, 0, 130], [0, 0, 255], [0, 128, 0], [255, 255, 255]
  40.         ];
  41.  
  42.         const rx = (4 - 1) / ww;
  43.         const ry = (2 - 1) / hh;
  44.  
  45.         function bicubic(c00, c10, c01, c11, x, y) {
  46.             const w00 = (1 - x) * (1 - y);
  47.             const w10 = x * (1 - y);
  48.             const w01 = (1 - x) * y;
  49.             const w11 = x * y;
  50.             const r = Math.round(w00 * c00[0] + w10 * c10[0] + w01 * c01[0] + w11 * c11[0]);
  51.             const g = Math.round(w00 * c00[1] + w10 * c10[1] + w01 * c01[1] + w11 * c11[1]);
  52.             const b = Math.round(w00 * c00[2] + w10 * c10[2] + w01 * c01[2] + w11 * c11[2]);
  53.             return [r, g, b];
  54.         }
  55.  
  56.         function transitionColor(x, y) {
  57.             x *= zz;
  58.             y *= zz;
  59.             const xRatio = x * rx;
  60.             const yRatio = y * ry;
  61.             const xIndex = Math.floor(xRatio);
  62.             const yIndex = Math.floor(yRatio) * 4;
  63.             const c00 = colors[xIndex + yIndex];
  64.             const c10 = colors[(xIndex + 1) + yIndex];
  65.             const c01 = colors[xIndex + (yIndex + 4)];
  66.             const c11 = colors[(xIndex + 1) + (yIndex + 4)];
  67.             const xFraction = xRatio - xIndex;
  68.             const yFraction = yRatio - yIndex;
  69.             return bicubic(c00, c10, c01, c11, xFraction, yFraction);
  70.         }
  71.  
  72.         let rgb = new Array(w0 * h0).fill([128, 128, 128]);
  73.         const xy2rgb = new Map();
  74.         const XYo = [];
  75.  
  76.         for (let y = 0; y < h0; y++) {
  77.             for (let x = 0; x < w0; x++) {
  78.                 rgb[x + y * w0] = transitionColor(x, y);
  79.                 xy2rgb.set(`${x},${y}`, x + y * w0);
  80.                 XYo.push([x, y]);
  81.             }
  82.         }
  83.  
  84.         function makeAlive(x, y) {
  85.             const nn0 = [[-1, 0], [0, -1], [0, 1], [1, 0]];
  86.             const n0 = rgb[xy2rgb.get(`${x},${y}`)];
  87.             const nn = [];
  88.  
  89.             for (const [i, j] of nn0) {
  90.                 const x0 = x + i;
  91.                 const y0 = y + j;
  92.                 if (xy2rgb.has(`${x0},${y0}`)) {
  93.                     const nx = rgb[xy2rgb.get(`${x0},${y0}`)];
  94.                     const colorDiff = Math.sqrt(
  95.                         (nx[0] - n0[0]) ** 2 + (nx[1] - n0[1]) ** 2 + (nx[2] - n0[2]) ** 2
  96.                     );
  97.                     nn.push([colorDiff, [x0, y0], [i, j]]);
  98.                 }
  99.             }
  100.  
  101.             nn.sort((a, b) => a[0] - b[0]);
  102.             const [, [x0, y0]] = nn[0];
  103.             const index1 = xy2rgb.get(`${x},${y}`);
  104.             const index2 = xy2rgb.get(`${x0},${y0}`);
  105.             [rgb[index1], rgb[index2]] = [rgb[index2], rgb[index1]];
  106.         }
  107.  
  108.         function shuffleArray(array) {
  109.             for (let i = array.length - 1; i > 0; i--) {
  110.                 const j = Math.floor(Math.random() * (i + 1));
  111.                 [array[i], array[j]] = [array[j], array[i]];
  112.             }
  113.         }
  114.  
  115.         function animate() {
  116.             shuffleArray(XYo);
  117.             for (const [x, y] of XYo) {
  118.                 makeAlive(x, y);
  119.             }
  120.  
  121.             const imageData = ctx.createImageData(w0, h0);
  122.             for (let i = 0; i < rgb.length; i++) {
  123.                 const [r, g, b] = rgb[i];
  124.                 imageData.data[i * 4] = r;
  125.                 imageData.data[i * 4 + 1] = g;
  126.                 imageData.data[i * 4 + 2] = b;
  127.                 imageData.data[i * 4 + 3] = 255;
  128.             }
  129.  
  130.             ctx.putImageData(imageData, 0, 0);
  131.             ctx.drawImage(canvas, 0, 0, w0, h0, 0, 0, ww, hh);
  132.  
  133.             requestAnimationFrame(animate);
  134.         }
  135.  
  136.         animate();
  137.  
  138.         document.addEventListener('keydown', (event) => {
  139.             if (event.code === 'Space') {
  140.                 shuffleArray(rgb);
  141.             }
  142.         });
  143.     </script>
  144. </body>
  145. </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement