2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CSS animation で遊び倒す - Dodger Loading -

Posted at

CSS animation day 43となりました。

本日も、microinteraction で使える、Loader を作っていきます。

1. 完成版

ダウンロード (45).gif

See the Pen Dodger Loading by hiroya iizuka (@hiroyaiizuka) on CodePen.

2. 参考文献

The goddess is coming

3. 分解してみる

❶.
マークアップしましょう。

index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="css/styles.css" />
  </head>
  <body>
    <div class="container">
      <div class="chaser"></div>
      <div class="escaper"></div>
      <div class="escaper"></div>
      <div class="escaper"></div>
      <div class="escaper"></div>
    </div>
  </body>
</html>
styles.scss
body {
  margin: 0;
  padding: 0;
  background: #000;
}

.container {
  width: 100%;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.chaser {
  background-color: hotpink;
  width: 50px;
  height: 50px;
  margin-right: 80px;
}

.escaper {
  background-color: dodgerblue;
  width: 50px;
  height: 50px;
  margin-right: 40px;
}

スクリーンショット 2019-03-06 8.22.44.png

これで、ピンクと青の四角形の配置が終わりました。
余談ですが、hotpink と dodgerblue (dodger: ひらりと素早く身をかわす人) っていうネーミングセンスが秀逸ですね。


❷.
アニメーションを実装します。
まず、chaser が、右に動いたり左に動いたりできるようにします。

styles.scss

.chaser {
  background-color: hotpink;
  width: 50px;
  height: 50px;
  margin-right: 80px;
  border-radius: 5px;
  animation: chase 3s ease-in-out infinite;
}

@keyframes chase {
  50% {
    transform: translateX(450px);
  }
}

ダウンロード (39).gif

easy ですね!

次に、この迫ってくるhotpink を軽やかにかわします。
どうしたら良いでしょうか?

・・・

正解は、transform: rotate (180deg) と、transform-origin を設定することで解決します。具体例をみていきましょう。

ダウンロード (41).gif

上のGif画像には、transform: rotate(-180deg)を設定しました。
transform-origin が各々異なり、左から

1: transform-origin: center;
2: transform-origin: -50%;
3: transform-origin: 150%;

となっております。
アニメーションの起点を変えるだけで、こんなに違う動きがうまれるなんて、大変面白いですね!
それでは、アニメーションを作っていきましょう。

styles.scss

.escaper {
  background-color: dodgerblue;
  width: 50px;
  height: 50px;
  margin-right: 40px;
  border-radius: 5px;

  &:nth-child(2) {
    animation: escape 1.5s ease-in-out infinite alternate;
  }

  &:nth-child(3) {
    animation: escape2 1.5s ease-in-out infinite alternate;
  }

  &:nth-child(4) {
    animation: escape3 1.5s ease-in-out infinite alternate;
  }

  &:nth-child(5) {
    animation: escape4 1.5s ease-in-out infinite alternate;
  }
}

@keyframes chase {
  50% {
    transform: translateX(450px);
  }
}

@keyframes escape {
  0%,
  15% {
    transform: rotate(0deg);
  }

  35%,
  100% {
    transform-origin: -50%;
    transform: rotate(-180deg);
  }
}
@keyframes escape2 {
  0%,
  30% {
    transform: rotate(0deg);
  }

  50%,
  100% {
    transform-origin: -50%;
    transform: rotate(-180deg);
  }
}

@keyframes escape3 {
  0%,
  45% {
    transform: rotate(0deg);
  }

  65%,
  100% {
    transform-origin: -50%;
    transform: rotate(-180deg);
  }
}

@keyframes escape4 {
  0%,
  60% {
    transform: rotate(0deg);
  }

  80%,
  100% {
    transform-origin: -50%;
    transform: rotate(-180deg);
  }
}

ダウンロード (42).gif

ポイントは1つ
animation-direction: alternate
このプロパティによって、アニメーションを反転して再生することができます。
keyframesをごちゃごちゃいじる必要がないため、非常に便利ですね。


❸.
表現力をつけます。
ジャンプして、ちょっとへこむようにしましょう。
このジャンプには、以下のように動きをわけて考えます。

1: ジャンプする前のためを作る → scale で横長にする
2: ジャンプする → scale で縦長にする
3: 着地する → scaleで横長にする

タイミングについては、実際にアニメーションを動かしながら、微調整してください。

styles.scss

.escaper {
  width: 50px;
  height: 50px;
  margin-right: 40px;

  &:nth-child(2) {
    animation: escape 1.5s ease-in-out infinite alternate;

    &:before {
      content: "";
      position: absolute;
      background-color: dodgerblue;
      border-radius: 5px;
      width: inherit;
      height: inherit;
      animation: sizeChange 1.5s ease-in-out infinite alternate;
    }
  }


@keyframes sizeChange {
  0% {
    transform: scale(1, 1);
  }

  15% {
    transform-origin: center bottom;
    transform: scale(1.4, 0.7);
  }

  25% {
    transform-origin: center bottom;
    transform: scale(0.4, 1.8);
  }

  40% {
    transform-origin: center top;
    transform: scale(1.4, 0.7);
  }

  65%,
  100% {
    transform: scale(1, 1);
  }
}

ダウンロード (43).gif

いい感じです!
なお、inherit プロパティで、要素のプロパティの計算値を、親要素から引き継ぐことができます。
わざわざ値を設定しないのでいいので、便利ですね。

ジャンプする前に、神々しい力を発動しているように表現します。

styles.scss
@keyframes sizeChange {
  0% {
    transform: scale(1, 1);
  }
    
   ・・・
 

  40% {
    transform-origin: center top;
    transform: scale(1.4, 0.7);
    box-shadow: 0px 0px 20px gold;
  }

     ・・・

}

ダウンロード (44).gif

神々しくなりました笑
では、他の3つにも同じようなアニメーションを作り、ループ文を使って、リファクタリングをしましょう。

styles.scss

.escaper {
  width: 50px;
  height: 50px;
  margin-right: 40px;

  @for $i from 1 through 4 {
    &:nth-child(#{$i + 1}) {
      animation: escape#{$i} 1.5s ease-in-out infinite alternate;

      &:before {
        content: "";
        position: absolute;
        background-color: dodgerblue;
        border-radius: 5px;
        width: inherit;
        height: inherit;
        animation: sizeChange#{$i} 1.5s ease-in-out infinite alternate;
      }
    }
  }
}

@keyframes chase {
  50% {
    transform: translateX(450px);
  }
}

@keyframes escape1 {
  0%,
  15% {
    transform: rotate(0deg);
  }

  35%,
  100% {
    transform-origin: -50%;
    transform: rotate(-180deg);
  }
}

@keyframes escape2 {
  0%,
  30% {
    transform: rotate(0deg);
  }

  50%,
  100% {
    transform-origin: -50%;
    transform: rotate(-180deg);
  }
}

@keyframes escape3 {
  0%,
  45% {
    transform: rotate(0deg);
  }

  65%,
  100% {
    transform-origin: -50%;
    transform: rotate(-180deg);
  }
}

@keyframes escape4 {
  0%,
  60% {
    transform: rotate(0deg);
  }

  80%,
  100% {
    transform-origin: -50%;
    transform: rotate(-180deg);
  }
}

@keyframes sizeChange1 {
  0% {
    transform: scale(1, 1);
  }

  15% {
    transform-origin: center bottom;
    transform: scale(1.4, 0.7);
  }

  25% {
    transform-origin: center bottom;
    transform: scale(0.4, 1.8);
  }

  40% {
    transform-origin: center top;
    transform: scale(1.4, 0.7);
    box-shadow: 0px 0px 20px gold;
  }

  65%,
  100% {
    transform: scale(1, 1);
  }
}

@keyframes sizeChange2 {
  0% {
    transform: scale(1, 1);
  }

  25% {
    transform-origin: center bottom;
    transform: scale(1.4, 0.7);
  }

  35% {
    transform-origin: center bottom;
    transform: scale(0.4, 1.8);
  }

  50% {
    transform-origin: center top;
    transform: scale(1.4, 0.7);
    box-shadow: 0px 0px 20px gold;
  }

  75%,
  100% {
    transform: scale(1, 1);
  }
}

@keyframes sizeChange3 {
  0% {
    transform: scale(1, 1);
  }

  35% {
    transform-origin: center bottom;
    transform: scale(1.4, 0.7);
  }
  55% {
    transform-origin: center bottom;
    transform: scale(0.4, 1.8);
  }

  70% {
    transform-origin: center top;
    transform: scale(1.4, 0.7);
    box-shadow: 0px 0px 20px gold;
  }

  85%,
  100% {
    transform: scale(1, 1);
  }
}

@keyframes sizeChange4 {
  0% {
    transform: scale(1, 1);
  }

  45% {
    transform-origin: center bottom;
    transform: scale(1.4, 0.7);
  }
  65% {
    transform-origin: center bottom;
    transform: scale(0.4, 1.8);
  }

  80% {
    transform-origin: center top;
    transform: scale(1.4, 0.7);
    box-shadow: 0px 0px 20px gold;
  }

  95%,
  100% {
    transform: scale(1, 1);
  }
}

ダウンロード (45).gif

ついに完成しました!

このアニメーションのポイントは、transform: rotate と、transform-origin との合わせ技でしたね。

大変興味深い動きになり、特にtransform-originプロパティの無限の可能性、に心が動かされました。
それではまた明日〜

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?