Here is my code. I don't think my logic is wrong but if it is please tell me:
function floodrecursive()
{
let x=0;
let y=0;
canvas.addEventListener('click', e => {
x = e.offsetX;
y = e.offsetY;
var basecolor = c.getImageData(x, y, 1, 1).data;
//alert(basecolor);
var fillcolor = document.getElementById("colorinput").value;
flood(c, x, y, basecolor, fillcolor);
});
}
function flood(c, x, y, basecolor, fillcolor)
{
var currentpixel = c.getImageData(x, y, 1, 1).data;
if (currentpixel === basecolor)
{
putpixel(c, x, y, fillcolor);
flood(c, x+1, y, basecolor, fillcolor);
flood(c, x-1, y, basecolor, fillcolor);
flood(c, x, y+1, basecolor, fillcolor);
flood(c, x, y-1, basecolor, fillcolor);
}
}
function putpixel(c, x, y, fillcolor)
{
c.fillStyle = "#" + fillcolor;
c.fillRect(x, y, 1, 1);
}
I tried putting the flood
and putpixel
functions inside the floodrecursive
function, or inside the addEventListener
but it still won't work. I don't know why.
I already have this function:
window.onload=function() {covercanvas()};
function covercanvas()
{
c.fillStyle="plum";
c.fillRect(0, 0, 1030, 430);
}
so that the basecolor
isn't transparent. And the alert(basecolor)
works too so I don't know what's going wrong here.
Here's the HTML:
<button class="floodbutton" onclick="floodrecursive()"> Flood fill </button>
<input type="text" id="colorinput"></input>
How I expected the code to work is that after I draw on the canvas, put the hexa value of a color in the input box, then click the button, and click the canvas again, it should start flood filling.
I've added a hexAtoRGBA
function and now it works perfectly. But I still... kinda don't understand. Here's the updated code:
function floodrecursive()
{
let x=0;
let y=0;
canvas.addEventListener('click', e => {
x = e.offsetX;
y = e.offsetY;
var basecolor = c.getImageData(x, y, 1, 1).data;
var base = hexAToRGBA(basecolor);
var fillcolor = document.getElementById("colorinput").value;
flood(c, x, y, base, fillcolor);
});
}
function flood(c, x, y, base, fillcolor)
{
var currentpixel = c.getImageData(x, y, 1, 1).data;
var currentpix = hexAToRGBA(currentpixel);
if (currentpix === base)
{
putpixel(c, x, y, fillcolor);
flood(c, x+1, y, base, fillcolor);
flood(c, x-1, y, base, fillcolor);
flood(c, x, y+1, base, fillcolor);
flood(c, x, y-1, base, fillcolor);
}
}
function hexAToRGBA(h) {
let r = 0, g = 0, b = 0, a = 1;
if (h.length == 4) {
r = "0x" + h[1] + h[1];
g = "0x" + h[2] + h[2];
b = "0x" + h[3] + h[3];
a = "0x" + h[4] + h[4];
} else if (h.length == 8) {
r = "0x" + h[1] + h[2];
g = "0x" + h[3] + h[4];
b = "0x" + h[5] + h[6];
a = "0x" + h[7] + h[8];
}
a = +(a / 255).toFixed(3);
return "rgba(" + +r + "," + +g + "," + +b + "," + a + ")";
}
The thing I don't understand is, the c.getImageData
already returns the value in RGBA format, so why does it work only after I've added the hexAtoRGBA
function for both base
and currentpix
? They're both using c.getImageData
so they're already comparing RGBA, right?