Canvasで円を浮遊させる

人のソースを見て勉強しようシリーズ第5弾

[Canvasの円の浮遊+なぞのくるくる](http://jsdo.it/matsui_q/klxs)

今回の参考ソースは今回の参考ソースは[ここ](http://codepen.io/HarrisCarney/pen/nEfJB)

![sample6.gif](https://qiita-image-store.s3.amazonaws.com/0/3140/1882d73c-b4da-f6af-770c-7ccfe93788ab.gif)

相変わらず微妙なロールオーバ処理を追加してみた。
`border dotted` + `border-radius50%`　でローディング中くるくるアニメーションを作ってる人がいて、よしパクろうと思ってやってみたけどパクり方を間違えた感がある。

# html

```html
<div id="circle"></div>
```

# CSS

```css
body {
  margin: 0;
  background: #F9F9F9;
}

#circle {
  position: absolute;
  top: 25%;
  left: 25%;
  -webkit-transform: translate(-50%, -50%);
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background: #FFF;
  border-top: 10px dotted #2ABFD4;
  border-left: 10px dotted #FFCD40;
  border-right: 10px dotted #E61875;
  border-bottom: 10px dotted #8BC34A;
  -webkit-animation: turn 6s linear infinite;
  animation: turn 6s linear infinite;
}

@-webkit-keyframes turn {
  0% {
    -webkit-transform: rotate(0);
    transform: rotate(0);
  }
  100% {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}
```

くるくるする円用に `#circle` を用意（周りの円はJS側でcanvasを生成して入れてる）

# JS

```js
//キャンバス要素を作成
$('body').append('<canvas></canvas>');

//canvasの2Dコンテキストオブジェクトを作成
var canvas = $('canvas')[0];
var context = canvas.getContext('2d');

function Dot() {
  this.alive = true;
  this.x = Math.round(Math.random() * canvas.width);  //x座標
  this.y = Math.round(Math.random() * canvas.height); //y座標
  this.diameter = Math.random() * 7;  //直径
  this.colorArray = ['#224687','#2ABFD4','#FFCD40','#E61875','#8BC34A','#AB47BC'];  //色の配列
  this.color = this.colorArray[Math.floor(Math.random() * this.colorArray.length)]; //配列からランダムに取り出す
  this.velocity = {x: Math.round(Math.random() < 0.5 ? -1 : 1), y: Math.round(Math.random() < 0.5 ? -1 : 1)}; //速度
}

Dot.prototype = {
  //描画
  Draw: function() {
    context.fillStyle = this.color; //色の設定
    context.beginPath();            //リセット
    context.arc(this.x, this.y, this.diameter, 0, Math.PI * 2, false);  //円の描画
    context.fill();                 //塗りつぶし
  },
  //円の移動＋大きくさせてみる
  Update: function() {
    this.x += this.velocity.x;
    this.y += this.velocity.y;

    if(this.y > 176 ) {
        this.diameter += Math.random() * 0.1;
    }

    if(this.x > canvas.width + 5 || this.x < 0 - 5 || this.y > canvas.height + 5 || this.y < 0 - 5) {
      this.alive = false;
    }
  }
};

//Dotを入れる用の配列
var EntityArray = [];


//初期化用関数
function Initialize() {

  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;

  for(var i = 0; i < 100; i++) {
    EntityArray.push(new Dot());
  }

  Update();
}


//円の移動用関数
function Update() {
  if(EntityArray.length < 100) {

    for(var i = EntityArray.length; i < 100; i++) {
      EntityArray.push(new Dot());
    }
  }

  EntityArray.forEach(function(dot) {
    dot.Update();
  });

  EntityArray = EntityArray.filter(function(dot) {
    return dot.alive;
  });

  Draw();

  requestAnimationFrame(Update);
}

//描画用関数
function Draw() {
  context.clearRect(0, 0, canvas.width, canvas.height);
  EntityArray.forEach(function(dot) {
    dot.Draw();
  });
}

//リサイズ処理
$(window).resize(function() {
  EntityArray = [];
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
});

//微妙なhover処理
$("#circle").hover(
  function(){
    $(this).stop().animate({
        width: "300px",
        height: "300px",
        top: "15%",
        left: "15%"
    }, 100);
  },
  function(){
    $(this).stop().animate({
        width: "200px",
        height: "200px",
        top: "25%",
        left: "25%"
    }, 100);
  }
);


//初期化
Initialize();
```

## Canvas

### $('canvas')[0]
`$('canvas')[0]` でcanvasが複数あってもその中の一つを指定できるらしい。

### arc() 書き方
抜けてたのでメモ

```
context.arc(this.x, this.y, this.diameter, 0, Math.PI * 2, false);
//書き方　x, y, radius, startAngle, endAngle, anticlockwise
```

| 書き方 |　内容 |
|:-----------|:------------|
| x | 円弧の中心のx座標 |
| y | 円弧の中心のx座標 |
| radius | 半径の距離 |
| startAngle | 円弧の開始角度 |
| endAngle | 円弧の終了角度 |
| anticlockwise | 円弧の作成方向を反時計回り（true）、または、時計回り（false）で指定（初期値はfalse） |

## 円の移動
円の移動はどうやってるんだろうって思ったら。

```
this.velocity = {x: Math.round(Math.random() < 0.5 ? -1 : 1), y: Math.round(Math.random() < 0.5 ? -1 : 1)};

this.x += this.velocity.x;
this.y += this.velocity.y;
```

こんなかんじで分岐させてた。