1

HTML5 canvasプログラムでを描画する際に、いくつかの競合状態を発見しましたJavaScript。これらは、画像をロードする前に変更しようとしたときに発生し、次の手法を使用してほとんどを修正できました。

var myImage = document.createElement('img');
myImage.onload = function(){
    console.log("image src set!");
};
myImage.src="img/foobar.png";

いくつかの画像の 1 つに対してこの操作を行っていますが、奇妙なことが起こっています。基本的に、イメージはロードされる前にキャンバスに描画されます。ブール値を使用して画像がまだ描画されているかどうかを指定することで、問題を回避しようとさえしました。出力を含む私のコードは次のとおりです。コンテキストを理解するために、このコードはキャンバスを更新するために毎秒呼び出される関数の一部です。

if (!at_arrow_black)//one of two images used to show an arrow on the canvas
{
    at_arrow_black = document.createElement('img');
    at_arrow_black.onload = function() {
        if (foregroundColor === "black")//which image to draw depends on the foreground color
        {
            console.log("black load");
            context.drawImage(at_arrow_black, canvas.width*.775, canvas.height*.66, canvas.width*.075, font*4/5);
        }
    };
    at_arrow_black.src = "img/at_arrow.png";
}
else
{
    if (foregroundColor === "black")
    {

        if (hasDrawnArrow)//this starts as false
        {
            console.log("1. black draw");
            context.drawImage(at_arrow_black, canvas.width*.775, canvas.height*.66, canvas.width*.075, font*4/5);
        }
        else
        {
            logDebug("2. black draw");
            hasDrawnArrow = true;
        }
    }
}

これにより、キャンバスは最初に 1 つの矢印を描画し、次にこのループの最初の繰り返しで (わずかに異なる場所で) もう 1 つの矢印を描画します。私が得る出力:

2. black draw
black load
1. black draw

これは予想される出力ですが、キャンバスが画像を描画するのはなぜですか? これはある種の競合状態ですか?修正するにはどうすればよいですか?

4

2 に答える 2

1

複数の画像をロードする場合は、作業を開始する前にすべての画像がロードされるように、画像ローダーを自分で作成することをお勧めします。

次に例を示します。

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>

<script>
$(function(){

  var canvas1=document.getElementById("canvas1");
  var ctx1=canvas1.getContext("2d");
  var canvas2=document.getElementById("canvas2");
  var ctx2=canvas2.getContext("2d");

  var imageURLs=[];
  var imagesOK=0;
  var imagesFailed=0;
  var imgs=[];
  imageURLs.push("http://upload.wikimedia.org/wikipedia/commons/d/d4/New_York_City_at_night_HDR_edit1.jpg");
  imageURLs.push("http://www.freebestwallpapers.info/bulkupload//20082010//Places/future-city.jpg");
  loadAllImages();

  function loadAllImages(){
      for (var i = 0; i < imageURLs.length; i++) {
        var img = new Image();
        imgs.push(img);
        img.onload = onLoad; 
        img.onerror = onFail;
        img.src = imageURLs[i];
      }      
  }

  var imagesAllLoaded = function() {
    if (imagesOK+imagesFailed==imageURLs.length ) {
       // all images are processed
       // ready to use loaded images
       // ready to handle failed image loads
       ctx1.drawImage(imgs[0],0,0,canvas1.width,canvas1.height);
       ctx2.drawImage(imgs[1],0,0,canvas2.width,canvas2.height);

    }
  };

  function onLoad() {
    imagesOK++;
    imagesAllLoaded();
  }

  function onFail() {
    // possibly log which images failed to load
    imagesFailed++;
    imagesAllLoaded();
  };   


}); // end $(function(){});
</script>

</head>

<body>
    <canvas id="canvas1" width=300 height=300></canvas><br/>
    <canvas id="canvas2" width=300 height=300></canvas>
</body>
</html>

これがJSFiddleです。

于 2013-04-03T21:07:46.180 に答える