From ba2856ede791cadc0abd4d4784b1316f374d831c Mon Sep 17 00:00:00 2001 From: sebastjanartic <45803536-sebastjanartic@users.noreply.replit.com> Date: Fri, 29 Aug 2025 16:57:14 +0000 Subject: [PATCH] Improve video scrolling with seamless infinite looping Update client-side logic to implement a triple-copy approach for videos, enabling smooth, seamless infinite scrolling. Adjust initial translation and scroll calculations to support the new wrapping mechanism. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 2eb1084e-b728-4449-9231-f1665924c8d5 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/2eb1084e-b728-4449-9231-f1665924c8d5/yexZbDm --- client/src/components/netflix-grid.tsx | 73 ++++++++++++++------------ 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/client/src/components/netflix-grid.tsx b/client/src/components/netflix-grid.tsx index 223dae3..24e7999 100644 --- a/client/src/components/netflix-grid.tsx +++ b/client/src/components/netflix-grid.tsx @@ -144,17 +144,19 @@ function CategoryRow({ category, onVideoClick }: CategoryRowProps) { const videoWidth = 120; // Width including spacing const scroll = (direction: 'left' | 'right') => { - // Simple step movement with wrap-around logic + // Smooth movement with seamless wrapping const step = direction === 'right' ? -200 : 200; setTranslateX(prev => { const newX = prev + step; - const maxWidth = category.videos.length * 220; // Approximate video width + const singleSetWidth = category.videos.length * 220; // One complete set - // Wrap around logic for infinite scroll - if (direction === 'right' && newX < -maxWidth) { - return 0; // Reset to start when going too far right - } else if (direction === 'left' && newX > 0) { - return -maxWidth + 800; // Jump to end when going too far left + // Seamless infinite scroll - when in middle copy, wrap smoothly + if (direction === 'right' && newX <= -singleSetWidth * 2) { + // When moved past second copy, jump back to first copy position + return newX + singleSetWidth; + } else if (direction === 'left' && newX >= 0) { + // When moved past first copy, jump back to second copy position + return newX - singleSetWidth; } return newX; @@ -231,8 +233,9 @@ function CategoryRow({ category, onVideoClick }: CategoryRowProps) { // Initialize with first video on the left side useEffect(() => { if (category.videos.length > 0) { - // Start with video 1 visible on the left side - setTranslateX(0); + // Start in middle copy for seamless wrapping + const singleSetWidth = category.videos.length * 220; + setTranslateX(-singleSetWidth); } }, [category.videos.length]); @@ -348,32 +351,36 @@ function CategoryRow({ category, onVideoClick }: CategoryRowProps) { willChange: 'transform' }} > - {/* Simple list to test movement */} - {category.videos.map((video, index) => ( -
- {/* Top 10 Number overlay for first category */} - {category.title.includes("Top 10") && ( -
- {index + 1} + {/* Triple copy for seamless infinite scroll */} + {[...category.videos, ...category.videos, ...category.videos].map((video, index) => { + const originalIndex = index % category.videos.length; + const copyNumber = Math.floor(index / category.videos.length) + 1; + return ( +
+ {/* Top 10 Number overlay for first category */} + {category.title.includes("Top 10") && ( +
+ {originalIndex + 1} +
+ )} + + {/* Debug number to see movement - shows copy and original position */} +
+ {copyNumber}.{originalIndex + 1}
- )} - - {/* Debug number to see movement */} -
- {index + 1}
-
- ))} + ); + })}