递归洪水填充在 Javascript 中不起作用
Recursive flood fill not working in Javascript
这是我的代码。我认为我的逻辑没有错,但如果是,请告诉我:
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);
}
我尝试将 flood
和 putpixel
函数放在 floodrecursive
函数中,或放在 addEventListener
函数中,但它仍然不起作用。不知道为什么。
我已经有这个功能了:
window.onload=function() {covercanvas()};
function covercanvas()
{
c.fillStyle="plum";
c.fillRect(0, 0, 1030, 430);
}
所以 basecolor
不是透明的。 alert(basecolor)
也能正常工作,所以我不知道这里出了什么问题。
这是 HTML:
<button class="floodbutton" onclick="floodrecursive()"> Flood fill </button>
<input type="text" id="colorinput"></input>
我希望代码工作的方式是,在 canvas 上绘制后,将颜色的六进制值放入输入框中,然后单击按钮,然后单击 canvas再次,它应该开始洪水填充。
我添加了一个 hexAtoRGBA
函数,现在可以正常使用了。但我还是……有点不明白。这是更新后的代码:
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 + ")";
}
我不明白的是,c.getImageData
已经是returnsRGBA格式的值了,为什么我加了hexAtoRGBA
函数才起作用对于 base
和 currentpix
?他们都在使用 c.getImageData
所以他们已经在比较 RGBA 了,对吧?
这是我的代码。我认为我的逻辑没有错,但如果是,请告诉我:
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);
}
我尝试将 flood
和 putpixel
函数放在 floodrecursive
函数中,或放在 addEventListener
函数中,但它仍然不起作用。不知道为什么。
我已经有这个功能了:
window.onload=function() {covercanvas()};
function covercanvas()
{
c.fillStyle="plum";
c.fillRect(0, 0, 1030, 430);
}
所以 basecolor
不是透明的。 alert(basecolor)
也能正常工作,所以我不知道这里出了什么问题。
这是 HTML:
<button class="floodbutton" onclick="floodrecursive()"> Flood fill </button>
<input type="text" id="colorinput"></input>
我希望代码工作的方式是,在 canvas 上绘制后,将颜色的六进制值放入输入框中,然后单击按钮,然后单击 canvas再次,它应该开始洪水填充。
我添加了一个 hexAtoRGBA
函数,现在可以正常使用了。但我还是……有点不明白。这是更新后的代码:
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 + ")";
}
我不明白的是,c.getImageData
已经是returnsRGBA格式的值了,为什么我加了hexAtoRGBA
函数才起作用对于 base
和 currentpix
?他们都在使用 c.getImageData
所以他们已经在比较 RGBA 了,对吧?