4

オンザフライで画像を生成し、キャンバスを使用してクライアントでそれら(のセグメント)をレンダリングするWebアプリケーションがあります-一般的なコードは次のようになります(簡略化)...

var width = ...
var height = ...
var img = new Image();
img.onload = function(){ // Set onload before setting image source ;)
  var canvas = document.createElement("canvas");
  canvas.setAttribute('width',width);  
  canvas.setAttribute('height',height);
  var context = canvas.getContext("2d");
  context.drawImage(this,0,0,width,height,0,0,width,height);
}
img.src = ...

firefox と chrome では、これで問題なく動作します。IE9 (場合によっては IE10) では、空白の画像が表示されることがあります。回避策として、私は入れました...

var width = ...
var height = ...
var img = new Image();
img.onload = function(){
  var canvas = document.createElement("canvas");
  canvas.setAttribute('width',width);  
  canvas.setAttribute('height',height);
  var context = canvas.getContext("2d");
  window.setTimeout(function(){
    context.drawImage(img,0,0,width,height,0,0,width,height);
  }, 10); // 10 millisecond delay here seems to give IE time to make sure the image is actually ready
}
img.src = ...

明らかに、ランダムな遅延を入れることは私を緊張させます - 私はむしろなぜこれが起こるのかを理解したいと思っています. 画像に使用できる別のイベント タイプ/メソッド/プロパティはありますか? これを引き起こしている画像/エンコーディング/転送方法で送信されたhttpヘッダーに何かがある可能性がありますか?

キャンバスに画像を描画することは、新しいユーザーをつまずかせるもののように思われるため、ほとんどの検索では、開発者が onload メソッドの前にソースを設定したインスタンスが生成されます。私が見つけることができた最も近い他の質問/返信はこれでした: https://stackoverflow.com/a/15186350/470062

編集:

最初に幅と高さの定義を含めるように例を更新しました

2013 年 4 月 29 日編集:

10 ミリ秒の遅延は必ずしも十分ではありません - 何かが描画されているかどうかを判断するためにキャンバスのピクセルをチェックするようにコードを変更しました - これはとても醜いハックのように感じます - もっと良い方法があるかどうか知りたいです:

... snip - this is at the end of the image load callback..

if((navigator.appVersion.indexOf("MSIE")) >= 0){    

    function checkAndRedraw(){
        context.clearRect(0,0,width,height);
        context.drawImage(img, 0, 0, width, height);
        var imageData = context.getImageData(0, 0, width, height),
        data = imageData.data,
        len = data.length;

        for (var i = 0; i < len; i += 4){
            if(data[i] || data[i+1] || data[i+2]){
                scheduleRedraw = null; // prevent memory leak
                return; // A pixel contained some non empty value so something was drawn - done.
            }
        }

        scheduleRedraw();
    }
    var redrawHackTimeout;
    function scheduleRedraw(){
        window.clearTimeout(redrawHackTimeout);
        redrawHackTimeout = window.setTimeout(checkAndRedraw, 500);
    }

    scheduleRedraw();
}
//END IE9 Hack
4

2 に答える 2