JavaScriptでスクロール位置を管理して、対象要素が画面上に表示されたらclassを追加して、CSS3のアニメーションを行う処理を実装してみます。
サンプルコード
スクロールで対象要素が表示されたら、フェードインしながら下から上に表示するアニメーションを実装してみます。
HTML
画像とテキストを左右に配置するレイアウトで、アニメーションさせる要素に対して.animation-scrollUp を追加しています。
<div class="image-block image-block_left"> <div class="image-block_inner"> <div class="image-block_img"> <img src="./img01.jpg" width="450" alt="" class="animation-scrollUp" /> </div> <div class="image-block_text"> <p class="image-block_ttl animation-scrollUp">キャッチコピー的なテキスト</p> <p class="image-block_description animation-scrollUp">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br /> キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p> </div> </div> </div> <div class="image-block image-block_right"> <div class="image-block_inner"> <div class="image-block_img"> <img src="./img02.jpg" width="450" alt="" class="animation-scrollUp" /> </div> <div class="image-block_text"> <p class="image-block_ttl animation-scrollUp">キャッチコピー的なテキスト</p> <p class="image-block_description animation-scrollUp">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br /> キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p> </div> </div> </div> <div class="image-block image-block_left"> <div class="image-block_inner"> <div class="image-block_img"> <img src="./img03.jpg" width="450" alt="" class="animation-scrollUp" /> </div> <div class="image-block_text"> <p class="image-block_ttl animation-scrollUp">キャッチコピー的なテキスト</p> <p class="image-block_description animation-scrollUp">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br /> キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p> </div> </div> </div> <div class="image-block image-block_right"> <div class="image-block_inner"> <div class="image-block_img"> <img src="./img04.jpg" width="450" alt="" class="animation-scrollUp" /> </div> <div class="image-block_text"> <p class="image-block_ttl animation-scrollUp">キャッチコピー的なテキスト</p> <p class="image-block_description animation-scrollUp">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br /> キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p> </div> </div> </div>
CSS
まずはレイアウトを行っている部分のCSSです。
/* 要素配置のスタイル */ .image-block { padding: 150px 0; overflow: hidden; } .image-block_left { background: #ecf0f1; } .image-block_right { background: #cfe9fa; } .image-block_inner { width: 1000px; margin: 0 auto; } .image-block_img { } .image-block_left .image-block_img { float: left; } .image-block_right .image-block_img { float: right; } .image-block_text { width: 500px; } .image-block_left .image-block_text { float: right; } .image-block_right .image-block_text { float: left; } .image-block_ttl { color: #3498DB; font-size: 32px; margin-bottom: 20px; } .image-block_description { line-height: 1.8; }
CSS
アニメーション部分のCSSです。
アニメーションはtransitionで行っていて、.is-animatedが追加されたタイミングでtransformとopacityの値を変更するようにしています。
/* アニメーションのスタイル */ .animation-scrollUp { -webkit-transform: translateY(40px); transform: translateY(40px); opacity: 0; -webkit-transition: 0.8s; transition: 0.8s; } .animation-scrollUp.is-animated { -webkit-transform: translateY(0); transform: translateY(0); opacity: 1; }
JavaScript
スクロール毎に対象要素が画面内に表示されたかどうかを確認して、表示されている場合はclassを追加してアニメーションを実行させています。
$(function() { $(window).on('load scroll', function() { setAnimationClass(); }); var animationClass = 'animation-scrollUp'; // アニメーション対象のclass名 var animationFinClass = 'is-animated'; // アニメーションが実行時に付与するclass名 var animationStartPosition = 0.75; // アニメーションが実行されるスクロール位置 // アニメーションが完了しているかどうかを管理する配列 var animationFlagArr = []; for(var i = 0; i < $('.' + animationClass).length; i++) { animationFlagArr[i] = false; } function setAnimationClass() { // アニメーションの実行前に、アニメーション完了済の要素を確認しておく for(var i = 0; i < $('.' + animationClass).length; i++) { if($('.' + animationClass).eq(i).hasClass(animationFinClass)) { animationFlagArr[i] = true; } } // スクロール位置と画面高さを取得 var scrollTop = $(window).scrollTop(); var windowHeight = $(window).height(); // アニメーション対象要素が開始位置までスクロールしている場合、classを付与する for(var i = 0; i < animationFlagArr.length; i++) { if(animationFlagArr[i] == false) { var thisElement = $('.' + animationClass).eq(i); var thisTop = thisElement.offset().top; if(scrollTop + (windowHeight * animationStartPosition) > thisTop) { thisElement.addClass(animationFinClass); } } } } });
サンプルコード2
テキストを1文字ずつ分解してアニメーションさせてみます。
HTML
基本的には先ほどと同じ構造で、アニメーションさせる要素に対して.animation-scrollRotateを追加しています。
<div class="image-block image-block_left"> <div class="image-block_inner"> <div class="image-block_img"> <img src="./img01.jpg" width="450" alt="" /> </div> <div class="image-block_text"> <p class="image-block_ttl animation-scrollRotate">キャッチコピー的なテキスト</p> <p class="image-block_description">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br /> キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p> </div> </div> </div> <div class="image-block image-block_right"> <div class="image-block_inner"> <div class="image-block_img"> <img src="./img02.jpg" width="450" alt="" /> </div> <div class="image-block_text"> <p class="image-block_ttl animation-scrollRotate">キャッチコピー的なテキスト</p> <p class="image-block_description">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br /> キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p> </div> </div> </div> <div class="image-block image-block_left"> <div class="image-block_inner"> <div class="image-block_img"> <img src="./img03.jpg" width="450" alt="" /> </div> <div class="image-block_text"> <p class="image-block_ttl animation-scrollRotate">キャッチコピー的なテキスト</p> <p class="image-block_description">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br /> キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p> </div> </div> </div> <div class="image-block image-block_right"> <div class="image-block_inner"> <div class="image-block_img"> <img src="./img04.jpg" width="450" alt="" /> </div> <div class="image-block_text"> <p class="image-block_ttl animation-scrollRotate">キャッチコピー的なテキスト</p> <p class="image-block_description">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br /> キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p> </div> </div> </div>
CSS
アニメーションは.animation-scrollRotateではなく、その子要素のspanに対して設定しています。
/* アニメーションのスタイル */ .animation-scrollRotate span { display: inline-block; -webkit-transform: rotate(-90deg); transform: rotate(-90deg); opacity: 0; -webkit-transition: 0.8s; transition: 0.8s; -webkit-transition-property: transform, opacity; transition-property: transform, opacity; } .animation-scrollRotate.is-animated span { -webkit-transform: rotate(0deg); transform: rotate(0deg); opacity: 1; }
JavaScript
アニメーション部分は先ほどとほぼ同じですが、最初に対象要素のテキストを1文字ずつ分解してspanで括るようにしています。
$(function() { $(window).on('load scroll', function() { setAnimationClass(); }); var animationClass = 'animation-scrollRotate'; // アニメーション対象のclass名 var animationFinClass = 'is-animated'; // アニメーションが実行時に付与するclass名 var animationStartPosition = 0.75; // アニメーションが実行されるスクロール位置 // アニメーションが完了しているかどうかを管理する配列 var animationFlagArr = []; for(var i = 0; i < $('.' + animationClass).length; i++) { animationFlagArr[i] = false; var thisText = $('.' + animationClass).eq(i).text().split(''); var animationTextInsert = ''; for(var j = 0; j < thisText.length; j++) { animationTextInsert += '<span>' + thisText[j] + '</span>' } $('.' + animationClass).eq(i).html(animationTextInsert); } function setAnimationClass() { // アニメーションの実行前に、アニメーション完了済の要素を確認しておく for(var i = 0; i < $('.' + animationClass).length; i++) { if($('.' + animationClass).eq(i).hasClass(animationFinClass)) { animationFlagArr[i] = true; } } // スクロール位置と画面高さを取得 var scrollTop = $(window).scrollTop(); var windowHeight = $(window).height(); // アニメーション対象要素が開始位置までスクロールしている場合、classを付与する for(var i = 0; i < animationFlagArr.length; i++) { if(animationFlagArr[i] == false) { var thisElement = $('.' + animationClass).eq(i); var thisTop = thisElement.offset().top; if(scrollTop + (windowHeight * animationStartPosition) > thisTop) { thisElement.addClass(animationFinClass); } } } } });
アニメーションのタイミングを1文字ずつずらしたい場合、1文字ずつtransition-delayをずらして設定します。
CSS
/* アニメーションのスタイル */ .animation-scrollRotate span { display: inline-block; -webkit-transform: rotate(-90deg); transform: rotate(-90deg); opacity: 0; -webkit-transition: 0.8s; transition: 0.8s; -webkit-transition-property: transform, opacity; transition-property: transform, opacity; } .animation-scrollRotate.is-animated span { -webkit-transform: rotate(0deg); transform: rotate(0deg); opacity: 1; } .animation-scrollRotate span:nth-child(2) {-webkit-transition-delay: 0.1s;transition-delay: 0.1s;} .animation-scrollRotate span:nth-child(3) {-webkit-transition-delay: 0.2s;transition-delay: 0.2s;} .animation-scrollRotate span:nth-child(4) {-webkit-transition-delay: 0.3s;transition-delay: 0.3s;} .animation-scrollRotate span:nth-child(5) {-webkit-transition-delay: 0.4s;transition-delay: 0.4s;} .animation-scrollRotate span:nth-child(6) {-webkit-transition-delay: 0.5s;transition-delay: 0.5s;} .animation-scrollRotate span:nth-child(7) {-webkit-transition-delay: 0.6s;transition-delay: 0.6s;} .animation-scrollRotate span:nth-child(8) {-webkit-transition-delay: 0.7s;transition-delay: 0.7s;} .animation-scrollRotate span:nth-child(9) {-webkit-transition-delay: 0.8s;transition-delay: 0.8s;} .animation-scrollRotate span:nth-child(10) {-webkit-transition-delay: 0.9s;transition-delay: 0.9s;} .animation-scrollRotate span:nth-child(11) {-webkit-transition-delay: 1.0s;transition-delay: 1.0s;} .animation-scrollRotate span:nth-child(12) {-webkit-transition-delay: 1.1s;transition-delay: 1.1s;} .animation-scrollRotate span:nth-child(13) {-webkit-transition-delay: 1.2s;transition-delay: 1.2s;} .animation-scrollRotate span:nth-child(14) {-webkit-transition-delay: 1.3s;transition-delay: 1.3s;} .animation-scrollRotate span:nth-child(15) {-webkit-transition-delay: 1.4s;transition-delay: 1.4s;}
一文字ずつタイミングをずらしてアニメーションさせるデモページ
サンプルコード3
アニメーションの種類を複数設定してみます。
HTML
画像、タイトル、本文のそれぞれでアニメーションを変更してみます。
それぞれ.animation-scrollScale、.animation-scrollRotate、animation-scrollUpとclassを追加しています。
<div class="image-block image-block_left"> <div class="image-block_inner"> <div class="image-block_img"> <img src="./img01.jpg" width="450" alt="" class="animation-scrollScale" /> </div> <div class="image-block_text"> <p class="image-block_ttl animation-scrollRotate">キャッチコピー的なテキスト</p> <p class="image-block_description animation-scrollUp">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br /> キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p> </div> </div> </div> <div class="image-block image-block_right"> <div class="image-block_inner"> <div class="image-block_img"> <img src="./img02.jpg" width="450" alt="" class="animation-scrollScale" /> </div> <div class="image-block_text"> <p class="image-block_ttl animation-scrollRotate">キャッチコピー的なテキスト</p> <p class="image-block_description animation-scrollUp">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br /> キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p> </div> </div> </div> <div class="image-block image-block_left"> <div class="image-block_inner"> <div class="image-block_img"> <img src="./img03.jpg" width="450" alt="" class="animation-scrollScale" /> </div> <div class="image-block_text"> <p class="image-block_ttl animation-scrollRotate">キャッチコピー的なテキスト</p> <p class="image-block_description animation-scrollUp">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br /> キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p> </div> </div> </div> <div class="image-block image-block_right"> <div class="image-block_inner"> <div class="image-block_img"> <img src="./img04.jpg" width="450" alt="" class="animation-scrollScale" /> </div> <div class="image-block_text"> <p class="image-block_ttl animation-scrollRotate">キャッチコピー的なテキスト</p> <p class="image-block_description animation-scrollUp">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br /> キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p> </div> </div> </div>
CSS
transitionを使ってアニメーションを設定しています。
/* アニメーションのスタイル */ .animation-scrollUp { -webkit-transform: translateY(40px); transform: translateY(40px); opacity: 0; -webkit-transition: 0.8s; transition: 0.8s; } .animation-scrollUp.is-animated { -webkit-transform: translateY(0); transform: translateY(0); opacity: 1; } .animation-scrollRotate span { display: inline-block; -webkit-transform: rotate(-90deg); transform: rotate(-90deg); opacity: 0; -webkit-transition: 0.8s; transition: 0.8s; -webkit-transition-property: transform, opacity; transition-property: transform, opacity; } .animation-scrollRotate.is-animated span { -webkit-transform: rotate(0deg); transform: rotate(0deg); opacity: 1; } .animation-scrollRotate span:nth-child(2) {-webkit-transition-delay: 0.1s;transition-delay: 0.1s;} .animation-scrollRotate span:nth-child(3) {-webkit-transition-delay: 0.2s;transition-delay: 0.2s;} .animation-scrollRotate span:nth-child(4) {-webkit-transition-delay: 0.3s;transition-delay: 0.3s;} .animation-scrollRotate span:nth-child(5) {-webkit-transition-delay: 0.4s;transition-delay: 0.4s;} .animation-scrollRotate span:nth-child(6) {-webkit-transition-delay: 0.5s;transition-delay: 0.5s;} .animation-scrollRotate span:nth-child(7) {-webkit-transition-delay: 0.6s;transition-delay: 0.6s;} .animation-scrollRotate span:nth-child(8) {-webkit-transition-delay: 0.7s;transition-delay: 0.7s;} .animation-scrollRotate span:nth-child(9) {-webkit-transition-delay: 0.8s;transition-delay: 0.8s;} .animation-scrollRotate span:nth-child(10) {-webkit-transition-delay: 0.9s;transition-delay: 0.9s;} .animation-scrollRotate span:nth-child(11) {-webkit-transition-delay: 1.0s;transition-delay: 1.0s;} .animation-scrollRotate span:nth-child(12) {-webkit-transition-delay: 1.1s;transition-delay: 1.1s;} .animation-scrollRotate span:nth-child(13) {-webkit-transition-delay: 1.2s;transition-delay: 1.2s;} .animation-scrollRotate span:nth-child(14) {-webkit-transition-delay: 1.3s;transition-delay: 1.3s;} .animation-scrollRotate span:nth-child(15) {-webkit-transition-delay: 1.4s;transition-delay: 1.4s;} .animation-scrollScale { -webkit-transform: scale(1.2); transform: scale(1.2); opacity: 0; -webkit-transition: 0.8s; transition: 0.8s; } .animation-scrollScale.is-animated { -webkit-transform: scale(1); transform: scale(1); opacity: 1; }
JavaScript
classなどを配列で管理するように変更して、複数のclassを設定できるように変更しています。
タイトル部分だけ1文字ずつアニメーションさせるため、19~28行目でspanを追加しています。
$(function() { $(window).on('load scroll', function() { setAnimationClass(); }); var animationClassArr = ['animation-scrollUp', 'animation-scrollRotate', 'animation-scrollScale']; // アニメーション対象のclass名 var animationFinClassArr = ['is-animated', 'is-animated', 'is-animated']; // アニメーションが実行時に付与するclass名 var animationStartPositionArr = [0.75, 0.75, 0.75]; // アニメーションが実行されるスクロール位置 // アニメーションが完了しているかどうかを管理する配列 var animationFlagArr = {}; for(var i = 0; i < animationClassArr.length; i++) { animationFlagArr[animationClassArr[i]] = []; for(var j = 0; j < $('.' + animationClassArr[i]).length; j++) { animationFlagArr[animationClassArr[i]][j] = false; } } // .animation-scrollRotateのテキストにspan追加 for(var i = 0; i < $('.' + animationClassArr[1]).length; i++) { var thisElem = $('.' + animationClassArr[1]).eq(i); var thisText = thisElem.text().split(''); var animationTextInsert = ''; for(var j = 0; j < thisText.length; j++) { animationTextInsert += '<span>' + thisText[j] + '</span>' } thisElem.html(animationTextInsert); } function setAnimationClass() { // アニメーションの実行前に、アニメーション完了済の要素を確認しておく for(var i = 0; i < animationClassArr.length; i++) { for(var j = 0; j < $('.' + animationClassArr[i]).length; j++) { if($('.' + animationClassArr[i]).eq(j).hasClass(animationFinClassArr[i])) { animationFlagArr[animationClassArr[i]][j] = true; } } } // スクロール位置と画面高さを取得 var scrollTop = $(window).scrollTop(); var windowHeight = $(window).height(); // アニメーション対象要素が開始位置までスクロールしている場合、classを付与する for(var i = 0; i < animationClassArr.length; i++) { for(var j = 0; j < animationFlagArr[animationClassArr[i]].length; j++) { if(animationFlagArr[animationClassArr[i]][j] == false) { var thisElement = $('.' + animationClassArr[i]).eq(j); var thisTop = thisElement.offset().top; if(scrollTop + (windowHeight * animationStartPositionArr[i]) > thisTop) { thisElement.addClass(animationFinClassArr[i]); } } } } } });
コメントが承認されるまで時間がかかります。