最近のWebサイトでよく見かける、スクロールに合わせてテキストや画像がフワッと表示されるアニメーションの実装方法についてまとめました。
簡易的に実装できるプラグインなどもありますが、自分でもカスタマイズしやすいように今回はjQueryでコードを書いて実装する方法を紹介します。
コードをそのまま載せるのでコピペOKですが、一応解説も載せておきますので、これからjQueryを勉強する方も参考にしてみてください!
また、今回は簡易的なデモサイトも用意したので先にこちらもご覧ください。
HTML/CSS
まずは共通のHTMLとCSSです。
<div class="top">
<p class="title">スクロールフェードインデモページ</p>
</div>
<div class="scroll-block fade-block1">要素1</div>
<div class="scroll-block fade-block2">要素2</div>
<div class="scroll-block fade-block3">要素3</div>
<div class="scroll-block fade-block4">要素4</div>
<div class="scroll-block fade-block5">要素5</div>
<div class="scroll-block fade-block6">要素6</div>
.top {
height: 100vh;
}
.title {
text-align: center;
line-height: 100vh;
}
/* ブロック共通初期設定 */
.scroll-block {
width: 50%;
height: 500px;
margin: 0 auto 400px;
line-height: 500px;
text-align: center;
background-color: lightcoral;
}
コードは必要部分のみ抜粋しています。
説明は本題の部分に絞った方がいいかもですが一応補足です。
いきなりスクロール要素を表示させないように、topは100vhで画面いっぱいの高さを設定しています。
また、このフェードインのアニメーションはjQueryではなくCSSに指定します。
先にjQueryの仕掛けから解説して、そのあとにアニメーションのCSSを紹介します。
jQueryコード全体
ここでは載せませんが、jQueryを使うのでCDNコードはHTMLのbodyの閉じタグ前に読み込んでおきましょう!詳しくはこちらから↓
$(function() {
$(window).scroll(function() {
$(".scroll-block").each(function() {
var scroll = $(window).scrollTop();
var blockPosition = $(this).offset().top;
var windowHeihgt = $(window).height();
if (scroll > blockPosition - windowHeihgt + 300) {
$(this).addClass("blockIn");
}
});
});
});
まずjQueryの概要から。
例えばウィンドウの高さが1000pxで、画面外にある要素の位置がトップから1200pxだとすると差分は200pxです。
ということは、201px以上スクロールしたら画面外にあった要素が画面下から表示されるわけですが、if式でこれを判定します。
画面に表示されたら、予めstyle.cssでスクロールアニメーションを設定しておいたクラスを付与し、アニメーションを発動させる、という内容です。
ここからは記述内容を分割して説明していきます。
スクロールイベント発動に必要な記述
$(window).scroll(function() {
スクロール時にイベントを発動させる場合はこの記述。
// ↓複数のオブジェクトに対して繰り返し処理を行う
$(".scroll-block").each(function() {
each(function()は複数のオブジェクトに対して繰り返し処理を行う場合のメッソドです。
必要な変数定義
今回は表示させたいscroll-block要素に対して指定しています。
var scroll = $(window).scrollTop(); // 画面トップからのスクロール量
var blockPosition = $(this).offset().top; // 画面トップから見たブロックのある位置
var windowHeihgt = $(window).height(); // ウィンドウの高さ
この3行ではスクロール量や要素位置を判定し、変数に格納しています。
varの後ろの変数名は規則に則っていたらなんでもいいです。
それぞれ見ていきます。
var scroll = $(window).scrollTop(); // 画面トップからのスクロール量
$(window).scrollTop()はスクロール量を計算するための記述です。
試しにconsole.log()を指定したらどうなるかデベロッパーツールで見てみましょう。
var scroll = $(window).scrollTop(); // 画面トップからのスクロール量
console.log(scroll);
少し分かりづらいですが上の画像のように絶えずスクロール量を計算しています。
var blockPosition = $(this).offset().top; // 画面トップから見たブロックのある位置
$(this)はイベントが発生した要素を取得するので、今回だったらscroll-blockクラスのことを指します。
offset().topは、画面トップから指定した要素までの距離を測るので、ここではscroll-blockクラスのついたが要素がそれぞれ画面トップからどれだけの高さなのかを測っています。
これもconsole.log()を指定しして見てみましょう。
var blockPosition = $(this).offset().top; // 画面トップから見たブロックのある位置
console.log(blockPosition);
今回HTMLで6つのdivブロックを用意しているので、6箇所の位置が測定されています。
var windowHeihgt = $(window).height(); // ウィンドウの高さ
次に$(window).height()ですが、heightは高さを測るメソッドですので、Windowの高さを測定しています。
これについてもconsole.log();を指定したらどうなるか見てみましょう。
var windowHeihgt = $(window).height(); // ウィンドウの高さ
console.log(windowHeihgt);
このように画面の高さを測定していることが分かります。
jQueryコード/if文で要素位置を判定
if (scroll > blockPosition - windowHeihgt + 300) {
$(this).addClass("blockIn");
}
要素の高さが代入されているblockPositionから、ウィンドウ高さが代入されているwindowHeihgtを引いて差分を計算します。
この差分をスクロール量が上回る=要素が画面に出現している、ということになります。
+300を指定しているのは、画面に要素が出現してから300pxの位置まで構えさせるためです。
これが無い場合、画面に入った瞬間にアニメーションが発動するので、動いている事が分かりづらいと思い今回は指定しました。
そして画面に出現して300pxの位置まできたらaddClassメソッドでアニメーションが設定されているblockInクラスを付与します。
アニメーション要素の説明(CSS)
各ブロックにfade-block1〜6という名前をつけています。
これに対し画面外にある時の状態と、画面に入った時の状態をそれぞれ設定しています。
また、画面に入った時の要素は、jQueryでblockInクラスを付与し連結させた状態で設定しています。
ここであらためてデモサイトのリンクを貼っておきます。
パターン1:透明度が変化
/* ----------パターン1:透明度が変化---------- */
/* 画面外 */
.fade-block1 {
opacity: .1;
transition: all 1.5s;
}
/* 画面に入った時の動き */
.fade-block1.blockIn {
opacity: 1;
}
opacityを0.1とほぼ透明にしておいて、画面に入るとopacity1とし、要素を浮かび上がらせるような動作にしています。
transitionの1.5sは透明度の変化スピードを指定したものです。このスピード指定がないと、パッと切り替わるような挙動になります。
ちなみにtransitionは他の全ての要素に指定しています。
パターン2:下からふわっと出現
/* ----------パターン2:下からふわっと---------- */
/* 画面外 */
.fade-block2 {
transform: translateY(100px);
transition: all .5s ease-in;
}
/* 画面に入った時の動き */
.fade-block2.blockIn {
transform: translateY(0);
}
今度はtranslateを使った挙動です。
アニメーションといえばこっちをイメージする方の方が多いかもしれませんね。
この指定はtransformで動きをつけています。transform自体は要素を移動させたり変形させたりするプロパティですが、それをclassの付け替え時に指定有→指定無とすることで動きがあるように見せています。
この指定はtranslateY(100px)で予め元の位置より100px下に配置させています。
そこにblockInが付与されたらtranslateY(0)として元の位置に戻すという記述になっています。
これにより下から上に移動してきたような見た目になります。
パターン3〜5:左右斜めから出現
/* ----------パターン3:右からふわっと---------- */
/* 画面外 */
.fade-block3 {
transform: translateX(200px);
transition: all .5s ease-in;
}
/* 画面に入った時の動き */
.fade-block3.blockIn {
transform: translateX(0);
}
/* ----------パターン4:左からふわっと---------- */
/* 画面外 */
.fade-block4 {
transform: translateX(-200px);
transition: all .5s ease-in;
}
/* 画面に入った時の動き */
.fade-block4.blockIn {
transform: translateX(0);
}
/* ----------パターン5:斜め下からふわっと---------- */
/* 画面外 */
.fade-block5 {
transform: translate(150px, 150px);
transition: all .5s ease-in;
}
/* 画面に入った時の動き */
.fade-block5.blockIn {
transform: translate(0);
}
これらはパターン2と理屈は同じです。
translateで位置をずらして配置しておき、blockInが付与されたら元の位置に戻す、という指定です。
パターン6:横から出現してどこかに飛んでいく
/* ----------パターン6:画面外に飛んでいく---------- */
/* 画面外 */
.fade-block6 {
transform: translate(-100vw);
transition: all 3s ease;
}
/* 画面に入った時の動き */
.fade-block6.blockIn {
transform: translate(100vw);
}
謎の目次名になりましたが文字の通り。
やっていることは他と変わりませんが、要素を-100vwから100vwとすることで、画面枠外から枠外へ移動していくような挙動になります。
この演出は使い方次第だとは思うけど、、、自然な感じで使うにはちょっとテクニックがいりそうですな。
まとめ
最後にデモサイトのコードをまとめて載せておきます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="robots" content="noindex" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="styles.css" />
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<title>ダイブログ|スクロールフェードインデモ</title>
</head>
<body>
<div class="top">
<p class="title">スクロールフェードインデモページ</p>
</div>
<div class="scroll-block fade-block1">要素1</div>
<div class="scroll-block fade-block2">要素2</div>
<div class="scroll-block fade-block3">要素3</div>
<div class="scroll-block fade-block4">要素4</div>
<div class="scroll-block fade-block5">要素5</div>
<div class="scroll-block fade-block6">要素6</div>
<script src="script.js"></script>
</body>
</html>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
overflow-x: hidden;
}
.top {
height: 100vh;
}
.title {
text-align: center;
line-height: 100vh;
}
@media screen and (min-width:481px) {
.title {
font-size: 1.5rem;
}
}
/* ブロック共通初期設定 */
.scroll-block {
width: 50%;
height: 500px;
margin: 0 auto 400px;
line-height: 500px;
text-align: center;
background-color: lightcoral;
}
/* ----------パターン1:透明度が変化---------- */
/* 画面外 */
.fade-block1 {
opacity: .1;
transition: all 1.5s;
}
/* 画面に入った時の動き */
.fade-block1.blockIn {
opacity: 1;
}
/* ----------パターン2:下からふわっと---------- */
/* 画面外 */
.fade-block2 {
transform: translateY(100px);
transition: all .5s ease-in;
}
/* 画面に入った時の動き */
.fade-block2.blockIn {
transform: translateY(0);
}
/* ----------パターン3:右からふわっと---------- */
/* 画面外 */
.fade-block3 {
transform: translateX(200px);
transition: all .5s ease-in;
}
/* 画面に入った時の動き */
.fade-block3.blockIn {
transform: translateX(0);
}
/* ----------パターン4:左からふわっと---------- */
/* 画面外 */
.fade-block4 {
transform: translateX(-200px);
transition: all .5s ease-in;
}
/* 画面に入った時の動き */
.fade-block4.blockIn {
transform: translateX(0);
}
/* ----------パターン5:斜め下からふわっと---------- */
/* 画面外 */
.fade-block5 {
transform: translate(150px, 150px);
transition: all .5s ease-in;
}
/* 画面に入った時の動き */
.fade-block5.blockIn {
transform: translate(0);
}
/* ----------パターン6:画面外に飛んでいく---------- */
/* 画面外 */
.fade-block6 {
transform: translate(-100vw);
transition: all 3s ease;
}
/* 画面に入った時の動き */
.fade-block6.blockIn {
transform: translate(100vw);
}
$(function() {
// ↓windowがスクロールされた時に実行する処理
$(window).scroll(function() {
// ↓複数のオブジェクトに対して繰り返し処理を行う
$(".scroll-block").each(function() {
// ↓要素が画面上に表示されたかどうかを判定させる変数を定義----------
var scroll = $(window).scrollTop(); // 画面トップからのスクロール量
var blockPosition = $(this).offset().top; // 画面トップから見たブロックのある位置
var windowHeihgt = $(window).height(); // ウィンドウの高さ
// ↓if式で計算する流れ----------
// 手順① 表示させたいブロックの位置している高さ - ウィンドウの高さ
// 手順② スクロール量が①より多くなった時=要素が画面上に表示されたと認識
// 手順③ 要素に「blockIn」クラスを付与。動きはCSSで制御。
if (scroll > blockPosition - windowHeihgt + 300) {
$(this).addClass("blockIn");
}
});
});
});
スクロール連動のアニメーションは入れすぎると視認性が悪くなりますが、個性を出したいサイトなどでポイントに絞って導入するのはアリだと思います。理屈がわかれば簡単なので、導入時は参考にしてみてください!
スクロール繋がりでページ内のスムーススクロール実装方法もまとめているので、興味のある方はこちらもどうぞ。
また、より柔軟にスクロールアニメーションを実装したい場合、JavaScriptライブラリを使うと効率的です。オススメのライブラリ「AOS.js」について解説している記事もあわせてご覧ください!
また、当記事を読まれている方の中にはWeb制作初学者の方もいるかと思います。デザインやコーディングの基礎知識を学びたい方向けの記事を用意しているので是非見ていってください!
PENGIN無料コーディング課題
オススメ書籍紹介
オススメUdemy講座紹介