(昔の)小学生向けcanvas要素入門

Title
A Comparative Study of Canvas Element and N88-BASIC Graphics
Author
AKIYAMA Kouhei
Date
2009-03-08 初稿
2009-03-20 導入部分に説明を追加

この文書は、昔子供の頃にBASICで育った、今おっさんたちに捧げるものである。これで昔BASICを触ったことのあるおっさんなら、現代でも同等のことくらいは出来るようになるだろう。

JavaScript+canvas要素でお絵かき

今回はウェブページ上に用意したJavaScriptインタラクティブコンソールで絵を描いてみよう。ブラウザだけで手軽にプログラミングができる環境だ。ただ、残念ながらIEには対応していない。FirefoxやOpera等で試してみて欲しい。技術的にはJavaScriptとcanvas要素というものを使う。それに対応したブラウザが必要だ。

SCREEN

まず、図形を書く場所を作成しよう。

var cv = document.createElement("canvas");
cv.setAttribute("width", "320");
cv.setAttribute("height", "240");
cv.style.cssText = "border: 1px solid;";
document.body.appendChild(cv);
var ctx = cv.getContext("2d");

JavaScriptインタラクティブコンソールのページを開き、上のテキストをソース欄に入力して実行すると、結果フレームにキャンバスが用意される。
これは現代のSCREEN文である! おまじないみたいな物なので、暗記しよう!

LINE

次に直線を描いてみよう。
「ソースクリア」ボタンを押していったんソース欄を消した後、以下を入力して実行する。(結果はクリアしないこと。した場合は最初から)

ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(320, 240);
ctx.stroke();

これで左上から右下へ直線が引かれたはずだ。
これは現代のLINE文である。LINE(0,0)-(320,240),0といったところか。

次は矩形。こちらのほうが単純。

ctx.strokeRect(10, 10, 40, 30);

これはLINE(10,10)-(10+40, 10+30),0,Bに対応する。(※(10,10)-STEP(40,30)でいいんだっけ?)

塗りつぶしはfillRectに変えるだけだ。

ctx.fillRect(10, 10, 40, 30);

これはLINE(10,10)-(50,40),0,BFあたりに対応する。

CIRCLE

円は次のように描く。

ctx.beginPath();
ctx.arc(160, 120, 30, 0, Math.PI*2, false);
ctx.stroke();

これはCIRCLE(160, 120),30あたりに相当する。arcの引数の後ろ三つは円弧の角度に関する物だが、N88BASICにもそれに相当するものがあったはずだが良く覚えていないので割愛する。

塗りつぶし円にするには最後のctx.stroke()をctx.fill();にするだけだ。

ところで、これまで色に関することに言及してこなかった。色は図形を描く度に指定するのではなく、描く前ににあらかじめ指定しておく必要がある。

色を指定するには、描く前に

ctx.fillStyle = "#F00";
ctx.strokeStyle = "#0F0";

のようにする。(別に#FF0000とかredとかrgb(255,0,0)でもいい。カラーコードは使えないので注意すること)

fillStyleはctx.fill()やctx.fillRect()に対して効く。
strokeStyleはctx.stroke()やctx.strokeRect()に対して効く。

ctx.fillStyle = "#F00";
ctx.strokeStyle = "#0F0";

ctx.fillRect(250,200, 30,30);
ctx.strokeRect(250,200, 30,30);

これで、緑色に縁取りされた赤い矩形が表示される。LINE(250,200)-(250+30,200+30),4,BF,2に相当する(と思う)。

FOR〜NEXTとRANDとLINE

ここで少しはプログラミングっぽいこともやってみよう。次のコードはランダムで画面に線を引くコードである。昔やったことがある人は多いのではないだろうか。

var i;
for(i = 0; i < 20; ++i){
  ctx.strokeStyle = "#" + Math.round((Math.random()*0xfff)).toString(16);
  ctx.beginPath();
  ctx.moveTo(Math.random()*320, Math.random()*240);
  ctx.lineTo(Math.random()*320, Math.random()*240);
  ctx.stroke();
}

これは次のコードに(だいたい)相当する(と思う)。(※RANDの使い方あってる?)

10 FOR I=0 TO 19
20 LINE(RAND(320),RAND(240))-(RAND(320),RAND(240)),RAND(7)
30 NEXT

PSET、POINT関数、PUT、GET

点を打ったり、点の色を取得したり、画像を切り出したり、貼り付けたり、そういったことをするには、getImageDataやsetImageDataを使う。

// PSET(160,10),1
ctx.putImageData({width:1, height:1, data:[0,0,255,255]}, 160, 10);

// PRINT POINT(160,10)
var p = ctx.getImageData(160, 10, 1, 1);
alert(p.data[0] + "," + p.data[1] + "," + p.data[2] + "," + p.data[3]);

// GET(120,100)-(232,132),G%
var g = ctx.getImageData(120, 100, 32, 32);

// PUT(0,0),G%
ctx.putImageData(g, 0, 0);

CLS

さて、画面が汚くなったところで、いったん画面を綺麗にしたい。もちろんCLSと入力しても無駄である。

ctx.clearRect(0,0,320,240);

あとは自由に絵を描いてもらいたい。

他にも画像を描いたり、半透明が扱えたり、多角形が描けたり、ベジェ曲線が描けたり、いろいろ出来るのだが、それはまた別のお話。

参考文献


AKIYAMA Kouhei
Last modified: 2013-08-30 14:06:07+0900