滚动视差元素

3

代码地址

我有一个水平页面,上面有多个部分。在第二个部分中,我有三张图片。当我滚动到第二个部分时,我希望这些图片向相反的方向移动50像素。

由于该页面是水平布局而不是垂直布局,所以我无法解决以下两个问题:

  1. 如何检测到我到达了第二个部分

  2. 如何将图片沿相反方向平滑地移动约50像素

我使用这段代码来确定滚动的方向

var $scrollWrapper = $('.scroll_wrapper');
var $scrollBtn = $('#scrollBtn');
var $scrollOuterWrapper = $('.scroll_outer-wrapper');

$scrollWrapper.scrollTop(0)
$('#scrollBtn').on('click', function() {
  $scrollWrapper.scrollTop($scrollWrapper.scrollTop() + 100)
});

var lastScrollTop = 0;

$scrollOuterWrapper.on('scroll', function() {
  var st = $(this).scrollTop();
  var endOfWrapper = $(this).scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight;
  if (st > lastScrollTop){
    // down scroll
    console.log('downscroll');

    // parallax elements - move to front
    // ??
    $moveElement = $('.move-on-scroll');

    $moveElement.each(function() {
      var firstTop = $(this).offset().top;
      var wrapperScrollTop = $scrollOuterWrapper.scrollTop();
      var shiftDistance = (firstTop - wrapperScrollTop)*0.02;

      $(this).css("transform","translateX("+shiftDistance+"px)");
    });


  } else {
    // upscroll
     console.log('upscroll');

     // parallax elements - move to back
     // ??
  }
  lastScrollTop = st;
});

这里还有一段代码片段:

var $scrollWrapper = $('.scroll_wrapper');
var $scrollBtn = $('#scrollBtn');
var $scrollOuterWrapper = $('.scroll_outer-wrapper');

$scrollWrapper.scrollTop(0)
$('#scrollBtn').on('click', function() {
  $scrollWrapper.scrollTop($scrollWrapper.scrollTop() + 100)
});

var lastScrollTop = 0;

$scrollOuterWrapper.on('scroll', function() {
  var st = $(this).scrollTop();
  var endOfWrapper = $(this).scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight;
  if (st > lastScrollTop){
    // down scroll
    console.log('downscroll');
    
    // parallax elements - move to front
    // ??
    $moveElement = $('.move-on-scroll');
    
    $moveElement.each(function() {
      var firstTop = $(this).offset().top;
      var wrapperScrollTop = $scrollOuterWrapper.scrollTop();
      var shiftDistance = (firstTop - wrapperScrollTop)*0.2;

      $(this).css("transform","translateX("+shiftDistance+"px)");
    });


  } else {
    // upscroll
     console.log('upscroll');
     
     // parallax elements - move to back
     // ??
  }
  lastScrollTop = st;
});
.scroll_outer-wrapper {
  width: 100vh;
  height: 100vw;
  transform: rotate(-90deg) translateX(-100vh);
  transform-origin: top left;
  overflow-y: scroll;
  overflow-x: hidden;
  position: absolute;
}
.scroll_wrapper {
  display: flex;
  flex-direction: row;
  width: 400vw;
  transform: rotate(90deg) translateY(-100vh);
  transform-origin: top left;
  transition: transform .5s ease;
}
.scroll_section {
  width: 100vw;
  height: 100vh;
}

.scroll_section.one{background: black; color: white;}
.scroll_section.two{background: white; color: black;}
.scroll_section.three{background: black; color: white;}
.scroll_section.four{background: pink; color: black;}

#scrollBtn {
    position: absolute;
    bottom: 20px;
    right: 20px;
    background-color: darkblue;
    color: white;
    border: none;
    width: 80px;
    height: 80px;
    border-radius: 50%;
    text-transform: uppercase;
    font-size: 12px;
    line-height: 20px;
    cursor: pointer;
}

.move-on-scroll {
  width: 150px;
  height: 150px;
  border: 2px solid red;
  margin: 0 20px;
}

.move-on-scroll img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.two_inner {
  display: flex;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="scroll_outer-wrapper">
  <div class="scroll_wrapper">
    <section class="scroll_section one">
      <h2>section 1</h2>
    </section>
    <section class="scroll_section two">
      <h2>section 2</h2>
      <div class="scroll_section two two_inner">
        <div class="move-on-scroll">
          <img src="https://images.unsplash.com/photo-1590336751349-f65720fee481?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80" >
        </div>
        <div class="move-on-scroll">
          <img src="https://images.unsplash.com/photo-1590336751349-f65720fee481?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80" >
        </div>
        <div class="move-on-scroll">
          <img src="https://images.unsplash.com/photo-1590336751349-f65720fee481?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80" >
        </div>
      </div>
    </section>
    <section class="scroll_section three">  
      <h2>section 3</h2>
    </section>
    <section class="scroll_section four">
      <h2>section 4</h2>
    </section>
  </div>
</div>

<button id="scrollBtn">Click to Scroll</button>


  1. 为了确定滚动到第二部分时,您可以使用滚动事件检查条件,其中section2的offsetX为零。
  2. 您可以检查当前滚动的位置并将其与section2的偏移量进行比较,根据此基础,您可以确定滚动的方向,并相应地移动图像50px。
- thenaamsake
1个回答

1
在回答时,请开始思考。我不太确定目标是什么。也许如果您展示一些结果的图像或解释场景-我可以更准确地做到。现在只能做到这个程度。图像的第一行从第二屏幕开始移动。图像的第二行从开头开始移动。在全屏模式下查看代码。 更新: 只需将transition添加到CSS中,用于通过jquery进行transform转换的元素。
.move-on-scroll {transition: all .5s cubic-bezier(.25,.99,.52,.9);}

如果您想更正transition-timing-function的轻松程度 - 您可以在此处创建自己的cubic-bezierhttps://cubic-bezier.com/

var $scrollWrapper = $('.scroll_wrapper');
var $scrollBtn = $('#scrollBtn');
var $scrollOuterWrapper = $('.scroll_outer-wrapper');

// Have no idea, what it shoud do
/*$scrollWrapper.scrollTop(0);
$('#scrollBtn').on('click', function() {
  $scrollWrapper.scrollTop($scrollWrapper.scrollTop() + 100)
});*/

$scrollOuterWrapper.on('scroll', function() {

  var st = $(this).scrollTop();
  var sOneWidth = $('.scroll_section.one').width();

  $moveElement = $('.move-on-scroll');
  $moveElement.each(function() {
    var firstTop = $(this).offset().left;
    var shiftDistance = -st * 0.3;
    // detects, when you reash section 2
    if (st >= sOneWidth) {
      //do something
    }
    $(this).css("transform", "translateX(" + shiftDistance + "px)");
  });

});
* {
  box-sizing: border-box;
}

html {
  height: 100%;
}

body {
  min-height: 100%;
  margin: 0;
  padding: 0;
}

.scroll_outer-wrapper {
  width: 100vh;
  height: 100vw;
  transform: rotate(-90deg) translateX(-100vh);
  transform-origin: top left;
  overflow-y: scroll;
  overflow-x: hidden;
  position: absolute;
}

.scroll_outer-wrapper {
  scrollbar-width: thin;
}

.scroll_outer-wrapper::-webkit-scrollbar {
  width: 6px;
  background-color: #fff;
}

.scroll_outer-wrapper::-webkit-scrollbar-track {
  background-color: #F5F5F5;
  border-radius: 10px;
}

.scroll_outer-wrapper::-webkit-scrollbar-thumb {
  background: #ffa000;
}

.scroll_wrapper {
  display: flex;
  flex-direction: row;
  width: 400vw;
  transform: rotate(90deg) translateY(-100vh);
  transform-origin: top left;
  transition: transform .5s ease;
}

.scroll_section {
  width: 100vw;
  height: 100vh;
}

.scroll_section.one {
  background: black;
  color: white;
}

.scroll_section.two {
  background: white;
  color: black;
}

.scroll_section.three {
  background: black;
  color: white;
}

.scroll_section.four {
  background: pink;
  color: black;
}

#scrollBtn {
  position: absolute;
  bottom: 20px;
  right: 20px;
  background-color: darkblue;
  color: white;
  border: none;
  width: 80px;
  height: 80px;
  border-radius: 50%;
  text-transform: uppercase;
  font-size: 12px;
  line-height: 20px;
  cursor: pointer;
}

.move-on-scroll {
  width: 150px;
  height: 150px;
  border: 2px solid red;
  margin: 0 20px;
  transition: all .5s cubic-bezier(.25, .99, .52, .9);
}

.move-on-scroll img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.two_inner {
  display: flex;
  justify-content: flex-end;
  overflow: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="scroll_outer-wrapper">
  <div class="scroll_wrapper">
    <section class="scroll_section one">
      <h2>section 1</h2>
    </section>
    <section class="scroll_section two">
      <h2>section 2</h2>
      <div class="two_inner">
        <div class="move-on-scroll">
          <img src="https://images.unsplash.com/photo-1590336751349-f65720fee481?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80">
        </div>
        <div class="move-on-scroll">
          <img src="https://images.unsplash.com/photo-1590336751349-f65720fee481?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80">
        </div>
        <div class="move-on-scroll">
          <img src="https://images.unsplash.com/photo-1590336751349-f65720fee481?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80">
        </div>
      </div>
    </section>
    <section class="scroll_section three">
      <h2>section 3</h2>
    </section>
    <section class="scroll_section four">
      <h2>section 4</h2>
    </section>
  </div>
</div>

<button id="scrollBtn">Click to Scroll</button>


感谢您的回答。请参见此网站。图片应该保持在第二部分内,就像现在一样,它们正在溢出。 - Aerra
哦,你的意思是当向前滚动时图像变得更宽,向后滚动时变得更短吗?请告诉我应该关注哪个具体效果? - focus.style
是的,当您向下滚动时,图像会慢慢地向左开始。当您向上滚动一点时,图像会平稳停止。如果您继续向上滚动,则图像会慢慢地向右开始。 - Aerra
这就是诀窍。我只会在.two_inner上添加overflow: hidden; justify-content: flex-end;,以便图像不会超出其部分。 - Aerra
已经将您的调整添加到答案中。很高兴能帮助您! - focus.style
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接