怠日記

写真・金魚・昆虫・プログラミングの趣味を語るサイトです。似たようなことをnoteにも書いたり書いてなかったり。

Canvas 要素のレスポンシブ対応

Canvas 要素の表示サイズは width 属性と height 属性に固定値を設定するため、そのままではレスポンシブ対応できない。

CSSwidthheight を指定しても、表示サイズに対する相対サイズで拡大/縮小されるだけで期待したとおりには動かない。

代わりに padding-top を使ってレスポンシブ対応してみる。

サンプル

次の HTML は Canvas 要素をレスポンシブ表示する。

ブラウザのウインドウ幅に合わせて、Canvas 要素も比率を保ったまま拡大/縮小される。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Canvas 要素のレスポンシブ対応</title>
</head>
<body>
  <div style="position: relative; padding-top: 56.25%;">
    <canvas width="640" height="360" style="position: absolute; top: 0; left: 0; width: 100%; height: auto; border: 1px solid red;"></canvas>
  </div>
  <script>
    document.addEventListener('DOMContentLoaded', function () {
      var canvas = document.querySelector('canvas');
      if (canvas.getContext) {
        var ctx = canvas.getContext('2d');
        ctx.fillRect(25, 25, 100,100);
      }
    });
  </script>
</body>
</html>

ポイント

まずは Canvas 要素の親要素に次のスタイルを設定する。

<div style="position: relative; padding-top: 56.25%;">

padding-top には、Canvas 要素の面積比を設定する。

今回は Canvas 要素の表示サイズを 640 × 360 (アスペクト比 16:9)とするため、その面積比である 56.25% を指定している。

もしアスペクト比が 4:3 なら 75% を、3:2 なら 66.66667% を設定する。

それ以外のアスペクト比なら、後述の式を使って計算で求めた比率を設定すればよい。


続けて Canvas 要素のスタイルを設定する。

<canvas width="640" height="360" style="position: absolute; top: 0; left: 0; width: 100%; height: auto; border: 1px solid red;"></canvas>

属性の widthheight には表示する内容の幅と高さを設定する。
(省略した場合、既定値の幅 300px、高さ 150px が設定される)

style 属性の position: absolute; top: 0; left: 0; により、親要素の左上と同じ位置に Canvas 要素が配置される。

同じく style 属性の width: 100%; height: auto; により、幅に合わせて高さが可変となる。

なお、サンプルでは border スタイルも設定しているが、これは確認しやすくする用途なので実際には指定しなくてよい。

面積比の求め方

padding-top に設定する面積比を計算で求める場合、次の計算式を使う。

面積比 = (高さ÷幅)×100

例1: 16:9 の面積比を求める

(9 ÷ 16) × 100 = 
0.5625 × 100 = 
56.25

例2: 幅 800px、高さ 581px の面積比を求める

(581 ÷ 800) × 100 =
0.72625 × 100 =
72.625