お絵かき掲示板Art.netLABOメニュー

HTML5canvasでお絵描きツール「しぃペインターもどき」を作りたい!

第1回: まずはキャンバスを作ってフリーハンドで線を描く!
青枠内がキャンバスで、マウスをドラッグすると線が描けます。

このキャンバスは、HTML 5 Canvas に対応したブラウザで使用できます。

お絵かき掲示板を愛する皆様こんばんは。
ARTNET LABORATORY 所長のミミニャ〜です(`A´)y-'
残念ながら更新の止まってしまった愛すべきお絵描きツール しぃペインター
この先、JAVAの更新で完全停止してしまう前に、次世代しぃペインターを作るべく立ち上がりました。

しかし残念な事に、私にはプログラムの知識がありません。
ここ数年の間に、解説書を何冊も買いまして、JAVAやFlashは難しすぎて絶対無理と悟りました。
そして辿り着いたのが、HTML5のcanvasと、ジャバスクリプトで作るお絵描きツールです。

まずは実際に上の青枠内で絵を描いてみると解ると思います。
Chrome等のブラウザならば描いた絵を右クリックからPNGで保存する事もできます。
HTML5のcanvasは、ブラウザだけで動作するため、JAVAやFlash等のインストールも不要だし、起動が早くて、
PCはもちろん、モバイルやゲーム機でも、お絵かき出来るツールが作れるはず!
(今のところPCでしか動作確認はしていません)
ただし、古いブラウザでは動かないという難点はあります。
動作確認は、IE11、Firefox、Chromeです。

これから作成を進めるにあたって、覚え書きがてら、ここに製作過程を連載していこうと思います。
第一回は「フリーハンドで線を描く!」
試行錯誤とトライ&エラーの連続で、ここに辿り着くまで半年以上かかりました(@Д@;)

はじめはwebで公開されている情報を調べて作ろうとしていたのですが、
上級者向けの情報ばかりで結局付いてゆけず。
それでHTML5関連の本を何冊も買って、その中で唯一この本は初心者でも理解できました。
(ちなみにこの本は無料で見れるweb版もあります)
それでこの本の「Flash不要のお絵かきツール」にあったサンプルソースをダウンロードして、それを元に改造していく事にしました。
しかし残念な事に、この本も上級者向けなのか手抜きなのか、サンプルソースには、コメントがほとんど付いていないので、どういう処理をしているのかまったく理解できません。
更に困った事にジャバスクリプトでは、変数も配列の頭にperlのような$や@やsub〜が付いていないので、変数なのか命令なのか関数なのか、他人の作ったプログラムではコメントが付いていないとそれらの見分けすら付きません。
そのような理由でここに辿り着くまで本当に大変でしたが、初心者なりに解読したソースをここに載せます。

動作サンプル単独ページ

(HTML5canvasに線を描くサンプル.lzh) 3kb

HTML部分

<!DOCTYPE html>は、HTML5用のドクタイプ宣言です。

CANVASタグは、HTML5で追加されたタグです。
ここで指定した横幅(width)と縦幅(heiht)の大きさのキャンバスが表示されます。
(そのままではキャンバスが透明なのでCSSで枠線を付けておかないとページ背景と同化して解り難いです)

id="ID_MYCANVAS1"は後で、ジャバスクリプトからこのキャンバスを認識する為に使います。
ID_MYCANVAS1部分は、自分で解りやすい任意の名前を付けられます。

今回はジャバスクリプトが難しくなるので、キャンバスの位置は、余白を付けずブラウザの左上にピッタリ付けます。
ブラウザ固有の余白が出ないように、CSSでページ内のすべての要素(*)のマージンとパディングを0にします。

(説明用なので動作に支障の出ない要素は省いています)


<!DOCTYPE html>
<HTML>
<HEAD>

<style type="text/css">
*{ margin:0px; padding:0px;}
canvas { border-style:solid; border-color:#000000; border-width:1px; }
</style>

</HEAD>
<BODY>

<CANVAS id="ID_MYCANVAS1" width="200" height="200"></CANVAS>

</BODY></HTML>
		

ジャバスクリプト部分

HTMLのcanvasタグに、線を描くプログラムを作ります。

処理内容としては、id=ID_MYCANVAS1の付いたcanvasタグ上を常時監視して、
その上でマウスカーソルが動く度に、関数(sub_oekaki)を実行します。
そこでマウスボタンが押されているか判定して、押されていれば線を描画します。

ジャバスクリプトでは、//から始まる行は、コメント部分となり、処理内容では無視されます。

変数や配列などは、関数(サブルーチン)を書く前に、最初にまとめて宣言var〜しておかないと、下の関数内で機能しない模様です。
(たぶん、関数内で宣言した変数や配列は、その関数内でしか機能しない模様)
上級者には当たり前過ぎるのか、入門書などにも説明がなくて、はじめはこのルールを知らずに本当に苦戦しました。
とにかく変数や配列は、プログラムのはじめにまとめて以下のように初期化?しておく必要があるようです(たぶん)
var 半角スペース 変数名;
行末にはセミコロン;を付けた方が良いみたい。
変数名は任意の半角英数字で付けても動きますが、他の命令文などと区別が付くように、
私の場合は、変数の頭には必ずMY_を付けて、見分けの付き易い大文字で統一しています。
本来ならば日本語を使いたい所ですが、試してみたら動かなかったので仕方なく屈しました( ̄□ ̄;)


<script type="text/javascript">
<!-- 

// ■グローバル変数■グローバル変数■グローバル変数■グローバル変数■

//■マウスボタンクリックフラグ(押=true/離=false)
var MY_DRAWFLAG = false;

//■描画終点座標
var MY_X=0;
var MY_Y=0;

//■描画始点座標
var MY_OLDX=0;
var MY_OLDY=0;



// ■HTMLのロードが完了したら自動実行するイベント
window.addEventListener("load", function()
			{//▼HTMLロード完了後に実行▼▼▼HTMLロード完了後に実行▼▼▼HTMLロード完了後に実行▼▼▼

// ■<CANVAS id=ID_MYCANVAS>要素のノードオブジェクトを作る
var MY_CANVAS1 = document.getElementById("ID_MYCANVAS1");

// ■キャンバス(MY_CANVAS1)の上でマウスを移動するたびにサブルーチンのsub_oekaki(描画処理)が実行される
MY_CANVAS1.addEventListener("mousemove", sub_oekaki, true);


// ■キャンバス(MY_CANVAS1)の上でマウスボタンを押した瞬間に実行
MY_CANVAS1.addEventListener("mousedown", function(e)
		{//▼マウスクリック▼マウスクリック

//■true=マウスクリックフラグを立てる=これでsub_oekaki内の処理が実行される■マウスボタンクリックフラグ(押=true/離=false)
MY_DRAWFLAG = true;
//■描画始点座標に今のマウスカーソル位置()をセット
MY_OLDX = e.clientX;
MY_OLDY = e.clientY;

	}, true);//▲マウスクリック▲マウスクリック


// ■キャンバス(MY_CANVAS1)の上でマウスボタンを押して離した瞬間に実行(マウスボタン押したフラグtrueを離した状態falseに戻す。)
MY_CANVAS1.addEventListener("mouseup", function() { MY_DRAWFLAG = false; }, true);

			}, true); //▲HTMLロード完了後に実行▲▲▲HTMLロード完了後に実行▲▲▲HTMLロード完了後に実行▲▲▲▲



// ■描画処理(キャンバスの上でマウスが動く度に実行されるイベント)
function sub_oekaki(e)
	{//▼描画処理▼▼▼描画処理▼▼▼描画処理▼▼▼描画処理▼▼▼描画処理▼

//■ボタンが押されてなかったら(true以外なら)終了■マウスボタンクリックフラグ(押=true/離=false)true (真)と false (偽)
if ( MY_DRAWFLAG != true ) return;

//■マウス位置の終点(eはマウスイベントのデータが自動で入っている変数。内容はconsole.log(e);で見れる。)
MY_X = e.clientX;
MY_Y = e.clientY;

//■描画用オブジェクト(MY_CONTEXT1)を作る■getCotextメソッドで得た2DコンテキストのオブジェクトをMY_CONTEXTに格納
MY_CANVAS1 = document.getElementById("ID_MYCANVAS1");
MY_CONTEXT1 = MY_CANVAS1.getContext("2d");

//■描画色
MY_CONTEXT1.strokeStyle = "#000000";
//■ペン太さ
MY_CONTEXT1.lineWidth = 1;
//■透明度(0.0(完全な透明)〜1(不透明))
MY_CONTEXT1.globalAlpha = 1;
//■筆跡の描き終わりに丸みをつける
MY_CONTEXT1.lineJoin= "round";
//■筆跡の描き終わりの丸み2(butt, round, square
MY_CONTEXT1.lineCap = "round";

//■線を描くと宣言
MY_CONTEXT1.beginPath();

//■描き始める場所を指定
MY_CONTEXT1.moveTo(MY_OLDX, MY_OLDY);
//■引きたい線の終点を指定 lineTo=直線/
MY_CONTEXT1.lineTo(MY_X, MY_Y);

//■出来た図形を線で描画する
MY_CONTEXT1.stroke();

//■描いた線を閉じる
MY_CONTEXT1.closePath();

//■マウス位置の始点を書き換える。
MY_OLDX = MY_X;
MY_OLDY = MY_Y;

	}//▲描画処理▲▲▲描画処理▲▲▲描画処理▲▲▲描画処理▲▲▲描画処理▲

 -->
</script>

あとがき

ご覧頂きありがとうございました。
HTML5canvasで、しぃペインターを作る!第一回はここまでにします。
プログラム作成とは別に、予想以上にこのページの作成も日数がかかったので、続きは未定です。
誰も見ていないようなら連載中止の方向で…… (^ ^;
いづれにしましても、あと何年かかるか解りませんが、しぃペインターもどきの製作は続けていきます。
今のところ、レイヤーの実装や、掲示板への投稿処理辺りまでは完成していますが、まだまだ程遠いです。

2015年06月21日



お絵かき掲示板Art.netLABOメニュー