12

だから私はこの小さな 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;
}

}

何か案は?前もって感謝します。

4

7 に答える 7

8

Firefox のバグです。Mozillaはそれを知っています。回避策は次のとおりです。

  1. 新しいインメモリ キャンバスを作成します。

    var spriteCanvas = document.createElement('canvas');
    
  2. キャンバスの高さ/幅を画像の高さ/幅に設定します。

    spriteCanvas.setAttribute('width', 20);
    spriteCanvas.setAttribute('height', 20);
    
  3. イメージ データをキャンバスの位置 (0,0) に配置します。

    spriteCanvas.getContext('2d').putImageData(imageData, 0, 0);
    
  4. メイン キャンバスのコンテキストで、画面上または画面外の任意の位置を使用して、drawImage を使用してキャンバス スプライトを描画します。

    context.drawImage(spriteCanvas, 50, 100); // clipping is allowed
    
于 2010-06-01T18:26:25.063 に答える
4

Yeah, this error seems to happen when using (get|put)ImageData off the edges of the canvas.

For my encounter with this problem, I simply added some clipping logic that checks the edges of the region to be drawn against the edges of the canvas, and clips it where necessary, only drawing the visible region. It seems to have fixed the problem.

于 2009-11-16T04:40:11.843 に答える
1

この方法で同じサイズのキャンバスにタイルを描画しようとすると、drawImage()で同様の問題が発生していました。

var image = new Image();
     image.onload = function() {
         context.drawImage(image, 0, 0, this.tileSize, this.tileSize);
       }
     image.src = this.baseURL + tileId;

呼び出しから高さと幅のパラメーターを削除してこれを使用すると、問題は解消されました。

context.drawImage(image, 0, 0);
于 2011-02-16T07:42:37.610 に答える
1

graphData.data[index] に設定しようとした値が整数ではなく文字列だったため、同じエラーが発生しました。それを修正するために、文字列を parseInt() で整数に変換しました。

于 2009-09-11T12:27:39.737 に答える
0

putImageData には、幅と高さの 2 つの引数をさらに指定する必要があると思います。

こちらをご覧ください

于 2009-06-11T16:42:52.407 に答える
0

私はこの問題に数日間対処してきました(Firefoxで)。私が思いついた最良のアイデアは、画面からはみ出すピクセルを動的に削除することです。これを行うにはCPUがかかりすぎるのではないかと心配しています。うまくいけば、誰かがより良いアイデアを思いつきます:/

繰り返しになりますが、このエラーは、putImageData がキャンバスの周囲の外側にピクセルを描画しようとしている場合にのみ見られます。例えば。任意の x または y 値 < 0。

-- 2 回目の読み取り時 -- 既に画像データのサイズを変更しているようです。70px のコンテナにいる場合は、画像のサイズを 68px に下げてみてはいかがでしょうか? おそらくうまくいかないでしょうが、試してみる価値はあります..

于 2010-05-04T16:37:02.620 に答える
0

これは今では古いですが、これは Windows 上の FF でのみ問題を引き起こします。Mac 上の FF は正常に動作します。

于 2010-05-28T05:20:37.060 に答える