title: Responsive canvas using webgl and meatballs.js
body: <p>I'm attempting to implement <a href="https://codepen.io/TC5550/pen/WNNWoaO" rel="nofollow noreferrer">this codepen</a> as a background of my personal website. I have no real knowledge of WebGL, so please bear with me. I temporarily added an event listener to update the width and height of the canvas when the page is resized. I can tell this works because when the bubbles start going out of bounds, they continue going and don't bounce off the edge of the page, so I know it somewhat works the way I want it to. When the fragment shader source is defined it also defines the width and height and I'm not sure how to change those variables after that. I tried redefining, recompiling, and reattaching the fragment shader source with the new widths and heights. This obviously doesn't work because the bubbles do not render past the size of the page when the canvas was created. I'm not sure if i'm even going about this the right way, if so what am I doing wrong? All/any help is appreciated, thank you.</p>
  <p>The code I changed:</p>
  <pre><code>var canvas = document.createElement(&quot;canvas&quot;);
  var width = canvas.width = window.innerWidth * 0.75;
  var height = canvas.height = window.innerHeight * 0.75;
  document.body.appendChild(canvas);
  var gl = canvas.getContext('webgl');
  
  var mouse = {x: 0, y: 0};
  
  var numMetaballs = 30;
  var metaballs = [];
  
  var first = true
  
  window.addEventListener('resize', function(){
      width = canvas.width = window.innerWidth * 0.75;
      height = canvas.height = window.innerHeight * 0.75;
      shaderStuff()
  })
  
  function shaderStuff(){
      if(!first) {
          gl.detachShader(program, gl.getAttachedShaders(program)[1])
      }
      first = false
      
      var fragmentShaderSrc = `
      precision highp float;
  
      const float WIDTH = ` + (width &gt;&gt; 0) + `.0;
      const float HEIGHT = ` + (height &gt;&gt; 0) + `.0;
  
      uniform vec3 metaballs[` + numMetaballs + `];
  
      void main(){
      float x = gl_FragCoord.x;
      float y = gl_FragCoord.y;
  
      float sum = 0.0;
      for (int i = 0; i &lt; ` + numMetaballs + `; i++) {
      vec3 metaball = metaballs[i];
      float dx = metaball.x - x;
      float dy = metaball.y - y;
      float radius = metaball.z;
  
      sum += (radius * radius) / (dx * dx + dy * dy);
      }
  
      if (sum &gt;= 0.99) {
      gl_FragColor = vec4(mix(vec3(x / WIDTH, y / HEIGHT, 1.0), vec3(0, 0, 0), max(0.0, 1.0 - (sum - 0.99) * 100.0)), 1.0);
      return;
      }
  
      gl_FragColor = vec4(0, 0, 0, 0);
      }
  
      `;
      
      var fragmentShader = compileShader(fragmentShaderSrc, gl.FRAGMENT_SHADER);
      gl.attachShader(program, fragmentShader);
  }
  
  for (var i = 0; i &lt; numMetaballs; i++) {
    var radius = Math.random() * 60 + 10;
    metaballs.push({
      x: Math.random() * (width - 2 * radius) + radius,
      y: Math.random() * (height - 2 * radius) + radius,
      vx: (Math.random() - 0.5) * 3,
      vy: (Math.random() - 0.5) * 3,
      r: radius * 0.75
    });
  }
  
  var vertexShaderSrc = `
  attribute vec2 position;
  
  void main() {
  // position specifies only x and y.
  // We set z to be 0.0, and w to be 1.0
  gl_Position = vec4(position, 0.0, 1.0);
  }
  `;
  
  
  
  var vertexShader = compileShader(vertexShaderSrc, gl.VERTEX_SHADER);
  
  
  var program = gl.createProgram();
  gl.attachShader(program, vertexShader);
  shaderStuff()
  gl.linkProgram(program);
  gl.useProgram(program);
  
  </code></pre>
  <p>The whole project <a href="https://meatballsjs.000webhostapp.com/" rel="nofollow noreferrer">https://meatballsjs.000webhostapp.com/</a></p>
  <p>The original <a href="https://codepen.io/TC5550/pen/WNNWoaO" rel="nofollow noreferrer">https://codepen.io/TC5550/pen/WNNWoaO</a></p>