2016-04-25 27 views
14

幫我理清了添加簡單視差行爲的正確邏輯。視差 - 偏移元素,與滾動相關

我想在頁面上有多個元素,它們的頂部偏移一定的距離(例如300px)。然後,當您向下滾動頁面時,一旦顯示元素的頂部,它將緩慢向上移動(連接到滾動),直到元素的頂部到達視口的中間,此時它的頂部偏移量爲0並保持原位。

我嘗試使用第三方腳本(滾動魔術,星等),但是當我無法得到它,現在我想自定義代碼:

https://jsfiddle.net/louiswalch/5bxz8fku/1/

var $Window = $(window); 
var offset_amount = 400; 
var window_height = $Window.height(); 
var window_half = (window_height/2); 
var sections  = $('SECTION.reveal'); 

sections.each(function() { 

    var element = $(this); 

    // Make sure we always start with the right offset 
    element.css({top: offset_amount}); 

    $Window.bind('scroll', function() { 

    var viewport_top = $Window.scrollTop(); 
    var viewport_middle = viewport_top + (window_height/2) 
    var viewport_bottom = viewport_top + window_height; 
    var element_top  = element.offset().top; 

    if (element_top > viewport_top && element_top <= viewport_bottom) { 

     var distance_to_middle = (element_top - viewport_middle); 
     var amount_to_middle = (distance_to_middle/window_half); 

     console.log(amount_to_middle); 

     if (amount_to_middle >= 0) { 
     element.css({top: (offset_amount * amount_to_middle)+ 'px'}); 
     } else { 
     // ? Lock to end position ? 
     } 

    } 

    }); 

}); 

回答

6

jsBin demo 1. (margin space effect on both enter and exit)
jsBin demo 2. (preserve 0 margin once touched)

而是定位到section元素,(創建和)定位它們的第一個子元素,
否則,您將創建一個併發混亂,嘗試獲取頂部位置,但同時修改它。

另外,你的不能依靠固定的300px的保證金(即:如果窗口高度小於500px,你已經缺少100px)。當屏幕高度非常小時,該空間可能會有所不同,因此您還需要找到idealMarg

var $win = $(window), 
    $rev = $('.reveal'), 
    winH2 = 0, 
    winSt = 0; 

function reveal() { 

    winSt = $win.scrollTop(); 
    winH2 = $win.height()/2; 

    $rev.each(function(i, el){ 
    var y = el.getBoundingClientRect().top, 
     toMiddleMax = Math.max(0, y-winH2), 
     idealMarg = Math.min(300, toMiddleMax), 
     margMin  = Math.min(idealMarg, idealMarg * (toMiddleMax/winH2)); 
    $(">div", this).css({transform: "translateY("+ margMin +"px)"}); 
    }); 

} 

$win.on({"load resize scroll" : reveal}); 
*{box-sizing:border-box; -webkit-box-sizing:border-box;} 
html, body{height:100%; margin:0;} 

section > div{ 
    padding: 40px; 
    min-height: 100vh; 
} 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 

<section> 
    <div style="background-color:red">1</div> 
</section> 
<section class="reveal"> 
    <div style="background-color: yellow">2</div> 
</section> 
<section class="reveal"> 
    <div style="background-color: orange">3</div> 
</section> 
<section class="reveal"> 
    <div style="background-color: pink">4</div> 
</section> 

我在HTML中使用只是一個<div>邏輯上,這必須是一個section父母的唯一的第一個孩子。
歡迎您調整上述代碼,使其更具性能。

+1

感謝您的幫助,關於併發的想法!你的演示看起來不錯,但它應該停止在最終位置,一旦進入框架50%並停止移動。所以一旦它滾動到位,當你向下滾動時,它們仍然粘在一起。基本上只顯示,不做任何事。 –

+0

對不起,以爲它是「直到元素的頂部到達視口的中間,此時它的頂部偏移量爲0,並且它保持原位」。無論如何,請不要急於求助,花點時間欣賞幫助。它非常接近。 –

+0

@LouisW添加了一個演示,一旦兩個元素觸摸就保留0 Y位置! –

2

嘿所以,這裏是我的一舉一動。

http://jsbin.com/wibiferili/edit?html,js,output

它的JIST如下。

JS

var $Window = $(window), 
    parallaxFactor = 2; 

$('.parallaxblock').each(function(a,b){ 
    var element = $(b); 
    element.css("top",element.data("pOffset") + "px"); 

    $Window.bind('scroll', function() { 
     var pos = 
      // Base Offset 
      element.data("pOffset") 
      // parallaxFactor 
      - ($Window.scrollTop()/parallaxFactor); 

     pos = pos < 0 ? 0 : pos; 

     element.animate({"top": pos + "px"},10); 

     return; 
    }); 

}); 

通過檢查offest我樣式

body{ 
    height: 4000px; 
} 

.parallaxblock{ 
    position:fixed; 
    background:#999; 
    opacity:.5; 
} 

示例用法

<div class="parallaxblock" data-p-offset=100>Im A Block</div> 
<div class="parallaxblock" data-p-offset=200>Im Also Block</div> 
<div class="parallaxblock" data-p-offset=1500>Im Another Block</div> 

所以ts永遠不會低於0,我們可以將它鎖定在屏幕的頂部。

我得到了div上數據標籤的偏移量。

如果您想更改不同位置的滾動速率,可以在屏幕高度的某個百分比處更改視差係數。

希望這會有所幫助。

+0

對不起,看起來你的鏈接不工作了。 「這個bin是匿名創建的,它的免費預覽時間已經過期」 –

+0

O真的很不好,所有的代碼都在上面。 – Spaceman