所以我正在进行这个小小的javascript实验,我需要一个小部件来跟踪它的FPS。我移植了一个小部件,我一直在使用Actionscript 3到Javascript,它似乎与Chrome / Safari一起工作正常但在Firefox上却抛出异常。
这是实验:
这是错误:
[Exception... "An invalid or illegal string was specified" code: "12" nsresult: "0x8053000c (NS_ERROR_DOM_SYNTAX_ERR)" location: "http://mrdoob.com/projects/chromeexperiments/depth_of_field__debug/js/net/hires/debug/Stats.js Line: 105"]
抱怨的是这一行:
graph.putImageData(graphData, 1, 0, 0, 0, 69, 50);
“滚动”位图像素是一个糟糕的代码。我的想法是,我只在位图的左侧绘制几个像素,然后在下一帧上复制整个位图并将其粘贴到右侧的像素上。这个错误通常被抛出,因为你粘贴了一个比源更大的位图并且它已经超出限制,但理论上不应该是这种情况,因为我将69定义为要粘贴的矩形的宽度(是位图70px宽)。
这是完整的代码:
var Stats = {
baseFps: null,
timer: null,
timerStart: null,
timerLast: null,
fps: null,
ms: null,
container: null,
fpsText: null,
msText: null,
memText: null,
memMaxText: null,
graph: null,
graphData: null,
init: function(userfps)
{
baseFps = userfps;
timer = 0;
timerStart = new Date() - 0;
timerLast = 0;
fps = 0;
ms = 0;
container = document.createElement("div");
container.style.fontFamily = 'Arial';
container.style.fontSize = '10px';
container.style.backgroundColor = '#000033';
container.style.width = '70px';
container.style.paddingTop = '2px';
fpsText = document.createElement("div");
fpsText.style.color = '#ffff00';
fpsText.style.marginLeft = '3px';
fpsText.style.marginBottom = '-3px';
fpsText.innerHTML = "FPS:";
container.appendChild(fpsText);
msText = document.createElement("div");
msText.style.color = '#00ff00';
msText.style.marginLeft = '3px';
msText.style.marginBottom = '-3px';
msText.innerHTML = "MS:";
container.appendChild(msText);
memText = document.createElement("div");
memText.style.color = '#00ffff';
memText.style.marginLeft = '3px';
memText.style.marginBottom = '-3px';
memText.innerHTML = "MEM:";
container.appendChild(memText);
memMaxText = document.createElement("div");
memMaxText.style.color = '#ff0070';
memMaxText.style.marginLeft = '3px';
memMaxText.style.marginBottom = '3px';
memMaxText.innerHTML = "MAX:";
container.appendChild(memMaxText);
var canvas = document.createElement("canvas");
canvas.width = 70;
canvas.height = 50;
container.appendChild(canvas);
graph = canvas.getContext("2d");
graph.fillStyle = '#000033';
graph.fillRect(0, 0, canvas.width, canvas.height );
graphData = graph.getImageData(0, 0, canvas.width, canvas.height);
setInterval(this.update, 1000/baseFps);
return container;
},
update: function()
{
timer = new Date() - timerStart;
if ((timer - 1000) > timerLast)
{
fpsText.innerHTML = "FPS: " + fps + " / " + baseFps;
timerLast = timer;
graph.putImageData(graphData, 1, 0, 0, 0, 69, 50);
graph.fillRect(0,0,1,50);
graphData = graph.getImageData(0, 0, 70, 50);
var index = ( Math.floor(Math.min(50, (fps / baseFps) * 50)) * 280 /* 70 * 4 */ );
graphData.data[index] = graphData.data[index + 1] = 256;
index = ( Math.floor(Math.min(50, 50 - (timer - ms) * .5)) * 280 /* 70 * 4 */ );
graphData.data[index + 1] = 256;
graph.putImageData (graphData, 0, 0);
fps = 0;
}
++fps;
msText.innerHTML = "MS: " + (timer - ms);
ms = timer;
}
}
有什么想法吗?提前谢谢。
答案 0 :(得分:7)
这是Firefox中的一个错误。 Mozilla knows about it。这是解决方法:
制作新的内存画布:
var spriteCanvas = document.createElement('canvas');
将画布的高度/宽度设置为图像的高度/宽度:
spriteCanvas.setAttribute('width', 20);
spriteCanvas.setAttribute('height', 20);
将图像数据放入画布中位置(0,0):
spriteCanvas.getContext('2d').putImageData(imageData, 0, 0);
在主画布的上下文中,使用drawImage在屏幕上或屏幕外的任何位置绘制画布精灵:
context.drawImage(spriteCanvas, 50, 100); // clipping is allowed
答案 1 :(得分:4)
是的,当在画布的边缘使用(get | put)ImageData时,似乎会发生此错误。
对于我遇到这个问题,我只是添加了一些剪切逻辑,用于检查要绘制在画布边缘上的区域的边缘,并在必要时剪切它,仅绘制可见区域。它似乎解决了这个问题。
答案 2 :(得分:1)
我遇到了同样的错误,因为我试图设置为graphData.data [index]的值是一个字符串而不是整数。 为了解决这个问题,我使用parseInt()将字符串转换为整数。
答案 3 :(得分:1)
当我尝试以这种方式在相同大小的画布上绘制图块时,我遇到了与drawImage()类似的问题:
var image = new Image();
image.onload = function() {
context.drawImage(image, 0, 0, this.tileSize, this.tileSize);
}
image.src = this.baseURL + tileId;
当我从调用中删除了height和width参数时,问题就消失了,并使用了这个:
context.drawImage(image, 0, 0);
答案 4 :(得分:0)
我认为你需要为putImageData指定另外两个参数:width和height。
答案 5 :(得分:0)
我已经处理了这个问题几天了(在firefox中)。我能想到的最好的想法是动态删除屏幕上的像素。我担心这样做需要太多的CPU。希望有人想出一个更好的主意:/
但重申一下,当putImageData试图在画布周边之外绘制任何像素时,我只看到了这个错误。例如。任何x或y值< 0
- 第二次阅读 - 看起来您已经在调整图像数据的大小。如果您使用的是70px容器,您可以尝试将图像大小调整为68px?可能不会起作用,但值得一试......
答案 6 :(得分:0)
现在这已经很老了,但这只会给我在Windows上的FF问题。 Mac上的FF工作原理应该如何。