滚动上的视差元素
Parallax elements on scroll
我有一个水平页面,上面有多个部分。在第 2 部分,我有三张图片。当我将第 2 部分滚动到视图中时,我希望图像沿相反的滚动方向移动 50 像素。
由于此页面的布局(水平而不是垂直),我有两个问题无法解决:
如何检测我何时到达第 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>
我有一个水平页面,上面有多个部分。在第 2 部分,我有三张图片。当我将第 2 部分滚动到视图中时,我希望图像沿相反的滚动方向移动 50 像素。
由于此页面的布局(水平而不是垂直),我有两个问题无法解决:
如何检测我何时到达第 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>