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