SaveText.Ru

  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <meta name="viewport"
  6.         content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  7.   <meta http-equiv="X-UA-Compatible" content="ie=edge">
  8.   <title>Document</title>
  9.   <link rel="stylesheet" href="normalize.css">
  10. </head>
  11. <body>
  12. <canvas id="canvas" width="500" height="500"></canvas>
  13.  
  14. <script >
  15.   const canvas = document.getElementById('canvas')
  16.   const ctx = canvas.getContext('2d')
  17.   window.canvasWidth = canvas.width
  18.   window.canvasHeight = canvas.height
  19.   window.canvasPixelsAmount = canvasWidth * canvasHeight
  20.  
  21.   window.particles = new Float64Array(new ArrayBuffer(canvasPixelsAmount * 8))
  22.   // window.particles[10] = 100000;
  23.  
  24.   canvas.addEventListener('click', (event) => {
  25.     particles[event.clientY * canvasWidth + event.clientX] += 1000000;
  26.   })
  27.  
  28.   draw()
  29.  
  30.   function draw() {
  31.     // console.time('draw')
  32.  
  33.     let image = ctx.createImageData(canvasWidth, canvasHeight);
  34.     if (image.data.length / 4 !== canvasPixelsAmount) {
  35.       throw new Error('Image doesn't fit particles.');
  36.     }
  37.  
  38.     particles.forEach((energy, energyIdx) => {
  39.       let roundedEnergy = ~~energy
  40.       let pixelIdx = energyIdx * 4;
  41.       // Red
  42.       image.data[pixelIdx] = 0;
  43.       // image.data[pixelIdx] = Math.min(255, roundedEnergy);
  44.       // Green
  45.       image.data[pixelIdx + 1] = roundedEnergy < 256 ? 0 : Math.min(256 * 2, roundedEnergy) - 256;
  46.       // Blue
  47.       image.data[pixelIdx + 2] = roundedEnergy < 256 * 2 ? 0 : Math.min(256 * 3, roundedEnergy) - 256 * 2;
  48.       image.data[pixelIdx + 3] = 255;
  49.     })
  50.  
  51.     ctx.putImageData(image, 0, 0);
  52.     // console.timeEnd('draw')
  53.     requestAnimationFrame(draw)
  54.   }
  55.  
  56. </script>
  57. <script>
  58.  
  59.  
  60.   const speedFactor = 0.5
  61.   const neighborsOffsets = [
  62.     -1, 1, -canvasWidth, canvasWidth,
  63.     -2, +2, -canvasWidth - 1, -canvasWidth + 1, canvasWidth - 1, canvasWidth + 1, 2 * canvasWidth, -2 * canvasWidth,
  64.   ];
  65.   let prevTimestamp = 0
  66.  
  67.   function work(timestamp) {
  68.     console.time('simple')
  69.  
  70.     let energyTransferIndex = 8;
  71.     if (timestamp) {
  72.       let interval = timestamp - prevTimestamp;
  73.       if (!interval) {
  74.         requestAnimationFrame(work);
  75.         return;
  76.       }
  77.       energyTransferIndex = (8 / (100 / interval)) / speedFactor;
  78.       prevTimestamp = timestamp
  79.     } else {
  80.       requestAnimationFrame(work);
  81.       return;
  82.     }
  83.  
  84.     // console.log('[email protected]# simple.html:35 ', energyTransferIndex)
  85.  
  86.     let newParticles = new Float64Array(new ArrayBuffer(canvasPixelsAmount * 8));
  87.     let calcEnergyTransition = (energy, distanceCoefficient) => {
  88.       return energy / distanceCoefficient / energyTransferIndex;
  89.     }
  90.  
  91.     particles.forEach((energy, particleIdx) => {
  92.       let energyModification = 0
  93.       neighborsOffsets.forEach((offset, offsetIdx) => {
  94.         let neighborIdx = particleIdx + offset
  95.         let distanceCoefficient = ~~(offsetIdx / 4) + 1;
  96.         if (particleIdx === 1) {
  97.           console.log('[email protected]# simple.html:52 ', distanceCoefficient);
  98.  
  99.         }
  100.         if (neighborIdx > 1 && neighborIdx < canvasPixelsAmount) {
  101.           if (energy < particles[neighborIdx]) {
  102.             energyModification += calcEnergyTransition(particles[neighborIdx], distanceCoefficient);
  103.           } else if (energy > particles[neighborIdx]) {
  104.             energyModification -= calcEnergyTransition(energy, distanceCoefficient);
  105.           }
  106.         } else {
  107.           energyModification -= calcEnergyTransition(energy, distanceCoefficient);
  108.         }
  109.       })
  110.       newParticles[particleIdx] = energy + energyModification;
  111.     });
  112.     particles = newParticles
  113.  
  114.     console.timeEnd('simple')
  115.     // requestAnimationFrame(work)
  116.   }
  117.  
  118.   // console.time('simple')
  119.   requestAnimationFrame(work);
  120.   // console.timeEnd('simple')
  121.   // console.log('[email protected]# simple.html:27 ', )
  122.   // console.time('simple')
  123.   // work()
  124.   // console.timeEnd('simple')
  125.  
  126. </script>
  127.  
  128. </body>
  129. </html>
  130.  

Share with your friends:

Print