I have made an automatic horizontal scroller with GSAP and NextJS, the only problem i have with the scroller is that the content is not repeating itself seamlessly.
I want each element to go back in the line when it is out of the viewport so it makes it repeat seamless.
This is the code i have so far.
const clientArray = data;
const duplicatedClients = [...clientArray]
const concanatedClientsArray = [...clientArray, ...duplicatedClients]
useEffect(() => {
const originalContent = document.querySelector('.projects__items');
const clonedContent = document.querySelector('.projects__items--cloned');
const clonedContentTwo = document.querySelector('.projects__items--cloned--two');
document.querySelector(".projects__container").style.width = `${concanatedClientsArray.length * 100}%`;
const scrollLength = clonedContent.offsetWidth;
const timeline = gsap.timeline({ repeat: -1 });
timeline.to(originalContent, {
x: -scrollLength,
duration: 3,
ease: 'none'
});
}, [])
return (
<div className="projects__container">
<motion.div variants={ProjectParentShow} initial="hidden" animate="visible" exit="exit" className="projects__items">
{concanatedClientsArray.map((project, index) => {
return (
<motion.div variants={ProjectChildShow} key={index} className="projects__item" onMouseEnter={(e) => handleHover(e, index)} onMouseLeave={(e) => handleHover(e)}>
<Link href={project.url}>
<div className="projects__image">
<Image unoptimized={true} priority src={urlFor(project.image).url()} alt={project.image.altText} width={323} height={475} />
</div>
<div className="projects__content">
<motion.div className="title" initial="hidden" animate={isActive === index ? "visible" : "hidden"} variants={ProjectParentAnimation}>{project.name.split("").map((letter, key) => {
return (
<motion.p key={key} variants={ProjectLetterDown} className="letter">{letter}</motion.p>
)
})}</motion.div>
<motion.div className="divider" initial="hidden" animate={isActive === index ? "visible" : "hidden"} variants={ProjectDivider}></motion.div>
<motion.div className="type" initial="hidden" animate={isActive === index ? "visible" : "hidden"} variants={ProjectParentAnimation}>{project.clientType.split("").map((letter, index) => {
return (
<motion.p key={index} variants={ProjectLetterUp} className="letter">{letter}</motion.p>
)
})}</motion.div>
</div>
</Link>
</motion.div>
)
})}
</motion.div>
</div>
)
I have tried to duplicate the data in the array and have made the array bigger for better result, but I can not seem the fix the scrolling issue where it does not repeat seamlessly.
I want to achieve the same smoothness when it resets as this website https://manonjouet.com/