トラブルシュート

canvas・WebGLが動かないときの原因と対処

AIに作らせたゲームやビジュアル表現を共有したら、canvasが真っ白で何も表示されない――そんなときは描画の前提が崩れていることがほとんどです。コンテキスト取得、サイズ指定、リソース読み込みの順にたどれば原因はすぐ見つかります。この記事で確認点を整理します。

まずコンテキストが取得できているか確認する

canvasに描画するには、最初にgetContextで描画コンテキストを取得します。2D描画なら getContext('2d')、WebGLなら getContext('webgl') または getContext('webgl2') です。ここで返り値がnullになっていると、その後の描画コードは一切効きません。真っ白になる典型はここです。

WebGLは環境によって無効化されていることがあります。古い端末、特定のブラウザ設定、リモートデスクトップ経由などでハードウェアアクセラレーションが切られていると、webglコンテキストがnullで返ります。webgl2が取れない場合にwebglへフォールバックする、取得できなければ案内を表示する、といった分岐を入れておくと原因の特定が早まります。

コンテキスト取得の直後にコンソールへ結果を出力しておくと、表示されないのが「取得失敗」なのか「描画ロジックの問題」なのかを切り分けられます。

canvasのサイズ指定を間違えていないか

canvasには2種類のサイズがあります。HTML属性のwidth/height(描画バッファの解像度)と、CSSのwidth/height(表示上の大きさ)です。この2つは別物で、混同すると描画がずれたり、にじんだり、何も見えなくなったりします。

よくある失敗は、CSSでだけ大きさを指定してwidth/height属性を設定し忘れるケースです。この場合バッファは初期値の300×150のままで、その外側に描いた図形は見えません。逆に属性とCSSの比率が食い違うと、内容が引き伸ばされてぼやけます。高解像度ディスプレイ対応では devicePixelRatio を掛けてバッファ解像度を上げるのが定石です。

  • width/height属性は描画バッファの実ピクセル数
  • CSSのwidth/heightは画面上の表示サイズ
  • 両方を意図して設定し、必要なら devicePixelRatio で補正する
  • 属性を未設定にすると300×150の初期値になる

症状別チェック表

canvas・WebGLが動かないときの原因と対処は、症状を分けずに直そうとすると原因探しが長引きます。まず「自分だけで起きるのか」「全員で起きるのか」「特定ブラウザだけか」「差し替え後だけか」を切り分けます。

確認順序を固定すると、相対パス、ファイル名、キャッシュ、認証、外部読み込みのどこで止まっているかが見えます。修正後はローカル確認だけで終わらせず、実際の共有URLで再表示して、相手と同じ条件で直ったことを確認します。

  • 自分だけ表示されない: キャッシュ、ログイン状態、ブラウザ拡張、端末幅を確認する
  • 全員で表示されない: ファイル構成、相対パス、大文字小文字、アップロード漏れを見る
  • 一部だけ崩れる: CSS/画像/JSごとに読み込みエラーを分ける
  • 差し替え後だけ古い: URL、キャッシュ、更新対象ファイルの取り違えを確認する

画像やテクスチャの読み込み完了を待っているか

drawImageや、WebGLでのテクスチャ転送は、画像の読み込みが終わる前に呼んでも反映されません。Imageオブジェクトを作ってすぐ描画すると、まだ中身が空なので何も出ません。onloadイベントの中で描画する、あるいはawaitで読み込み完了を待ってから描く、という順序が必要です。

外部URLの画像をWebGLのテクスチャに使う場合はCORSの制約も関わります。クロスオリジン画像を適切な設定なしに読み込むと、canvasが汚染(tainted)状態になり、WebGLでのテクスチャ利用や toDataURL がエラーになります。画像側がCORSを許可しているか、crossOriginの指定が適切かを確認してください。

描画されないときの切り分け手順

原因が読めないときは、上流から順に潰すのが確実です。次の順番でチェックすると、どこで止まっているかが見えてきます。

  1. ブラウザの開発者ツールを開き、コンソールにエラーが出ていないか確認する
  2. getContextの返り値がnullでないかをログ出力で確かめる
  3. canvasのwidth/height属性が意図した値か、要素を検証して見る
  4. 画像やフォントなどのリソースがNetworkタブで200で読めているか確認する
  5. 単純な塗りつぶし矩形を1つ描いて、最小構成で表示されるか試す
  6. 表示されたら、そこから本来の描画ロジックを少しずつ戻していく

共有して第三者の環境でも確認する

canvasやWebGLは、書いた本人の環境では動いても、別のブラウザや端末では再現しないことがよくあります。ハードウェアアクセラレーションの有無やGPUの差で挙動が変わるためです。自分のPCだけで判断せず、複数環境で見てもらうのが安全です。

ギガサイト便を使うと、作ったHTMLをドロップするだけで 〇〇.giga-site.com の共有URLが発行され、HTTPS配信で他の人にすぐ見てもらえます。同じURLのままファイルを差し替えられるので、サイズ指定やコンテキスト取得を直すたびにリンクを送り直す必要はありません。レビュー相手の端末で表示を確かめてもらう用途に向いています。

よくある質問

canvasが真っ白で何も表示されません。最初にどこを見ればよいですか。

まずgetContextの返り値がnullでないかを確認してください。nullなら描画は一切効きません。次にcanvasのwidth/height属性が設定されているか、コンソールにエラーが出ていないかを見ます。多くの場合この2点で原因が見つかります。

WebGLだけが動きません。原因は何が考えられますか。

環境側でWebGLが無効化されている可能性があります。古い端末やハードウェアアクセラレーションを切った設定だと、webglコンテキストがnullで返ります。webgl2が取れない場合にwebglへフォールバックし、取得できなければ案内を出すようにしておくと切り分けが楽です。

画像をcanvasに描いても表示されません。

読み込み完了前に描画している可能性が高いです。Imageのonload内で描く、またはawaitで読み込みを待ってから描いてください。外部URLの画像の場合はCORS設定によりcanvasが汚染され、利用が制限されることもあります。

自分のPCでは動くのに他の人の環境では表示されません。

GPUやブラウザ設定の差で挙動が変わるためです。複数の環境で確認するのが確実です。ギガサイト便で共有URLを発行すれば、相手の端末で実際に表示されるかをすぐ確かめてもらえます。

原因が分からないときはどこから確認すべきですか?

まず自分だけの問題か全員の問題かを分けます。次にシークレットウィンドウ、別ブラウザ、スマホで確認し、ファイル構成・相対パス・キャッシュ・認証設定を順に見ます。

関連記事

トラブルシュート

公開後にJavaScriptが動かないときの原因と直し方

ローカルでは動いていたボタンやアニメーションが公開後に反応しなくなった方向け。JavaScriptが止まる主な原因をファイルパスや読み込み順の観点で切り分け、自分で直せるかどうかを判断できます。

5分で読める
トラブルシュート

共有先でパスワードが通らないときの対処

パスワード認証で共有した資料に相手がアクセスできず困っているなら、まずこの記事で原因を絞り込めます。入力ミスから文字コードの違いまで、よくある詰まりどころと対処手順を順番に整理しました。

4分で読める
トラブルシュート

localStorageが使えない・保存されないときの対処

リロードすると保存した内容が消えてしまうlocalStorageのトラブルを、プライベートモード・容量上限・JSON変換漏れの観点から切り分けて解決したい開発者向けの実践的な解説です。

5分で読める
トラブルシュート

CSS・JSアニメーションが動かないときの対処

ホバーで何も起きない、要素がふわっと出てこないアニメーション不具合の原因を、変化前後の状態・タイミング・対象プロパティの観点から切り分けて解決したい人向けの解説です。

6分で読める
トラブルシュート

スマホでホバーが効かないときの対処

PCでは動くホバー演出がスマホでは効かない・タップ後に状態が残るのは、タッチ端末にホバー状態がないことが根本原因です。スマホで意図通り動く実装に切り替えるための考え方と方法を解説します。

5分で読める
トラブルシュート

外部APIが呼べない・データが出ないときの対処

JavaScript で外部 API を叩いたのにデータが出ず、コンソールに赤いエラーが並ぶ。CORS・API キー・HTTPS の3パターンそれぞれでエラーの出方が違います。見分け方と対処を素早く特定する手順を解説します。

6分で読める
「トラブルシュート」の記事をもっと見る →