See the Pen scroll-event¶llax by nanba (@nanba) on CodePen.
強引に縮小表示してるので動きが少し悪いです…
本来ならIntersection Observer APIとか使ってスマートに解説したいところですが…今回はあくまでも視差効果の考え方・基本実装がメインな記事となりますので、ゴッリゴリのベッタベタなjQuery書いてます。
スクロールイベントで制御しているのは以下三点
上記を実現させるために、下記をそれぞれ取得して算数してパララっています
$(window).on('load scroll', function() {
let windowH = $(window).height();
let scrollT = $(window).scrollTop();
$('該当要素').each(function(){
const pos_trigger = $(this).offset().top;
if (scrollT > pos_trigger - windowH + 50){
$(this).addClass('js-switch_on');
}else{
$(this).removeClass('js-switch_on');
}
})
})
該当要素{
margin-top:6em;
opacity:0;
transition:all .5s ease;
&.js-switch_on{
margin-top:0;
opacity:1;
}
}
class付与・削除のみ js にて制御して、アニメーション部分は css で実装しています。
この場合におけるtransitionは、リアルタイムでの逆再生的な動きも付けることが出来ますので、とても便利ですね!
animationだと、ON・OFFの2パターンを設定する必要があり、尚且つアニメーションしている最中に違うアクションが起こっても、逆再生することは出来ないので、インタラクティブサイト構築の初期設計段階でナニを使ってドウ動かすのかを決めておく必要がありますね。
例)全てjs制御/トリガーのみjs制御/全てcss制御など...
$(window).on('load scroll', function() {
let windowH = $(window).height();
let scrollT = $(window).scrollTop();
const pos_box = $('パララ親要素').offset().top;
const h_box = $('パララ親要素').height();
if(pos_box < scrollT + windowH && scrollT < pos_box + h_box){
// $('サンプル').css({top:(scrollT - pos_box) + 'px'}).fadeIn('1000');
$('パララ要素A').css({top:(scrollT - pos_box) * 2 + windowH + 'px'}).fadeIn('1000');
$('パララ要素B').css({top:(pos_box - scrollT) * 1.5 + (windowH / 3) + 'px'}).fadeIn('1000');
}else{
$('サンプル,パララ要素A,パララ要素B').fadeOut('1500');
}
})
コメントアウトしてある7行目を例として解説します。
サンプル要素に対して、cssのtopを動的に制御してます。
この場合top:(scrollT - pos_box) + 'px'なので、パララ親要素が画面最下部に来た時点で、サンプル要素にtop:0pxがDOM的に付与され、さらにスクロールし続けるとスクロール量分だけサンプル要素のtop値がプラスされていきます。
ようするに見た目的にはブラウザ画面最上部に表示され続けます。
パララ親要素が画面上部から100px上にスクロールすると、サンプル要素にはtop:100pxが動的に付与され、結果的にposition:fixed: top:0;と同じくなりますね!
文章で説明すると物凄く分かりにくいですね…これ。
実際に組んでみたら、0.1秒で仕組みが理解できます!
これを基準に考え、あとは各パララ要素を【上に動かす】【下に動かす】【早く動かす】【ゆっくり動かす】をイイ感じに調整してあげたら、視差効果の完成です。
もちろん制御するのをleftにすれば横に動かすことも可能ですし、top・leftともに制御すれば斜めに動かすことも曲線的に動かすことも可能ですね。
三角関数などを使わなくても、これまで解説した内容をアレンジして算数すれば、イロイロな視差効果が創れるはずです^^
$(window).on('load scroll', function() {
let windowH = $(window).height();
let scrollT = $(window).scrollTop();
$('.p-collage-element li').each(function(i){
const pos_collage = $('.p-collage').offset().top;
if(pos_collage < scrollT - (i * windowH * 0.15) + (windowH * 0.2)){
$('.p-collage-element li').eq(24 - i).fadeIn('1000');
}else{
$('.p-collage-element li').eq(24 - i).fadeOut('1000');
}
})
})
構造的には.p-collage-elementというulタグに25枚の画像を配置してposition:fixedにて絶対位置表示させており、その親要素はheight:475vhという高さを持たせてあります。
※高さ(475vh)はコラージュCG画像枚数・表示する際の速度感に応じて調整
あとはスクロール量に応じて、一枚づつ画像を表示・非表示制御しているだけです@L6~10
※このCG画像作成・スライス作業のみで1日は費やしました…
ぶっちゃけコーディング自体は2時間程度だったので、本末転倒な時間の使い方とも言える
今回は『視差効果』に関する記事でしたが、ちょっとしたアイディアで、様々なインパクトのある表現が出来ると思っています。
その閃いたモノを、より効果的に具現化するために必要なのはスキルよりも、むしろ設計だと私は日頃から考えております。
この閃きを、より効率的に、ストレスなく実装するには、手を動かす前に、ある程度の粒度でキッチリと設計しておくべきだと思います、ココに時間をかけることは結果的に最終的な工数を下げると断言できます。
実装がイメージできていたら、実作業的な手戻りを防ぎつつ、具体的な検証・調べものも効率的に出来るからですね٩(๑❛ᴗ❛๑)۶