この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:11
ページ更新者:guest
更新日時:2026-06-11 07:07:02

タイトル: Canvas API
SEOタイトル: HTML5 Canvas API 入門(描画 / アニメーション / Three.js / PixiJS への発展)

この記事の要点
  • Canvas API は 要素 + JavaScript でブラウザにビットマップ描画する API
  • canvas.getContext("2d") で 2D コンテキスト、"webgl" で 3D(OpenGL ES2 ラッパ)
  • 基本図形: fillRect / strokeRect / arc(円) / beginPath + moveTo + lineTo + stroke(線)
  • 画像・テキスト: drawImage(img, x, y) / fillText(text, x, y)
  • アニメーションは requestAnimationFrame。複雑になったら PixiJS(2D)・Three.js(3D)を使う

Canvas API とは

HTML5 で導入された 要素は、JavaScript からピクセル単位で描画できるビットマップキャンバスです。ゲーム、グラフ、画像処理、データビジュアライゼーションなど幅広く使われます。

最小サンプル: 四角形を描く







width / height は CSS でなく属性で指定するのが鉄則。CSS で指定すると拡大表示になりピクセルがぼやけます。

基本図形の描画

// 直線
ctx.beginPath();
ctx.moveTo(50, 50);
ctx.lineTo(200, 100);
ctx.lineTo(50, 150);
ctx.closePath();      // パスを閉じる
ctx.stroke();         // 線として描画
// ctx.fill();        // 塗りつぶし

// 円 / 円弧
ctx.beginPath();
ctx.arc(300, 100, 50, 0, Math.PI * 2);  // x, y, r, 開始角, 終了角(ラジアン)
ctx.fillStyle = '#2ecc71';
ctx.fill();

// 半円
ctx.beginPath();
ctx.arc(400, 100, 50, 0, Math.PI);
ctx.stroke();

// 二次ベジェ曲線
ctx.beginPath();
ctx.moveTo(50, 200);
ctx.quadraticCurveTo(150, 100, 250, 200);  // 制御点, 終点
ctx.stroke();

テキスト描画

ctx.font = 'bold 32px sans-serif';
ctx.fillStyle = '#2c3e50';
ctx.textAlign = 'center';        // start | end | left | right | center
ctx.textBaseline = 'middle';     // top | hanging | middle | alphabetic | ideographic | bottom
ctx.fillText('Hello Canvas', 250, 50);

// 枠線のみ
ctx.strokeStyle = '#e74c3c';
ctx.lineWidth = 2;
ctx.strokeText('Outline', 250, 100);

// 文字幅を測る
const m = ctx.measureText('Hello');
console.log(m.width);  // pixel

画像の描画

const img = new Image();
img.src = '/path/to/photo.jpg';
img.onload = () => {
    // 原寸
    ctx.drawImage(img, 50, 50);

    // サイズ指定
    ctx.drawImage(img, 50, 50, 200, 150);

    // 切り抜き + 配置(sx, sy, sw, sh, dx, dy, dw, dh)
    ctx.drawImage(img, 0, 0, 100, 100, 300, 50, 200, 200);
};

変形(回転・拡大・移動)

ctx.save();                          // 状態を保存
ctx.translate(250, 150);             // 原点を移動
ctx.rotate(Math.PI / 4);             // 45 度回転
ctx.scale(1.5, 1.5);                 // 1.5 倍拡大
ctx.fillStyle = '#9b59b6';
ctx.fillRect(-50, -25, 100, 50);     // 移動後の原点が中心
ctx.restore();                       // 元の状態に戻す

アニメーション: requestAnimationFrame

毎フレーム描き直すには requestAnimationFrame を使います。setInterval ではブラウザの再描画タイミングと同期しないのでカクつきます。

let x = 0;
let vx = 2;

function tick() {
    // 1. 画面クリア
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    // 2. 状態更新
    x += vx;
    if (x > canvas.width - 50 || x < 0) vx = -vx;

    // 3. 描画
    ctx.fillStyle = '#3498db';
    ctx.fillRect(x, 100, 50, 50);

    // 4. 次フレームを予約
    requestAnimationFrame(tick);
}

tick();

マウス入力でお絵描き

let drawing = false;
canvas.addEventListener('mousedown', e => {
    drawing = true;
    ctx.beginPath();
    ctx.moveTo(e.offsetX, e.offsetY);
});
canvas.addEventListener('mousemove', e => {
    if (!drawing) return;
    ctx.lineTo(e.offsetX, e.offsetY);
    ctx.stroke();
});
canvas.addEventListener('mouseup', () => drawing = false);

Canvas API でできることの限界

用途素の Canvas推奨ライブラリ
簡単な図形・グラフOKChart.js
2D ゲーム(スプライト多数)遅いPixiJS(WebGL 加速)
3D 描画不可(getContext("webgl") 必要)Three.js / Babylon.js
SVG 的なベクタパスは描けるが座標管理が大変SVG + D3.js
動画フィルタgetImageData / putImageData で可能WebGL + シェーダ

WebGL コンテキストへの拡張

// 2D → 3D の入り口
const gl = canvas.getContext('webgl2');
if (!gl) {
    alert('WebGL2 がサポートされていません');
}

// 実際は Three.js を使うのが現実的
// npm install three
import * as THREE from 'three';
const scene  = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, w/h, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ canvas });
const cube = new THREE.Mesh(
    new THREE.BoxGeometry(),
    new THREE.MeshNormalMaterial()
);
scene.add(cube);
camera.position.z = 3;

renderer.setAnimationLoop(() => {
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;
    renderer.render(scene, camera);
});

FAQ

Q: Canvas で描いた絵を画像保存したい
A: canvas.toDataURL('image/png') で base64 取得、canvas.toBlob(cb) で Blob 取得が可能です。

Q: 高 DPI(Retina)でぼやける
A: canvas.width = w * devicePixelRatio にして ctx.scale(devicePixelRatio, devicePixelRatio)、CSS 側は w px に。

Q: SVG とどちらが良い?
A: 拡大に強く要素単位でイベント取りたいなら SVG、ピクセル制御や多数オブジェクトのアニメは Canvas が高速です。