背景画像を使ったパララックスに関するメモ。
参考にさせていただいたサイト:
「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>