回転する見た目も実装、jQueryで作るコイントスシステム

# どうも7noteです。コインが回転するコイントスシステムを作った

コイントスで調べると、表と裏がランダムで表示されるレベルのコイントスシステムはあったのですが、**実際にコインが空中で回転するような見た目のコイントスはなかったので作ってみました。**

![sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/bfa5352d-8fef-9973-b07c-311403661317.gif)


## コイントスシステムのソース

```index.html
<div class="coin"></div>
```

```style.css
.coin {
  width: 50px;  /* コインの幅 */
  height: 50px; /* コインの高さ */
  background: url(omote.png) no-repeat center / 100% auto; /* 背景にコインの画像を設定 */
  position: relative; /* 表示位置を変更するために必要 */
  cursor: pointer;    /* hover時にカーソルを指の形にする */
}

.coin.toss {
  animation : toss 0.3s linear infinite,toss2 0.3s infinite steps(1, end),updown 2s ease; /* anime「toss」、anime「toss2」、anime「updown」 */
}

/* X軸を基準に回転させるアニメーション */
@keyframes toss{
  0% { 
    transform:rotateX(0deg);
  }
  100% {
    transform:rotateX(360deg);
  }
}

/* 表裏を切り替えるアニメーション */
@keyframes toss2{
  25% {
    background-image: url(ura.png);
  }
  75% {
    background-image: url(omote.png);
  }
}

/* コインを上下させるアニメーション */
@keyframes updown{
  0% {
    top: 0;
  }
  50% {
    top: -100px;
  }
  100% {
    top: 0;
  }
}

```

```script.js
$(function(){
  $('.coin').not(':animated').on('click',function(){
    
    /* ランダムで0か1を取得 */
    rndm = Math.floor( Math.random() * 2 );

    /* アニメーションを開始させる */
    $(this).addClass('toss');

    /* 1.9秒後にアニメーションを停止し、コインの裏表を表示する */
    setTimeout(function(){
      $('.coin').removeClass('toss');
      if(rndm == 1){
        $('.coin').css(`background-image`,`url(ura.png)`);
      } else {
        $('.coin').css(`background-image`,`url(omote.png)`);
      }
    },1900);
  });
});
```

※jQueryを使用しています。jQueryについては[こちら]()

## 解説

・3種類のcssアニメーション
・jsでの表裏のランダム、アニメーションの起動

大きくこの2つに分けて解説します。

### ▼ 3種類のcssアニメーション

アニメーションは3つのアニメーションをカンマ区切りで書いて1行にしているだけですのでこれも分けて解説していきます。

#### 「toss」

```css
.coin {
  animation : toss 0.3s linear infinite; /* 0.3秒ごとにアニメーションを繰り返す */
}

/* X軸を基準に回転させるアニメーション */
@keyframes toss{
  0% { 
    transform:rotateX(0deg);
  }
  100% {
    transform:rotateX(360deg);
  }
}
```
X軸、つまり コインを(ー)←この向きを軸として回転をさせるアニメーションです。

#### 「toss2」

```css
.coin {
  animation : toss2 0.3s infinite steps(1, end); /* 0.3秒ごとにアニメーションを繰り返す。かつ徐々にではなくコマ割りで動かす。 */
}

/* 表裏を切り替えるアニメーション */
@keyframes toss2{
  25% {
    background-image: url(ura.png);
  }
  75% {
    background-image: url(omote.png);
  }
}
```
表のコインを回転させるだけでは、コインが回転してもずっと表の絵が見えてしまうので、コインが反転したタイミング、つまり**コインが回転する際に横一線になる瞬間の25%時間経過したタイミングで裏に、75%時間経過したタイミングでまた表に戻すことで表裏のあるコインが回転しているように見せることができます。**
通常backgroundはアニメーションを指定すると徐々に変化してしまうので、表の文字がどんどん薄くなる・・・みたいなことになってしまうのでそうならないように`steps(1, end)`を指定することで、コマ撮りのような瞬時に切り替わる設定を入れています。

#### 「updown」

```css
.coin {
  animation : updown 2s ease; /* 2秒かけて1回アニメーションする */
}

/* コインを上下させるアニメーション */
@keyframes updown{
  0% {
    top: 0;
  }
  50% {
    top: -100px;
  }
  100% {
    top: 0;
  }
}
```
topの指定を変更することで、コインを空中に飛ばすようなアニメーションになります。

### ▼ jsでの表裏のランダム、アニメーションの起動

jsに関してはほぼコメントを入れている通りの処理を順番に行っているだけです。

```js
$(function(){
  $('.coin').not(':animated').on('click',function(){
    
    /* ランダムで0か1を取得 */
    rndm = Math.floor( Math.random() * 2 );

    /* アニメーションを開始させる */
    $(this).addClass('toss');

    /* 1.9秒後にアニメーションを停止し、コインの裏表を表示する */
    setTimeout(function(){
      $('.coin').removeClass('toss');
      if(rndm == 1){
        $('.coin').css(`background-image`,`url(ura.png)`);
      } else {
        $('.coin').css(`background-image`,`url(omote.png)`);
      }
    },1900);
  });
});
```

**コインがクリックされた時**
↓
**ランダムで0か1を決定、かつtossアニメーションを開始させるためにクラス「toss」を付与**
↓
**1.9秒後にアニメーションを停止させるためにクラス「toss」を取り除く。かつ0か1の値を取得してそれに合わせて表示する画像を決定。**

こんな感じの流れになりますね。

## まとめ

本当はcssだけで作りたかったのですがランダムを再現しようと思うとさすがに骨が折れそうだったので、js便りになってしまいました。
cssマスターならきっとランダムっぽい再現もできるのかもしれませんがまだまだ勉強不足を感じます。

私的にはきれいにアニメーションを作ることができたので、webのオンラインゲーム等を作成するときにはぜひ使ってみたいですね。
jsを追加して、これまで出た表か裏かを画面端に記録していくようなシステムなんかも追加してもいいかもしれませんね。

画像データ：いらすとやよりお借りしました。
https://www.irasutoya.com/2017/12/blog-post_410.html

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)