帆布油漆桶/洪水填充工具卡在循环中

时间:2014-08-01 16:11:46

标签: javascript html5 canvas

我正在使用this tutorial中的代码。我还让用户使用<input type="color">选择颜色(我将其转换为RGB,因为它返回十六进制值)。如果颜色保留默认值(初始化时设置为黑色),填充似乎工作正常。如果使用input更改颜色,有时会结束冻结。据我所知,它在这个循环中陷入困境:

while (pixelStack.length) {...}

循环中有一个部分将新值推送到pixelStack数组:

while (y++ < height - 1 && matchStartColor(pixelPos)) {
   colorPixel(pixelPos);
   if (x > 0) {
      if (matchStartColor(pixelPos - 4)) {
         if (!reachLeft) {
            pixelStack.push([x - 1, y]);
            reachLeft = true;
         }
      } else if (reachLeft) {
            reachLeft = false;
         }
   }

   if (x < width - 1) {
      if (matchStartColor(pixelPos + 4)) {
         if (!reachRight) {
            pixelStack.push([x + 1, y]);
            reachRight = true;
         }
      } else if (reachRight) {
            reachRight = false;
        }
      }
      pixelPos += width * 4;
   }

据我所知,它不断推送到pixelStack数组的唯一原因是matchStartColor函数永远不会返回false。

function matchStartColor(pixelPos) {
   var r = imageData.data[pixelPos];
   var g = imageData.data[pixelPos + 1];
   var b = imageData.data[pixelPos + 2];

   return (r && g && b);
}

但是,我不明白为什么这有时会起作用,有时则不行。

基本上pixelStack数组最终会不断增长,因此它永远不会退出循环。我用一个工作示例制作了一个jsFiddle(虽然如果你改变颜色并尝试填充,它最终会锁定)。当颜色改变时,100%的时间似乎没有失败,但是改变颜色并填充它最终会做(并且某些颜色看起来比其他颜色更失败。左上角的粉红色/红色例如,颜色选择器窗口是坏的。

1 个答案:

答案 0 :(得分:2)

您的问题似乎出现在matchStartColor的实施中。

通过以下实施:

function matchStartColor(pixelPos) {
    var r = imageData.data[pixelPos];
    var g = imageData.data[pixelPos + 1];
    var b = imageData.data[pixelPos + 2];

    return (r && g && b);
}

如果rgb为0,则只返回false。当您使用黑色(或任何带有0分量的颜色)时,这都有效。如果您选择的颜色中没有任何组件为0,则此函数永远不会返回false。

我认为你真正想要做的就是将图像的颜色与你选择的颜色进行比较。

根据您使用此功能的方式,我认为这应该有效:

function matchStartColor(pixelPos) {
    var r = imageData.data[pixelPos];
    var g = imageData.data[pixelPos + 1];
    var b = imageData.data[pixelPos + 2];

    return (r !== curColor.r || g !== curColor.g || b !== curColor.b);
} 

http://jsfiddle.net/6Uy3U/4/