【发布时间】:2018-11-05 04:38:34
【问题描述】:
我正在尝试使用canvas(指代码中元素的 2DContext)创建一个基本的绘制应用程序。但是,以当前时间,所有浏览器都放弃并说Maximum call stack size exceeded。如何改进此代码以填充更大的区域?
我以 fillAround(Math.round(x), Math.round(y), colorAt(Math.round(x), Math.round(y)), fillcolor); 开头代码,其中 x 和 y 是点击的坐标。
function hexToRgb(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
function colorToRgb(arr) {
return {
r: arr[0],
g: arr[1],
b: arr[2]
}
}
function colorAt(xp, yp) {
return colorToRgb(canvas.getImageData(xp, yp, 1, 1).data);
}
function setColorAt(xp, yp, fill) {
var color = canvas.getImageData(xp, yp, 1, 1)
var set = hexToRgb(fill);
color.data[0] = set.r;
color.data[1] = set.g;
color.data[2] = set.b;
canvas.putImageData(color, xp, yp);
}
function sameColor(a, b) {
return a.r == b.r && a.g == b.r && a.b == b.b;
}
function fillAround(xp, yp, original, fill) {
if (sameColor(colorAt(xp, yp), original)) {
setColorAt(xp, yp, fill);
if (sameColor(colorAt(xp + 1, yp), original)) {
fillAround(xp + 1, yp, original, fill);
}
if (sameColor(colorAt(xp - 1, yp), original)) {
fillAround(xp - 1, yp, original, fill);
}
if (sameColor(colorAt(xp, yp + 1), original)) {
fillAround(xp, yp + 1, original, fill);
}
if (sameColor(colorAt(xp, yp - 1), original)) {
fillAround(xp, yp - 1, original, fill);
}
}
}
十六进制到RGB的转换器来自RGB to Hex and Hex to RGB。
更新的代码(在@trincot 的帮助下)
var canvasData;
function hexToRgb(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
function colorToRgb(arr) {
return {
r: arr[0],
g: arr[1],
b: arr[2]
}
}
function colorAt(xp, yp) {
return colorToRgb(canvasData.data.slice(4 * canvasTag.width * (yp - 1) + 4 * (xp + 1), 4 * canvasTag.widthwidth * (yp - 1) + 4 * xp + 8));
}
function setColorAt(xp, yp, fill) {
var set = hexToRgb(fill);
var o = 4 * canvasTag.width * (yp - 1) + 4 * (xp + 1);
canvasData.data[o] = set.r;
canvasData.data[o + 1] = set.g;
canvasData.data[o + 2] = set.b;
}
function sameColor(a, b) {
return a.r == b.r && a.g == b.r && a.b == b.b;
}
function fillAround(xp, yp, original, fill) {
const stack = [[xp, yp]];
while (stack.length) {
const [xp, yp] = stack.pop();
if (!sameColor(colorAt(xp, yp), original)) continue;
setColorAt(xp, yp, fill);
stack.push([xp + 1, yp], [xp - 1, yp], [xp, yp + 1], [xp, yp - 1]);
}
}
并通过调用
canvasData = canvas.getImageData(0, 0, canvasTag.width, canvasTag.height);
fillAround(Math.round(x), Math.round(y), colorAt(Math.round(x), Math.round(y)), fillcolor);
canvas.putImageData(canvasData, 0, 0);
【问题讨论】:
-
您似乎在询问一个非常具体的问题(堆栈溢出),但您已经粘贴了整个应用程序。 stackoverflow.com/help/mcve
-
我假设您在谷歌搜索该错误消息的含义。如果您将问题编辑为专门关于将递归算法转换为非递归算法,这将对社区有所帮助。
标签: javascript canvas optimization