29033
フォルダ内のpngデータをcanvasに描画したいのですが。  
以下のようなerrorをもらってしまいました。

chrome

```

    Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': 
    The provided value is not of type '(HTMLImageElement or HTMLVideoElement or HTMLCanvasElement 
    or ImageBitmap)'
    
```

safari

```

    drawImage — index.html:39TypeError: Type error
    
```

type errorと書いてあるのでdrawImage近辺でくまなく探したのですが。どうしても発見できません。  
試しにfillRectで四角を描画したら正常に描画できました。  
どうしてもわからないので教えて下さい。

```

      window.addEventListener('load', eventWindowLoadew,false);
    function eventWindowLoadew(){
      canvasApp();
    }
    function canvasSupport(){
      return Modernizr.canvas;
    }
    function canvasApp(){
      if(!canvasSupport()){
        return;
      } else {
        var canvas = document.getElementById("mycanvas");
        var ctx = canvas.getContext("2d");
      }
      drawScreen();
    
      var image1 = new Image();
      image1.src = "mon_024.png";
      image1.addEventListener("load", eventMonsterLoaded, false);
    
      function eventMonsterLoaded(){
        drawScreen();
      }
      function drawScreen(){
          ctx.drawImage(image1, 0, 0); //39行目です。ここにエラーがでます。
      }
    }
    
```
CC BY-SA 3.0
2016-09-21T13:01:00.640
29032
2023-05-07T09:23:56.470
2023-05-07T09:23:56.470
4236
18870
question
javascript html html5
HTML５canvasでpngデータを描画したいのですが、つまづいています。
```

    function canvasApp(){
      if(!canvasSupport()){
        return;
      } else {
        var canvas = document.getElementById("mycanvas");
        var ctx = canvas.getContext("2d");
      }
      drawScreen();   // ←
    
      var image1 = new Image();
    
```

この時点ではまだ`image1`には何も代入されておらず`ctx.drawImage()`に失敗するのも当然です。

* * *

蛇足ですが

```

    var image1 = new Image();
    image1.src = "mon_024.png";
    image1.addEventListener("load", eventMonsterLoaded, false);
    
```

この順ですと`mon_024.png`がキャッシュ済みの場合に先に読み込みが完了してしまって`load`イベントが発生しないことがあります。先に`addEventListener()`すべきです。

* * *

`Image()`（＝`<img>`要素）では`load`イベントを待つ必要がありました。近年は[`fetch`関数](https://developer.mozilla.org/ja/docs/Web/API/fetch)および[`createImageBitmap`関数](https://developer.mozilla.org/ja/docs/Web/API/createImageBitmap)が利用できます。これらを使うとイベントに頼らない実装ができます。

```

    fetch("mon_024.png")
    .then(response => response.blob())
    .then(blob => createImageBitmap(blob))
    .then(image => ctx.drawImage(image, 0, 0));
    
```

もしくは`await function`内であれば

```

    const response = await fecth("mon_024.png");
    const blob = await response.blob();
    const image = await createImageBitmap(blob);
    ctx.drawImage(image, 0, 0);
    
```
CC BY-SA 4.0
2016-09-21T13:20:06.633
29033
2023-05-07T09:23:49.237
2023-05-07T09:23:49.237
4236
4236
29032
answer