web front end engineer

web制作でつまづいたこと

【inview.js応用編】かっこいいスクロールアニメーションの作り方。フェードインだけだと物足りない人向け。

ちょっとおしゃれなサイトでよくみるスクロールアニメーションをinview.jsを使って簡単に確実に再現する方法を解説します。

正直「これが やりたかった」という人もおおいのではないでしょうか。

フェードインだけだと少し物足りないなぁ。でもjsのプログラミングとかめんどくさいことはしたくない。という人におすすめです。
CSSをプラスするだけでちょっと格上のアニメーションを演出できます。

inview.jsの基本的な設定は以下で解説していますのでこちらをご覧ください。

ここではinvew.js応用編として付加するCSSアニメーションについて詳しく触れていきます。

まず完成イメージがこちらになります。

See the Pen inview.js demo by uhaha (@uhaha) on CodePen.

要素自体の座標は動かさず、カーテンを開けるように表示されていくアニメーションをメインに画像の縮小やフェードインなど複数のアニメーションを組み合わせて作成しています。要素自体のスライドインなどとは少し違いますね。

まず上記の様にカーテンを開くように出現させるアニメーションを作成します。画像の上に乗った要素をスライドして画像を出現させるようにCSSトランジション効果を使います。

HTML

スクロールアニメーションを設定する要素にvisibleを設定します。

<div class="wrap_img visible">
    <img src="img/img01.jpg" alt="">
</div><!-- wrap_img -->

JS

スクロールがビューポートに入ったら.visible.effectを追加します。

$(function() {
  $('.visible').on('inview', function(event, isInView) {
    if (isInView) {
        $(this).addClass('effect');
    } else {
        $(this).removeClass('effect');
    }
  });
});

CSS(本題!)

画像の上に背景と同じ色の要素を::beforeで乗せておきます。
jsで.effectが付加されたときにscaleXを0にします。
::beforeにあらかじめtransition: 1s;を設定しアニメーションとして稼働させます。

.visible{
    position: relative;
    overflow: hidden;
}
.visible::before{
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 101%; /* 必要なら微調整する */
    height: 100%;
    background: #fff;
    transform-origin: right top;/* アニメーションの軸となる座標 */
    transition: 1s;/* 1秒かけてアニメーションする */
    z-index: 2;
}

.effect.visible::before {
    transform: scale(0, 1);
}

上記をメインに次の過程でもう少しアニメーション演出をプラスしていきます。

次に以下のCSSをプラスしてスクロールした際のスライドアップとフェードインのアニメーションを作成します。

.visible{
     position: relative;
     overflow: hidden;
     opacity: 0; /* 初期設定:透明度を0にする */
     transform: translateY(30px); /* 初期設定:30px下に下げる */
}
.visible::before{
     content: "";
     position: absolute;
     top: 0;
     left: 0;
     width: 101%;
     height: 100%;
     background: #000;
     background: rgba(255,255,255,0.7);
     transform-origin: right top;
     transition: 1s;
     z-index: 2;
}
.effect.visible::before {
    transform: scale(1, 0);
}
.effect {
   animation-name: effect_anime; /* アニメーション名 */
   opacity: 1; /* アニメーションが到達した状態 */
   transition: 0.5s; /* 0.5秒かけてアニメーションする */
   transform: translateY(0px); /* アニメーションが到達した状態 */
}
@keyframes effect_anime {
  0% {/* 初期値 */
     opacity: 0;
      transform: translateY(30px);
  }
  100% {/* アニメーションが到達した状態 */
     opacity: 1;
      transform: translateY(0px);
  }
}

CSSでトランジション効果が始まるまでの待ち時間を指定することで要素を順番に表示させることができます。

上記の様にCSSトランジション効果が始まるまでの待ち時間を指定することで要素を順番に表示させることができます。
少しの記述で可能なのでオススメです。

.effect:nth-last-of-type(3n-1) {/* 2列目 */
    transition-delay: 0.2s;
}
.effect:nth-last-of-type(3n-2) {/* 3列目 */
    transition-delay: 0.4s;
}

※今回はtransition-delayを使用しましたがanimation-delayを使用する場合もあります。

最後にスクロールされた際に画像を拡大もしくは縮小しながら表示されるアニメーションを CSSトランジション効果を使って作成します。

まず画像の囲いとなる.wrap_imgのアスペクト比を固定して画像が拡大されてもずれないようにします。

画像部分は初期設定としてあらかじめscaleで1.5倍にしておいて.effectが付加されたらscaleを1に戻し縮小するアニメーションを作成します。

.wrap_img{/* アスペクト比を固定しておいてく */
     width: 31.333%;
     margin: 0 1% 30px 1%;
  position: relative;
  overflow: hidden;
}
.wrap_img::after {
    content: "";
    display: block;
    padding-top: 56.25%;
}
.wrap_img img {
     animation-name: animation;
     transition: 0.7s;/* 0.7秒かけてアニメーションする */
    transform: scale(1.5);/* 初期設定:1.5倍にしておく */
    max-width: inherit;
     position: absolute;
    top: 50%;
    left: 50%;
}
.effect.wrap_img img {
    transform: scale(1.0);/* 初期設定:1.5倍にしておく */
}

仕上げに透明度を調整したり、画像と文字列でトランジション効果の方向を変えたり、微調整します。

.visible{
    position: relative;
    overflow: hidden;
    opacity: 0;
    transform: translateY(30px);
}
.visible::before{
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 101%;
    height: 100%;
    background: #000;
    background: rgba(255,255,255,0.7);
    transform-origin: right top;
    transition: 1s;
    z-index: 2;
}
.effect.visible::before {
    transform: scale(1, 0);
}
.effect {
  animation-name: effect_anime;
  opacity: 1;
  transition: 0.5s;
  transform: translateY(0px);
}
.effect:nth-last-of-type(3n-1) {
    transition-delay: 0.2s;
}
.effect:nth-last-of-type(3n-2) {
    transition-delay: 0.4s;
}
@keyframes effect_anime {
  0% {
    opacity: 0;
    transform: translateY(30px);
  }
  100% {
    opacity: 1;
    transform: translateY(0px);
  }
}
.wrap_img::after {
    content: "";
    display: block;
    padding-top: 56.25%;
}
.wrap_img img {
    animation-name: animation;
    transition: 0.7s;
    max-width: inherit;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) scale(1.5);
}
.effect.wrap_img img {
    transform: translate(-50%, -50%) scale(1.0);
}

今回のようなスクロールアニメーションは一見複雑にみえるのですがCSSの組み合わせを工夫すればGSAPを使用しなくてもそれっぽく演出することができます。

また、CSSアニメーションといえばanimation-nameを設定して@keyframesを使うーーといったイメージが強かったのですが、transformのscaleといったトランジション効果が意外とつかえます。

プログラミングの知識がなくても簡単にできるのでフェードインやスライドイン アニメーションに飽きたデザイナーさんにおすすめの方法です。

uhaha

もう当分これでいいですw