Canvas入門

JavaScript

JSのお絵かきツールCanvasの基本を学ぼう。

Canvas下地づくり

任意のフォルダ(desktopなど)にcanvasフォルダを作成し、その中にindex.htmlを以下のように作成する

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
  <canvas id="cvs"></canvas>
  <script src="js/main.js"></script>
</body>
</html>

canvasフォルダの中にjsフォルダを作成し、その中にmain.jsを以下のように作成する

//canvas取得(画用紙)
const cvs=document.getElementById('cvs');
//2dコンテキスト取得(筆&絵の具)
const ctx=cvs.getContext('2d');

//キャンバスの大きさ設定
cvs.width=800;
cvs.height=500;

//キャンバスの背景色設定
ctx.fillStyle="#ddd";
ctx.fillRect(0,0,cvs.width,cvs.height);

確認

以下のようにグレーの800*500のキャンバスが描画されれば成功だ。

四角の描画

main.jsの末尾に以下を追記し実行する

//塗りの設定
ctx.fillStyle="blue";
//四角書いて塗りつぶす
ctx.fillRect(30,20,150,100);

fillRect(30,20,150,100)で与えられている4つの引数の意味を下図を見てしっかり理解する

罫線の追加

四角形に罫線を追加してみよう。以下のようにmain.jsに追記

//線の設定
ctx.strokeStyle="yellow";
ctx.lineWidth=4;//strokeWidthではないので注意
//線で4角を描画
ctx.strokeRect(30,20,150,100);

ラインの描画

main.jsに以下のように追記、実行

//線の設定
ctx.strokeStyle="purple"
ctx.lineCap="round" //ラインの端の設定(round,butt,square)

//ラインの描画
ctx.beginPath();
ctx.moveTo(50,200);
ctx.lineTo(150,250);
ctx.stroke();

ここでlineCapは以下の三種類の設定ができる

三角形の描画

main.jsに以下を追記

//三角形の描画
ctx.beginPath();
ctx.moveTo(50,300);
ctx.lineTo(200,300);
ctx.lineTo(200,450);
ctx.closePath();
ctx.fill();

線を追加したければ以下1行を追加

//線の追加
ctx.stroke();

円の描画

以下を追記

//円の追加
ctx.fillStyle="red";
ctx.beginPath();
ctx.arc(250,70,50,0,Math.PI*2);
ctx.closePath();
ctx.fill();

中心角2PIラジアン(360度)の円弧を描いてFillしている。isCounterClockwiseにtrueを渡すと反時計周りの円弧がかける

ctx.arc(x,y,r,0,Math.PI*2,isCounterclockwise);

パックマン

//パックマン
ctx.fillStyle="yellow";
ctx.beginPath();
ctx.moveTo(250,200);
ctx.arc(250,200,50, -1 * Math.PI / 6 , Math.PI /6,true);
ctx.closePath();
ctx.fill();

テキスト

以下のように追記

//テキスト
ctx.font = "36px sans-serif";
ctx.fillText("こんにちはCanvas",250,350);
ctx.font = "36px serif";
ctx.fillText("こんにちはCanvas",250,400);

画像

canvasフォルダにimagesフォルダを追加。
以下から画像をダウンロード&解凍して3枚の画像をimagesフォルダに配置する

以下のようにmain.jsに追記。(パスに注意)

//画像配置
const img1=new Image();
img1.src="./images/kaba1.jpg";
// 画像読み込み終了してから描画
img1.onload = ()=>{
  ctx.drawImage(img1,350,20);
}

このままでは元画像の大きさで描画されてしまうので、以下のようにwidthとheightを指定する。

//画像配置
const img1=new Image();
img1.src="./images/kaba1.jpg";
// 画像読み込み終了してから描画
img1.onload = ()=>{
  //ctx.drawImage(img1,350,20);
  ctx.drawImage(img1,350,20,200,150);
}
/*

canvasの回転

canvasを回転させることによって画像を傾けて表示してみよう。以下のようにmain.jsに追記

//canvas回転
const img2=new Image();
img2.src="./images/kaba2.jpg";
// 画像読み込み終了してから描画
img2.onload = ()=>{
  ctx.save();//既存の座標系を保存
  ctx.translate(500,80);//座標系の原点をx方向に500,y方向に80移動(回転の中点となる)
  ctx.rotate(Math.PI / 8);//canvasを回転
  ctx.drawImage(img2,0,0,200,150);//新しくなった原点から描画
  ctx.restore();//座標系を元に戻す
}

回転の繰り返し

回転を繰り返し行ってみよう。main.jsに以下を追記

//canvasの連続回転
const img3=new Image();
img3.src="./images/kaba3.jpg";
// 画像読み込み終了してから描画
img3.onload = ()=>{
  for(let i=0;i<8;i++){
    ctx.save();
    ctx.translate(600,300);
    ctx.rotate(Math.PI / 4 *i);
    ctx.drawImage(img3,0,0,200,150);
    ctx.restore();
  }
}

画像をランダムに散りばめる処理

サムネにあるような、復数の画像をランダムに散りばめる処理を作成してみよう。

//canvas取得(画用紙)
const cvs=document.getElementById('cvs');
//2dコンテキスト取得(筆&絵の具)
const ctx=cvs.getContext('2d');
//キャンバスの大きさ設定
cvs.width=800;
cvs.height=500;

//キャンバスの背景色設定
ctx.fillStyle="#ddd";
ctx.fillRect(0,0,cvs.width,cvs.height);

//画像配列作成
const imgs=[new Image(),new Image(),new Image()];
const paths=["kaba1.jpg","kaba2.jpg","kaba3.jpg"];
for(let i=0;i<imgs.length;i++){
  imgs[i].src="./images/"+paths[i];
}

//すべての画像の読み込み完了時に動かすcallbackをセットする関数
const setLoadAllCallback=(imgs, callback) =>{
  let count = 0;
  for (let i = 0; i < imgs.length; i++) {
      imgs[i].onload = () =>{
          ++count;
          if (count == imgs.length) {
              callback(imgs);
          }
      };
  }
}
//実行
setLoadAllCallback(imgs,(imgs)=>{
  let count=0;
  let timerId=setInterval(()=>{
      count++;
      let idx=Math.floor(Math.random()*imgs.length);
      let img=imgs[idx];
      ctx.save();
      ctx.translate(Math.random()*cvs.width,Math.random()*cvs.height);
      ctx.rotate(Math.random()*2*Math.PI);
      let width=Math.floor(Math.random()*200)+100;
      ctx.drawImage(img,0,0,width,width*3/4);
      ctx.restore();
      if(count > 100){
        clearInterval(timerId);
      }
  },30);
});


コメント

タイトルとURLをコピーしました