はじめに

サイト制作で要望の多いアニメーション
でも過度なアニメーションは嫌われがち
そんなときちょうどいいアニメーションが「下からふわっと」です

でもそのためにわざわざプラグインを導入するのは、不要な記述がたくさん含まれているので
サイトが重くなる原因にもなりかねないし、なるべく自作したいところではありますね 💡
この記事ではそんなお悩みを解決するべく、僕が普段使用している自作コードを紹介します!

完成コード

まずはデモサイトをご覧ください

デモを見る

↑のような動きさえあればお客様の要望に応え、かつ必要最低限のアニメーションといえるでしょう

ということでコードの詳細について以下に記載していきます

HTML

ご自身の手元でこれを確認したい場合は以下のHTMLをコピペしてください(とくに必要ないというかたはスルーしてOKです)

<div class="wrapper">

    <div class="card anm">
      <p>単純にふわっと<br>(.anm)</p>
    </div>

    <div class="card anm-up">
      <p>下から上へふわっと<br>(.anm-up)</p>
    </div>

    <div class="card anm-right">
      <p>左から右へふわっと<br>(.anm-right)</p>
    </div>

    <div class="card anm-left">
      <p>右から左へふわっと<br>(.anm-left)</p>
    </div>

    <div class="anm-list">
      <div class="card">
        <p>下から上へ順々にふわっと<br>(.anm-list)</p>
      </div>
      <div class="card">
        <p>下から上へ順々にふわっと<br>(.anm-list)</p>
      </div>
      <div class="card">
        <p>下から上へ順々にふわっと<br>(.anm-list)</p>
      </div>
      <div class="card">
        <p>下から上へ順々にふわっと<br>(.anm-list)</p>
      </div>
    </div>

  </div>

Sass

続いてSassです

//スタイル用と記載しているところはデモ用に記述したものですので手元で動作確認する必要がない場合は不要な記述です

23行目のanimationから下は必要な記述になります

//スタイル用
.wrapper {
  width: (800 / 1200 * 100vw);
  background-color: #e4e4e4;
  margin: 0 auto;
  padding: 30px;
}
//スタイル用
.card {
  background-color: #f98f8f;
  width: 200px;
  max-width: 100%;
  height: 200px;
  margin: 100px auto;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}


/*------------------------------------------------------------------------------
  animation
------------------------------------------------------------------------------*/
@keyframes startFadeIn {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

.anm {
  opacity: 0;

  &.is-animated {
    animation: fadeIn 1.5s forwards;
  }
}

.anm-up {
  opacity: 0;
  transform: translateY(30px);

  &.is-animated {
    animation: fadeInUp 1.5s forwards;
  }
}

.anm-left {
  opacity: 0;
  transform: translateX(30px);

  &.is-animated {
    animation: fadeInLeft 1.5s forwards;
  }
}

.anm-right {
  opacity: 0;
  transform: translateX(-30px);

  &.is-animated {
    animation: fadeInRight 1.5s forwards;
  }
}

.anm-list > * {
  opacity: 0;
  transform: translateY(30px);
}

.anm-list > *.is-animated {
  animation: fadeInUp 1.5s forwards;
}

@keyframes fadeIn {
  0% {
    opacity: 0;
  }

  100% {
    opacity: 1;
  }
}

@keyframes fadeInUp {
  0% {
    opacity: 0;
    transform: translateY(20px);
    transition-timing-function: cubic-bezier(0, 0.4, 0.2, 1);
  }

  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes fadeInDown {
  0% {
    opacity: 0;
    transform: translateY(-20px);
    transition-timing-function: cubic-bezier(0, 0.4, 0.2, 1);
  }

  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes fadeOutUp {
  0% {
    opacity: 1;
    transform: translateY(0);
  }

  100% {
    opacity: 0;
    transform: translateY(-20px);
    transition-timing-function: cubic-bezier(0, 0.4, 0.2, 1);
  }
}

@keyframes fadeInLeft {
  0% {
    opacity: 0;
    transform: translateX(30px);
    transition-timing-function: cubic-bezier(0, 0.4, 0.2, 1);
  }

  100% {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes fadeInRight {
  0% {
    opacity: 0;
    transform: translateX(-30px);
    transition-timing-function: cubic-bezier(0, 0.4, 0.2, 1);
  }

  100% {
    opacity: 1;
    transform: translateX(0);
  }
}

jQuery

続いてjQueryです

これはすべて必要な記述です

/* animation
------------------------------*/

// scroll effects
$.fn.acs = function (options) {

  const elements = this;
  const defaults = {
    screenPos: 0.8,
    className: 'is-animated'
  };
  const setting = $.extend(defaults, options);


  $(window).on('load scroll', function () {
    add_class_in_scrolling();
  });

  function add_class_in_scrolling() {
    const winScroll = $(window).scrollTop();
    const winHeight = $(window).height();
    const scrollPos = winScroll + (winHeight * setting.screenPos);

    if (elements.offset().top < scrollPos) {
      elements.addClass(setting.className);
    }
  }
}

$('.anm, [class*="anm-"], .anm-list > *').each(function () {
  $(this).acs();
});



// list animation delay
$.fn.anmDelay = function (options) {
  const elements = this;
  const defaults = {
    delay: 0.2,
    property: 'animation-delay'
  };
  const setting = $.extend(defaults, options);

  const index = elements.index();
  const time = index * setting.delay;
  elements.css(setting.property, time + 's');
}

$('.anm-list > *').each(function () {
  $(this).anmDelay();
});

以上の記述をコピペすればデモサイトと同じ記述になるかと思います💡

解説

コードについて少し解説します

Sassについて

  • 単純にふわっとさせたいと場合は、.anm .anm-up .anm-left .anm-rightつけてください
  • 順々にふわっとさせたい場合は、.anm-list を要素の親要素のクラスにつけてください
  • animation-durationに関しては1.5sとしているので、お好みで変えてください

jQuery について

なかなか見慣れない以下の記述ですが、これは独自メソッドを作成しています

$.fn.acs = function (options){ ... }

$.fnに対して、.hoge = function(...) とすると独自のメソッドを作成することができ、.hoge() で呼び出すことが可能となります

アニメーションを発火させるポイントを変えたい場合は、9行目のscreenPosの値を変えてください

screenPos: 0.8

この値を変えると、アニメーションを開始するタイミング変更することが可能です 
具体的には以下のようなイメージです(クリックしたら別タブで開きます👇) 

余談

今回紹介したjQueryのコードは、スクロールイベントの中で要素の位置とスクロールの位置を監視してイベントを発火させていますが、よりサイトパフォーマンスを意識したい方はIntersection Observer を使用するのも良いでしょう

おわりに

プラグインを使用してもいいのですが、なにかと使わない機能が多く、ファイルの容量が増えてしまうのが嫌だったので必要最低限のアニメーションを実現できるコードを紹介しました

ぜひ明日からのWEB制作に役立てていただければ幸いです