diff --git a/src/Pages/Home/Testimonial.jsx b/src/Pages/Home/Testimonial.jsx index 1c9f77c2..794d073c 100644 --- a/src/Pages/Home/Testimonial.jsx +++ b/src/Pages/Home/Testimonial.jsx @@ -1,5 +1,5 @@ "use client"; -import React, { useState } from "react"; +import React, { useState, useRef, useEffect, useMemo } from "react"; import { motion } from "framer-motion"; import PropTypes from "prop-types"; import img1 from "/assets/testimonials/img5.jpg"; @@ -46,6 +46,19 @@ const testimonials = [ }, ]; +/** + * Deduplicate testimonials by id to prevent duplicate entries. + * Returns a new array with only unique testimonials. + */ +const getUniqueTestimonials = (items) => { + const seen = new Set(); + return items.filter((item) => { + if (seen.has(item.id)) return false; + seen.add(item.id); + return true; + }); +}; + const TestimonialCard = ({ text, name, image, rating }) => { return ( { const [isPaused, setIsPaused] = useState(false); - const duplicatedTestimonials = [...testimonials, ...testimonials]; + const scrollRef = useRef(null); + const [scrollWidth, setScrollWidth] = useState(0); + + // Deduplicate testimonials to ensure no duplicate entries exist + const uniqueTestimonials = useMemo(() => getUniqueTestimonials(testimonials), []); + + // Duplicate once for seamless infinite scroll looping + const scrollTestimonials = useMemo( + () => [...uniqueTestimonials, ...uniqueTestimonials], + [uniqueTestimonials] + ); + + // Measure the exact pixel width of one set of testimonials + // so the scroll resets seamlessly without visible duplication + useEffect(() => { + if (scrollRef.current) { + const totalWidth = scrollRef.current.scrollWidth; + setScrollWidth(totalWidth / 2); + } + }, [scrollTestimonials]); + + // Calculate animation duration based on content width for consistent speed + const animationDuration = Math.max(scrollWidth / 50, 20); return (
@@ -139,18 +174,22 @@ const TestimonialSection = () => {
setIsPaused(true)} onMouseLeave={() => setIsPaused(false)} > - {duplicatedTestimonials.map((testimonial, index) => ( + {scrollTestimonials.map((testimonial, index) => ( ))} @@ -159,11 +198,11 @@ const TestimonialSection = () => {
- {/* Keyframes */} + {/* Keyframes - scroll by exact pixel width of one set for seamless loop */}