滚动上的视差元素

Parallax elements on scroll

Fiddle

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

由于此页面的布局(水平而不是垂直),我有两个问题无法解决:

  1. 如何检测我何时到达第 2 部分

  2. 如何将图像沿滚动的相反方向移动 ~50px 并使其尽可能平滑

我用这段代码来判断滚动的方向

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>

一边写答案,一边思考。我不太确定,目标是什么。也许如果你展示一些结果图片或解释场景 - 我可以做得更准确。现在 - 做了这个。第一行图​​像开始与第二个屏幕一起移动。第二行图像从头开始移动。在整页模式下查看代码。

已更新

简单地将 transition 添加到 CSS 的元素,该元素正在通过 jquery 与 transform 进行转换。

.move-on-scroll {transition: all .5s cubic-bezier(.25,.99,.52,.9);}

如果您要更正 transition-timing-function - 您可以在此处创建自己的 cubic-bezier https://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>