canvasで簡単なお絵かきをしてみたメモ

タイトルのまんまです。
Firefox/Chromeあたりで動きます。

デモページ

html

canvasを用意しとくだけです。
canvas内の座標を取るときに、layerX/Y で取りたいので、styleにposition:relativeを当てておきます。
(positionが当たってないと、layerX/Yは pageX/Y の値と等しくなるらしいので。
positionを当てたくないなら、pageX/Yからcanvasのオフセットを引いたりすることになるんでしょうか。)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>

<canvas id="c" style="position:relative; border:3px solid #999" width="600" height="480"></canvas>

</body>
</html>

javascript

var cEle, cCtx;
var drawing = false;  // ドラッグ中フラグ

window.addEventListener('load', function() {  // window onload
    cEle = document.getElementById('c');
    cCtx = cEle.getContext('2d');

    // canvasの設定
    cCtx.lineJoin    = 'round';  // 角を丸く
    cCtx.lineCap     = 'round';  // 線の終端を丸く
    cCtx.lineWidth   = 5;        // 線の幅
    cCtx.strokeStyle = '#00F';   // 線の色

    // event
    cEle.addEventListener('mousedown', start, false);  // canvas上のmousedownイベントでstart()を呼び出す
    cEle.addEventListener('mousemove', move, false);   // canvas上のmousemoveイベントでmove()を呼び出す
    window.addEventListener('mouseup', stop, false);   // window上のmouseupイベントでstop()を呼び出す
}, false);

function start(event) {
    cCtx.beginPath();  // サブパスリセット

    cCtx.moveTo(event.layerX, event.layerY);  // 初期座標を指定
    drawing = true;  // ドラッグ中フラグを立てる

    move(event);  // ドラッグせずにすぐmouseupした場合に、点を書くため
}
function move(event) {
    if (!drawing) return;

    cCtx.lineTo(event.layerX, event.layerY);  // 直前の座標と現在の座標を直線で繋ぐ
    cCtx.stroke();  // canvasに描画
}
function stop(event) {
    if (!drawing) return;

    cCtx.closePath();  // サブパスを閉じる
    drawing = false;   // ドラッグ中フラグを落とす
}

stop()をcanvasでなくwindowに登録しているのは、
canvas上でmousedownし、ドラッグしたままcanvas外まで出てからmouseupした際にもちゃんと動作するためです。


クリックした場合、Firefoxでは点が描画されますが、Chromeでは描画されません。
また、FirefoxでもlineCapがroundでないと点は描画されません。


おまけ

ネット上の画像をcanvasに描画できる機能を追加してみます。

html

画像のURLを入力するフォームを追加

<form onsubmit="loadImage(this.image_url.value); return false;">
  Image URL:
  <input type="text" size="80" name="image_url" />
  <input type="submit" value="load" />
</form>
javascript
function loadImage(imgUrl) {
    var img = new Image();
    img.src = imgUrl + '?' + (new Date/1);  // 一応、キャッシュ対策とかしとく
    img.onload = function() {
        cCtx.drawImage(img, 0, 0);  // 画像が読み込めたらcanvasに描画
    }
    img.onerror = function() {
        alert('image load error');
    }
}

リサイズとか何もせずにただ描画しているので、はみ出した部分は描画されません。


Chromeは無理ですが、Firefoxなら [右クリック] --> [名前を付けて画像を保存] で
canvasの画像をローカルに保存できます。


(※) なお、紹介したコードはわかりやすく書くために、グローバル変数とか気にせず使ってますが、
本当ならクラスとか作って、その中に閉じ込める方がベターです。


各メソッドやプロパティなどの詳細は、Canvasリファレンス - HTML5.JP を参照。