here2share

$ plasma_ref_for_py_to_js.proj.html

Nov 11th, 2022
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <!DOCTYPE html>
  2. <meta charset="utf-8" />
  3. <body
  4.   style="position: fixed; left: 0px; right: 0px; top: 0px; bottom: 0px; overflow: hidden; margin: 0; padding: 0;"
  5. >
  6.   <canvas
  7.     id="canvas"
  8.     style="width: 100%; height: 100%; padding: 0;margin: 0;"
  9.   ></canvas>
  10.   <script>
  11.     const canvas = document.getElementById("canvas");
  12.     const c = canvas.getContext("2d");
  13.  
  14.     // size of canvas
  15.     const imgSize = 512;
  16.  
  17.     canvas.width = imgSize;
  18.     canvas.height = imgSize;
  19.  
  20.     // init image data with black pixels
  21.     const image = c.createImageData(imgSize, imgSize);
  22.     for (let i = 0; i < image.data.length; i += 4) {
  23.       image.data[i] = 0; // R
  24.       image.data[i + 1] = 0; // G
  25.       image.data[i + 2] = 0; // B
  26.       image.data[i + 3] = 255; // A
  27.     }
  28.  
  29.     // size of our height maps
  30.     const mapSize = 1024;
  31.  
  32.     // returns the distance of point x,y from the origin 0,0
  33.     const distance = (x, y) => Math.sqrt(x * x + y * y);
  34.  
  35.     // init height map 1
  36.     const heightMap1 = [];
  37.     for (let u = 0; u < mapSize; u++) {
  38.       for (let v = 0; v < mapSize; v++) {
  39.         // index of coordinate in height map array
  40.         const i = u * mapSize + v;
  41.  
  42.         // u,v are coordinates with origin at upper left corner
  43.         // cx and cy are coordinates with origin at the
  44.         // center of the map
  45.         const cx = u - mapSize / 2;
  46.         const cy = v - mapSize / 2;
  47.  
  48.         // distance from middle of map
  49.         const d = distance(cx, cy);
  50.  
  51.         // stretching so we get the desired ripple density on our map
  52.         const stretch = (3 * Math.PI) / (mapSize / 2);
  53.  
  54.         // wavy height value between -1 and 1
  55.         const ripple = Math.sin(d * stretch);
  56.  
  57.         // wavy height value normalized to 0..1
  58.         const normalized = (ripple + 1) / 2;
  59.  
  60.         // height map value 0..128, integer
  61.         heightMap1[i] = Math.floor(normalized * 128);
  62.       }
  63.     }
  64.  
  65.     const heightMap2 = [];
  66.     for (let u = 0; u < mapSize; u++) {
  67.       for (let v = 0; v < mapSize; v++) {
  68.         const i = u * mapSize + v;
  69.         const cx = u - mapSize / 2;
  70.         const cy = v - mapSize / 2;
  71.  
  72.         // skewed distance as input to chaos field calculation,
  73.         // scaled for smoothness over map distance
  74.         const d1 = distance(0.8 * cx, 1.3 * cy) * 0.022;
  75.         const d2 = distance(1.35 * cx, 0.45 * cy) * 0.022;
  76.  
  77.         const s = Math.sin(d1);
  78.         const c = Math.cos(d2);
  79.         // height value between -2 and +2
  80.         const h = s + c;
  81.  
  82.         // height value between 0..1
  83.         const normalized = (h + 2) / 4;
  84.         // height value between 0..127, integer
  85.         heightMap2[i] = Math.floor(normalized * 127);
  86.       }
  87.     }
  88.  
  89.     // color helpers
  90.  
  91.     const interpolate = (c1, c2, f) => {
  92.       return {
  93.         r: Math.floor(c1.r + (c2.r - c1.r) * f),
  94.         g: Math.floor(c1.g + (c2.g - c1.g) * f),
  95.         b: Math.floor(c1.b + (c2.b - c1.b) * f)
  96.       };
  97.     };
  98.  
  99.     // returns a random color
  100.     const randomColor = () => {
  101.       const r = Math.floor(Math.random() * 255);
  102.       const g = Math.floor(Math.random() * 255);
  103.       const b = Math.floor(Math.random() * 255);
  104.       return { r, g, b };
  105.     };
  106.  
  107.     // returns a random color palette with 256 color entries
  108.     const makeRandomPalette = () => {
  109.       const c1 = randomColor();
  110.       const c2 = randomColor();
  111.       const c3 = randomColor();
  112.       const c4 = randomColor();
  113.       const c5 = randomColor();
  114.  
  115.       return makeFiveColorGradient(c1, c2, c3, c4, c5);
  116.     };
  117.  
  118.     const makeFiveColorGradient = (c1, c2, c3, c4, c5) => {
  119.       const g = [];
  120.  
  121.       for (let i = 0; i < 64; i++) {
  122.         const f = i / 64;
  123.         g[i] = interpolate(c1, c2, f);
  124.       }
  125.  
  126.       for (let i = 64; i < 128; i++) {
  127.         const f = (i - 64) / 64;
  128.         g[i] = interpolate(c2, c3, f);
  129.       }
  130.  
  131.       for (let i = 128; i < 192; i++) {
  132.         const f = (i - 128) / 64;
  133.         g[i] = interpolate(c3, c4, f);
  134.       }
  135.  
  136.       for (let i = 192; i < 256; i++) {
  137.         const f = (i - 192) / 64;
  138.         g[i] = interpolate(c4, c5, f);
  139.       }
  140.  
  141.       return g;
  142.     };
  143.  
  144.     // offsets for moving height maps
  145.     let dx1 = 0;
  146.     let dy1 = 0;
  147.  
  148.     let dx2 = 0;
  149.     let dy2 = 0;
  150.  
  151.     // adjust height maps offsets
  152.     const moveHeightMaps = t => {
  153.       dx1 = Math.floor(
  154.         (((Math.cos(t * 0.0002 + 0.4 + Math.PI) + 1) / 2) * mapSize) / 2
  155.       );
  156.       dy1 = Math.floor((((Math.cos(t * 0.0003 - 0.1) + 1) / 2) * mapSize) / 2);
  157.       dx2 = Math.floor((((Math.cos(t * -0.0002 + 1.2) + 1) / 2) * mapSize) / 2);
  158.       dy2 = Math.floor(
  159.         (((Math.cos(t * -0.0003 - 0.8 + Math.PI) + 1) / 2) * mapSize) / 2
  160.       );
  161.     };
  162.  
  163.     // two palettes we interpolate between
  164.     const palettes = [makeRandomPalette(), makeRandomPalette()];
  165.  
  166.     // current palette is edstablished durting animation
  167.     let palette = [];
  168.  
  169.     // stores whether we're interpolating colors
  170.     // from palette 0 -> 1 (1) or 1 -> 0 (-1)
  171.     let prevDirection = 1;
  172.  
  173.     const updatePalette = t => {
  174.       const timeScale = 0.0005;
  175.       const x = t * timeScale;
  176.  
  177.       // normalized value 0..1 used to interpolate palette colors
  178.       const inter = (Math.cos(x) + 1) / 2;
  179.  
  180.       // did we switch direction, and should ergo pick a new palette
  181.       // random palette to interpolate towards?
  182.  
  183.       const direction = -Math.sin(x) >= 0 ? 1 : -1;
  184.       if (prevDirection != direction) {
  185.         prevDirection = direction;
  186.         if (direction == -1) {
  187.           palettes[0] = makeRandomPalette();
  188.         } else {
  189.           palettes[1] = makeRandomPalette();
  190.         }
  191.       }
  192.  
  193.       // create interpolated palette for current frame
  194.       for (let i = 0; i < 256; i++) {
  195.         palette[i] = interpolate(palettes[0][i], palettes[1][i], inter);
  196.       }
  197.     };
  198.  
  199.     const updateImageData = () => {
  200.       for (let u = 0; u < imgSize; u++) {
  201.         for (let v = 0; v < imgSize; v++) {
  202.           // indexes into height maps for pixel
  203.           const i = (u + dy1) * mapSize + (v + dx1);
  204.           const k = (u + dy2) * mapSize + (v + dx2);
  205.  
  206.           // index for pixel in image data
  207.           // remember it's 4 bytes per pixel
  208.           const j = u * imgSize * 4 + v * 4;
  209.  
  210.           // height value of 0..255
  211.           let h = heightMap1[i] + heightMap2[k];
  212.           // get color value from current palette
  213.           let c = palette[h];
  214.  
  215.           // h = heightMap2[i];
  216.           // c = { r: h, g: h, b: h };
  217.  
  218.           // set pixel data
  219.           image.data[j] = c.r;
  220.           image.data[j + 1] = c.g;
  221.           image.data[j + 2] = c.b;
  222.         }
  223.       }
  224.     };
  225.  
  226.     // helper to create a linear gradient palette
  227.     const linearGradient = (c1, c2) => {
  228.       const g = [];
  229.  
  230.       // interpolate between the colors
  231.       // in the gradient
  232.  
  233.       for (let i = 0; i < 256; i++) {
  234.         const f = i / 255;
  235.         g[i] = interpolate(c1, c2, f);
  236.       }
  237.  
  238.       return g;
  239.     };
  240.  
  241.     const tick = time => {
  242.       moveHeightMaps(time);
  243.       updatePalette(time);
  244.       updateImageData();
  245.  
  246.       c.putImageData(image, 0, 0);
  247.  
  248.       requestAnimationFrame(tick);
  249.     };
  250.  
  251.     requestAnimationFrame(tick);
  252.   </script>
  253. </body>
Add Comment
Please, Sign In to add comment