title: p5.js Flood Fill (bucket tool) works slowly and wierd
body: <p>So I wrote a flood fill function that works like a paint-app bucket tool: you click inside a closed shape and it'll fill with a color.</p>
  
  <p>I have two problems with it:</p>
  
  <ol>
  <li><p>performance - let's say my canvas is 600*600 (370,000 pixels) and I draw a big circle in it that for example has about 100K pixels in it, it can take about 40(!!!) seconds to fill this circle! thats insane!
  A sqaure of exactly 10,000 pixels takes 0.4-0.5 seconds on average, but (I guess) since the sizes of the arrays used the program are growing so much, a sqaure 10 times the size takes about 100 times the length to fill.</p></li>
  <li><p>there's something wierd about the filling. I'm not really sure how it happens but it's always leaving a few un-filled pixels. Not much at all, but it's really wierd.</p></li>
  </ol>
  
  <p>My flood fill function uses 4 helper-functions: get and set pixel color, checking if it's a color to fill, and checking if that's a pixel that has been checked before.
  Here are all the functions:</p>
  
  <pre><code>getPixelColor = (x, y) =&gt; {
    let pixelColor = [];
    for (let i = 0; i &lt; pixDens; ++i) {
      for (let j = 0; j &lt; pixDens; ++j) {
        index = 4 * ((y * pixDens + j) * width * pixDens + (x * pixDens + i));
        pixelColor[0] = pixels[index];
        pixelColor[1] = pixels[index + 1];
        pixelColor[2] = pixels[index + 2];
        pixelColor[3] = pixels[index + 3];
      }
    }
    return pixelColor;
  };
  
  setPixelColor = (x, y, currentColor) =&gt; { //Remember to loadPixels() before using this function, and to updatePixels() after.
    for (let i = 0; i &lt; pixDens; ++i) {
      for (let j = 0; j &lt; pixDens; ++j) {
        index = 4 * ((y * pixDens + j) * width * pixDens + (x * pixDens + i));
        pixels[index] = currentColor[0];
        pixels[index + 1] = currentColor[1];
        pixels[index + 2] = currentColor[2];
        pixels[index + 3] = currentColor[3];
      }
    }
  }
  
  isDuplicate = (posHistory, vector) =&gt; {
    for (let i = 0; i &lt; posHistory.length; ++i) {
      if (posHistory[i].x === vector.x &amp;&amp; posHistory[i].y === vector.y) {
        return true;
      }
    }
    return false;
  }
  
  compareColors = (firstColor, secondColor) =&gt; {
    for (let i = 0; i &lt; firstColor.length; ++i) {
      if (firstColor[i] !== secondColor[i]) {
        return false;
      }
    }
    return true;
  }
  
  floodFill = () =&gt; {
    loadPixels();
    let x = floor(mouseX);
    let y = floor(mouseY);
    let startingColor = getPixelColor(x, y);
    if (compareColors(startingColor, currentColor)) {
      return false;
    }
    let pos = [];
    pos.push(createVector(x, y));
    let posHistory = [];
    posHistory.push(createVector(x, y));
    while (pos.length &gt; 0) {
      x = pos[0].x;
      y = pos[0].y;
      pos.shift();
      if (x &lt;= width &amp;&amp; x &gt;= 0 &amp;&amp; y &lt;= height &amp;&amp; y &gt;= 0) {
        setPixelColor(x, y, currentColor);
        let xMinus = createVector(x - 1, y);
        if (!isDuplicate(posHistory, xMinus) &amp;&amp; compareColors(getPixelColor(xMinus.x, xMinus.y), startingColor)) {
          pos.push(xMinus);
          posHistory.push(xMinus);
        }
        let xPlus = createVector(x + 1, y);
        if (!isDuplicate(posHistory, xPlus) &amp;&amp; compareColors(getPixelColor(xPlus.x, xPlus.y), startingColor)) {
          pos.push(xPlus);
          posHistory.push(xPlus);
        }
        let yMinus = createVector(x, y - 1);
        if (!isDuplicate(posHistory, yMinus) &amp;&amp; compareColors(getPixelColor(yMinus.x, yMinus.y), startingColor)) {
          pos.push(yMinus);
          posHistory.push(yMinus);
        }
        let yPlus = createVector(x, y + 1);
        if (!isDuplicate(posHistory, yPlus) &amp;&amp; compareColors(getPixelColor(yPlus.x, yPlus.y), startingColor)) {
          pos.push(yPlus);
          posHistory.push(yPlus);
        }
      }
    }
    updatePixels();
  }
  </code></pre>
  
  <p>I would really apprciate it if someone could help me solve the problems with the functions.
  Thank you very much!!</p>
  
  <p>EDIT: So I updated my flood fill function itself and removed an array of colors that I never used. this array was pretty large and a few push() and a shift() methods called on it on pretty much every run.
  UNFORTUNATLY, the execution time is 99.9% the same for small shapes (for example, a fill of 10,000 takes the same 0.5 seconds, but large fills, like 100,000 pixels now takes about 30 seconds and not 40, so that's a step in the right direction.
  I guess that RAM usage is down as well since it was a pretty large array but I didn't measured it.
  The wierd problem where it leaves un-filled pixels behind is still here as well.</p>