I am hoping to recreate the carousel present on this site. I want to achieve the same functionality without using any library. I have come across a lot of resources on how to achieve that. Most of them were creating two copies of the carousel track and then switching in between but I do not want to do that. The below code works fine as long as I am sliding within the boundary elements (1st and last slide). How can I switch from the last slide to the first slide and vice versa? I can switch to the first slide from the last slide by adjusting the left offset but that would not make it look like an infinite slider. I want to make it look like the one on the site. Is appending first slide after the last the only way to achieve?
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;