理系公務員のプログラミング日記

JavaScriptとCanvasで2Dグラフィックを生成する その1

タグ:
JavaScript

JavaScriptで2Dグラフィックを生成する

参考:Canvas チュートリアル - Web API | MDN

canvasのエリアを設定し、長方形を描く。

HTMLで2Dグラフィックを生成するには、canvas要素が必要です。
HTML側で容姿したcanvasに対して、JavaScriptでグラフィックを描くことになります。

まず簡単な動作として長方形を描いてみます。

canvas.html

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Canvas</title> <style> </style> </head> <body> <canvas id="canvas" width="800" height="600"></canvas> </body> <script src="canvas.js"></script> </html>

canvas.js

const canvas = document.getElementById("canvas") const drawCanvas = () => { const ctx = canvas.getContext('2d'); ctx.fillRect(100,100,100,100); } drawCanvas()

drawCanvas関数は内部でfillRectメソッドを呼び出しています。
fillRectメソッドはcanvas内の左上を原点とした時のx,y座標と長方形の幅、高さを引数にとり、長方形を描画してくれます。

canvas1

(長方形ですがブログの設定で画像の縦横比が正しく出てませんorz)

矩形(くけい)を描く関数

長方形や正方形などをまとめて矩形と呼びます。
canvas上で矩形を描く関数は下記の3種類です。

  • ・fillRect(x, y, width, height)・・・塗りつぶされた矩形を描く。
  • ・strokeRect(x, y, width, height)・・・矩形の輪郭を描く。
  • ・clearRect(x, y, width, height)・・・指定された領域を消去し、完全な透明にする。
const canvas = document.getElementById("canvas") const drawCanvas = () => { const ctx = canvas.getContext('2d'); ctx.fillRect(25, 25, 100, 100); ctx.clearRect(45, 45, 60, 60); ctx.strokeRect(50, 50, 50, 50); } drawCanvas()

canvas2

clickイベントに反応させる

const canvas = document.getElementById("canvas") const drawCanvas = (x, y) => { const ctx = canvas.getContext('2d'); ctx.fillRect(x, y, 100, 100); ctx.clearRect(x+20, y+20, 60, 60); ctx.strokeRect(x+25, y+25, 50, 50); } canvas.addEventListener("click", (evt) => { let x = evt.clientX; let y = evt.clientY; drawCanvas(x, y) })

canvas3

クリックするとマウスの位置と矩形が描画される位置が微妙にズレているのがわかります。
これはcanvas自体にデフォルトでマージンが掛かっているためです。

このズレを専用のメソッドcanvas.offsetLeft,offsetTopで補正しましょう。

() let x = evt.clientX - canvas.offsetLeft; let y = evt.clientY - canvas.offsetTop;

丸を描く

矩形以外の図形は全てパスという方法で描きます。
Adobe Illustratorなどでよく使われる図形の描き方です。

ひとまず丸を描いてみます。

  • ・beginPath()・・・新しいパスを作成する。
  • ・arc(x, y, radius, startAngle, endAngle, anticlockwise)・・・(x, y) を中心の位置、radius を半径、startAngle を開始角度、endAngle を終了角度、anticlockwise を方向 (デフォルトは時計回り) とする円弧のパスを描く。
  • ・fill()・・・パスの内部を塗りつぶして描く。
const canvas = document.getElementById("canvas") const drawCanvas = (x, y) => { const ctx = canvas.getContext('2d'); // パスを開始する ctx.beginPath(); // 円のパスを設定する ctx.arc(x, y, 50, 0, Math.PI * 2, true); // パスを塗りつぶして描く ctx.fill(); } canvas.addEventListener("click", (evt) => { let x = evt.clientX; let y = evt.clientY; drawCanvas(x, y) })

canvas4

スマイルのグラフィックを描く

丸を組み合わせてスマイルの絵を描いてみます。

  • ・moveTo()・・・次のパスの開始の座標を移動する。(ペンを移動する)
  • ・lineTo()・・・直線でパスを描く。
  • ・stroke()・・・パスの輪郭を描く。
const canvas = document.getElementById("canvas") const drawCanvas = (x, y) => { const ctx = canvas.getContext('2d'); ctx.beginPath(); ctx.arc(x, y, 50, 0, Math.PI * 2, true); // 外の円 ctx.moveTo(x+30, y); ctx.arc(x, y, 30, 0, Math.PI, false); // 半円で口 (時計回り) ctx.lineTo(x+30,y) // 口の上の横線 ctx.moveTo(x-10, y-15); ctx.arc(x-15, y-15, 5, 0, Math.PI * 2, true); // 左目 ctx.moveTo(x+20, y-15); ctx.arc(x+15, y-15, 5, 0, Math.PI * 2, true); // 右目 ctx.stroke(); } canvas.addEventListener("click", (evt) => { let x = evt.clientX; let y = evt.clientY; drawCanvas(x, y) })

canvas5