Canvas再入門
Canvas再入門
以前、Canvasを使って一発ネタなツールをいつくか作ったのですが、それ以来まったく触って無くていろいろ忘れてしまってました。ということで今回再入門してみようと思います。
なお、ここは専門家による解説サイトではありませんので、詳しい解説と正しい知識は各自ググってください。
このサイトが検索の参考程度でも助けになれたら幸いです。
Canvas要素とは
ここでCanvasと書いてあるのは、HTML5のCanvas要素のことです。動的に画像描画を行うことが出来るHTML要素で、HTML5で実装されています。
本格的に使いたいなら、Canvasを使いやすくするライブラリがたくさんあるようなので、そちらの方から目的にあったものを使いましょう。
CREATEJSとかjQueryプラグイン「jCanvas」などなど…各種特徴があるようです。
ここではライブラリを使わない、そのままでの取り扱い方法で作っていきます。
Canvas要素を載せたHTML5の書き方
早速サンプルを使って動くところを見ましょう。 文字エンコードは「UTF-8(BOM無し)」で保存してください。(サンプルページが下にあります。)
<!DOCTYPE html>
<html>
<head>
<title>canvas sample</title>
<style>
#canvas_id { background: #666; }
</style>
</head>
<body>
<canvas id="canvas_id" width="640" height="480"></canvas>
<div id="log">
</div>
<script src="sample01.js"></script>
</body>
</html>
極シンプルなHTML5ですね。
canvas要素がわかりやすくなるように、style要素で背景を灰色にしてあります。
<div id="log">
には操作結果を文字列で表示します。console.log()
だとF12押して開発者ツール開かないといけないので、分かりやすいかなと思って付けました。
"sample01.js"にスクリプトを書いていきます。
とりあえず動くサンプル
次のスクリプトをファイル名「sample01.js」で保存してください。ファイルはさっきのhtmlファイルと同じフォルダに置きます。 もちろん文字エンコードは「UTF-8(BOM無し)」で。
// --------------------
// グローバルな変数
// --------------------
// canvas要素
// めんどうなのでグローバルな場所にcanvas要素の変数を作る
var cve = document.getElementById("canvas_id");
// ログの行数カウント
var logrow = 0;
// --------------------
// キャンバスで発生するイベントによる動作内容
// --------------------
// ログを表示
function DrawLog(txt) {
// 操作のログを表示
document.getElementById('log').innerHTML =
logrow + " : " + txt + "<br>" + document.getElementById('log').innerHTML;
console.log(txt);
logrow++;
}
// 長方形を描画
function drawRect(x, y, width, height) {
// --------------------
// キャンバスを操作
// --------------------
if (cve.getContext) { // Canvasを利用できない環境では動作させない
// 図形を描画するためのコンテキストを取得
var context = cve.getContext('2d');
// コンテキストIDの種類
// 2d : 2次元グラフィックス
// webgl : 3次元グラフィックス(WebGL ver1)
// webgl2 : 3次元グラフィックス(WebGL ver2)
// 図形の塗りつぶし色を指定
context.fillStyle = 'blue';
// 色の指定は CSS と同じフォーマット(例:#FF0000, red)
// 関連:
// context.fillStyle : 塗りつぶしの色
// context.strokeStyle : 枠の色
// 長方形を描画
context.fillRect(x, y, width, height);
// 引数:x座標, y座標, 幅, 高さ
// 関連:
// context.fillRect() :塗りつぶし長方形
// context.strokeRect() :枠線のみの長方形
}
}
// マウスボタンをクリックした
function onClick(e) {
// キャンバス上の座標を取得
// (イベント発行した地点の座標) = (ブラウザの viewport における座標) - (キャンバスのオフセット)
var x = e.pageX - cve.offsetLeft;
var y = e.pageY - cve.offsetTop;
DrawLog("click! x:"+ x + ", y:" + y);
// screenX/Y : スクリーン画面(モニタ・ディスプレイ)における座標
// clientX/Y : ブラウザ ウィンドウ表示領域内における座標
// pageX/Y : 現在表示しているページ内における座標
// 図形を描画
drawRect(x, y, 10, 10);
}
// --------------------
// イベントのリスナーを登録
// --------------------
// 要素.addEventListener(イベントの種類, 実行する関数, デフォ値)
cve.addEventListener('click', onClick, false);
htmlファイルをブラウザで開いて動作確認してみてください。
灰色の領域(canvas要素)をクリックすると青い四角が描画されます。
同時に操作内容が灰色の領域の下に表示されます。
サンプルページ
今回は参考にさせていただいたサイトがあります。とても分かりやすいのでぜひご覧ください。
HTML5 Canvas 入門(https://qiita.com/kyrieleison/items/a3ebf7c55295c3e7d8f0)
解説
var cve = document.getElementById("canvas_id");
変数 cve に canvas要素を代入しました。
jQueryならvar cve = $("#canvas_id");
と書けばいいに面倒ですね。
jQuery使う人はjQueryの書式で書くことをお勧めします。しかし今回は使用しません。
解説:関数
DrawLog : 操作のログを表示しています。
onClick : 座標を取得して、座標位置に描画を行います。
drawRect : canvasに描画を行います。
解説:イベント処理
cve.addEventListener('click', onClick, false);
addEventListener()でイベント リスナーを追加しています。
ブラウザさんに、「canvas要素に対するマウス クリック操作」に対して聞き耳を立ててもらっておき、動作が聞こえたら(イベント発生したら)作っておいた関数を実行してもらっています。
解説:canvas上のマウス座標を取得
var x = e.pageX - cve.offsetLeft;
var y = e.pageY - cve.offsetTop;
(クリックした要素の左上からマウスまでの座標)=(ページ内におけるクリック座標) - (クリックした要素の左上座標)
これでcanvas要素上のマウス座標(クリック位置)が取得できます。
座標がいくつもあることに混乱するかもしれませんが、こちらのサイトの画像がとてもわかり易いものでしたのでこちらも参照してください。
マウスイベントで取得されるカーソル座標パラメータの整理(offset, page, screen, client)(https://qiita.com/yukiB/items/31a9e9e600dfb1f34f76)
解説:canvas要素上に図形を描画
いよいよ本題です。まずCanvasを利用できない環境では動作させないようにするためif文で囲みます。
if (cve.getContext) { ~ }
次に図形を描画する空間を確保します。今回は2D画像なので「2d」です。
cve.getContext('2d')
ここまでがcanvasを使う時の毎回必要なお決まりの手順です。
用意した領域に絵を書いていきます。図を描画するときは、先に色を設定してから描画を行います。
context.fillStyle = 'blue';
context.fillRect(x, y, width, height);
ここを変えるといろいろな図形がかけるわけです。
次回予告
ここまでが基本的な流れになります。
マウス操作を受け付けて、操作に反応して描画が出来るのでが出来るようになりました。
これはもうゲーム作るのには十分なレベル…ということはもうゲームが出来たも同然。HTML5凄いですね。
ゲームは完成したと言っても過言ではないので(※だいぶ過言)、ゲーム方面とは違う方向で行きたいと思います。
ということで、次は画像の読み込みでもやってみようと思います。