背景画像を使ったパララックスに関するメモ。
参考にさせていただいたサイト:
「HTML5 × CSS3 × jQueryを真面目に勉強 – #6 パララックスエフェクトの基本」
jQuery を使用しないで CSS で単純なパララックス(背景画像を固定して表示)を実現する方法。
HTML
<!doctype html> <html> <head> <meta charset="utf-8"> <title>CSS Parallax</title> </head> <body> <div id="wrapper"> <div id="first" class="content"> <p class="title">CSS Parallax</p> <div class="inner"> <h1>1. Lorem ipsum dolor</h1> <p>Ducimus, deleniti, minus minima delectus beatae... </p> </div> </div> <div id="second" class="content"> <div class="inner"> <h2>2. Facilis, molestias</h2> <p>laboriosam, asperiores quisquam recusandae ipsum ...</p> </div> </div> <div id="third" class="content"> <div class="inner"> <h2>3. Quod, illum fuga</h2> <p>Laudantium, accusamus, sit, adipisci animi quae... </p> </div> <img src="images/pallarax1/picture01.jpg" alt=""/> </div> <div id="end" class="content"> <h2>The End.</h2> </div> </div> </body> </html>
CSS
body { margin: 0; padding: 0; line-height: 1.5; font-size: 16px; } #wrapper { position: relative; width: 960px; height: 3500px; margin: 0 auto; padding: 0; } .content { position: relative; margin: 0 auto; padding: 0; height: 800px; } #first { background: url(images/pallarax1/div1_bg.jpg) 50% 0 no-repeat fixed; } #second { background: url(images/pallarax1/div2_bg.jpg) 50% 0 no-repeat fixed #000; } #third { background: url(images/pallarax1/div3_bg.jpg) 50% 0 no-repeat fixed #000; } #end { background: url(images/pallarax1/div4_bg.jpg) 50% 0 no-repeat fixed #FFF ; } /* div#first */ .title { position: fixed; /*z-index: 10;*/ } #first .inner { position: absolute; top: 200px; left: 20px; width: 400px; } /* div#second */ #second .inner { position: absolute; top: 80px; left: 100px; padding: 10px 20px; width: 445px; } /* #third .inner */ #third .inner { position: absolute; top: 0; padding: 10px 20px; color: white; } #third img { position: absolute; left: 30px; top: 500px; } /* div#end */ #end h2 { position: absolute; color: white; font-size: 4em; left: 50%; top: 180px; width: 300px; }
背景画像の CSS で fixed を使わず jQuery を使って同じことをするには以下のようにできる。
HTML は同じ。
CSS では背景画像の指定で「fixed」を削除(ポジションは削除してもそのままでも同じ。 jQueryで変更)
CSS の変更箇所
#first { background: url(images/div1_bg.jpg) no-repeat ; } #second { background: url(images/div2_bg.jpg) no-repeat #000; } #third { background: url(images/div3_bg.jpg) no-repeat #000; } #end { background: url(images/div4_bg.jpg) no-repeat #FFF ; }
jQuery ではそれぞれの div 要素(.content)について、それらがブラウザに表示されている場合に background-position を調整。
ブラウザに表示されているかの判定
その領域の垂直位置の値を、その時点のスクロール量「$window.scrollTop()」からその領域のオフセットを引いたものに指定。
jQuery
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script> jQuery(function($){ var $window = $(window); $('.content').each(function(index) { var $self = $(this); var offsetPositions = $self.offset(); $(window).scroll(function() { //この領域がブラウザに表示されている場合 if (($window.scrollTop() + $window.height()) > offsetPositions.top && ((offsetPositions.top + $self.height()) > $window.scrollTop())) { var offsetY = $window.scrollTop() - offsetPositions.top ; var positions = '50%' + offsetY + 'px'; $self.css('backgroundPosition', positions); //console.log(index + ' offsetY : ' + offsetY + ' $window.scrollTop: ' + $window.scrollTop()); } }); }); }); </script>
または、以下のようにすると似たようなことが可能。但し表示される重なり順が異なる。
jQuery(function($){ var first$ = $('#first'); var first_ot = first$.offset().top; var second$ = $('#second'); var second_ot = second$.offset().top; var third$ = $('#third'); var third_ot = third$.offset().top; var end$ = $('#end'); var end_ot = end$.offset().top; $(window).scroll(function(){ var dy = $(this).scrollTop(); if(dy > first_ot) { first$.css('background-position', '0 ' + (dy-first_ot) + 'px'); }else{ first$.css('background-position', '0 0'); } if(dy > second_ot) { second$.css('background-position', '0 ' + (dy-second_ot) + 'px'); }else{ second$.css('background-position', '0 0'); } if(dy > third_ot) { third$.css('background-position', '0 ' + (dy-third_ot) + 'px'); }else{ third$.css('background-position', '0 0'); } if(dy > end_ot) { end$.css('background-position', '0 ' + (dy - end_ot) + 'px'); }else{ end$.css('background-position', '0 bottom'); } }); });
背景画像がゆっくりと上に動いていくように見えるようにする。
HTML は同じ。
CSS は 背景画像に fixed を指定。
CSS
#first { background: url(images/div1_bg.jpg) center 0% no-repeat fixed; } #second { background: url(images/div2_bg.jpg) center 0% no-repeat fixed; } #third { background: url(images/div3_bg.jpg) center 0 no-repeat fixed; } #end { background: url(images/div4_bg.jpg) center 0 no-repeat fixed; }
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script> jQuery(function($){ var $window = $(window); $('.content').each(function(index) { var $self = $(this); var offsetPositions = $self.offset(); $(window).scroll(function() { // この領域がブラウザに表示されている場合 if (($window.scrollTop() + $window.height()) > offsetPositions.top && ((offsetPositions.top + $self.height()) > $window.scrollTop())) { var offsetY = -(($window.scrollTop() - offsetPositions.top)/ 17); //var offsetY = -($window.scrollTop()/ 17); var positions = '50%' + offsetY + 'px'; $self.css('backgroundPosition', positions); } }); }); }); </script>
背景画像の CSS で fixed を使わない場合は以下のようにする。
「var offsetY」の値を「-(($window.scrollTop() – offsetPositions.top)/ 17)」から
「$window.scrollTop() – offsetPositions.top -(($window.scrollTop() – offsetPositions.top)/ 17)」に変更するだけ。
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script> jQuery(function($){ var $window = $(window); $('.content').each(function(index) { var $self = $(this); var offsetPositions = $self.offset(); $(window).scroll(function() { // この領域がブラウザに表示されている場合 if (($window.scrollTop() + $window.height()) > offsetPositions.top && ((offsetPositions.top + $self.height()) > $window.scrollTop())) { var offsetY = $window.scrollTop() - offsetPositions.top -(($window.scrollTop() - offsetPositions.top)/ 17); var positions = '50%' + offsetY + 'px'; $self.css('backgroundPosition', positions); } }); }); }); </script>
似たような効果を別の方法で行ってみる。
(背景画像の CSS で fixed を指定)
jQuery を以下のように記述
xxxx_factor は速度を調節するための適当な値。
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script> jQuery(function($){ var first$ = $('#first'); var first_ot = first$.offset().top; var first_factor = -0.1; var second$ = $('#second'); var second_ot = second$.offset().top; var second_factor = -0.1; var third$ = $('#third'); var third_ot = third$.offset().top; var third_factor = -0.2; var end$ = $('#end'); var end_ot = end$.offset().top; var end_factor = -0.5; $(window).scroll(function(){ var dy = $(this).scrollTop(); first$.css('background-position', '50% ' + (dy-first_ot) * first_factor + 'px'); second$.css('background-position', '50% ' + (dy-second_ot) * second_factor + 'px'); third$.css('background-position', '50% ' + (dy-third_ot) * third_factor + 'px'); end$.css('background-position', '50% ' + ((dy - end_ot) * end_factor) + 'px'); }); }); </script>
以下のように記述しても同じ。
$(window).scroll(function(){ var dy = $(this).scrollTop(); $('.content').each(function(index) { var $self = $(this); var offsetPositions = $self.offset(); var positions; switch(index) { case 0: positions = '50% ' + (dy-offsetPositions.top) * (-0.1 ) + 'px'; $self.css('backgroundPosition', positions); break; case 1: positions = '50% ' + (dy-offsetPositions.top) * (-0.1 ) + 'px'; $self.css('backgroundPosition', positions); break; case 2: positions = '50% ' + (dy-offsetPositions.top) * (-0.2 ) + 'px'; $self.css('backgroundPosition', positions); break; case 3: positions = '50% ' + (dy-offsetPositions.top) * (-0.5 ) + 'px'; $self.css('backgroundPosition', positions); break; default: break; } }); });
jQuery での効果のためのパラメータを、以下のような HTML5 のデータ属性を使って指定。
また効果を与える要素にクラス「movingElement」を追加。
HTML
変更箇所は「<!–*–>」が付いた3箇所。
<body> <div id="wrapper"> <div id="first" class="content"> <!--*--><p class="title movingElement" data-speed="-1.5" data-offsety="100">CSS Parallax 4</p> <div class="inner"> <h1>1. Lorem ipsum dolor</h1> <p>Ducimus, deleniti, minus minima delectus... </p> </div> </div> <div id="second" class="content"> <div class="inner"> <h2>2. Facilis, molestias</h2> <p>laboriosam, asperiores quisquam ...</p> </div> </div> <div id="third" class="content"> <div class="inner"> <h2>3. Quod, illum fuga</h2> <p>Laudantium, accusamus, sit... </p> </div> <!--*--><img src="images/picture01.jpg" class="movingElement" data-speed="1.4" data-offsety="1200" alt="" /> </div> <div id="end" class="content"> <!--*--><h2 class="movingElement" data-speed="0.8" data-offsety="3180">The End.</h2> </div> </div> </body>
以下の3つの要素を動かすための jQuery の記述を追加
<p class=”title movingElement” >
<img class=”movingElement” >
<h2 class=”movingElement” >
HTML で指定したデータ属性の値は、以下のようにして取得することができる
$(セレクタ).data(データ属性の「data-」を除いた部分);
<p class="title movingElement" data-speed="-1.5" data-offsety="100"> $('.title').data('speed'); // -1.5 $('.title').data('offsety'); // 100
jQuery
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script> jQuery(function($){ var $window = $(window); $('.content').each(function(index) { var $self = $(this); var offsetPositions = $self.offset(); $(window).scroll(function() { if (($window.scrollTop() + $window.height()) > offsetPositions.top && ((offsetPositions.top + $self.height()) > $window.scrollTop())) { var offsetY = -(($window.scrollTop() - offsetPositions.top)/ 17); var positions = '50%' + offsetY + 'px'; $self.css('backgroundPosition', positions); //追加部分 $('.movingElement', $self).each(function(index) { var $movingElement = $(this); var yPos = -($window.scrollTop() / $movingElement.data('speed')) + $movingElement.data('offsety'); $movingElement.css('top', yPos); }); //ここまで } }); }); }); </script>