CSSだけで作ったメルティーキッスを降らせる

## 概要
今日、2月14日といえば**「バレンタインデー」**です。
僕は例年通りチョコはもらえないとして、いつもブログを読んでくださる方々になにかプレゼントできないかと考えました。

考えた末、**「メルティーキッスを降らせる。」**というのを思いつきました。
メルティーキッスといえば、「降る雪が全部 メルティーキッスなら いいのにな♪」というCMソングで有名ですね。
[Meltykiss（メルティーキッス）｜株式会社 明治](http://www.meiji.co.jp/sweets/chocolate/meltykiss/)

バレンタインまでに完成させるために、思いつきでパパッと作ったから改善点はたくさんあると思います。

## 作業
- メルティーキッス本体となる要素の生成
- 立方体の成形（=メルティーキッスの構築）
- 回す
- 降らす

## メルティーキッス本体となる要素の生成
わざわざ、`<div>~</div>`を生成数個書くのも面倒な作業なので、javascriptのループ処理で生成させる。
また、以下の処理では10個生成するものとする。


```HTML
<div id="melty"></div>
```

```js
var cubes = 10; //立方体の生成数

const faceList = [
  'front',
  'back',
  'left',
  'right',
  'top',
  'bottom',
];

//#melty の中に立方体の生成
for (i = 0; i < cubes; i++) {
  document.getElementById('melty').insertAdjacentHTML('afterbegin', '<div class="cube"></div>');
};

//立方体の面の生成
for (j = 0; j < cubes; j++) {
  k = 0;
  for (k = 0; k < 6; k++) {
    document.getElementsByClassName('cube')[j].insertAdjacentHTML('afterbegin', '<div class="face"></div>');
    document.getElementsByClassName('cube')[j].firstElementChild.classList.add(faceList[k]);
  };
};
```
![cube.jpg](https://qiita-image-store.s3.amazonaws.com/0/181263/ab82b0d7-5d75-e843-7842-539343624807.jpeg)
まず、立方体の面の親要素となる`<div class="cube">~</div>`を生成後、**面**`<div class="face"></div>`を**６つ（前、後、左、右、上、下）**子要素として追加しています。また、各面にclass名を当てるようにしました。

## 立方体の成形
WebGLを使えば、よりリアルな立方体を作成することもできるのですが、今回はCSSの**`transform`**を駆使して立方体を成形します。

```css
:root{
  --cube-size: 30px; /*立方体の各辺の大きさ*/
}

div#melty {
  position: relative;
}
.cube {
  width: var(--cube-size);
  height: var(--cube-size);
  position: absolute;
  top: calc(var(--cube-size) * -1);
  -webkit-transform-style: preserve-3d;
}

.face {
  width: var(--cube-size);
  height: var(--cube-size);
  border: 1px solid #795548;
  box-sizing: border-box;
  text-align: center;
  line-height: calc(var(--cube-size) - 2px);
  position: absolute;
  background-color: #4E342Ecc;
}
.cube .front {
  top: 0;
  left: 0;
  -webkit-transform: translateZ(calc(var(--cube-size) / 2));
}
.cube .back {
  top: 0;
  left: 0;
  -webkit-transform: translateZ(calc(var(--cube-size) / -2));
}
.cube .left {
  top: 0;
  left: calc(var(--cube-size) / 2);
  -webkit-transform: rotateY(90deg);
}
.cube .right {
  top: 0;
  right: calc(var(--cube-size) / 2);
  -webkit-transform: rotateY(-90deg);
}
.cube .top {
  top: calc(var(--cube-size) / 2);
  left: 0;
  -webkit-transform: rotateX(90deg);
}
.cube .bottom {
  bottom: calc(var(--cube-size) / 2);
  left: 0;
  -webkit-transform: rotateX(-90deg);
}
```
まず、`.face`を**3D要素**として操作するために**`transform-style: preserve-3d`**と設定します。この操作をしてやらないと、フラット（平面）な要素として認識され、立方体になりません。

そして、**各面のX,Y,Z軸**を操作し、立方体を成形しています。

また、立方体のサイズを自由に変えれるように、最初に変数を使用します。

## 回す
立方体は完成したものの、この状態では、ただの正方形しか表示されないので、CSSの**`animation`**を使用して、立方体を回してみます。

```css
.cube{
  -webkit-animation: meltykiss 4s linear infinite;
}

@keyframes "meltykiss" {
  0% {
    transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg);
  }
  100% {
    transform: rotateX(179deg) rotateY(179deg) rotateZ(179deg);
  }
}

@-webkit-keyframes "meltykiss" {
  0% {
    -webkit-transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg);
  }
  100% {
    -webkit-transform: rotateX(179deg) rotateY(179deg) rotateZ(179deg);
  }
}
```
立方体の本体である`.cube`のX,Y,Z軸をそれぞれ180°回転させます。
![index.gif](https://qiita-image-store.s3.amazonaws.com/0/181263/db5654d2-1525-c38c-b1f3-725375084c9e.gif)

## 降らす
メルティーキッスは降るもの。降ってこそのメルティーキッスですから、降らせましょう。

先程のアニメーションに、**上から下へ移動**するプロパティを追加します。

```css
@keyframes "meltykiss" {
  0% {
    transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg);
    margin-top: 0;
  }
  100% {
    transform: rotateX(179deg) rotateY(179deg) rotateZ(179deg);
    margin-top: calc(var(--cube-size) + 500px);
  }
}

@-webkit-keyframes "meltykiss" {
  0% {
    -webkit-transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg);
    margin-top: 0;
  }
  100% {
    -webkit-transform: rotateX(179deg) rotateY(179deg) rotateZ(179deg);
    margin-top: calc(var(--cube-size) + 500px);
  }
}
```

また、立方体一つ一つに、**水平位置**・**アニメーションの繰り返し速度**・**アニメーションのの遅延**を設定して完成です。
![index2.gif](https://qiita-image-store.s3.amazonaws.com/0/181263/4538bfa5-0609-2882-626d-7e9512a70905.gif)
こちらでデモが確認できます。
[CodePen - Meltykiss](https://codepen.io/puchun/pen/BYZBqj)

## あとがき
ちなみにメルティーキッス食べたことないです。