I am looking to replicate the carousel feature seen on this website. I want to mimic the same functionality without relying on any external libraries. I have found several resources explaining how to achieve this. Most suggest creating duplicate copies of the carousel track and switching between them, but I prefer not to do that. The code below works well when sliding within the boundary elements (1st and last slide). How can I smoothly transition from the last slide to the first slide and vice versa? Adjusting the left offset can move me from the last back to the first slide, but it doesn't give the carousel an infinite looping effect. Is appending the first slide after the last one the only solution to achieve this?
import {useRef, useEffect} from "react";
import {details} from "./constants";
const App = () => {
const carousel_track = useRef();
const container = useRef();
let counter = 0;
const card = useRef();
const prevSlide = () => {
const width = card.current.offsetWidth;
counter--;
carousel_track.current.style.left = -width * counter + "px";
};
const nextSlide = () => {
const width = card.current.offsetWidth;
counter++;
carousel_track.current.style.left = -width * counter + "px";
};
useEffect(() => {
addEventListener("keydown", (e) => {
if (e.code === "ArrowRight") nextSlide();
if (e.code === "ArrowLeft") prevSlide();
});
}, []);
return (
<div className="w-screen h-screen flex items-center bg-slate-500">
<div
ref={container}
className="w-screen h-2/3 transition-all overflow-x-hidden relative border-cyan-800 border-4"
>
<div
onClick={prevSlide}
className="absolute cursor-pointer text-2xl text-white z-10 left-0 top-1/2"
>
Prev
</div>
<div
onClick={nextSlide}
className="absolute cursor-pointer text-2xl text-white z-10 right-0 top-1/2"
>
Next
</div>
<div
ref={carousel_track}
className="w-[200%] h-full flex transition-all justify-start items-center absolute bg-red-800"
>
{details.map((slide) => (
<div
ref={card}
className="w-screen h-full flex-shrink-0"
key={slide.title}
>
<div className="rounded-lg h-full">
<img
src={slide.image}
alt="image"
className="rounded-lg w-full h-full object-cover"
/>
</div>
</div>
))}
</div>
</div>
</div>
);
};
export default App;