Canvasのサイズ設定

CSSでCanvasサイズを設定しようとすると歪んだ表示になってしまう。


const size = 300;
canvas.style.width = `${size}px`;
canvas.style.height = `${size}px`;

ctx.fillStyle = '#0055aa';
ctx.fillRect(0, 0, size, size);
ctx.fillStyle = '#557799';
ctx.fillRect(20, 20, size - 40, size - 40);

原因は、Canvas要素がデフォルトで持つ縦横サイズに対し、CSSで引き伸ばした表示にしようとするため。CSSを当てる場合は先にCanvas要素のサイズを設定する。


// 最初に要素のサイズを固定してから...
const canvasSize = 300;
canvas.width = canvasSize;
canvas.height = canvasSize;

ctx.fillStyle = '#0055aa';
ctx.fillRect(0, 0, canvasSize, canvasSize);
ctx.fillStyle = '#557799';
ctx.fillRect(20, 20, canvasSize - 40, canvasSize - 40);

// CSSで見た目のサイズを設定する
const cssSize = 150;
canvas.style.width = `${cssSize}px`;
canvas.style.height = `${cssSize}px`;

*CSSを当てた後にctx.fillRectするのは問題ない

Retinaディスプレイの対応

Retinaディスプレイで曲線を含む描画をするとぼやけた表示になる


  ctx.fillStyle = '#557799';
  ctx.fillRect(20, 20, canvasSize - 40, canvasSize - 40);

  ctx.fillStyle = '#aaccff';
  ctx.font = `${canvasSize - 40}px Arial`;
  ctx.textBaseline = 'top';

  ctx.fillText('あ', 20, 40);

「Retinaディスプレイでも画像をぼやけさせない処置」と同様に、一旦Canvasを大きいサイズにしてから縮小させることでぼやけを解消する


  // 最初に要素のサイズを固定してから...
  const canvasSize = 200;
  canvas.width = canvasSize;
  canvas.height = canvasSize;

  // 解像度に合わせた拡大率を指定する
  const scale = window.devicePixelRatio;
  ctx.scale(scale, scale);

scaleを設定しても、canvas要素自体は大きくならないのでscaleを設定前に、Canvasのサイズも大きくしておく


  const scale = window.devicePixelRatio;

  // 最初に要素のサイズを固定してから...
  const canvasSize = 200;
  canvas.width = canvasSize * scale;
  canvas.height = canvasSize * scale;

  // 拡大率を指定する
  ctx.scale(scale, scale);

scaleの指定で拡大した見た目になったCanvasをCSSの指定で本来のCanvasサイズに戻す


  const scale = window.devicePixelRatio;

  // 最初に要素のサイズを固定してから...
  const canvasSize = 200;
  canvas.width = canvasSize * scale;
  canvas.height = canvasSize * scale;

  // 拡大率を指定する
  ctx.scale(scale, scale);

  // scaleで拡縮した見た目になったcanvasをstyleで本来のcanvasサイズに戻す
  canvas.style.width = `${canvasSize}px`;
  canvas.style.height = `${canvasSize}px`;