javascript - Vanilla JS 中的动量水平滚动
问题描述
我目前正在做一个需要水平滑块的项目。我把这个滑块做成可拖动的,并找到了一些让它随着动量滑动的代码。我设法用鼠标滚轮制作了这个水平滚动,但我不知道如何使它与这种动量效应一起工作。我能怎么做 ?
Lorem ipsum dolor sit amet, consectetur adipiscing elit。前庭 nec dapibus leo。Nunc odio massa, tempor eu aliquam vel, viverra vitae est. Suspendisse dignissim nisi arcu。Vivamus non sem et mi auctor varius。类 aptent taciti socialsqu ad litora torquent per conubia nostra, per inceptos himenaeos。Proin blandit malesuada sem, vel gravida tortor volutpat nec。Ut eu前庭neque。
(对不起,但我认为我不能更精确,我需要向您展示代码以使您理解)
// Slider dragging
const slider = document.querySelector('.slider');
let isDown = false;
let startX;
let scrollLeft;
slider.addEventListener('mousedown', (e) => {
isDown = true;
slider.classList.add('active');
startX = e.pageX - slider.offsetLeft;
scrollLeft = slider.scrollLeft;
cancelMomentumTracking();
});
slider.addEventListener('mouseleave', () => {
isDown = false;
slider.classList.remove('active');
});
slider.addEventListener('mouseup', () => {
isDown = false;
slider.classList.remove('active');
beginMomentumTracking();
});
slider.addEventListener('mousemove', (e) => {
if(!isDown) return;
e.preventDefault();
const x = e.pageX - slider.offsetLeft;
const walk = (x - startX); //scroll-fast
var prevScrollLeft = slider.scrollLeft;
slider.scrollLeft = scrollLeft - walk;
velX = slider.scrollLeft - prevScrollLeft;
});
// Momentum
var velX = 0;
var momentumID;
slider.addEventListener('wheel', (e) => {
cancelMomentumTracking();
});
function beginMomentumTracking(){
cancelMomentumTracking();
momentumID = requestAnimationFrame(momentumLoop);
}
function cancelMomentumTracking(){
cancelAnimationFrame(momentumID);
}
function momentumLoop(){
slider.scrollLeft += velX * 2;
velX *= 0.95;
if (Math.abs(velX) > 0.5){
momentumID = requestAnimationFrame(momentumLoop);
}
}
//Scroll
const scrollContainer = document.querySelector(".slider");
scrollContainer.addEventListener("wheel", (evt) => {
evt.preventDefault();
scrollContainer.scrollLeft += evt.deltaY;
});
.slider {
display: flex;
width: 100vw;
height: 75vh;
cursor: grab;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
-ms-overflow-style: none;
scrollbar-width: none;
}
.slider:active {
cursor: grabbing;
}
.slider::-webkit-scrollbar {
display: none;
}
.slide {
margin: auto;
margin-left: 3rem;
flex-shrink: 0;
width: 70%;
height: 80%;
background-color: crimson;
}
.slide:last-child {
margin-right: 3rem;
}
<div class="slider" data-scroll-container="">
<div class="slide" id="slide-1"></div>
<div class="slide" id="slide-2"></div>
<div class="slide" id="slide-3"></div>
<div class="slide" id="slide-4"></div>
<div class="slide" id="slide-5"></div>
</div>
解决方案
将此添加到您的函数中。它不像我希望的那样顺利,但它可以完成工作:
scrollContainer.addEventListener("wheel", (evt) => {
// scrollContainer.scrollLeft += evt.deltaY;
window.requestAnimationFrame(() => {
scrollContainer.scrollTo({ top: 0, left: scrollContainer.scrollLeft + (evt.deltaY * 2), behavior: "smooth" });
});
});
我所做的是用具有行为参数的操作替换了scrollLeft
操作。我还补充说,就我而言,它滚动不够。scrollTo
smooth
evt.deltaY * 2
我想改进的是使用滚轮时的滚动捕捉和更少的“jankyness”。
在此处查看演示(滚动到蓝色/紫色框) - JavaScript 平滑水平滚动
推荐阅读
- css - 在 ::after 动画期间,块在某些区域是不可点击的
- algorithm - 将不同的出现计数为子序列
- python - python-evdev:同时读取游戏手柄的 X 轴和 Y 轴
- apache - 403 Forbidden - 无法解决,搜索高低
- python - Coinbase Pro 中的限价单
- git - 锁定本地 git 分支以防止任何进一步的更改
- matplotlib - 创建后更改 Matplotlib Plot?
- angular - ngFor 停止自动换行
- visual-studio-code - 如何让 Visual Studio Code 及时标记错误?
- javascript - 将数字等级转换为字母等级 - 显示等级的问题