我正在使用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%的时间内失败,但是要进行足够的更改以填充颜色,最终它会更改(某些颜色似乎比其他颜色更失败。在颜色左上角的粉红色/红色例如,颜色选择器窗口是一个不好的窗口)。

最佳答案

看来您的问题出在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/

09-11 20:29
查看更多