ぬるぬると動くパララックスが必要になったのでjQueryのスクリプトを作った
唐突に、ぬるぬると動くパララックスを作らなければならなくなった。
CSSでの擬似パララックスではない、本当の意味でのパララックス。
・・・パララックス系のスクリプトは色々面倒くさい。正直なところで言えば作りたくねぇ。
そんなわけなので、話を持ち込まれたときに声と眉をひそめて嫌な様相をかもしだしてみたが・・・。
まぁ案の定無視されました。あーそうですかそうですか。
まぁ気乗りはしないけど、物は試しで作ってみっか!気乗りしないけど!気乗りしないけど!
・・・大事なことなのでしつこく言いました。
というわけで、一応のところスマホに対応も念頭にいつもどおり作成してみた。
動作としてはこちらのページのような形。
疑似パララックスの代表格であるbackground-attachment: fixed;を利用せずに、スクロールに連動してぬるぬる動かしている。
古いiPhoneで動作を確認しつつ、スマホにも対応させた。
疑似パララックスみたいにスマホだけパララックス効果がかからないということもないと思う。
また、せっかくスクリプトを使うので、CSS3のみでのパララックスにありがちなcontainerからperspectiveを書いていく必要がないように、プレーンなHTMLとCSSの構造で使えるように作った。
以下は今回書いたスクリプトの内容になる。
jquery.paraslimy.js
(function($){ $.fn.paraslimy = function(options){ var option = { background: '.background', perspect: 250, }; var static = { body: 'paraslimy-body', bg: 'paraslimy-bg', }; var config = $.extend(option, options); var inc = $(this), win = $(window), scrolling = false; var paraslimy = (function(){ return{ init: function(){ inc.addClass(static.body) .children(config.background).addClass(static.bg); $('.' + static.body).css({ 'perspective': config.perspect + 'px', 'transform-style': 'preserve-3d' }) .children('.' + static.bg).css({ 'transform': 'translateZ(' + ( config.perspect * -1 ) + 'px)' }); paraslimy.move(); paraslimy.clip(); }, clip: function(){ win.bind('scroll', function(){ paraslimy.move(); }); }, move: function(){ if( ! scrolling ) { scrolling = true; requestAnimationFrame(function(){ scrolling = false; $('.' + static.body).each(function(n){ $(this).css({ 'perspective-origin': '0%' + ' ' + paraslimy.calc($(this)) + '%' }); }); }); } }, calc: function(target){ var rate = ( $(window).scrollTop() - target.offset().top ) / target.outerHeight(true) * 100; return rate; } }; })(); paraslimy.init(); return(this); }; })(jQuery);
続いて、こいつの動作に必要なCSS。
jquery.paraslimy.css
.paraslimy-body{ position: relative; z-index: 1; perspective: 250px; transform: translateZ(0); transform-style: preserve-3d; overflow: hidden; } .paraslimy-bg{ position: absolute; z-index: -1; top: -12.5%; left: -12.5%; right: auto; bottom: auto; width: 225%; height: 225%; min-height: 225vh; transform: translateZ(-250px); background-position: 50% 50%; background-repeat: no-repeat; background-size: cover; }
<link />や<script />のタグ周りは適宜設置のこと、HTMLの構造とスクリプトの設置は以下のような形。
HTML
<script type="text/javascript"> (function($){ $(document).ready(function(){ $('.parallax').paraslimy({ background: '.background-image', // background layer. }); }); })(jQuery); </script> <div id="container"> <div class="parallax"> <p>動作ブロック1</p> <div class="background-image" style="background-image: url(bg1.jpg);"></div> </div> <div class="parallax"> <p>動作ブロック3</p> <div class="background-image" style="background-image: url(bg2.jpg);"></div> </div> <div class="parallax"> <p>動作ブロック2</p> <div class="background-image" style="background-image: url(bg3.jpg);"></div> </div> </div>
背景はbackground-image: url();を前提で取っている。
一昔前だとdiv厨などという言葉が流行ったものの、いまやdivはスタイル用の要素以外の何物でもない。
どうしても気になるなら、object-fit: cover;などを利用したら実体画像も一応設置はできると思う。
一応、以上でぬるぬると動くパララックスの実装はできるはず。
スクリプトを書くにあたって、最初はrequestAnimationFrameにtranslateYを使って動かしていたけど、複数ブロックの設置を考えるとピクセルを算出が非常に面倒だった。
perspectiveとpreserve-3dで比率単位で動かしたほうが制御しやすく確実そうなので採用したら、しっくり来たのが今回のこぼれ話。
デモ用の動作をまとめたファイル群はこちらからダウンロードできます。
ご利用はご自由に。そして、計画的に。
・・・しかし、ここまで書いていてなんか書き口にデジャブを感じた。
この記事の出だしの流れ・・・これ前に同じ流れで書いていたような気がする。
・・・あぁ、この記事や。
まぁJavaScript/jQuery系の記事を書いていると、さしづめ文面はおおよそおなじになってくるのかもしれない。
あるいは、俺の足りない知性と文才ではワンパターンな流れのサルなみの記事しか書けないということなんやろか(´・ω・`)