LoginSignup
13
8

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-02-13

概要

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

考えた末、「メルティーキッスを降らせる。」というのを思いつきました。
メルティーキッスといえば、「降る雪が全部 メルティーキッスなら いいのにな♪」というCMソングで有名ですね。
Meltykiss(メルティーキッス)|株式会社 明治

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

作業

  • メルティーキッス本体となる要素の生成
  • 立方体の成形(=メルティーキッスの構築)
  • 回す
  • 降らす

メルティーキッス本体となる要素の生成

わざわざ、<div>~</div>を生成数個書くのも面倒な作業なので、javascriptのループ処理で生成させる。
また、以下の処理では10個生成するものとする。

<div id="melty"></div>
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
まず、立方体の面の親要素となる<div class="cube">~</div>を生成後、<div class="face"></div>6つ(前、後、左、右、上、下)子要素として追加しています。また、各面にclass名を当てるようにしました。

立方体の成形

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

: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);
}

まず、.face3D要素として操作するためにtransform-style: preserve-3dと設定します。この操作をしてやらないと、フラット(平面)な要素として認識され、立方体になりません。

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

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

回す

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

.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

降らす

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

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

@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
こちらでデモが確認できます。
CodePen - Meltykiss

あとがき

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

13
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
8