2016-09-16 11 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/

関連する問題