I have a momentum based drag scrolling and I implement snapping behavior. The problem is the snapping animation is instantaneous. How to make it smoother?
I try this using the momentum based horizontal drag by Lachlan https://codepen.io/loxks/details/KKpVvVW
<div class="grid-container">
<main class="grid-item main">
<div class="items">
<div class="item item1"></div>
<div class="item item2"></div>
<div class="item item3"></div>
<div class="item item4"></div>
</div>
</main>
</div>
@import url(https://fonts.googleapis.com/css?family=Rubik);
body,
html {
color: #fff;
text-align: center;
background: #efefef;
font-family: Helvetica, sans-serif;
margin: 0;
}
.grid-container {
background: #efefef;
font-family: "Rubik", sans-serif;
height: 100vh
}
.grid-item {
color: #fff;
background: skyblue;
padding: 3.5em 1em;
font-size: 1em;
font-weight: 700;
height: 100vh
}
.main {
color: #959595;
background-color: white;
padding: 0;
overflow-x: scroll;
overflow-y: hidden;
}
.footer {
background-color: #5bbce4;
grid-area: footer;
padding: 0.6em;
}
.items {
position: relative;
width: 100%;
overflow-x: scroll;
overflow-y: hidden;
white-space: nowrap;
transition: all 0.2s;
transform: scale(0.98);
will-change: transform;
user-select: none;
cursor: pointer;
}
.items.active {
background: rgba(255, 255, 255, 0.3);
transform: scale(1);
}
.item {
display: inline-block;
background: skyblue;
min-height: 250px;
min-width: calc(100vw - 2rem);
margin: 2em 1em;
scroll-snap-align: center;
scroll-snap-stop: always;
}
.snap {
scroll-snap-type: x mandatory;
}
const slider = document.querySelector('.items');
let isDown = false;
let startX;
let scrollLeft;
slider.addEventListener('mousedown', (e) => {
isDown = true;
slider.classList.add('active');
slider.classList.remove('snap');
startX = e.pageX - slider.offsetLeft;
scrollLeft = slider.scrollLeft;
cancelMomentumTracking();
});
slider.addEventListener('mouseleave', () => {
isDown = false;
slider.classList.remove('active');
slider.classList.add('snap');
});
slider.addEventListener('mouseup', () => {
isDown = false;
slider.classList.remove('active');
slider.classList.add('snap');
beginMomentumTracking();
});
slider.addEventListener('mousemove', (e) => {
if(!isDown) return;
e.preventDefault();
const x = e.pageX - slider.offsetLeft;
const walk = (x - startX) * 3; //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;
velX *= 0.95;
if (Math.abs(velX) > 0.5){
momentumID = requestAnimationFrame(momentumLoop);
}
}
I also try this /questions/67962715/how-to-make-drag-to-scroll-work-smoothly-with-scroll-snapping
but the animation is instant. I also tried the no.2 solution by adding style= "scroll-behavior: smooth;"
in the parent .items
but the scroll is too sticky, it does not even let me scroll.
I expect to make the snapping animation smoother, also if you can make the item
scale up when it is in the center of the screen and scale down when they are not. I appreciate it. Thanks
John Lee Ingua is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.