javascript - 对水平滚动的影响
问题描述
我只使用 CSS 创建了这个水平滚动(因为滚动样式只在 Chrome 上工作)。
* {
-webkit-box-sizing: border-box;
box-sizing: border-box;
font-family: 'Nunito', sans-serif;
}
::-webkit-scrollbar {
height: 0;
width: 0;
}
::-webkit-scrollbar-button {
height: 0;
width: 0;
}
h2 {
margin: 0;
}
p {
font-size: 1.25em;
letter-spacing: 0.56px;
line-height: 32px;
}
.container {
background-color: #000;
bottom: 0;
height: 100vh;
left: 0;
margin: auto;
position: absolute;
right: 0;
top: 0;
width: 100vw;
}
.horScroll {
background-color: #abc;
height: 100vw;
overflow-x: hidden;
overflow-y: auto;
position: absolute;
-ms-scroll-snap-type: mandatory;
scroll-snap-type: mandatory;
-ms-scroll-snap-points-y: repeat(100vw);
scroll-snap-points-y: repeat(100vw);
-ms-scroll-snap-type: y mandatory;
scroll-snap-type: y mandatory;
-webkit-transform: translateX(-100%) rotate(-90deg);
-ms-transform: translateX(-100%) rotate(-90deg);
transform: translateX(-100%) rotate(-90deg);
-webkit-transform-origin: top right;
-ms-transform-origin: top right;
transform-origin: top right;
width: 100vh;
}
.item {
background-color: #e4e4e4;
height: 100vw;
position: -webkit-sticky;
position: sticky;
scroll-snap-align: start;
top: 0;
width: 100vh;
}
.horScroll > div:nth-of-type(2n) {
background-color: #333;
color: #fff;
}
.item-inner {
height: 100vh;
max-height: 100vh;
overflow: scroll;
padding: 40px;
-webkit-transform: rotate(90deg) translateX(-100vh);
-ms-transform: rotate(90deg) translateX(-100vh);
transform: rotate(90deg) translateX(-100vh);
-webkit-transform-origin: bottom left;
-ms-transform-origin: bottom left;
transform-origin: bottom left;
width: 100vw;
}
.item-content {
height: 100%;
}
<div class="container">
<div class="horScroll">
<div class="item">
<div class="item-inner">
<div class="item-content">
<h2>Item 1</h2>
<div>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p>
</div>
</div>
</div>
</div>
<div class="item">
<div class="item-inner">
<div class="item-content">
<h2>Item 2</h2>
<div>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p>
</div>
</div>
</div>
</div>
<div class="item">
<div class="item-inner">
<div class="item-content">
<h2>Item 3</h2>
<div>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p>
</div>
</div>
</div>
</div>
<div class="item">
<div class="item-inner">
<div class="item-content">
<h2>Item 4</h2>
<div>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p>
</div>
</div>
</div>
</div>
<div class="item">
<div class="item-inner">
<div class="item-content">
<h2>Item 5</h2>
<div>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p>
</div>
</div>
</div>
</div>
<div class="item">
<div class="item-inner">
<div class="item-content">
<h2>Item 6</h2>
<div>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p>
</div>
</div>
</div>
</div>
</div>
</div>
它按预期工作。现在我正在尝试在 JavaScript 中创建一个额外的效果。
我希望当下一个项目到来时,前一个项目的不透明度、比例或类似效果会发生变化,表明它正在“淡出”。它是两个项目之间的过渡效果。在这种情况下,我正在尝试不透明度。
在相反的方向会发生相反的情况:消失的项目“淡入”。
在forEach()
循环内部,我可以确定当前正在滚动的项目(您可以在 中检查console.log
),但现在我没有正确计算不透明度。我有几个因素需要考虑,比如当前项目和当前滚动位置。
var widthBase = window.innerWidth;
window.addEventListener("resize", function() {
widthBase = window.innerWidth;
})
var items = document.querySelectorAll(".item");
document.querySelector(".horScroll").addEventListener("scroll", function(e) {
items.forEach(function(item, i) {
var currentScroll = e.target.scrollTop;
if (currentScroll >= widthBase * (i) && currentScroll < widthBase * (i + 1)) {
console.log("item index: " + i + ", scroll position: " + currentScroll);
// item.querySelector(".item-content").style.opacity = ? // opacity calculation value
}
})
})
我试过item.querySelector(".item-content").style.opacity = (widthBase * (i + 1))/currentScroll - 1
了,但它可以部分工作。其他一些变体也失败了。我错过了一些东西。
另外,我认为循环遍历每个卷轴中的所有项目不是表演性的,但我想不出有什么不同。
解决方案
我修正了计算。首先,我必须考虑这一点:
项目的顶部位置等于1。
项目的底部位置等于0.001。
所以,当前滚动将是X,我需要每个滚动的值。
1 和 0.001 是opacity
,transform: scale()
或另一个值介于 0 和 1 之间的属性。
它必须是 0.001 而不是 0,否则计算将失败。“Top position”也不能为0,所以我总是加1。
.
现在,使用比例而不是不透明度,结果将是:
"scale(" + (1 - (currentScroll-((widthBase * i) + 1))*(1-0.55)/(((widthBase * (i + 1)) + 1)-((widthBase * i) + 1))) + ")";
工作片段:
var widthBase = window.innerWidth;
window.addEventListener("resize", function() {
widthBase = window.innerWidth;
})
var items = document.querySelectorAll(".item");
document.querySelector(".horScroll").addEventListener("scroll", function(e) {
items.forEach(function(item, i) {
var currentScroll = e.target.scrollTop;
if (currentScroll > widthBase * (i) && currentScroll < widthBase * (i + 1)) {
item.querySelector(".item-content").style.transform = "scale(" + (1 - (currentScroll-((widthBase * i) + 1))*(1-0.55)/(((widthBase * (i+1)) + 1)-((widthBase * i) + 1))) + ")";
}
})
})
* {
-webkit-box-sizing: border-box;
box-sizing: border-box;
font-family: 'Nunito', sans-serif;
}
::-webkit-scrollbar {
height: 0;
width: 0;
}
::-webkit-scrollbar-button {
height: 0;
width: 0;
}
h2 {
margin: 0;
}
p {
font-size: 1.25em;
letter-spacing: 0.56px;
line-height: 32px;
}
.container {
background-color: #000;
bottom: 0;
height: 100vh;
left: 0;
margin: auto;
position: absolute;
right: 0;
top: 0;
width: 100vw;
}
.horScroll {
background-color: #abc;
height: 100vw;
overflow-x: hidden;
overflow-y: auto;
position: absolute;
-ms-scroll-snap-type: mandatory;
scroll-snap-type: mandatory;
-ms-scroll-snap-points-y: repeat(100vw);
scroll-snap-points-y: repeat(100vw);
-ms-scroll-snap-type: y mandatory;
scroll-snap-type: y mandatory;
-webkit-transform: translateX(-100%) rotate(-90deg);
-ms-transform: translateX(-100%) rotate(-90deg);
transform: translateX(-100%) rotate(-90deg);
-webkit-transform-origin: top right;
-ms-transform-origin: top right;
transform-origin: top right;
width: 100vh;
}
.item {
background-color: #e4e4e4;
height: 100vw;
position: -webkit-sticky;
position: sticky;
scroll-snap-align: start;
top: 0;
width: 100vh;
}
.horScroll > div:nth-of-type(2n) {
background-color: #333;
color: #fff;
}
.item-inner {
height: 100vh;
max-height: 100vh;
overflow: scroll;
padding: 40px;
-webkit-transform: rotate(90deg) translateX(-100vh);
-ms-transform: rotate(90deg) translateX(-100vh);
transform: rotate(90deg) translateX(-100vh);
-webkit-transform-origin: bottom left;
-ms-transform-origin: bottom left;
transform-origin: bottom left;
width: 100vw;
}
.item-content {
height: 100%;
}
<div class="container">
<div class="horScroll">
<div class="item">
<div class="item-inner">
<div class="item-content">
<h2>Item 1</h2>
<div>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p>
</div>
</div>
</div>
</div>
<div class="item">
<div class="item-inner">
<div class="item-content">
<h2>Item 2</h2>
<div>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p>
</div>
</div>
</div>
</div>
<div class="item">
<div class="item-inner">
<div class="item-content">
<h2>Item 3</h2>
<div>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p>
</div>
</div>
</div>
</div>
<div class="item">
<div class="item-inner">
<div class="item-content">
<h2>Item 4</h2>
<div>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p>
</div>
</div>
</div>
</div>
<div class="item">
<div class="item-inner">
<div class="item-content">
<h2>Item 5</h2>
<div>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p>
</div>
</div>
</div>
</div>
<div class="item">
<div class="item-inner">
<div class="item-content">
<h2>Item 6</h2>
<div>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ad tempora ducimus tenetur facilis magnam assumenda atque? Minus molestiae hic consectetur voluptatibus maxime, a eum laudantium explicabo similique, iure dignissimos quae.</p>
</div>
</div>
</div>
</div>
</div>
</div>
不幸的是,我没有更改每次滚动的迭代,这会稍微影响性能。
推荐阅读
- xamarin.forms - Xamarin Form 中的水平和垂直滚动
- node.js - NPM 在 docker 容器中从 github 安装一些东西失败
- python - Django 表单集和文件
- arrays - 在一个写时钟周期内读取多个块 RAM 索引
- javascript - 当自更新道具发生变化时如何进行反应组件更新?
- avro - 我可以限制 avro-tools 读取的行数吗?
- php - 未通过中间件时来自节流请求的 TypeError
- php - 从数据库结果 PHP 构建 JSON
- swift - 在 Swift 中创建一个以可变整数作为输入的平方数数组
- android - Google In App Purchase 检索已消费的购买