title: Flood fill algorithm for bucket tool in P5.js electron paint application
body: <p>I'm trying to create a bucket tool for my paint application made with electron.js and P5.js for the canvas stuff. everytime a user clicks on the canvas and his <code>mode</code> variable is equal to "fill", it calls the floodFill function. i tried to implement the algorithm from here: <a href="https://en.wikipedia.org/wiki/Flood_fill#Pseudocode" rel="nofollow noreferrer">https://en.wikipedia.org/wiki/Flood_fill#Pseudocode</a> (Stack-based recursive implementation (four-way)), but i have a problem - i'm reaching maximum call stack.
  the way i render everything to the screen is i have an array called <code>drawing</code> and there are constructor functions for the types of things you can draw (Circle, Square) so i created a Pixel constructor function so that i can render it everytime, i cannot call <code>updatePixels()</code> because i render everything every frame with the <code>draw()</code> function.
  this is my floodFill function:</p>
  
  <pre><code>function floodFill(x, y, target_col, replace_col) {
     if (x &gt;= 0 &amp;&amp; y &gt;= 0 &amp;&amp; x &lt;= width &amp;&amp; y &lt;= height) {
          let index = (x + y * width) * 4;
          if (target_col === replace_col) {
              return;
          } else if (
              pixels[index] !== target_col.levels[0] &amp;&amp;
              pixels[index + 1] !== target_col.levels[1] &amp;&amp;
              pixels[index + 2] !== target_col.levels[2] &amp;&amp;
              pixels[index + 3] !== target_col.levels[3]
          ) {
              return;
          } else {
              drawing.push(new Pixel(x, y, replace_col));
              floodFill(x, y - 1, target_col, replace_col);
              floodFill(x, y + 1, target_col, replace_col);
              floodFill(x - 1, y, target_col, replace_col);
              floodFill(x + 1, y, target_col, replace_col);
          }
      }
  }
  </code></pre>
  
  <p>this is how i call the function:</p>
  
  <pre><code>if (mode === "fill") {
      loadPixels();
      let index = (mouseX + mouseY * width) * 4;
  
      // target_color = what the user wants to replace
      let target_color = color(
          pixels[index],
          pixels[index + 1],
          pixels[index + 2],
          pixels[index + 3]
      );
     // replacement_color = the color that will be instead of the target_color
     let replacement_color = color(current_color);
      floodFill(mouseX, mouseY, target_color, replacement_color);
  }
  </code></pre>
  
  <p>by the way in the <code>floodFill</code> function in the <code>else if</code> i used this technique because simply doing <code>color(pixels[index], pixels[index + 1], pixels[index + 2], pixels[index + 3]) !== target_col</code> didn't work</p>
  
  <p>EDIT: 
  I realized i had an error with the floodFill function, my <code>else if</code> is almost never true because it also tries to check if the alphas are not equal and they are almost always 255. so i added to the else if this:</p>
  
  <pre><code>else if (
       (pixels[index] !== target_col.levels[0] &amp;&amp;
           pixels[index + 1] !== target_col.levels[1] &amp;&amp;
          pixels[index + 2] !== target_col.levels[2]) ||
      pixels[index + 3] !== target_col.levels[3]
   ) {
  </code></pre>
  
  <p>now what happens is if i try to fill something it draws a straight line up until it reaches the other color, but then reaches maximum stack size,
  example:
  <img src="https://i.stack.imgur.com/LzoT7.png" alt="paint">
  this is probably because in the <code>floodFill</code> function the first recursive call i make is to <code>y - 1</code> (up). 
  I would love to hear more suggestions</p>
  
  <p>ANOTHER EDIT:
  i figured out that in the <code>floodFill</code> in the recursive section im calling it with <code>y - 1</code> then with <code>y + 1</code> which makes no sense because it goes up and then down means it stays at the same pixel, so i edited it to be like this:</p>
  
  <pre><code>floodFill(x, y - 1, target_col, replace_col);
  floodFill(x - 1, y, target_col, replace_col);
  floodFill(x, y + 1, target_col, replace_col);
  floodFill(x + 1, y, target_col, replace_col);
  </code></pre>
  
  <p>now it shows up like this:
  <img src="https://i.stack.imgur.com/qvcnZ.png" alt="paint"></p>