私は視差の実験を試み、この魔法の核心部分を理解するためにゼロから始めました。私がインスピレーションとして好んで使う例を挙げると、このリンクから「写真」セクションにあります。
最新のコードは関連情報とともにページの下部にあります。質問の全体像を把握するには、残りの詳細を参照してください。
私が既に知っているコア部分は、scrollTop()
の$window
とoffsetTop
要素の です。これらは、DOM 要素に視差効果を適用するのに重要であり、スクロール速度に対する効果の感度を決定する も重要です。最終結果は、または座標をピクセルまたはパーセンテージでfactor
計算する何らかの数式になるはずです。translateY
translate3d
インターネットで読んだところ、CSSプロパティはtranslate
、例えば よりも高速でtop
、position: absolute
translate と組み合わせて使用することも好みです。トゥイーンマックスGSAPそうすれば、視差の動きが非常にスムーズになります。ただし、CSS プロパティだけでtranslate
十分な場合は、それでも問題ありません。TweenMax を使用している例をいくつか見たので、今のところはそれを使用しています。
JS
基本的なものをコード化しました:
var win = $(window);
var el = $('#daily .entry').find('figure');
win.scroll(function() {
var scrollTop = win.scrollTop();
var parallaxFactor = 5;
el.each(function() {
var image = $(this).find('img');
var offsetTop = $(this).offset().top;
// This is the part where I am talking about.
// Here should be the magic happen...
});
});
上記のコードを記述しましたが、もちろん何も実行されません。上記のコードのCodePenはこちらをご覧くださいコンソール ログscrollTop
とのみが出力されますoffsetTop
。前述のように、視差効果を適用するにscrollTop
は、や などoffsetTop
のコア部分しかわかりません。次に、視差効果がトリガーされて発生する領域を作成する必要があります。そのため、パフォーマンスを良好に保つために、計算はビューポート内の要素に対してのみ実行されます。その後、いくつかの計算を行う必要がありますが、これを何をどのように達成するかは正確にはわかりません。最終的な数値がわかったら、たとえばTweenMax
Greensock から次のように使用できます。
トゥイーンマックス
TweenMax.to(image, 0.1, {
yPercent: offsetPercent + '%',
ease: Linear.easeNone
});
視差の式
式を理解するために調べてみると、次のようなものを見つけました (インターネットで見つけたもの)。
var viewportOffset = scrollTop - offsetTop + win.height();
var offsetPercent = ((viewportOffset / win.height() * 100) - 100) / parallaxFactor;
if (viewportOffset >= 0 && viewportOffset <= win.height() * 2) {
TweenMax.to(image, 0.1, {
yPercent: offsetPercent + '%',
ease: Linear.easeNone
});
}
しかし、正直に言うと、これが正確に何をするのか、なぜこのようにすべきか、またはできるのかはわかりません。これを知りたいので、視差が発生するプロセス全体を理解できます。scrollTop()
、、の機能offsetTop
は$(window).height()
明らかですが、式の背後にあるトリックが何であるかは、私が理解していない部分です。
アップデート
アップデート1
@Scottは、インスピレーションサイトでは、スクロールマジックですが、プラグインを使用せずに自分で視差効果を作成する方法について非常に興味があります。それがどのように機能し、どのように実現するか。式に重点を置いて、なぜこのようにまたはこのように行う必要があるのか、そして正確には何が計算されるのかを知りたいです。なぜなら、私はそれを理解していないので、これを本当に知りたいからです。そうすれば、将来視差効果を適用するときにこの知識を使用できます。
アップデート2
次のコード スニペットが具体的に何をするのか理解しようとしました。次のコード スニペットについて説明しています。
var viewportOffset = scrollTop - offsetTop + win.height();
デバッグ セッションをいくつか行った後、手がかりがつかめたと思います。scrollTop
ページをスクロールダウンしてビューから隠れているピクセル数です。offsetTop
は DOM 内の要素の開始位置で、は$(window).height
ビューポートの高さ (ブラウザーに表示される部分) です。
この式は次のような動作をすると思います:
ゼロ ポイントを要素の開始点に設定します。たとえば、scrollTop
が 0 で、要素が240px
上から から始まる場合、数式は 0 マイナス 240 です-240
。つまり、現在のスクロール位置はゼロ ポイントより下です。240 ピクセル下にスクロールした後、当然 240 マイナス 240 は0
(ゼロ) なので、数式は 0 を出力します。正しいでしょうか?
しかし、私がまだ理解していない部分は、なぜ です+ win.height
。上記の式に戻って (Update 2)、 scrollTop が 0 の場合、 は$(window).height
240 ピクセルからビューポートの下部までのスペースです。下にスクロールすると、スクロール時にピクセルの量が増えますが、私には意味がわかりません。誰かがこれの目的を説明してくれると嬉しいです。とても興味があります。視差を計算する式の 2 番目の部分がoffsetPercent
まだ理解できません。一般的には、スクロール時の視差の強さの計算です。
アップデート3/4
@Edisoniのアドバイスに従って、ここ数日は歩いていましたトラヴィス・ニールソンのビデオそして、私はパララックスに関する基本的な機能についてより深く理解するようになりました。パララックスについて深く知りたい人には必読です。私はパララックスに関する新しい知識を使って、上記のスクリプトを作成しました。
var root = this;
var win = $(window);
var offset = 0;
var elements = $('#daily .entry figure');
if (win.width() >= 768) {
win.scroll(function() {
// Get current scroll position
var scrollPos = win.scrollTop();
console.log(scrollPos);
elements.each(function(i) {
var elem = $(this);
var triggerElement = elem.offset().top;
var elemHeight = elem.height();
var animElem = elem.find('img');
if (scrollPos > triggerElement - (elemHeight / 2) && scrollPos < triggerElement + elemHeight + (elemHeight / 2)) {
// Do the magic
TweenMax.to(animElem, 0.1, {
yPercent: -(scrollPos - elemHeight / 2) / 100,
ease: Linear.easeNone
});
} else {
return false;
}
});
});
}
しかし、スクリプトは特定の要素に対してのみ機能します。問題は、最初の 2 つの要素に対してのみ機能することです。特に&&
if ステートメントの AND 記号の後に「エラー」があるのではないかと疑っていますが、エラーを解決できません。http://codepen.io/anon/pen/XKwBAB
トリガーで動作する要素がアニメーション化されると、いくつかのピクセルが下にジャンプしますが、これをどのように修正すればよいかわかりません。トリガーが起動された後、 にジャンプします。したがって、0% から開始されません。CSSに CSS プロパティを追加して、数値のタイプを に設定する1.135%
必要があるかどうかは既に確認しましたが、これは機能しません。translate
%
-webkit-transform: translateY(0%);
-moz-transform: translateY(0%);
-o-transform: translateY(0%);
transform: translateY(0%);
開始位置も設定できるように、 関数をTweenMax
.fromTo()
使用する代わりに 関数を使用する必要がありますか、それともこれに関する私の考えが間違っていて、別の原因があるのでしょうか?.to()
このようなもの:
TweenMax.fromTo(animElem, 0.1, {
yPercent: triggerElement,
z: 1
}, {
yPercent: -(scrollPos - elemHeight / 2) / 100,
ease: Linear.easeNone
});
それ以外にも、インスピレーションの源として使いたいサイトの効果を、scrollMagic プラグインを使わずに再現しようとしていますが、アニメーション化された 2 つの異なるオブジェクトを使用して、これがどのように機能するのかよくわかりません。
最後に、コードのフォーマットを改善できると思う人がいたら、遠慮なく提案を聞かせてください。
私の実際の質問はアップデート 2 と 3/4 に関するものです。
- 「魔法」を実現するための視差 y 座標を計算するにはどうすればよいでしょうか?
- 更新 2 では、ゼロ ポイントが各要素の offsetTop にリセットされるというのは正しいでしょうか?
- 私のコードはなぜ最初の 2 つの要素に対してのみ機能し、アニメーション要素にインライン スタイル
translate
が追加されるといくつかのピクセルが下にジャンプするのでしょうか? すべての情報については、更新 3/4 を参照してください。
ベストアンサー1
パララックスは原理的には非常にシンプルです。パララックス要素のスクロール速度を他のコンテンツよりも遅くするだけです。そうは言っても、パララックスの実装は、スクロール距離を係数で割るだけで簡単にできます。
var parallaxFactor = 3;
window.addEventListener("scroll", function(e){
el.style.top = (document.body.scrollTop / parallaxFactor) + "px";
// This is the magic. This positions the element's y-cord based off of the page scroll
}, false);
これは、視差効果の非常にシンプルなデモンストレーションです。他のより徹底した実装では、値をパーセンテージとして処理したり、TweenMax を使用してアニメーションをスムーズにしたりすることがあります。しかし、これはあなたが探している魔法です。
長く生きると繁栄。
アップデート:
この例は、画面上部の要素にのみ適用されます。より一般的な目的であれば、要素のデフォルトの y 位置を保存し、次のようなものを保存することになりますdefaultYCord + (document.body.scrollTop / parallaxFactor)
。
アップデート2:
パララックスの非常に優れた視覚化は、純粋な CSS パララックス スクロールを作成した Keith Clark によるものです。http://keithclark.co.uk/articles/pure-css-parallax-websites/demo3/左上のデバッグをクリックすると、魔法の素晴らしい 3D ビューが表示されます。