年末まで毎日webサイトを作り続ける大学生 〜68日目 オブジェクト指向と綺麗な円〜

##はじめに
こんにちは！@70days_jsです。
今日はオブジェクト指向で円を作りました。(gif)↓
![test3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516248/8b72158a-1d5f-aa87-c1e6-f3ee0199770e.gif)

今日は68日目。(2019/12/25)
よろしくお願いします。

##サイトURL
https://sin2cos21.github.io/day68.html

##やったこと
オブジェクト指向で円を作りました。

html↓

```html
  <body>
    <canvas id="canvas"></canvas>
  </body>
```

css↓

```css
body {
  margin: 0;
}
```

JavaScript↓

```javascript
let canvas = document.getElementById("canvas"),
  ctx = canvas.getContext("2d"),
  circles = [],
  canvasW = (canvas.width = window.innerWidth),
  canvasH = (canvas.height = window.innerHeight),
  numberOfCircle = 50;

function Circle(ctx, x, y, size) {
  this.ctx = ctx;
  this.x = x;
  this.y = y;
  this.size = size;
  this.r = Math.random() * 256;
  this.g = Math.random() * 256;
  this.b = Math.random() * 256;
  this.a = Math.random() * 11;
  this.v = Math.ceil(Math.random() * 3);
}

Circle.prototype.render = function() {
  this.draw();
  this.statusChange();
};
Circle.prototype.draw = function() {
  let color = this.r + "," + this.g + "," + this.b + "," + this.a;
  let ctx = this.ctx;
  let random = Math.ceil(Math.random() * 2);
  ctx.beginPath();
  ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
  if (random > 1) {
    ctx.strokeStyle = "rgba(" + color + ")";
    ctx.stroke();
  } else {
    ctx.fillStyle = "rgba(" + color + ")";
    ctx.fill();
  }
  ctx.closePath();
};

Circle.prototype.statusChange = function() {
  this.size += this.v;
  if (this.size > canvasW / 2 || this.size > canvasH / 2) {
    this.x = Math.random() * canvasW;
    this.y = Math.random() * canvasH;
    this.size = 0;
  }
};

for (var i = 0; i < numberOfCircle; i++) {
  let x = Math.random() * canvasW;
  let y = Math.random() * canvasH;
  let size = Math.random() * canvasH;
  let circle = new Circle(ctx, x, y, size);
  circles.push(circle);
}

function render() {
  ctx.clearRect(0, 0, canvasW, canvasH);
  circles.forEach(function(obj) {
    obj.render();
  });

  requestAnimationFrame(render);
}

render();

```

では解説していきます。

Circleオブジェクトは位置（x,y)、色(r,g,b)、大きさ(半径）、速度のプロパティを持っています。
これらはコンストラクターでセットします。↓

> function Circle(ctx, x, y, size) {...}

メソッドはrender()、draw()、statusChange()の3つを持っています。

renderはdraw()、statusChange()のトリガーになるメソッドです。
draw()は円を描くメソッドです。
statusChange()は円をプロパティを変更するメソッドです。

毎回、円のサイズが速度分大きくなっています。↓

>Circle.prototype.statusChange = function() {
  this.size += this.v;
...
}

もしサイズが大きくなりすぎると（今回は画面の縦もしくは横の半分以上）サイズを0に戻して位置を変更します。↓

>   if (this.size > canvasW / 2 || this.size > canvasH / 2) {
    this.x = Math.random() * canvasW;
    this.y = Math.random() * canvasH;
    this.size = 0;
}

サイズが0からで位置が変わっているので、新しい円ができたように見えます。

最後に、ここが今回の肝なのですが毎回draw()するたびに色のつけ方を変えています。

まず毎回ランダムで1か2をrandam変数に格納します。↓

>Circle.prototype.draw = function() {
...
  let random = Math.ceil(Math.random() * 2);

その後、randam変数の値によって、円のスタイルをstroke(枠線のみ）かfill(塗りつぶし）に割り振ります。↓

>  if (random > 1) {
    ctx.strokeStyle = "rgba(" + color + ")";
    ctx.stroke();
  } else {
    ctx.fillStyle = "rgba(" + color + ")";
    ctx.fill();
  }

こうすることでチカチカする円が出来上がります。

##感想
もうそろそろ年末ですね。そろそろオセロを考え始めないと。
今年はオセロで締めくくります。

最後まで読んでいただきありがとうございます。明日も投稿しますのでよろしくお願いします。