视差滚动–降低容器的高度以匹配变换间隙

时间:2019-06-06 15:18:30

标签: javascript jquery parallax

我在页面上安排了元素的排列-通过CMS控制位置,该元素给每个元素一个宽度,顶部位置,左侧位置,z索引和“速度”。

该速度用于使用JS创建视差效果。它取“速度”并用window.pageYOffset进行计算–如果速度小于0,则将window.pageYOffset除以速度,如果速度大于0,则将其乘以{{1} }的速度。在滚动时,它会调整Y平移以产生这种“视差”效果。

这通常没问题,但是当然,当您更改滚动元素的Y位置时,您会在底部留下一个“间隙”(如果滚动速度与用户滚动速度匹配,元素将位于此处)。

要纠正这一点,我认为我将获得最底部的元素,并使其处于window.pageYOffset位置,并在滚动时减小容器的高度以匹配此元素的底部,以便在向下或向上滚动容器时会收缩/扩展以匹配,从而消除差距。

但是,这似乎不起作用。数学/逻辑错误或者我错过了整个事情。

下面是我的代码,我建立了一个JSFiddle来帮助可视化。

https://jsfiddle.net/6up3vqjn/2/

getBoundingClientRect().bottom

已更新JSFiddle,已删除容器高度计算:https://jsfiddle.net/ejqhvz2c/

3 个答案:

答案 0 :(得分:2)

我不是100%正是您所追求的,但是我已经停止了过度滚动和滚动到空白区域。首先,我更改了事件触发的方式。由于它是视差,因此我将其绑定到wheel事件而不是实际的滚动,当页面上实际包含内容时,滚动实际上并不重要。然后,我使用了一个名为paralaxYOffset的全局变量,我认为最好以+-50的间隔增加平滑度并停止过度滚动,我添加了一个检查以查看.is--last的位置是否<= 0然后不允许视差进一步滚动。

事件更改:

if(e.originalEvent.deltaY  > 0){
        if($(".is--last")[0].getBoundingClientRect().y > 0){
            window.paralaxYOffset += 50;
      }
  }else{
    window.paralaxYOffset -= 50;
  }

  if(window.paralaxYOffset < 0)
    window.paralaxYOffset = 0;

为确保一切正常,并删除溢出滚动条,我将.parallax设置为100vhoverflow: hidden

我相信这可以达到您的要求:)

https://jsfiddle.net/fynmtk9b/4/

答案 1 :(得分:0)

我不确定您要在这里实现什么。但是,如果您想限制容器的高度以匹配组div组件的高度,只需将容器显示设置为内容,然后从组div组件中删除所有的heights属性,便可以使用。

<div class="parallax" style="display:contents;">

这是小提琴:https://jsfiddle.net/bf3e82o4/3/

答案 2 :(得分:0)

尝试此修改! 我已经限制了容器的高度以适合所有组件的高度

function parallaxInit() {
  var $container = $('.parallax'),
    container = $container[0];

  var testArray = [],
    $testLastElement;

  $('.parallax > .group').each(function() {

    var $group = $(this),
      group = $group[0],
      groupBounds = group.getBoundingClientRect(),
      $lastElement,
      lastElementBoundsBottom = 0;

    $group.find('> div').each(function() {

      var $div = $(this),
        div = $div[0],
        initTop = $div.attr('data-top');

      if (initTop == 0) {
        $div.css('top', '0');
      } else {
        $div.css('top', $(window).width() / 12 * initTop - 26 + 'px');
      };

      group.removeAttribute('style');
      //$group.height(group.scrollHeight).attr('data-height', group.scrollHeight);

      var divBounds = div.getBoundingClientRect();
      testArray.push(divBounds.bottom);

    });

  });

  $('.parallax > .group > div').each(function() {

    var divBottomBounds = $(this)[0].getBoundingClientRect().bottom;

    if (divBottomBounds == Math.max.apply(Math, testArray)) {
      $testLastElement = $(this);
      $(this).addClass('is--last');
    }

    var letters = "0123456789ABCDEF";
    var color = '#';
    for (var i = 0; i < 6; i++) color += letters[(Math.floor(Math.random() * 16))];
    $(this).css('background-color', color);

  });
}
parallaxInit();
$(window).on('resize', parallaxInit);

function parallax() {
	var $container = $('.parallax');

	var test = 0;
	var testArray = [],
		$testLastElement;

	$('.parallax > .group').each(function() {

		var $group = $(this),
			group = $group[0],
			groupHeight = $group.attr('data-height'),
			groupBounds = group.getBoundingClientRect();

		$group.find('> div').each(function() {

			var $this = $(this),
				speed = $this.attr('data-speed');

			if (speed < 0) {
				speed = Math.abs(speed);
				var yPos = window.pageYOffset / speed;
			} else {
				var yPos = window.pageYOffset * speed;
			}
			yPos = -yPos;

			$this[0].style.transform = "translate3d(0, " + yPos + "px, 0)";

			var divBounds = $this[0].getBoundingClientRect(),
				divRelativeBounds = {};
			testArray.push(divBounds.bottom);
		});
	});
	$('.parallax > .group > div').each(function() {

		var divBottomBounds = $(this)[0].getBoundingClientRect().bottom;
		$(this).removeClass('is--last');

		if (divBottomBounds == Math.max.apply(Math, testArray)) {
			$testLastElement = $(this);
			$(this).addClass('is--last');
	  }
	});
}
$(window).bind('scroll', parallax);
.parallax {
	position: relative;
  overflow: hidden;
	z-index: 1;
	.group {
		position: relative;
		> div {
			position: absolute;
      picture {
        display: block;
      }
		}
	}
}
<div class="parallax" style="display:contents;">
  <div class="group" data-height="">
    <div style="width:50%;left:0%;z-index:1" data-top="1" data-speed="2">
      <picture data-ratio data-format="portrait" style="padding-bottom:128.97%;"></picture>
    </div>
    <div style="width:83.333333333333%;left:8.3333333333333%;z-index:2" data-top="6" data-speed="1">
      <picture data-ratio data-format="landscape" style="padding-bottom:93.31%;"></picture>
    </div>
    <div style="width:33.333333333333%;left:66.666666666667%;z-index:3" data-top="2" data-speed="2.5">
      <picture data-ratio data-format="portrait" style="padding-bottom:129.29%;"></picture>
    </div>
    <div style="width:50%;left:0%;z-index:4" data-top="14" data-speed="2.5">
      <picture data-ratio data-format="portrait" style="padding-bottom:133.33%;"></picture>
    </div>
    <div style="width:50%;left:50%;z-index:5" data-top="14" data-speed="1">
      <picture data-ratio data-format="landscape" style="padding-bottom:69.38%;"></picture>
    </div>
    </div>
    <div class="group" data-height="">
    <div style="width:83.333333333333%;left:8.3333333333333%;z-index:1" data-top="1" data-speed="2">
      <picture data-ratio data-format="landscape" style="padding-bottom:75%;"></picture>
     </div>
    <div style="width:50%;left:41.666666666667%;z-index:2" data-top="6" data-speed="2">
      <picture data-ratio data-format="portrait" style="padding-bottom:133.33%;"></picture>
     </div>
   </div>
   <div class="group" data-height="">
   <div style="width:33.333333333333%;left:0%;z-index:1" data-top="1" data-speed="3">
      <picture data-ratio data-format="portrait" style="padding-bottom:129.66%;"></picture>
    </div>
    <div style="width:33.333333333333%;left:25%;z-index:2" data-top="5" data-speed="3.5">
      <picture data-ratio data-format="portrait" style="padding-bottom:133.33%;"></picture>
    </div>
    <div style="width:58.333333333333%;left:16.666666666667%;z-index:3" data-top="5" data-speed="3">
      <picture data-ratio data-format="landscape" style="padding-bottom:66.5%;"></picture>
    </div>
    <div style="width:58.333333333333%;left:16.666666666667%;z-index:4" data-top="13" data-speed="3.6">
      <picture data-ratio data-format="landscape" style="padding-bottom:43.3%;"></picture>
    </div>
  </div>
  <div class="group" data-height="">
    <div style="width:100%;left:0%;z-index:1" data-top="0" data-speed="3.2">
      <picture data-ratio data-format="landscape" style="padding-bottom:74.89%;"> </picture>
    </div>
    <div style="width:50%;left:0%;z-index:2" data-top="5" data-speed="4">
      <picture data-ratio data-format="portrait" style="padding-bottom:133.33%;"></picture>
    </div>
    <div style="width:41.666666666667%;left:58.333333333333%;z-index:3" data-top="0" data-speed="3.5">
      <picture data-ratio data-format="landscape" style="padding-bottom:75%;"></picture>
     </div>
  <div style="width:33.333333333333%;left:58.333333333333%;z-index:4" data-top="18" data-speed="4.7">
      <picture data-ratio data-format="portrait" style="padding-bottom:133.33%;"></picture>
    </div>
  </div>
</div>

希望这会有所帮助。 你很好走!!!