JavaScriptでお絵描きできるcanvas要素



JavaScriptでお絵描きできるcanvas要素

最近のWebブラウザには、JavaScriptで「お絵描き」が楽しめる「キャンバス(canvas要素)」を置くことができます。実際にどんな感じで絵を描くことができるのか、試してみることにしましょう。

目次
  1. Webブラウザに「お絵描き」できるcanvas要素
  2. canvas要素に長方形を描く
  3. canvas要素に文字列を描く
  4. canvas要素に画像を描く
  5. Webブラウザで手軽なお絵描きプログラミング

Webブラウザに「お絵描き」できるcanvas要素

canvas要素は、Webブラウザの画面内に動的(表示時にプログラムで操作可能)な描画領域を作る仕組みです。Webブラウザ上にcanvas要素を配置すると、その部分は画像(img要素)に近い感覚で扱える描画領域になります。

描画機能のAPIには、長方形、パス(経路)を指定した多角形、円、文字列などを描くための基本的な機能が用意され、JavaScriptに読み込んだ画像を描画することも可能です。さらに、canvas要素の各ピクセルの色を直接読み書きするフレームバッファ機能も用意されています。

通常の「グラフィックプログラミング」に必要なものは、一通り用意されていると言えるでしょう。各ピクセルの色を直接設定できるので、標準機能に不足があってもやろうと思えば(自力計算で)「何でもあり」です(現実的かどうかはともかく)。

canvas要素に描かれた画像は、通常の画像と同じくユーザーが画像ファイルに保存したりJavaScriptからpngやjpegのデータを取得することも可能です。つまり、Web上でちょっとした画像処理を行って処理結果を表示、さらに画像ファイルとして保存する「画像処理アプリケーション」を開発することもできます。

では実際にcanvas要素を配置したhtmlファイルを作成し、JavaScriptで何か描いてみましょう。

html内にcanvas要素を配置するには、以下のようなcanvasタグを記述します。

<canvas id="test_canvas" width=256 height=256></canvas>

JavaScriptから扱いやすいように、idと大きさも指定してみました。

JavaScriptからcanvas要素を扱うには、「context」が必要になります。contextは、以下のようにcanvas要素のgetContext()メソッドで取得します。

var test_context = document.getElementById('test_canvas').getContext('2d');

今回は、getContext()の引数に基本的な描画機能を利用するための「2d」を指定しました。getContext()の引数によっては、WebGL(Webブラウザ向けOpenGL ES)を通して高度な演算・描画処理を行うWebGL用contextを取得することもできます。

実際に描画を行う際は、このcontextのプロパティやメソッドを通してcanvas要素にアクセスするわけです。

以上の流れを一つのhtmlファイルにまとめたのが、以下になります。

<!DOCTYPE html>
<html>
<body>

<canvas id="test_canvas" width=256 height=256 style="border: 1px solid;"></canvas>

<script>
var test_context = document.getElementById('test_canvas').getContext('2d');
</script>

</body>
</html>

このhtmlを適当なファイル名で保存したら、Webブラウザで表示してください。枠で囲われたcanvas要素が表示されるはずです。

image

canvas要素に長方形を描く

これでtest_contextを通してcanvas要素に描画できる状態になったので、Webブラウザのアドレス欄に以下のようなJavaScriptのコードを入れて改行キーを押してみましょう。

javascript:test_context.fillRect(64,64,128,128)

枠で囲われたcanvas要素内に、黒い正方形が描かれたと思います。contextのfillRect()は、「左上のx/y座標と幅/高さ」を指定して塗りつぶし長方形を描く関数です。事前に色を設定していないので、デフォルトの黒で描かれました。

塗りつぶしの色は、fillStyleプロパティで設定できます。たとえば、以下のようにするとcontextの塗りつぶし色は、青(0000ff)に設定されます。

test_context.fillStyle = '#0000ff';

先ほどのhtmlを以下のように書き換えて、リロードしてみましょう。

<!DOCTYPE html>
<html>
<body>

<canvas id="test_canvas" width=256 height=256 style="border: 1px solid;"></canvas>

<script>

var test_context = document.getElementById('test_canvas').getContext('2d');

test_context.fillStyle = '#0000ff';
test_context.fillRect(64,64,128,128)

</script>

</body>
</html>

fillStyleの設定が反映されて、青い正方形が表示されました。

image

今度は、塗りつぶさない輪郭だけの長方形を描いてみましょう。fillRect()の代わりにstrokeRect()という関数を使ってみます。

輪郭を描くときも、色などの設定が可能です。輪郭(contextで描く線)の色は、strokeStyleプロパティで設定します。たとえば、輪郭を赤線にしたいなら以下のようにします。

test_context.strokeStyle = '#ff0000';

さらに、線の太さもlineWidthプロパティで設定できます。少し太めに描いてみましょうか。

test_context.lineWidth = 8;

線の設定を行ったら、実際に描いてみます。

<!DOCTYPE html>
<html>
<body>

<canvas id="test_canvas" width=256 height=256 style="border: 1px solid;"></canvas>

<script>

var test_context = document.getElementById('test_canvas').getContext('2d');

test_context.strokeStyle = '#ff0000';
test_context.lineWidth = 8;

test_context.strokeRect(32, 32, 64, 64);

</script>

</body>
</html>

Webブラウザ上に図形が描かれているのを確認したら、通常の画像と同じく「保存」してみてください。たとえばWindows版のChromeなら、canvas要素の上で右クリックすると出てくるコンテキストメニューから名前を付けて保存できます。

image

canvas要素に文字列を描く

次に、文字列を描いてみましょう。

文字列も、中を塗りつぶすfillText()と輪郭だけを描くstrokeText()が用意されていて、いずれも引数に「文字列, x座標, y座標」を指定します(オプションで最大幅を追加指定することもできます)。

輪郭正方形を描くhtmlのstrokeRect()を、以下のようにstrokeTextに差し替えて再度読み込んでみてください。

test_context.strokeText("abc", 64, 64);

なにやらごちゃごちゃした「赤い塊」が描かれましたね……

image

デフォルトのフォントが小さめなので、太い線で描くと線に埋もれてしまうようです。fontプロパティで大き目のフォントに変更してみましょう。

fontプロパティには、cssのfontと同じ形式でフォント設定を行えるので、以下の文をstrokeText()の前に入れてみてください。

test_context.font = '72px serif';

今度は、大きな文字が太線で描かれました。

先の例では文字列が指定x座標に対して「左寄せ」で描かれましたが、中央寄せにしたい場合もあるでしょう。その場合は、textAlignプロパティに「center」を指定すると、文字列描画関数に渡すx座標が中央に来るように文字列を描くことができます。

今回作成したcanvas要素は、width(横幅)を256に設定していたので

test_context.textAlign = 'center';
test_context.strokeText("abc", 128, 64);

とすると、ちょうど中央に描かれます。

image

canvas要素に画像を描く

以上、長方形や文字列を描く方法を見てきましたが、続いてcanvas上に画像を描いてみることにします。

canvas要素に画像を描くためには、まずJavaScriptで画像を読み込む必要があります。

画像はhtml内のimg要素でも良いのですが、今回はImageオブジェクトを使用してみました。Imageオブジェクトは、画像を保持するオブジェクトです。srcプロパティに画像の場所を指定すると画像を読み込み、JavaScriptから利用できるようになります。

ただ、実際の描画は画像の読み込みが終わってから行う必要があるので、「onload」プロパティで「画像の読み込みが終わったら実行する関数」を設定しておきます。

以下のようにすると、同じディレクトリにあるtest.jpgをImageオブジェクトimgに読み込んで、読み込みが終わったらdraw()関数を実行することができます。

var img = new Image();
img.onload = draw;
img.src = 'test.jpg';

src(Imageオブジェクトに読み込む画像)は、onloadイベント設定の後に指定している点に注意してください。この順序を逆にするとonloadが設定される前に読み込みが終わってしまい、draw()関数が呼ばれなくなる可能性があります。

画像を読み込んだら、実際にcontextを通して描画を行います。画像の描画に使用する関数は、drawImage()関数です。

drawImage()には、いくつもの呼び出し(引数)の形がありますが、まずは一番簡単な「描画する画像, x座標, y座標」の形で試してみましょう。

以下のhtmlファイルを作成し、適当な画像test.jpgと同じディレクトリに置いた上でWebブラウザで表示してみてください。

<!DOCTYPE html>
<html>
<body>

<canvas id="test_canvas" width=256 height=256 style="border: 1px solid;"></canvas>

<script>

function draw() {

    test_context.drawImage(img, 0, 0);

}

var test_context = document.getElementById('test_canvas').getContext('2d');

var img = new Image();

img.onload = draw;
img.src = 'test.jpg';

</script>

</body>
</html>

canvas要素の左上に画像が表示されたと思います。

image

drawImage()では、画像の一部を描くことも可能です。画像の一部を描く場合は

drawImage(転送元x座標, 転送元y座標, 転送する横幅, 転送する高さ, 描画先x座標, 描画先y座標, 描画する横幅, 描画する高さ)

という形で呼び出します。「転送元」は、画像の、「描画先」はcanvas要素の画像で指定します。

試しに、先ほどのhtmlファイルのdrawImage()を以下のように書き換え再読み込みしてみてください。

test_context.drawImage(img, 0, 0, 64, 64, 96, 96, 64, 64);

今度は、画像の左上の部分(0, 0)-(63,63)が、canvas要素の中央(96, 96, 159, 159)に描かれました。

先の例では描画する大きさを画像に合わせましたが、画像の転送(切り出し)サイズと描画サイズを異なる値にすると「拡大縮小」を実現できます。たとえば、

test_context.drawImage(img, 0, 0, 64, 64, 64, 64, 128, 128);

とすれば、画像の左上64×64の部分をcanvas要素の中央128×128の範囲に拡大描画できるわけです。

image

Webサイト担当者としてのスキルが身に付く

CodeCampの無料体験はこちら

Webブラウザで手軽なお絵描きプログラミング

以上、駆け足で図形や文字列・画像の描画、さらに画像ファイルに保存といったcanvas要素の基本的な使い方を試してみました。図形や画像を描くプログラムがごく短いコードで実現できるのは、「画面に表示されているWebブラウザ」を対象にプログラミングを行うJavaScriptならではですね。

Webブラウザ上にJavaScriptで絵を描いて画像ファイルに保存できる、ということは、テキストエディタだけで「絵を描くプログラム」を作成し、描いた絵を保存できることを意味します。

ちょっとした図形や文字列を組み合わせたイラストが欲しい、というときは手軽で便利な方法にもなり得ますので、機会があればWebブラウザを「お絵描きツール」としても活用してみてください。

宍戸輝光
この記事を書いた人
宍戸輝光
\ 無料体験開催中!/自分のペースで確実に習得!
オンライン・プログラミングレッスンNo.1のCodeCamp