canvasまとめ

基本

var CV = document.getElementById('canvas');
var CX = CV.getContext('2d');

canvasに対応しているかどうかは気にしない(気にするくらいだったら使わない)。

canvas自体のサイズを変える

CV.width = 256;
CV.height = 256;

CV.style.widthとかをいじると、canvas自体のサイズではなくて、表示サイズが変わって拡大縮小がかかる。

ビットマップをいじる

var DT = CX.getImageData(0, 0, CV.width, CV.height);
var DD = DT.data;

for (var p, y = 0; y < DT.height; ++y) {
  for (var x = 0; x < DT.width; ++x) {
    p = (x + y * DT.width) * 4;
    DD[p  ] = 255;
    DD[p+1] = 0;
    DD[p+2] = 0;
    DD[p+3] = 255;
  }
}

CX.putImageData(DT, 0, 0);

getImageDataとputImageDataを使う。ImageData.dataに画素情報が入っていてArrayっぽく操作できる。並びはR→G→B→alpha。

画像の描画

ImageとかIMG要素とかをdrawImageで描画できる。CANVAS要素も描画できるので、描画した一部分を拡大とかできる。

// (0,0)-(32,32)の範囲にいろいろ描画

// (0,0)-(32,32)を(0,0)-(256,256)に拡大して描画
CX.drawImage(CV, 0, 0, 32, 32, 0, 0, 256, 256);

座標

translate、scale、rotateで平行移動、拡大縮小、回転ができる。これらの変換は維持されるので、save→座標変換+描画→restoreとするのが無難。

setTransformやtransformで、せん断みたいな座標変換もできるけれども、3Dっぽいのは無理っぽい。

自分ルール

自分としては、左上が(0,0)になっているよりも、中央が(0,0)になっていたほうが楽。さらに、canvasのサイズが変更されても描画コードを変更しなくてもいいようになっていると楽。こういったことはtranslateとscaleで実現できる。

常に、(-300,-300)-(300,300)の範囲がcanvas内におさまるようにするにはこんな感じ。

var SIZE = 600, SIZE1_2 = SIZE >> 1;
var SCALE = 1;

function set_canvas_size() {
  var w = CV.width = window.innerWidth;
  var h = CV.height = window.innerHeight;
  SCALE = Math.min(w / SIZE, h / SIZE);
}

function my_draw() {
  CX.clearRect(0, 0, CV.width, CV.height);
  CX.save();
  CX.translate(SIZE1_2, SIZE1_2);
  CX.scale(SCALE, SCALE);

  // 描画コード

  // ↓これは常に画面の中央いっぱいに正方形の枠が描かれる
  CX.strokeRect(-SIZE1_2, -SIZE1_2, SIZE, SIZE);

  CX.restore();
}

window.addEventListener('resize', function() {
  set_canvas_size();
  my_draw();
}, false);