Parallax

Parallax(パララックス効果)

  • マウスにあわせて画像が3D的に追従するサイトを簡単に作れるjQuery jParallaxプラグイン
  • スクロールに応じて要素がアニメーションする、視差効果(見た目がずれる)
  • カメラ用語:ファインダーから見た映像と撮影結果にずれがある
  • 遠くのものほどゆっくり、近くのものほど早く動いて見える







Parallax Slider

HTMLとCSS
  • z-indexを指定しない場合、あとに記述された要素が上になるため、section内でのlayerは内容よりも先に記述する
<!DOCTYPE html>
<html lang="ja">
<head>
<title>Parallax Slider with jQuery</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="wrapper">
<h1>Parallax Slider Demo</h1>
<h2>Create some depth with the parallax effect</h2>
</div>
<div id="pxs_container" class="pxs_container">
<div class="pxs_bg">
<div class="pxs_bg1"></div>
<div class="pxs_bg2"></div>
<div class="pxs_bg3"></div>
</div>
<div class="pxs_loading">Loading images...</div>
<div class="pxs_slider_wrapper">
<ul class="pxs_slider">
<li><img src="images/1.jpg" alt="First Image"></li>
<li><img src="images/2.jpg" alt="Second Image"></li>
<li><img src="images/3.jpg" alt="Third Image"></li>
<li><img src="images/4.jpg" alt="Forth Image"></li>
<li><img src="images/5.jpg" alt="Fifth Image"></li>
<li><img src="images/6.jpg" alt="Sixth Image"></li>
</ul>
<div class="pxs_navigation">
<span class="pxs_next"></span>
<span class="pxs_prev"></span>
</div>
<ul class="pxs_thumbnails">
<li><img src="images/thumbs/1.jpg" alt="First Image"></li>
<li><img src="images/thumbs/2.jpg" alt="Second Image"></li>
<li><img src="images/thumbs/3.jpg" alt="Third Image"></li>
<li><img src="images/thumbs/4.jpg" alt="Forth Image"></li>
<li><img src="images/thumbs/5.jpg" alt="Fifth Image"></li>
<li><img src="images/thumbs/6.jpg" alt="Sixth Image"></li>
</ul>
</div>
</div>
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="js/jquery.easing.1.3.js"></script>
<script src="js/parallax.js"></script>
<script type="text/javascript">
$(function() {
var $pxs_container = $('#pxs_container');
$pxs_container.parallaxSlider();
});
</script>
</body>
</html>
@charset "UTF-8";

*{
  margin:0;
  padding:0;
}
body{
  font-family:"Trebuchet MS", "Myriad Pro", Arial, sans-serif;
  font-size:14px;
  background:#222;
  color:#333;
  text-shadow:1px 1px 1px #FFF;
  overflow-x:hidden;
}
h1{
  font-size:56px;
  color:#ccc;
}
h2{
  font-size:20;
  padding:10 0 10 0;
  margin:15px 0 20 0;
}
a{
  color:#555;
  text-decoration:none;
}
a:hover{
  color:#222;
}
p{
  padding:5px 0;
}
.wrapper{
  width:960;
  margin:20 auto;
}

/* Slider Style */
.pxs_container{
  width:100%;
  height:420;
  position:relative;
  border-top:7px solid #333;
  border-bottom:7px solid #333;
  overflow:hidden;
  -moz-box-shadow:0 0 7px #000;
  -webkit-box-shadow:0 0 7px #000;
  box-shadow:0 0 7px #000;
}
.pxs_bg{
  background:transparent url(../images/bg.png) repeat top left;
}
.pxs_bg div{
  position:absolute;
  top:0;
  left:0;
  width:7584px; /*1264px window width times number of images*/
  height:420;
  background-repeat:repeat;
  background-position:top left;
  background-color:transparent;
}
.pxs_bg .pxs_bg1{
  background-image:url(../images/bg1.png);
  /*left negative 1/8 of ww*/
}
.pxs_bg .pxs_bg2{
  background-image:url(../images/bg2.png);
  /*left negative 1/4 of ww*/
}
.pxs_bg .pxs_bg3{
  background-image:url(../images/bg3.png);
  /*left negative 1/2 of ww*/
}
.pxs_slider_wrapper{
  display:none;
}
.pxs_container ul{
  margin:0;
  padding:0;
  list-style:none;
}
ul.pxs_slider{
  position:absolute;
  left:0;
  top:0;
  height:420;
}
ul.pxs_slider li{
  height:420;
  float:left;
  position:relative;
}
ul.pxs_slider li img{
  display:block;
  margin:35px auto 0 auto;
  -moz-box-shadow:0 0 7px #222;
  -webkit-box-shadow:0 0 7px #222;
  box-shadow:0 0 7px #222;
  border: 8px solid transparent;
  -moz-border-radius:4px;
  -webkit-border-radius:4px;
  border-radius:4px;
}
ul.pxs_thumbnails{
  height:35px;
  position:absolute;
  top:320;
  left:50%;
}
ul.pxs_thumbnails li{
  position:absolute;
  display:block;
}
ul.pxs_thumbnails li img{
  border: 5px solid #FFF;
  -moz-box-shadow:1px 1px 7px #555;
  -webkit-box-shadow:1px 1px 7px #555;
  box-shadow:1px 1px 7px #555;
  cursor:pointer;
  display:block;
  opacity:0.7;
}
ul.pxs_thumbnails li.selected img{
  opacity:1.0;
}
.pxs_navigation span{
  position:absolute;
  width:30;
  height:60;
  -moz-box-shadow:0 0 2px #000;
  -webkit-box-shadow:0 0 2px #000;
  box-shadow:0 0 2px #000;
  top:145px;
  opacity:0.6;
  -moz-border-radius:4px;
  -webkit-border-radius:4px;
  border-radius:4px;
  cursor:pointer;
}
.pxs_navigation span:hover{
  opacity:0.9;
}
.pxs_navigation span.pxs_prev{
  background:#000 url(../images/prev.png) no-repeat center center;
}
.pxs_navigation span.pxs_next{
  background:#000 url(../images/next.png) no-repeat center center;
}
.pxs_loading{
  color:#fff;
  font-size:20;
  padding:15px 15px 15px 50;
  position:absolute;
  background:#333 url(../images/ajax-loader.gif) no-repeat 10 50%;
  -moz-border-radius:15px;
  -webkit-border-radius:15px;
  border-radius:15px;
  opacity:0.7;
  width:180;
  position:absolute;
  top:150;
  left:50%;
  margin-left:-90;
}

デザインと構造

  • div要素で4つのセクションを作る



プラグイン

jQuery Easing Plugin

  • 動きの緩急をつける効果
  • デフォルト:linear(イージングなし)、swingr(イージングあり)


jQuery.ScrollTo

  • ページ内の指定した要素にスムーズにスクロール
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>SAVE THE NATURE PROJECT</title>
<link href="css/index.css" rel="stylesheet">
</head>
<body>
<div id="contents">
<div id="section0" class="section">
<!-- ▼layer あとで削除する -->
<div class="layer layer1"></div>
<div class="layer layer2"></div>
<!-- ▲layer あとで削除する -->
<h1><img src="images/logo.png" width="540" height="285" alt="SAVE THE NATURE PROJECT"></h1>
<ul id="topNav">
<li><a href="javascript:pageScroll(1)"><img src="images/btn_project.png" width="110" height="33" alt="Project"></a></li>
<li><a href="javascript:pageScroll(2)"><img src="images/btn_about.png" width="98" height="33" alt="About"></a></li>
<li><a href="javascript:pageScroll(3)"><img src="images/btn_report.png" width="106" height="33" alt="Report"></a></li>
</ul>
</div>
<div id="section1" class="section">
<!-- ▼layer あとで削除する -->
<div class="layer layer1"></div>
<div class="layer layer2"></div>
<!-- ▲layer あとで削除する -->
<h2><img src="images/title_project.png" width="256" height="71" alt="Project"></h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque pulvinar tellus sit amet erat malesuada mollis. Donec at purus id magna cursus aliquam in eget sapien. Vivamus bibendum tortor non arcu sollicitudin convallis. In hac habitasse platea dictumst. Sed enim lorem, imperdiet ac ornare ut, pretium nec libero. Morbi vulputate nisl in justo tincidunt in sollicitudin metus vehicula. Nunc nec ipsum neque, a convallis mi. Morbi vitae elit ac velit posuere consequat. Morbi dictum libero ac sapien tristique lobortis. Proin sit amet elit nec elit tristique dapibus. Nunc magna nibh, adipiscing quis lacinia et, placerat eget sem. Maecenas at lectus in diam egestas interdum.</p>
</div>
<div id="section2" class="section">
<!-- ▼layer あとで削除する -->
<div class="layer layer1"></div>
<div class="layer layer2"></div>
<!-- ▲layer あとで削除する -->
<h2><img src="images/title_about.png" width="224" height="71" alt="About"></h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse lectus nulla, ornare eu elementum eu, mollis id est. Ut non lobortis risus. Vestibulum aliquam ante nec lectus egestas in tristique enim fringilla. Morbi dignissim fermentum lacus, sed interdum nisi sollicitudin eget. In cursus risus eget orci ullamcorper a semper felis scelerisque. Cras bibendum sapien non sapien dapibus pellentesque. Donec mattis, arcu sed venenatis sodales, lacus tortor lobortis arcu, id mollis ipsum nunc in lorem. In rhoncus fermentum mauris, sed iaculis nisi placerat ac.Praesent viverra laoreet sollicitudin. Ut volutpat auctor faucibus. Nam venenatis molestie felis ut condimentum. Etiam sodales nunc vitae augue sollicitudin vitae luctus est scelerisque.</p>
</div>
<div id="section3" class="section">
<!-- ▼layer あとで削除する -->
<div class="layer layer1"></div>
<div class="layer layer2"></div>
<!-- ▲layer あとで削除する -->
<h2><img src="images/title_report.png" width="241" height="71" alt="Report"></h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque pulvinar tellus sit amet erat malesuada mollis. Donec at purus id magna cursus aliquam in eget sapien. Vivamus bibendum tortor non arcu sollicitudin convallis. In hac habitasse platea dictumst. Sed enim lorem, imperdiet ac ornare ut, pretium nec libero. Morbi vulputate nisl in justo tincidunt in sollicitudin metus vehicula. Nunc nec ipsum neque, a convallis mi. Morbi vitae elit ac velit posuere consequat. Morbi dictum libero ac sapien tristique lobortis. Proin sit amet elit nec elit tristique dapibus. Nunc magna nibh, adipiscing quis lacinia et, placerat eget sem. Maecenas at lectus in diam egestas interdum.</p>
</div>
</div>
<ul id="nav">
<li><a href="javascript:pageScroll(0)"><img src="images/btn_top2.png" width="33" height="17" alt="Top"></a></li>
<li><a href="javascript:pageScroll(1)"><img src="images/btn_project2.png" width="62" height="17" alt="Project"></a></li>
<li><a href="javascript:pageScroll(2)"><img src="images/btn_about2.png" width="56" height="17" alt="About"></a></li>
<li><a href="javascript:pageScroll(3)"><img src="images/btn_report2.png" width="61" height="17" alt="Report"></a></li>
</ul>
<p id="memo"></p>
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="js/jquery.easing.1.3.js"></script>
<script src="js/jquery.scrollTo-min.js"></script>
<script src="js/parallax.js"></script>
</body>
</html>
@charset "UTF-8";

/* reset */
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td { 
  margin:0;
  padding:0;
}
table {
  border-collapse:collapse;
  border-spacing:0;
}
fieldset,img { 
  border:0;
}
address,caption,cite,code,dfn,em,strong,th,var {
  font-style:normal;
  font-weight:normal;
}
ol,ul {
  list-style:none;
}
caption,th {
  text-align:left;
}
h1,h2,h3,h4,h5,h6 {
  font-size:100%;
  font-weight:normal;
}
q:before,q:after {
  content:'';
}
abbr,acronym {
  border:0;
}

/*全体の調整*/
body {
  font:13px Georgia, Century, serif;
  *font-size:small;
  *font:x-small;
  -webkit-text-size-adjust: none;
  background:#eee;
}
a{
  ouline: 0;
}
/*セクションの設定*/
div.section {
  width: 100%;
  max-width: 1900px;
  height: 800px;
  position: relative;
  margin: 0 auto;
}
/*レイヤーの設定*/
div.layer {
  width: 100%;
  height: 100%;
  position: absolute;
  left: 0;
  top: 0;
}

/*背景画像の設定*/
/*0*/
#section0 {
  background: url(../images/section0_bg.jpg) no-repeat 0px 0px;
}
#section0 .layer1 {
  background: url(../images/sec0_layer1_bg.png) repeat-y 650px 0px;
}
#section0 .layer2 {
  background: url(../images/sec0_layer2_bg.png) repeat-y 750px 0px;
}

/*1*/
#section1 {
  background: url(../images/section1_bg.jpg) no-repeat 0px 0px;
}
#section1 .layer1 {
  background: url(../images/sec1_layer1_bg.png) no-repeat 20px 120px;
}
#section1 .layer2 {
  background: url(../images/sec1_layer2_bg.png) no-repeat 300px 250px;
}

/*2*/
#section2 {
  background: url(../images/section2_bg.jpg) no-repeat 0px 0px;
}
#section2 .layer1 {
  background: url(../images/sec2_layer1_bg.png) repeat-y 700px 30px;
}
#section2 .layer2 {
  background: url(../images/sec2_layer2_bg.png) repeat-y 650px 120px;
}

/*3*/
#section3 {
  background: url(../images/section3_bg.jpg) no-repeat 0px 0px;
}
#section3 .layer1 {
  background: url(../images/sec3_layer1_bg.png) no-repeat 290px 140px;
}
#section3 .layer2 {
  background: url(../images/sec3_layer2_bg.png) no-repeat 100px 200px;
}

/*各セクション内のレイアウト等*/
/*0*/
#section0 h1 {
  position: absolute;
  left: 8%;
  top: 80px;
}
ul#topNav {
  position: absolute;
  left: 8%;
  bottom: 130px;
}
ul#topNav li {
  display: inline;
  margin-right: 40px;
}

/*1*/
#section1 h2 {
  position: absolute;
  left: 58%;
  top: 200px;
}
#section1 p {
  position: absolute;
  left: 58%;
  top: 300px;
  color: #fff;
  font-size: 108%;
  width: 450px;
  line-height: 2;
}

/*2*/
#section2 h2 {
  position: absolute;
  left: 8%;
  top: 200px;
}
#section2 p {
  position: absolute;
  left: 8%;
  top: 300px;
  color: #fff;
  font-size: 108%;
  width: 450px;
  line-height: 2;
}
/*3*/
#section3 h2 {
  position: absolute;
  left: 58%;
  top: 200px;
}
#section3 p {
  position: absolute;
  left: 58%;
  top: 300px;
  color: #fff;
  font-size: 108%;
  width: 450px;
  line-height: 2;
}

/*ナビゲーション*/
ul#nav {
  position: fixed;
  left: 20px;
  top: 20px;
  background: #000;
    border-radius: 5px;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
  padding: 8px 15px 0px 15px;
}
ul#nav li {
  display: inline;
  margin: 0 10px;
}
ul#nav li a {
  opacity: 0.6;
}
ul#nav li a:hover {
  opacity: 1;
}
削除したレイヤーを、JavaScriptで追加する
//レイヤー用のdiv要素を2枚追加
 $(".section")
  .prepend('<div class="layer layer2"></div>')
  .prepend('<div class="layer layer1"></div>');


《parallax.js》

/*======================================================
初期設定
======================================================*/
//セクションの高さの最小値
var minHeight = 500;
//自動スクロールの速度(1000で1秒、多いほどゆっくり)
var scrollSpeed = 1000;

//各要素の背景初期位置を格納しておくオブジェクト
var originBgPosition = new Object();

/*======================================================
ドキュメント読み込み後の処理
======================================================*/
$(document).ready(function(){

 //選択枠を隠す
 $('a').focus(function(e){this.blur()});

 //レイヤー用のdiv要素を2枚追加
 $(".section")
  .prepend('<div class="layer layer2"></div>')
  .prepend('<div class="layer layer1"></div>');

 //背景画像の初期位置を取得
 $(".section").each(function(i){
  var _thisID = $(this).attr("id");
  originBgPosition[_thisID] = new Object();
  originBgPosition[_thisID]["section"] = getbackgroundPosition($(this));
  originBgPosition[_thisID]["layer1"] = getbackgroundPosition($(this).find(".layer1"));
  originBgPosition[_thisID]["layer2"] = getbackgroundPosition($(this).find(".layer2"));
 });

 //背景の配置を「fixed」に変更
 $(".section, .layer1, .layer2").css("background-attachment","fixed");

 //画面をアップデート
 $(window).trigger("resize");

});

/*======================================================
背景位置を取得してハッシュで返す
======================================================*/
function getbackgroundPosition(obj) {
 var pos = obj.css("background-position");
 var posArray = new Array();
 //IE対策
 if(pos){
  //IE以外
  posArray = pos.split(" ");
 }else{
  //IE
  posArray = [obj.css("backgroundPositionX"), obj.css("backgroundPositionY")];
 } 
 return {x:parseInt(posArray[0]), y:parseInt(posArray[1])};
}

/*======================================================
パララックスを実現するための関数
======================================================*/
$(window).bind("scroll resize", parallaxScroll);
function parallaxScroll (event) {

 //イベントタイプがresizeのときの処理
 if(event.type == "resize"){
  //セクションの高さを画面の高さに合わせる
  if($(window).height() > minHeight){
   $(".section").height($(window).height() + 50);
  }
 }

 //ナビゲーションの表示・非表示切り替え
 if($(window).scrollTop() < $("ul#topNav").offset().top + $("ul#topNav").height()){
  $("#nav").animate({opacity:"hide"}, 200);
 } else {
  $("#nav").animate({opacity:"show"}, 200);
 }

 //画面内に入っている要素を返す
 var activeContents = $(".section").filter(function (i) { 
  if($(window).scrollTop() + $(window).height() > $(this).offset().top && $(window).scrollTop() < $(this).offset().top + $(this).height()){
   return true;
  }else{
   return false;
  }
 });

 //背景画像位置のアップデート
 activeContents.each(function(i){

  //現在の要素内でのスクロール位置を取得
  var scrollTop = $(this).offset().top - $(window).scrollTop();
  var scrollLeft = $(this).offset().left- $(window).scrollLeft();

  //新しい背景座標を計算
  var _thisID = $(this).attr("id");
  var newBgPosition = {section:{x:0, y:0}, layer1:{x:0, y:0}, layer2:{x:0, y:0}}
  //X座標
  newBgPosition["section"]["x"] = originBgPosition[_thisID]["section"]["x"] + scrollLeft * 0.2;
  newBgPosition["layer1"]["x"] = originBgPosition[_thisID]["layer1"]["x"] + scrollLeft * 0.3;
  newBgPosition["layer2"]["x"] = originBgPosition[_thisID]["layer2"]["x"] + scrollLeft * 0.6;
  //Y座標
  newBgPosition["section"]["y"] = originBgPosition[_thisID]["section"]["y"] + scrollTop * 0.2;
  newBgPosition["layer1"]["y"] = originBgPosition[_thisID]["layer1"]["y"] + scrollTop * 0.3;
  newBgPosition["layer2"]["y"] = originBgPosition[_thisID]["layer2"]["y"] + scrollTop * 0.6;

  //各背景を移動させる
  $(this).css("background-position", newBgPosition["section"]["x"] + "px " + newBgPosition["section"]["y"] + "px");
  $(this).find(".layer1").css("background-position", newBgPosition["layer1"]["x"] + "px " + newBgPosition["layer1"]["y"] + "px");
  $(this).find(".layer2").css("background-position", newBgPosition["layer2"]["x"] + "px " + newBgPosition["layer2"]["y"] + "px");
 });
}

/*======================================================
ナビゲーションによるスクロール
======================================================*/
function pageScroll(n){
 $.scrollTo('#section' + n, scrollSpeed, {easing:"easeInOutQuart"});
}