2016-09-16 75 views
1

我試圖創建一個視差效果,即絕對定位的子元素應的速度移動速度慢於它的父上滾動子抵消母公司。視差效果 - 計算上滾動

孩子永遠是父母的130%的高度,但家長可以是任何高度:

HTML:

<div class="parallax-window lg"> 
 
    <div class="parallax-image image-1"></div> 
 
    <div class="parallax-content">Hello World</div> 
 
</div> 
 

 
<div class="parallax-window"> 
 
    <div class="parallax-image image-2"></div> 
 
    <div class="parallax-content">Hello World</div> 
 
</div>

CSS:

.parallax-window { 
 
    min-height: 300px; 
 
    position: relative; 
 
    overflow: hidden; 
 
} 
 

 
.parallax-window.lg { 
 
    min-height: 600px; 
 
} 
 

 
.parallax-image { 
 
    position: absolute; 
 
    top: 0; 
 
    left: 0; 
 
    width: 100%; 
 
    height: 130%; 
 
    background-size: cover; 
 
    background-repeat: no-repeat; 
 
    background-position: 50% 50%; 
 
    transform: translate3d(0, 0, 0); 
 
    z-index: -1; 
 
} 
 

 
.image-1 { 
 
    background-image: url(https://i.ytimg.com/vi/TbC-vUPMR7k/maxresdefault.jpg); 
 
} 
 

 
.image-2 { 
 
    background-image: url(https://i.ytimg.com/vi/xi5-YrAEChc/maxresdefault.jpg); 
 
}

我有一個公式來移動圖像,但我的數學是明確的路要走:

var win = $(window), 
 
     win_h = win.height(), 
 
     parallaxers = $('.parallax-window'); 
 

 
    function scroll_events() { 
 
     var win_top = win.scrollTop(), 
 
      win_btm = win_top + win_h; 
 
    
 
     parallaxers.each(function() { 
 
      var cont = $(this), 
 
       cont_top = cont.offset().top, 
 
       cont_h = cont.height(), 
 
       cont_btm = cont_top + cont_h, 
 
       para = cont.find('.parallax-image'), 
 
       para_h = Math.round(cont_h * 1.3); 
 
      if (cont_btm > win_top && cont_top <= win_btm) { 
 
       var diff = (win_h - cont_h)/(win_h - para_h), 
 
        value = -Math.round((win_top * diff)); 
 
       // para.css('transform', 'translate3d(0,' + value*-1 + 'px, 0)'); 
 
       para.css('top', value + 'px'); 
 
      } 
 
     }); 
 
    }

的圖像移動,但不是在正確率。

圖像應是與母體的頂部線的時候,元件首先進入視區。然後在滾動後,當圖像到達視口頂部時,圖像的底部應該與父視圖的底部一致。

任何幫助將大規模感激!

FIDDLE(https://jsfiddle.net/8dwLwgy7/1/

回答

0

我想通了這一點。

對於任何在將來對這個絆腳石 - 的伎倆是,以取代與窗口滾動金額減去元素的偏移最高,減去元素的高度,其餘的窗口滾動值。

// Wrong: 
// value = -Math.round((win_top * diff)); 

// Right: 
var diff = elem_h - cont_h, 
    max = Math.max(cont_h, win_h), 
    speed = diff/max, 
    cont_scrolled = win_top - cont_top - cont_h, 
    value = Math.round(cont_scrolled * speed); 

para.css('top', value + 'px'); 

完整工作代碼:

(function() { 
 
    var lastTime = 0; 
 
    var vendors = ['ms', 'moz', 'webkit', 'o']; 
 
    for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { 
 
    window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; 
 
    window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame']; 
 
    } 
 
    if (!window.requestAnimationFrame) 
 
    window.requestAnimationFrame = function(callback, element) { 
 
     var currTime = new Date().getTime(); 
 
     var timeToCall = Math.max(0, 16 - (currTime - lastTime)); 
 
     var id = window.setTimeout(function() { 
 
      callback(currTime + timeToCall); 
 
     }, 
 
     timeToCall); 
 
     lastTime = currTime + timeToCall; 
 
     return id; 
 
    }; 
 
    if (!window.cancelAnimationFrame) 
 
    window.cancelAnimationFrame = function(id) { 
 
     clearTimeout(id); 
 
    }; 
 
}()); 
 

 

 
(function($) { 
 

 
    var win = $(window), 
 
    win_h = win.height(); 
 
\t \t parallaxers = $('.parallax-window'), 
 
\t \t parallax_objs = [], 
 
    scroll_busy = false; 
 

 
\t function init_parallax() { 
 
\t \t win_h = win.height(); 
 
\t \t parallax_objs = []; 
 
\t \t parallaxers.each(function() { 
 
\t \t \t var cont = $(this), 
 
\t \t \t \t elem = cont.find('.parallax-image'), 
 
\t \t \t \t cont_top = cont.offset().top, 
 
\t \t \t \t cont_h = cont.height(), 
 
\t \t \t \t elem_h = Math.round(cont_h * 1.3), 
 
\t \t \t \t diff = elem_h - cont_h, 
 
\t \t \t \t max = Math.max(cont_h, win_h), 
 
\t \t \t \t speed = diff/max, 
 
\t \t \t \t parallaxer = { 
 
\t \t \t \t \t cont_top: cont_top, 
 
\t \t \t \t \t cont_h: cont_h, 
 
\t \t \t \t \t elem: elem, 
 
\t \t \t \t \t speed: speed 
 
\t \t \t \t }; 
 
\t \t \t parallax_objs.push(parallaxer); 
 
\t \t }); 
 
\t } 
 
    
 
    function on_scroll() { 
 
    if (!scroll_busy) { 
 
     scroll_busy = true; 
 
     window.requestAnimationFrame(init_scroll); 
 
    } 
 
    } 
 

 
    function init_scroll() { 
 
    scroll_events() 
 
    scroll_busy = false; 
 
    } 
 

 
    function scroll_events() { 
 
    var win_top = win.scrollTop(), 
 
     win_btm = win_top + win_h; 
 

 
\t \t $.each(parallax_objs, function(i, para) { 
 
\t \t \t cont_btm = para.cont_top + para.cont_h; 
 
\t \t \t if(cont_btm > win_top && para.cont_top <= win_btm) { 
 
\t \t \t \t var cont_scrolled = win_top - para.cont_top - para.cont_h, 
 
\t \t \t \t \t value = Math.round(cont_scrolled * para.speed); 
 
\t \t \t \t para.elem.css('top', value + 'px'); 
 
\t \t \t } 
 
\t \t }); 
 
    } 
 

 
    $(document).ready(function() { 
 
    \t init_parallax(); 
 
    win.resize(init_parallax); 
 
    scroll_events(); 
 
    win.scroll(on_scroll); 
 
    }); 
 

 
})(jQuery);
.parallax-window { 
 
    min-height: 300px; 
 
    position: relative; 
 
    overflow: hidden; 
 
} 
 

 
.parallax-window.lg { 
 
    min-height: 600px; 
 
} 
 

 
.parallax-image { 
 
    position: absolute; 
 
    top: 0; 
 
    left: 0; 
 
    width: 100%; 
 
    height: 130%; 
 
    background-size: cover; 
 
    background-repeat: no-repeat; 
 
    background-position: 50% 50%; 
 
    transform: translate3d(0, 0, 0); 
 
    z-index: -1; 
 
} 
 

 
.image-1 { 
 
    background-image: url(https://i.ytimg.com/vi/TbC-vUPMR7k/maxresdefault.jpg); 
 
} 
 

 
.image-2 { 
 
    background-image: url(https://i.ytimg.com/vi/xi5-YrAEChc/maxresdefault.jpg); 
 
} 
 

 
.parallax-content { 
 
    position: absolute; 
 
    top: 50%; 
 
    left: 0; 
 
    width: 100%; 
 
    text-align: center; 
 
    font-family: arial, sans-serif; 
 
    font-size: 60px; 
 
    color: #fff; 
 
    transform: translateY(-50%); 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
 
<div class="parallax-window lg"> 
 
    <div class="parallax-image image-1"></div> 
 
    <div class="parallax-content">Hello World</div> 
 
</div> 
 
<div class="parallax-window"> 
 
    <div class="parallax-image image-2"></div> 
 
    <div class="parallax-content">Hello World</div> 
 
</div> 
 
<div class="parallax-window lg"> 
 
    <div class="parallax-image image-1"></div> 
 
    <div class="parallax-content">Hello World</div> 
 
</div> 
 
<div class="parallax-window"> 
 
    <div class="parallax-image image-2"></div> 
 
    <div class="parallax-content">Hello World</div> 
 
</div> 
 
<div class="parallax-window lg"> 
 
    <div class="parallax-image image-1"></div> 
 
    <div class="parallax-content">Hello World</div> 
 
</div>

然後通過將容器的高度和與最大任一窗口和容器中的元件的高度之間的差來計算速度

更新小提琴:https://jsfiddle.net/8dwLwgy7/2/