jQueryやCSSを使ったアニメーションやちょっと動きがついた表現をしたいときに、
これさえ覚えておけばある程度のことはできるものをまとめてみました。

使うものはこちら

css
animation
CSSアニメーション
rotate
要素に傾きをつける
jQuery
$(window).scroll
画面がスクロールしている時に処理を実行します。
scrollTop()
スクロール値を取得する
offset().top
要素までの距離を取得する
addClass()
特定のclassを追加する
fadeIn
フェードで表示させる
setTimeout
実行するタイミングを時間指定できる
if文
条件によって処理を実行する

これさえ使って、ちょっと工夫すれば簡単に動きをつけられます。

デモサイト

スクロールに合わせて、図形が大きくなったり、スライドしながらフェードインします。

けっこうよく見かける表現だと思います。

こういうのを見ると真っ先にプラグインを探していましたが、意外と簡単にできます。

HTML

デモサイトのHTMLですが、抜粋すると以下のようになっています。

<section class="sec1">
  <div class="circle1"></div>
  <div class="circle1-small"></div>
</section>
<section class="sec2">
  <div class="circle2"></div>
  <div class="circle2-small"></div>
</section>
<section class="sec3">
  <div class="square"></div>
  <div class="square-small"></div>
</section>

各セクションに大小の図形を一つずつ配置しています。

今回はCSSで図形を描いてますが、画像でも問題ありません。

CSS

各図形のスタイルですが、ほぼ似ているので、
最初のセクションの大きい方の円形のCSSです。

.circle1 {
  background-color: #1e8d96;
  border-radius: 50%;
  width: 200px;
  height: 200px;
  position: absolute;
  top: 30%;
  left: 40%;
  opacity: .8;
  z-index: 2;
  display: none;
}

親要素のsectionにposition:relativeを付けておき、各図形はpositionで好きな位置に配置しています。
また、フェードインさせるために最初はdisplay:noneで非表示にしておきます。

これを各図形ごとに設定しています。

さらに、CSSではアニメーションの設定もしておきます。

CSSとjQueryの役割分担は、CSSでアニメーションの設定までしておき、
jQueryでそのアニメーションのタイミングをコントロールします。

CSSアニメーションについて

CSSアニメーションはアニメーションの時間や、繰り返しなどを指定できます。

.animationclass {
  /* アニメーションの名前 */
  animation-name: animation;
  /* アニメーションの時間 */
  animation-duration: 5s;
  /* アニメーションの動き方 */
  animation-timing-function: ease;
  /* アニメーションの開始タイミング */
  animation-delay: 2s;
  /* 繰り返し回数を指定。数字で回数を指定できる */
  animation-iteration-count: infinite;
  /* アニメーションを反転再生させるかどうか。例)伸び縮みする動き */
  animation-direction: normal;
}

これらをスペースで区切って一括指定もできます。

.animationclass {
  animation: animation 5s ease 2s infinite normal;
}

実際のアニメーションはkeyframesで指定します。

@-webkit-keyframes scale {
  0% {
    /* 開始時のスタイル */
  }
  100% {
    /* 終了時のスタイル */
  }
}

この%はanimation-durationで指定した時間内の割合です。

例えばanimation-durationが10秒の場合50%は5秒時点のスタイルになります。

これを細かく設定すると、凝った動きができます。

円が拡大する動き

最初のセクションの円が拡大する動きはtransform:scaleを使っています。

.scale {
  -webkit-animation: scale 2s ease;
  animation: scale 2s ease;
}
@-webkit-keyframes scale {
  0% {
    -webkit-transform: scale(.8);
  }
  100% {
    -webkit-transform: scale(1);
  }
}
@keyframes scale {
  0% {
    transform: scale(.8);
  }
  100% {
    transform: scale(1);
  }
}

縮小させて、アニメーション終了時点で元の大きさになるようにしています。

スライドイン

スライドの動きはpositionの位置を変えています。

.slide-left {
  -webkit-animation: slide-left 2s ease;
  animation: slide-left 2s ease;
}
@-webkit-keyframes slide-left {
  0% {
    left: 36%;
  }
  100% {
    left: 40%;
  }
}
@keyframes slide-left {
  0% {
    left: 36%;
  }
  100% {
    left: 40%;
  }
}

左の動きだけですが、同様に右側も指定します。

回転の動き

回転の動きはtransform:rotateを使っています。

.rotate-left {
  -webkit-animation: rotate-left 1s ease;
  animation: rotate-left 1s ease;
}
@-webkit-keyframes rotate-left {
  0% {
    -webkit-transform: rotate(-30deg);
  }
  100% {
    -webkit-transform: rotate(0deg);
  }
}
@keyframes rotate-left {
  0% {
    transform: rotate(-30deg);
  }
  100% {
    transform: rotate(0deg);
  }
}

これもスライドの動きと同様に右側の図形ようにも用意しておきます。

jQuery

jQueryの記述は以下のようになっています。

// 各セクションまでの距離-200pxを変数に格納
var scrollsec1 = $('.sec1').offset().top - 200;
    scrollsec2 = $('.sec2').offset().top - 200;
    scrollsec3 = $('.sec3').offset().top - 200;
$(window).scroll(function(){
  // スクロール値を取得
  var scroll = $(this).scrollTop();
  // スクロール値が条件の箇所に到達した時に処理を行う
  if (scroll > scrollsec1 && scrollsec2 > scroll){
    // .circle1に.scaleを追加し、フェードインさせる。
    $(".circle1").addClass("scale").fadeIn();
    // 0.5秒後にcircle1-smallにも.scaleを追加し、フェードインさせる。
    setTimeout(function(){
      $(".circle1-small").addClass("scale").fadeIn();
    },500);
    // 以下、条件によって同じ処理を各図形に行う
  } else if (scroll >= scrollsec2 && scrollsec3 > scroll){
    $(".circle2").addClass("slide-left").fadeIn(1500);
    setTimeout(function(){
      $(".circle2-small").addClass("slide-right").fadeIn(1500);
    },300);
  } else if (scroll >= scrollsec3) {
    $(".square").addClass("rotate-left").fadeIn("slow");
    setTimeout(function(){
      $(".square-small").addClass("rotate-right").fadeIn("slow");
    },200);
  }
});

最初に各セクションまでの距離を取得しておいてスクロール値と比較し、条件に合えば処理を実行というのが大まかな内容です。

1.各セクションの位置を変数に格納しておく

図形の動きを発動させるタイミングを指定するために各セクションの位置を測っておき、
そこに差し掛かった時に動きが発動するようにします。

.offset().topを使うと、要素までの距離、表示位置を取得してくれます。

今回は各セクションまでの距離を取得し、そのままだと動き始めが少し遅いので、200px引いてます。

2.スクロール値を取得する

今回の動きはスクロールに合わせて動きを発動させるので、スクロール値を取得し続ける必要があります。

まずは、$(window).scrollを使います。

window(画面)がスクロールしている時の処理を書くことができます。

$(window).scroll(function(){
  // ここに処理を書く
});

そして、$(this).scrollTop();で最上部からどれぐらいスクロールしたかを取得し、スクロールするたびに変数に上書きしていきます。

var scroll = $(this).scrollTop();

if文で動き始めのタイミングを指定

1と2で取得した値を比較して、条件にあった場合処理を実行するようにif文を書きます。

if (条件1) {
  // 処理1
} else if (条件2) {
  // 処理2
} else if (条件3) {
  // 処理3
}

最初の条件は、(scroll > scrollsec1 && scrollsec2 > scroll)。

「&&」は、「且つ(かつ)」という意味で、両方を満たした場合に条件が合います。

処理1の条件は「スクロール値がセクション1までの距離より大きい、かつ、セクション2までの距離より小さい」です。

こんな感じで全てのパターンの条件を書きます。

条件にあった場合に動き開始!

条件にあった場合の処理はこんな感じです。

$(".circle1").addClass("scale").fadeIn();
  setTimeout(function(){
    $(".circle1-small").addClass("scale").fadeIn();
},500);

大きい図形にも、小さい図形にも共通しているのは、addClassでアニメーション用のclassを追加し、fadeInさせています。

display:noneが指定されていた図形はfadeInでフェードで表示されつつ、アニメーション用のclassが追加されることでその動きも始まります。

さらに、小さい方の図形はsetTimeoutで処理のタイミングをほんのわずかずらしています。

同時にアニメーションを開始させてもいいですが、ちょっとずらすと工夫した感がでます(笑)

setTimeout(function(){
  // 処理
},500 /* どれぐらい遅らせるか指定 */);

jQueryの説明も以上ですが、そんなに難しいものはなかったと思います。

さいごに

こういうアニメーションさせる時、真っ先にプラグイン探したりしてましたが、
仕組みを考えるとけっこう自分で書けるものです。

先日書いたスターウォーズのオープニングをCSSとjQueryで実装した記述も、この記事で紹介しているものだけでできます。

【イベントレポ】映画とJS vol.0 映画のワンシーンをJavascriptで作ってみよう!に参加しました。 #‎eigatojs‬

上記で紹介したCSSやjQueryの記述は簡単な部類に入るものだと思いますが、使い方次第で動きのバリエーションはいろいろできると思います。

かく言う自分もまだまだなので、もっと勉強して思い通りの動きを実装できるようになります。

プラグインだけに依存せず、自分で思った動きを実装できると楽しいでしょうね。

Tweet
このエントリーをはてなブックマークに追加
Pocket