ユーザーにとって価値ある情報を繰り返し発信していく「まるログ」

要素がスクロール画面に現れたらアニメーションさせるJS

JSアニメーション
ページをスクロールしていき任意の要素が見えたときに、その要素をアニメーションさせたいということがあると思います。wow.jsと同じようなことがしたいと言えばわかりやすいでしょうか。
wow.jsはとても簡単に様々な動きが付けられますが、Animation.cssと一緒に使用する都合上、実現が難しい動きもあったりします。今回は、そういった状況でも対応できる、動きを自由に付けられるようなJavaScriptを自作してみました。

$(window).scroll(function(){
  var top = $("ターゲットとなる要素").offset().top; // ターゲットの位置取得
  var position = top - $(window).height();  // 発火させたい位置
  if($(window).scrollTop() > position){
    // 要素が見えたときの動き 
  }else{
    // それ以外の動き
  }
})

javascript簡単に説明しますと、2行目でoffset().topを使い、ターゲットの位置(y座標)を取得し、topに代入します。次に、3行目でtopからブラウザの高さの分だけ引き、positionに代入します。そうすることにより、if文で$(window).scrollTop()とtopの比較では、条件を満たした時にターゲットの要素がブラウザトップまでスクロールされたときに発火されますが、ブラウザの高さ分引いてあげることにより、ターゲットがブラウザ下部から現れたときに発火されるようになります。
あとはif文を使用し、スクロール量がpositionを超えたときの動きを記述すれば、動き自体は完成です。
デモ1

デモでは、背景画像を動かすためにJSで下記のように命令をだしています。

if($(window).scrollTop() > position){
  $(".bg_triangle").css("background-size","100%");
}else{
  $(".bg_triangle").css("background-size","0%");
}

実際の動きに関する記述は下記のようにCSSで指定しています。

.bg_triangle {
  height: 600px;
  background: url(../img/bg_triangle.png) left top/0% no-repeat #ccc;
  transition: all 1s;
  text-align: center;
}

background-sizeの初期値は0%にしています。動作時間などを変える場合はtransitionの数値を変更してください。
ちなみにですが、スクロールのたびに動くのは邪魔だというときは、else部分を削除すると1回のみのアニメーションとなります。

下からのスクロールにも対応させたい場合

先程の記述だと、要素を超えたらずっと動いた状態のままなので、下からスクロールしていって要素が現れたときは発火されません。下からのスクロールにも対応させる場合は、ターゲットまでの位置に、ターゲット自体の高さを足した変数を追加します。

$(window).scroll(function(){
  var top = $("ターゲットとなる要素").offset().top; // ターゲットの位置取得
  var position = top - $(window).height();  // ターゲットが上からスクロールしたときに見える位置
  var position_bottom = top + $("ターゲットとなる要素").height();  // ターゲットが下からスクロールしたときに見える位置
  if($(window).scrollTop() > position && $(window).scrollTop() < position_bottom){
    // 要素が見えたときの動き 
  }else{
    // それ以外の動き
  }
})

上記が実際に追加したものになります。
変わったところは、4行目にposition_bottomを追加し、if文の条件をスクロール量がposition とposition_bottomの間にある時に書き換えています。
デモ2

コーディングデモ2では、デモ1で無かった下からのスクロールに対応させた物となっているのがわかるかと思います。こちらもelse部分を削除することで、1回のみの動きにすることが出来ます。
デモ1と2では.css()で直接動きを指定していますが、複雑な動きを指定する場合だと記述が長くなってしますので、.addClass()を使って要素にclassを付与し、動きは自体はCSSで指定するのがいいかもしれません。

記述方法を少し変えてみる

CSSで複数のパラメータを変更させて、アニメーションさせたい場合は下記のような記述の方がシンプルです。
デモ3

if($(window).scrollTop() > position  && $(window).scrollTop() < position_bottom){
  $(".bg_triangle").addClass("act");
}else{
  $(".bg_triangle").removeClass("act");
}

デモ3では、ターゲット要素が見えている間はactというクラス名を付与されるようにしています。実際の動きはCSSで指定します。個人的にはこちらのほうがわかりやすいかなと思います。

.bg_triangle.act {
  background-color: #000;
  border: 5px solid #f70000;
  background-size: 100%;
}
.bg_triangle.act p {
  color: #fff;
  font-size: 50px;
}

実際に変化させている部分はこちらです。background-imageなど、transitionでアニメーションできないプロパティもあるので、注意してください。

wow.jsのオプションと同じような動きをつける

wow.jsには、
data-wow-duration(アニメーションする時間)、
data-wow-delay(アニメーションがスタートするまでの時間)、
data-wow-offset(アニメーションの開始位置)、
data-wow-iteration(繰り返し回数)
を設定することが出来ますが、今回のscriptでも同じように動くように設定することが出来ます。なお、data-wow-durationとdata-wow-iterationはCSS側で設定できるため、今回は省略します。

data-wow-delayのようにする
(動きを遅延させる)

アニメーションの開始を遅延させる場合は、setTimeoutを使用して、実行を遅らせます。

if ($(window).scrollTop() > position) {
  setTimeout(function () {
    // 要素が見えたときの動き
  }, 1000);
}

上記のように、アニメーション部分をsetTimeoutで囲ってあげることで、実行を遅らせることができます。1000の部分を変えることで、遅延秒数を変更できます。
また、CSSでtransitionに値を追加するだけでも遅延をさせることができます。

transition: all 1s 2s;

このように書くことで、変化するプロパティ、アニメーション時間、遅延秒数の3つを指定することができます。この場合は、2秒遅延させてから全てのプロパティを1秒かけてアニメーションするという指定になります。

data-wow-offsetのようにする
(アニメーションの開始位置設定)

こちらはpositionの値に任意の数値を足すだけで実装できます。

var position = top - $(window).height() + 100;

上記のように、任意の数値を足すだけで完了です。この場合はターゲット要素がブラウザ下端から100px上に来た時にアニメーション開始となります。

まとめ

リッチコンテンツ今回は、比較的簡単でしたが、数値のとり方が少しわかりにくいかなと思ったscriptを紹介いたしました。スクロール関係のscriptは、書き方は簡単ですが位置のとり方が複雑だったりするものがあるので、今回の記事を参考にしていただければと思います。
wow.jsや今回ご紹介した方法は、比較的簡単にスクロールアニメーションを実装できます。動きはシンプルですが、これだけでページの印象がリッチになり、心を惹きつけるデザインになるので、手間に対する効果を考えるとかなりオススメです。

WEBプログラマー / K.S