こんにちは。
今回はJavaScriptさわってみる企画10回目をやります。テーマはCanvas。CanvasとはHTML5の要素で、webページ上に線や円、文字や画像などを描画できるもののようです。
ってことでこれが使えたらかなり表現できる幅が広がりそうですね!
まずは免責。
*この記事は初心者が思うままにやってみたという内容ですので確かな情報とは言えません。無論、ここの情報によるトラブル等の一切の責任は負いかねます。
Canvasにはcontext(コンテキスト)という概念がありまして、線の太さや色など描画の元となる情報のことを言うようです。それらの情報をオブジェクトへ格納し、線を引くなどのメソッドを呼び出すことで描画を行います。
オブジェクトのハナシはコチラ↓
そして’描画をする’という処理は特定の要素に対して行うので最初にそれを指定します。DOMの概念ですね。
DOM(Document Object Model)のハナシはコチラ↓
書き方の例はこう↓
<body onload="init()">
<canvas id="area" width="300" height="300"></canvas>
</body>
<script>
let ctx;
function init(){
const canvas = document.getElementById("area");
ctx = canvas.getContext("2d");
}
</script>
body部分に300×300pxの要素を置いています。canvas要素です。1行目のbodyの後にonload= と書くとおそらくbodyが読み込まれたときにそこに書いた関数が呼び出されるようですね。
<script></script>で囲った中(JavaScript)のfunction init()内の2行で処理の対象とするcanvas要素の指定、コンテキストの取得をしていて、.getContext("2d")っていうのは固定のようで丸暗記で良さそう。この後にコンテキストの設定を書きます。
コンテキストの設定は値をプロパティに代入することで行います。
コンテキストの主なプロパティ↓
.strokeStyle //線、輪郭の色
.lineWidth //線の幅
.fillStyle //塗りつぶしの色
色はHTML/CSSのカラーコードで指定できます。
カラーコード参考↓
次にいよいよ描画の処理です。描画はメソッドを呼び出すことで行いますがちょっとクセがありそうです。たとえば線を一つ引くだけでも
.beginPath() //パスをクリアする
.moveTo(x,y) //始点座標の設定
.lineTo(x,y) //次点座標の設定
.stroke() //始点から次点へ線を引く
と、これだけの処理が必要です。
折れ線を描くなら.lineToメソッドの次に再度.lineToメソッドで新たな座標を指定することで先の.lineToの座標から次の.lineToの座標へ線が描き加えられるので次々と指定して様々な形にすることができます。
他にも円を描くためのメソッド、文字や画像を描くためのメソッドなどもあります。
メソッド・プロパティ参考↓
それでは実践。
ただ線を描くだけでは味気ないので前回のさわってみる企画のイベントハンドラと組み合わせ、下のグレーの範囲でマウスを動かすとマウス位置を中心に十字線と円が描かれるっていうものにしてみました(スマホなどの場合はタップした位置)。前回同様、ブラウザによってはうまく行かないかも。
マウス座標
クリックした座標
中身↓
前回との組み合わせなのでcanvas要素の参照とコンテキスト取得は window.onload = のところ (画面読み込み時に実行される関数) へ入れ込みました。最初の例のように<body onload = ○○>を使っても問題ないと思います。
同関数内でコンテキスト設定。10px幅の赤色線にしてます。fillStyleはfill(塗りつぶし)メソッドを使わなかったので要らなかったw
座標を引数とする描画処理の関数を作成しイベントハンドラで実行、という形です。線と円を描いてます。
コピペ用↓
<style>
#area {background-color:gray; width:400px; height:300px;margin-top:0px}
#posi {background-color:yellow; width:400px;margin: 0px; padding:0px;}
#posi2 {background-color:lightgreen;width:400px;margin: 0px; padding:0px;}
</style>
<script>
let ctx;
window.onload = function () {
document.getElementById("area").onmousemove = presentposition;
document.getElementById("area").onclick = clickedposition;
const canvas = document.getElementById("area");
ctx = canvas.getContext("2d");ctx.strokeStyle = "#FF0000";
ctx.fillStyle = "#00FF00";
ctx.lineWidth = 10;
}
function presentposition(e) {
document.getElementById("posi").textContent = "マウス座標 X=" + e.offsetX + ", Y=" + e.offsetY;
drawline(e.offsetX,e.offsetY)
}
function clickedposition(e) {
document.getElementById("posi2").textContent = "クリックした座標 X=" + e.offsetX + ", Y=" + e.offsetY;
drawline(e.offsetX,e.offsetY)
}
function drawline(x,y){
ctx.clearRect(0,0,400,300)
ctx.beginPath();
ctx.moveTo(0, y);
ctx.lineTo(400, y);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(x, 0);
ctx.lineTo(x, 300);
ctx.stroke();
ctx.beginPath();
ctx.arc(x,y,30,0,2*Math.PI);
ctx.stroke();
ctx.closePath();
}
</script>
<body>
<p id="posi">マウス座標</p>
<p id="posi2">クリックした座標</p>
<canvas id="area" width="400" height="300"></canvas>
</body>
ここまでくるとイベントハンドラにボタンを追加したりなんかしてゲームっぽいものが作れそうな気がしないこともないですね。
今回はここまでです。ありがとうございました!
次回↓icedtomatobazooka.site