"How can I implement both cursor-based and button-based horizontal scrolling for cards? I'm facing a challenge in understanding how to integrate these two scrolling mechanisms cohesively within my project. My current implementation involves a series of cards arranged horizontally, and the buttons trigger the scrolling animation to reveal the next card. Now, I want users to have the flexibility to achieve the same scrolling using just their cursor. Could someone please provide insights, a potential approach, or even code snippets that can help me achieve this dynamic dual scrolling functionality?
To summarize, I'm seeking guidance on how to combine both button-triggered and cursor-based horizontal scrolling for a series of cards. Your expertise and suggestions would be immensely valuable in helping me accomplish this task effectively. Thank you in advance!"
import React, { useState,useEffect } from "react";
import ProductCard from "../components/ProductCard";
const products = [
{ _id: 1, name: 'Product 1', imageUrl: 'product1.jpg' },
{ _id: 2, name: 'Product 2', imageUrl: 'product2.jpg' },
{ _id: 3, name: 'Product 3', imageUrl: 'product3.jpg' },
{ _id: 4, name: 'Product 4', imageUrl: 'product4.jpg' },
{ _id: 4, name: 'Product 4', imageUrl: 'product4.jpg' },
{ _id: 4, name: 'Product 4', imageUrl: 'product4.jpg' },
];
const CardContainer = () => {
const [currentIndex, setCurrentIndex] = useState(0);
const [numberOfColumns, setNumberOfColumns] = useState(4);
useEffect(() => {
const handleResize = () => {
if (window.innerWidth >= 1024) {
setNumberOfColumns(4); // Large screens
} else if (window.innerWidth >= 768) {
setNumberOfColumns(3); // Medium screens
} else {
setNumberOfColumns(2); // Small screens
}
};
handleResize();
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
const handlePrev = () => {
setCurrentIndex((prevIndex) => Math.max(prevIndex - 1, 0));
};
const handleNext = () => {
setCurrentIndex((prevIndex) =>
Math.min(prevIndex + 1, products.length - numberOfColumns)
);
};
const showPrevButton = currentIndex > 0;
const showNextButton = currentIndex < products.length - numberOfColumns;
return (
<section className="text-gray-600 body-font mt-32">
<div className=" px-8 py-8 mx-auto">
<div className="flex flex-wrap w-full mb-4 flex-col items-center text-center">
<h1 className="sm:text-3xl text-2xl font-medium title-font mb-2 text-gray-900">
Hurry! Sale Ends Soon
</h1>
<h1 className="flex text-center">..........</h1>
</div>
<div className="relative">
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4 overflow-hidden">
{showPrevButton && (
<button
onClick={handlePrev}
className="lg:flex items-center justify-center w-12 h-12 bg-gray-300 hover:bg-gray-400 text-gray-700 hover:text-gray-800 absolute left-0 top-1/2 transform -translate-y-1/2 transition-opacity duration-300 ease-in-out opacity-50 lg:opacity-100 z-10"
style={{ zIndex: 10 }}
>
<
</button>
)}
{products
.slice(currentIndex, currentIndex + numberOfColumns)
.map((product) => (
<ProductCard key={product._id} product={product} />
))}
{showNextButton && (
<button
onClick={handleNext}
className="lg:flex items-center justify-center w-12 h-12 bg-gray-300 hover:bg-gray-400 text-gray-700 hover:text-gray-800 absolute right-0 top-1/2 transform -translate-y-1/2 transition-opacity duration-300 ease-in-out opacity-50 lg:opacity-100 z-10"
style={{ zIndex: 10 }}
>
>
</button>
)}
</div>
<div className="flex items-center justify-center">
<button
className=" px-6 py-2 border border-r2 border-black text-black"
onClick={() => router.push("/collection/sale")}
>
View All
</button>
</div>
</div>
</div>
</section>
);
};
export default CardContaine