diff --git a/attached_assets/image_1756480103081.png b/attached_assets/image_1756480103081.png new file mode 100644 index 0000000..fb0aeff Binary files /dev/null and b/attached_assets/image_1756480103081.png differ diff --git a/attached_assets/image_1756480148246.png b/attached_assets/image_1756480148246.png new file mode 100644 index 0000000..8b7f977 Binary files /dev/null and b/attached_assets/image_1756480148246.png differ diff --git a/client/src/components/netflix-grid.tsx b/client/src/components/netflix-grid.tsx index aa8a886..7ec0f50 100644 --- a/client/src/components/netflix-grid.tsx +++ b/client/src/components/netflix-grid.tsx @@ -133,59 +133,39 @@ interface CategoryRowProps { function CategoryRow({ category, onVideoClick }: CategoryRowProps) { const scrollRef = useRef(null); - const scrollIntervalRef = useRef(null); + const scrollIntervalRef = useRef(null); const [showLeftButton, setShowLeftButton] = useState(false); const [showRightButton, setShowRightButton] = useState(true); - const [translateX, setTranslateX] = useState(0); - const [isAnimating, setIsAnimating] = useState(false); + const [currentIndex, setCurrentIndex] = useState(0); const videosToShow = 5; // Show 5 videos at a time - const videoWidth = 120; // Width including spacing const scroll = (direction: 'left' | 'right') => { - const step = direction === 'right' ? -videoWidth : videoWidth; - setTranslateX(prev => prev + step); + const totalVideos = category.videos.length; + if (direction === 'right') { + // Move to next video in circular fashion: 1→2→3→...→10→1→2→... + setCurrentIndex(prev => (prev + 1) % totalVideos); + } else { + // Move to previous video in circular fashion: 1→10→9→...→2→1→10→... + setCurrentIndex(prev => prev === 0 ? totalVideos - 1 : prev - 1); + } }; const startAutoScroll = (direction: 'left' | 'right') => { - // Clear any existing animation + // Clear any existing interval if (scrollIntervalRef.current) { - cancelAnimationFrame(scrollIntervalRef.current); + clearInterval(scrollIntervalRef.current); } - setIsAnimating(true); - - // Continuous smooth animation - no jumping - const speed = direction === 'right' ? -1 : 1; // Pixels per frame - - const animate = () => { - setTranslateX(prev => { - const newX = prev + speed; - const totalWidth = category.videos.length * videoWidth; - - // Infinite loop - reset seamlessly - if (direction === 'right' && newX <= -totalWidth) { - return 0; // Reset to start for infinite loop - } else if (direction === 'left' && newX >= 0) { - return -totalWidth + videoWidth; // Reset for reverse - } - - return newX; - }); - - if (isAnimating) { - scrollIntervalRef.current = requestAnimationFrame(animate); - } - }; - - animate(); + // Start continuous circular scrolling + scrollIntervalRef.current = setInterval(() => { + scroll(direction); + }, 600); // Auto scroll every 600ms }; // Always start with video 1 visible at first position useEffect(() => { - if (category.videos.length > 0) { - setTranslateX(0); // Start with video 1 at first position - } + setCurrentIndex(0); // Start with video 1 at first position }, [category.videos.length]); // Always show both buttons @@ -195,9 +175,8 @@ function CategoryRow({ category, onVideoClick }: CategoryRowProps) { }, []); const stopAutoScroll = () => { - setIsAnimating(false); if (scrollIntervalRef.current) { - cancelAnimationFrame(scrollIntervalRef.current); + clearInterval(scrollIntervalRef.current); scrollIntervalRef.current = null; } }; @@ -291,42 +270,34 @@ function CategoryRow({ category, onVideoClick }: CategoryRowProps) { - {/* Continuously flowing carousel */} -
-
- {/* Create infinite loop by tripling the videos */} - {[...category.videos, ...category.videos, ...category.videos].map((video, index) => { - const actualIndex = index % category.videos.length; - return ( -
- {/* Top 10 Number overlay for first category */} - {category.title.includes("Top 10") && ( -
- {actualIndex + 1} -
- )} - -
- ); - })} -
+ {/* Circular carousel - videos rotate in circle */} +
+ {/* Show 5 videos in circular fashion */} + {Array.from({ length: videosToShow }, (_, index) => { + const videoIndex = (currentIndex + index) % category.videos.length; + const video = category.videos[videoIndex]; + return ( +
+ {/* Top 10 Number overlay for first category */} + {category.title.includes("Top 10") && ( +
+ {videoIndex + 1} +
+ )} + +
+ ); + })}