「5分でわかるCanvas API」サンプル

Canvas APIの基礎

パスの描画

ctx.beginPath();
ctx.moveTo(0, 80);
ctx.bezierCurveTo(40, -50, 80, 100, 200, 0);
ctx.arcTo(150, 60, 180, 80, 10);
ctx.lineTo(180, 80);
ctx.closePath();
ctx.fillStyle   = "#ddf";
ctx.strokeStyle = "#00f";
ctx.fill();
ctx.stroke();

文字列描画の例

var text = "maxWidthで文字列を指定幅内に" +
           "収めることができます";
ctx.fillText(text, 0, 10);
ctx.fillText(text, 0, 30, 200);

font属性の指定

ctx.font = "normal normal 16px sans-serif";
ctx.fillText(ctx.font, 0, 16);

ctx.font = "italic normal 16px monospace";
ctx.fillText(ctx.font, 0, 40);

ctx.font = "normal bold 20px serif";
ctx.fillText(ctx.font, 0, 70);

textAlignの効果

ctx.font = "normal normal 16px sans-serif";

ctx.textAlign = "left";
ctx.fillText("textAlign = left", 150, 16);

ctx.textAlign = "right";
ctx.fillText("textAlign = right", 150, 40);

ctx.textAlign = "center";
ctx.fillText("textAlign = center", 150, 64);

文字列のアンダーラインを描画

var text = "文字列のアンダーラインを描画";

ctx.font = "normal normal 16px sans-serif";
ctx.textBaseline = 'bottom';
ctx.fillText(text, 0, 20);

var metrix = ctx.measureText(text);
ctx.beginPath();
ctx.moveTo(0, 20);
ctx.lineTo(metrix.width, 20);
ctx.strokeStyle = "black";
ctx.stroke();

画像の描画

var image = new Image();
image.onload = function() {
  ctx.drawImage(image, 0, 0);
};
image.src = "image01.jpg";

画像のリサイズ

var image = new Image();
image.onload = function() {
  ctx.drawImage(image, 0, 0, 200, 100);
};
image.src = "image01.jpg";

画像のトリミング

var image = new Image();
image.onload = function() {
  ctx.drawImage(
    image, 20, 40, 60, 60, 0, 0, 100, 100);
};
image.src = "image01.jpg";

描画スタイルの指定

線形グラデーション

var grad = ctx.createLinearGradient(0, 0, 0, 100);
grad.addColorStop(0.0,  "#feb");
grad.addColorStop(0.5,  "#fc4");
grad.addColorStop(0.51, "#fb0");
grad.addColorStop(1.0,  "#fd9");

ctx.fillStyle = grad;
ctx.fillRect(0, 0, 200, 100);

円形グラデーション

var grad = ctx.createRadialGradient(
  70, 30, 3, 50, 50, 50);
grad.addColorStop(0.0, "#fff");
grad.addColorStop(0.5, "#fb0");
grad.addColorStop(0.9, "#c90");
grad.addColorStop(1.0, "#a80");

ctx.fillStyle = grad;
ctx.beginPath();
ctx.arc(50, 50, 50, 0, Math.PI*2, false);
ctx.fill();

パターン

var image = new Image();
image.onload = function() {
  var pat = ctx.createPattern(image, "repeat");

  ctx.fillStyle = pat;
  ctx.fillRect(0, 0, 200, 100);
};
image.src = "image02.png";

線幅の指定

var values = [1, 3, 7, 11];
var y = 1.5;
for(var i = 0 ; i < 4 ; i++) {
  ctx.lineWidth = values[i];
  ctx.beginPath();
  ctx.moveTo(0, y);
  ctx.lineTo(200, y);
  ctx.stroke();
  y += values[i] + 10;
}

端点のスタイル

ctx.lineWidth = 10;

var values = ["butt", "round", "square"];
var y = 10;
for(var i = 0 ; i < 3 ; i++) {
  ctx.lineCap = values[i];
  ctx.beginPath();
  ctx.moveTo(10, y);
  ctx.lineTo(190, y);
  ctx.stroke();
  y += 20;
}

接続点のスタイル

ctx.lineWidth = 10;
var values = ["miter", "miter", "round", "bevel"];
var limits = [4, 2, 4, 4];
for(var i = 0 ; i < 4 ; i++) {
  var x = 70 * i;
  ctx.lineJoin   = values[i];
  ctx.miterLimit = limits[i];
  ctx.beginPath();
  ctx.moveTo(x + 40, 50);
  ctx.lineTo(x + 10, 10);
  ctx.lineTo(x + 60, 10);
  ctx.stroke();
}

globalAlphaによる半透明描画

var image = new Image();
image.onload = function() {
  ctx.drawImage(image, 0, 0);
  ctx.globalAlpha = 0.5;
  ctx.drawImage(image, 50, 30);
};
image.src = "image01.jpg";

CSSカラーによる半透明描画

ctx.fillStyle = "rgba(255, 0, 0, 1.0)";
ctx.fillRect(0, 0, 100, 80);

ctx.fillStyle = "rgba(0, 0, 255, 0.5)";
ctx.fillRect(50, 30, 100, 80);

座標変換と合成

座標変換

var image = new Image();
image.onload = function() {
  ctx.save();
  ctx.translate(55, 55);
  ctx.rotate(Math.PI/4);
  ctx.translate(-55, -55);
  ctx.drawImage(image, 16, 16, 78, 78);
  ctx.restore();
};
image.src = "image01.jpg";

globalCompositeOperationの効果

var modes = [
  'source-atop', 'source-in', 'source-out', 'source-over',
  'destination-atop', 'destination-in', 'destination-out',
  'destination-over', 'lighter', 'copy', 'xor'];
var image = new Image();
image.onload = function() {
  for(var i = 0 ; i < 11 ; i++) {
    var ctx = document.getElementById('c18-' + i).getContext('2d');
    ctx.drawImage(image, 0, 0, 50, 50);
    ctx.globalCompositeOperation = modes[i];
    ctx.drawImage(image, 20, 20, 50, 50);
    ctx.globalCompositeOperation = 'source-over';
    ctx.font      = 'normal normal 10px sans-serif';
    ctx.textAlign = 'center';
    ctx.fillText(modes[i], 35, 80, 70);
  }
};
image.src = "image01.jpg";

クリッピング

var image = new Image();
image.onload = function() {
  ctx.save();
  ctx.beginPath();
  ctx.arc(50, 50, 50, 0, Math.PI*2, false);
  ctx.clip();
  ctx.drawImage(image, 0, 0);
  ctx.restore();
};
image.src = "image01.jpg";

図形の影を表示

ctx.shadowColor   = "rgba(0, 0, 0, 0.5)";
ctx.shadowOffsetX = 4;
ctx.shadowOffsetY = 4;
ctx.shadowBlur    = 10;
ctx.fillStyle = "#c44";
ctx.fillRect(5, 5, 180, 80);

アニメーションとその他の機能

アニメーション

var image = new Image();
image.onload = function() {
  function tick() {
    ctx.clearRect(0, 0, 150, 150);

    var a = +new Date() % 4000 / 2000 * Math.PI;
    ctx.save();
    ctx.translate(75, 75);
    ctx.rotate(a);
    ctx.translate(-75, -75);
    ctx.drawImage(image, 25, 25);
    ctx.restore();

    requestAnimFrame(tick);
  }
  requestAnimFrame(tick);
};
image.src = "image01.jpg";

ヒットテスト

function buildPath() {
  ctx.beginPath();
  ctx.rect(50, 10, 100, 80);
}

canvas.onclick = function(e) {
  var x = event.clientX + window.pageXOffset - canvas.offsetLeft;
  var y = event.clientY + window.pageYOffset - canvas.offsetTop;
  buildPath();
  if(ctx.isPointInPath(x, y)) {
    alert('クリックされました');
  }
};

buildPath();
ctx.fillStyle = '#c44';
ctx.fill();
ctx.fillStyle = 'black';
ctx.fillText('ここをクリック', 60, 30);

toDataURL()の使用例

ctx.fillStyle = "#c44";
ctx.fillRect(0, 0, 80, 80);
ctx.fillStyle = "#44c";
ctx.fillRect(20, 20, 80, 80);

var img = document.createElement('img');
img.src = canvas.toDataURL('image/png');
canvas.parentNode.appendChild(img);

ビットマップの操作

ctx.fillStyle = "#c44";
ctx.fillRect(0, 0, 80, 80);
ctx.fillStyle = "#44c";
ctx.fillRect(20, 20, 80, 80);

var img = document.createElement('img');
img.src = canvas.toDataURL('image/png');
canvas.parentNode.appendChild(img);