魔法少女サイト

これは、魔法少女になれなかった男の記録である。

ニートに学ぶCSS Animation演出講座 1時間目

あいさつ

f:id:yuki540com:20180303195622p:plain

ほんとはミライアカリになりきって、記事書きたかったんですが怒られそうだったんでやめます ↓

f:id:yuki540com:20180225031307p:plain

ニートに教わっても面白くないと思うので、僕のことを美少女だと思い込んで講座を受けてください。

はい。改めまして。

ハロー、yuki540だよ!ピロリン

結構、需要があったみたいなので今回から僕が今まで作ったcss animation作品の演出パターンを解説していくよ!

ホントにやってることは単純でcssの初歩的な知識で再現できるものなので、みんななら10秒あれば理解できると思います!

この講座では、sassとかpugは使わず、あくまで素のhtml, cssを使っていきます。

それでは、早速やっていきまーしょう!

今回のアニメーション

↑ 今回は僕がよく使う演出の「スライドショーのようなアニメーション」を解説していきます。

これは、共依存でも使った演出で、シンプルかつ応用がきくパターンだと思うのでぜひ、試しに一緒に作って見てください。

解説

まず、完成したものを実際に見たいかと思うので、最終的に出来上がるものはこちらです。

はい。見ましたね。 さあ、エディタを立ち上げて一緒にコード書きましょう!

マークアップしよう

まずは、土台となるマークアップから。

<main id="root">
  <div id="screen">
    <section class="images">
      <div class="image"></div>
      <div class="image"></div>
      <div class="image"></div>
      <div class="image"></div>
    </section>
    <section class="paint"></section>
  </div>
</main>

いたって単純ですね。(#rootは正直いらないけど癖で書きます)

で、これを大まかに分けると

#screenがスライドショーの土台

.imagesが画像一覧の要素

.paintが最初にスライドショー全体に覆いかぶせる要素

です。(説明が下手で申し訳ない)

スタイルをあてよう

マークアップが終わったら、次はスタイルを当てていきましょう。

最初に#root#screenから。

html, body {
  margin: 0;
  padding: 0;
}
#root {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  min-width: 1100px; min-height: 650px;
  background-color: #eee;
}

#screen {
  position: absolute;
  left: calc(50% - 330px);
  top: calc(50% - 235px);
  width: 650px; height: 450px;
  background-color: #fff;
  border: solid 10px #fff;
  box-shadow: 0 0 20px #444;
  overflow: hidden;
}

全体の外枠の#rootを画面全体にして、#screenが中央にくるようにスタイルを当てます。

calc使いたくないよ!」って方は、left: 50%; margin-left: -330px;などで代用してください。

次に画像一覧のスタイル

.images {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
}

.images .image {
  position: absolute;
  top: 0; left: 0;
  width: 0%; height: 100%;
  overflow: hidden;
}
.images .image:after {
  content: "";
  display: block;
  position: absolute;
  top: 0; left: 0;
  width: 650px; height: 450px;
  background-size: cover;
  background-position: center;
}
.images .image:nth-child(1):after { background-image: url(./images/1.png); }
.images .image:nth-child(2):after { background-image: url(./images/2.png); }
.images .image:nth-child(3):after { background-image: url(./images/3.png); }
.images .image:nth-child(4):after { background-image: url(./images/4.png); }

4枚の画像は自分のお気に入りのものを使ってね!

.images自体は#screenのサイズに合わせるだけですが、注目してほしいのは

  • .imagewidth0%であること

  • .imageoverflow: hiddenがあてられていること

  • .image:afterのサイズ指定が%ではなくpxで数値を固定していること

この3点です。

今回のスライドショーのように中身の画像の形を保持したままwidthを変更していくには、.imageの子要素(めんどくさかったので擬似要素で代用)である.image:afterwidthを固定させる必要があります。

仮に%指定でスタイルをあてると、親要素(.image)のwidthに合わせようとするので、親要素(.image)のwidthが変更されるたびに子要素(.image:after)の画像が動いているように見えてしまいます。

%指定の場合

f:id:yuki540com:20180225101922p:plain

px指定の場合

f:id:yuki540com:20180225102106p:plain

で、px指定するだけでは、親要素より子要素が大きい場合、はみ出て表示されるのでoverflow: hiddenをあてる必要があるということになります。

次に.paintのスタイル

.paint {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  background-color: #444;
}

終わり。.paintは最初、全体に覆いかぶせるだけなので。

アニメーションをあてる

下準備は済んだので、お待ちかねのアニメーションをあてていきましょう!

皆さんは@keyframes {}animationの使い方と書き方は知っているでしょうか?

知っている人が多いと思いますが、一応、簡単に説明しますね。

css animationは単純な動き(ホバーした時に色が変わるなど)の場合は、transitionプロパティを使うのが一般的ですが、僕のHPのように動画並に長い&複雑なアニメーションでは使うことができません。

そこで登場するのがanimationプロパティです。

animationプロパティは、下記のように記述します。

.demo {
  animation: fadeout 0.5s ease 0s forwards;
}

@keyframes fadeout {
  0% { opacity: 1; }
  100% { opacity: 0; }
}

これはページが表示されて、0.5秒かけながら要素が徐々に透明になって消えるアニメーション(フェードアウト)です。

animationプロパティの各パラメータは以下のようになっています。

animation: [キーフレーム名] [アニメーション時間] [アニメーションのイージング指定] [アニメーション開始時間] [アニメーション終了後プロパティをどのように保持するか]

まだまだオプションはありますが、今回はこれだけで十分です。

で、重要なのが@keyframes {}です。

これは0% ~ 100%(from toでも代用可)の間にプロパティを指定して、アニメーションを作っていくものです。

動画編集するときのキーフレームと同じ考えです。中間点を細かく打っていくことで複雑なアニメーションも組むことができます。

「ちょっとよくわからない...」って方は、こちらを参考にしてください。

.paintのアニメーション

はい。では先にスライドショー全体に覆いかぶさっている.paintをどけるアニメーションを作っていきましょう。

@keyframes fadeout_paint {
  0% { /* 初期状態 */
    transform: translate(0, 0) scale(1);
    width: 100%; height: 100%;
    border-radius: 0;
  }
  30% { /* 小さなボール状に変化 */
    transform: translate(305px, 205px) scale(1);
    width: 40px; height: 40px;
    border-radius: 50%;
  }
  50% {
    transform: translate(305px, 205px) scale(1.3);
    width: 40px; height: 40px;
    border-radius: 50%;
  }
  70% { /* バウンドしたように弾ませる */
    transform: translate(305px, 205px) scale(1);
    width: 40px; height: 40px;
    border-radius: 50%;
  }
  100% { /* 画面左に逃げていく */
    transform: translate(-40px, 205px) scale(1);
    width: 40px; height: 40px;
    border-radius: 50%;
  }
}

なにやら煩雑な書き方ですが、多めに見てください。

0% ~ 30%の間は小さくなり丸みを帯びながら、ボール状になります。

30% ~ 70%の間はボールがバウンドしているようにscaleで少し拡大縮小をさせます。

70% ~ 100%の間はtranslateで左に逃げていくようにします。

アニメーションをたくさん使う場合は、今回のようにtranslatescaleのような描画コストが少ないものできるだけ指定してあげてください。

あとは、.paintにアニメーションを登録してあげてください。

/*** 画面表示のアニメーション ***/
.paint { animation: fadeout_paint 1s ease 0.5s forwards; }

画面表示から0.5秒後に1秒かけながらアニメーションする指定ですね。

あと、forwardsでアニメーション終了後もプロパティが100%のときのものを保持するようにします。

.imageのアニメーション

.imageは単純です。 widthを0%から100%に変えるだけです。

@keyframes show_image {
  0%   { width: 0%; }
  100% { width: 100%; }
}

あとは、各.imageにアニメーションを登録してあげてください。

/*** スライドショーのアニメーション ***/
.images .image:nth-child(1) { animation: show_image 0.6s ease 1.5s forwards; }
.images .image:nth-child(2) { animation: show_image 0.6s ease 1.7s forwards; }
.images .image:nth-child(3) { animation: show_image 0.6s ease 1.9s forwards; }
.images .image:nth-child(4) { animation: show_image 0.6s ease 2.1s forwards; }

.paintのアニメーションが終了後、0.2秒間隔を開けながら、各.imageがアニメーションが開始されるようにします。

はい!これで完成です!

ブラウザをリロードして見てください!

はい!完成!あなたは天才!

全てのコードはこちらにあります。

終わりに

僕は英語ができないことが知られていますが、もはや日本語すらダメでした。

読みづらくて申し訳ない...

「わかりづらい!こうして!」や「こんな説明欲しい!」みたいなものがあったらtwitterでリプライ飛ばしてください。

css animationはひたすら、@keyframesの調整と自身の工夫が重要なのでどんどんパラメータやプロパティを変更していってみてください!

皆さんのcss animationの新しいアイデアの手助けになれば幸いです!

毎週日曜に更新していくので、サザエさん感覚でみてください。

じゃーねー!

f:id:yuki540com:20180225112914p:plain