Some context:
I'm trying to achieve a similar scrolling effect as in Etsy's product image thumbnails carousel. When you hover over the top part of the div, it automatically scrolls until it reveals the last image and same occurs on the bottom part.
Here's a link to a random product where you can check the functionality.
I've been trying to achieve this with react so I decided to start with scroll on mouse down and stop scrolling on mouse up.
I found a great example of this here
Problem is that it's using jquery. I tried to convert it to vanilla js and use on my react app but had no success.
After some more research I ended up with a working solution but the animation is not smooth at all. I used a setInterval hook. Here's my code.
import { useRef, useState, useLayoutEffect, useEffect } from "react";
import styled from "styled-components";
const Wrapper = styled.div`
margin: 5% 40%;
.test {
height: 300px;
width: 100px;
overflow: scroll;
.inner {
background-image: linear-gradient(red, blue);
height: 800px;
width: 100%;
}
}
`;
function useInterval(callback, delay) {
const savedCallback = useRef(callback);
useLayoutEffect(() => {
savedCallback.current = callback;
}, [callback]);
useEffect(() => {
if (!delay) {
return;
}
const id = setInterval(() => savedCallback.current(), delay);
return () => clearInterval(id);
}, [delay]);
}
const Scroll = () => {
const scrollRef = useRef();
const [delay, setDelay] = useState(100);
const [scrolling, setScrolling] = useState(false);
useInterval(
() => {
console.log("Scrolling");
scrollRef.current.scrollBy({ top: 10, behavior: "smooth" });
},
scrolling ? delay : null
);
return (
<Wrapper>
<div ref={scrollRef} className="test">
<div className="inner"></div>
</div>
<button
onMouseDown={() => setScrolling(true)}
onMouseUp={() => setScrolling(false)}
>
HOLD DOWN TO SCROLL
</button>
</Wrapper>
);
};
export default Scroll;
I would really appreciate some directions and if possible a quick example on how I can achieve a smooth continuous scrolling