確實,早期大部分視差滾動效果基本上就是如此,滾動事件是前提,然後要麼是直接改變位置,要麼如果是使用了背景,則改變背景的background-position
,不過實際上這種方法是存在缺陷的。
監聽滾動事件,要想做到盡可能地流暢渲染效果,就不可以讓滾動事件 節流防抖動(throttle debounce immediate
),必須要時刻緊跟滾動事件才行,顯然是有些耗費效能的。
js
是單執行緒的,存在事件輪詢概念,滾動事件並不一定會立刻在滾動的每一幀執行,這取決於主線程是否繁忙,也就是說並不能保證視差滾動與頁面滾動位置同步。
改變乙個非絕對定位元素的位置,是很有可能會觸發頁面的重繪,而改變background-position
同樣是會出現這種情況,比較耗費效能,會對動畫造成明顯的破壞。
實際上,是使用css3
來實現,所以ie9
及以下就嗝屁了,而按照 caniuse 上查到的資料,ie10+
是可以用的,但我在本地模擬ie10+
以及edge
都是不行的,條件有限,沒有用真實版本測過,所以也不太清楚,不過如果不想管ie9
或者ie
,只想用在移動端的話,那就完全沒關係了。
主要是css3
中的perspective
以及translate3d
或者translatez
屬性的應用。
乙個基本的視差滾動實現如下:
真正產生視覺差關鍵的屬性就兩句,分別在// html
是滾動容器,class="container">
class="box2">正常滾動元素div>
class="box1">視覺差元素div>
div>container
box1
是產生視覺差的元素,box2
是正常的對照元素。
// css
.container
.box1
.box2
container
父容器中和視覺差元素中,其中,transform: translatez(-2px) scale(3);
中,translatez(-2px)
讓元素擁有透視效果,而scale(3)
則是為了保證元素不因為透視而產生視覺上的縮放效果才設定的,這裡的數字3
,可根據以下公式計算得來:
(透視距離-移動距離)/ 透視距離
這裡的透視距離就是父容器中perspective: 1px;
中的1
,移動距離指的是在z
軸上的移動距離,也就是translatez(-2px)
中的-2
,由此得到了3
,這樣就能保證視覺差元素不縮放變形。
效果如下:
視覺差元素經過3d
變換後,視覺上的位置發生了偏移,為了保持元素停留在原先的位置上,我們可以為父容器container
設定perspective-origin
屬性,並且同時為box1
設定translate-origin
,以保證縮放原點與透視原點保持同步。
// css
.container
.box1
另外,需要注意的是,perspective
和perspective-origin
作用的元素並不是設定了這兩個屬性的元素本身,而是作用在這個元素的子元素上,也就是說其子元素才能獲得透視效果,並且這兩個屬性只影響3d
轉換元素,例如translatez
或者translate3d
。
如果在透視元素和它的視差子元素之間的層級內有其他元素,那麼3d透視的效果可能會消失。例如以下
html
結構:
解決方法很簡單直接,那就是直接為此不相關元素新增乙個transform-style
屬性。
不過,可能那篇文章的歷史較為久遠了,針對的是以前那些舊版本的瀏覽器,才會有這個問題,最新的瀏覽器大部分都已經做了修復。
唯一一種至今依舊會有這個問題的現代瀏覽器好像只有火狐瀏覽器,我用的54.0.1.6388
版本的firefox
,就完全符合上面說的情況。
另外,還有個小問題:
由於種種原因,移動端我沒有 移動端safari
在上述情況下,沒辦法使用transform-style: preserve-3d;
來繼續保持3d
效果
safari
,所以上面這句話也是我道聽途說,相對於舊版本的移動端safari
來說,可能真的是這樣,但是現在最新的移動端safari
還存不存在這種情況就不清楚了。
如果在使用 移動端safari
測試的時候遇到這種情況,可使用另外乙個除了safari
和firefox
之外其餘瀏覽器(包括chrome
在內)幾乎不支援的屬性值:position:sticky;
一種相容的寫法,包括解決在移動端safari
上出現的問題的**如下(本人沒親自驗證過):
// html
overflow">
class="perspective">
class="sticky parallax"
style="transform: translatez(-1.2px)">z = -1.2div>
class="sticky parallax"
style="transform: translatez(-1.0px)">z = -1.0div>
class="sticky parallax"
style="transform: translatez(-0.8px)">z = -0.8div>
class="sticky parallax"
style="transform: translatez(-0.6px)">z = -0.6div>
class="sticky parallax"
style="transform: translatez(-0.4px)">z = -0.4div>
class="sticky parallax"
style="transform: translatez(-0.2px)">z = -0.2div>
class="sticky parallax"
style="transform: translatez(0px)">z = 0div>
div>
div>
// css
.overflow
.perspective
.preserve
.parallax
.sticky
本以為很簡單的乙個效果,沒想到最後發現處處是坑,各種瀏覽器相容,各種偏僻屬性大顯身手,稍微意志不堅定點說不定就大不了不實現這個效果了。
如果你只是心血來潮想在自己的個人小站上實現這個效果,當然你想用就用,不想用也沒人逼著你,但是如果是在工作中,產品經理非要逼著你實現這個功能怎麼辦,難道要跟pm
撕逼不成?
當然不用,早就有人想到了這個問題,並且把此功能封裝成了乙個開箱即用的jquery
外掛程式 parallax.js
如果專案中沒用jquery
怎麼辦,畢竟現在不用jquery
的專案可是很常見的了,沒關係這裡還有乙個由 googlechrome出品的原生js
庫 parallax.js
stellar製作視差滾動效果
html 單個元素選項中data stellar background ratio比較常用。接受乙個正整數的值,可以改變它被應用到元素的影響速度。例如,data stellar background ratio 0.5 意味著改變速度為自然滾動速度的一半。如果想使這個屬性值低於1,建議在樣式表裡設定...
頁面滾動視差效果的實現
今天在發現乙個視差滾動的例子,想自己實現一下視差效果。開啟例子 首先呢,我們可以選擇監聽scroll和mousewheel事件,說說各自的優缺點。scroll 優點 當頁面滾動到邊界時,不會觸發事件。缺點 需要自己判斷滑鼠滾動方向。mousewheel 優點 可以直接知道滾動方向。缺點 當到達頁面邊...
VUE實現背景視差滾動效果
視差滾動 parallax scrolling 指網頁滾動過程中,多層次的元素進行不同程度的移動,視覺上形成立體運動效果的網頁展示技術。先看我寫的乙個簡單效果 咱先建立乙個vue專案,寫乙個簡單頁面,目錄結構如下 我們先刪除home.vue中的布局 重新寫乙個簡單介面 aaaaaaaaaaaaaaa...