Add smooth scrolling to video rows by hovering over directional areas
Introduce auto-scrolling functionality to the CategoryRow component. When a user hovers over the left or right half of the row's area, the row will automatically scroll in that direction. This is achieved using `setInterval` for continuous scrolling and clearing the interval on mouse leave. The previous fixed buttons have been replaced with these interactive hover areas. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 074b0e4c-6171-43bd-aa98-f9e04623ca14 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/074b0e4c-6171-43bd-aa98-f9e04623ca14/6upLu3q
This commit is contained in:
parent
debc079e39
commit
0d97d83050
@ -1,4 +1,4 @@
|
||||
import { useState, useRef } from "react";
|
||||
import { useState, useRef, useEffect } from "react";
|
||||
import { type Video } from "@shared/schema";
|
||||
import VideoCard from "./video-card";
|
||||
import BunnyVideoModal from "./bunny-video-modal";
|
||||
@ -133,6 +133,8 @@ interface CategoryRowProps {
|
||||
|
||||
function CategoryRow({ category, onVideoClick }: CategoryRowProps) {
|
||||
const scrollRef = useRef<HTMLDivElement>(null);
|
||||
const [isScrolling, setIsScrolling] = useState(false);
|
||||
const scrollIntervalRef = useRef<NodeJS.Timeout>();
|
||||
|
||||
const scroll = (direction: 'left' | 'right') => {
|
||||
if (scrollRef.current) {
|
||||
@ -152,6 +154,31 @@ function CategoryRow({ category, onVideoClick }: CategoryRowProps) {
|
||||
}
|
||||
};
|
||||
|
||||
const startAutoScroll = (direction: 'left' | 'right') => {
|
||||
setIsScrolling(true);
|
||||
scrollIntervalRef.current = setInterval(() => {
|
||||
if (scrollRef.current) {
|
||||
const scrollStep = direction === 'left' ? -3 : 3;
|
||||
scrollRef.current.scrollLeft += scrollStep;
|
||||
}
|
||||
}, 16); // 60fps smooth scrolling
|
||||
};
|
||||
|
||||
const stopAutoScroll = () => {
|
||||
setIsScrolling(false);
|
||||
if (scrollIntervalRef.current) {
|
||||
clearInterval(scrollIntervalRef.current);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (scrollIntervalRef.current) {
|
||||
clearInterval(scrollIntervalRef.current);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="relative group mb-8">
|
||||
<h2 className="text-2xl font-bold text-bunny-light mb-6 px-4">
|
||||
@ -159,23 +186,27 @@ function CategoryRow({ category, onVideoClick }: CategoryRowProps) {
|
||||
</h2>
|
||||
|
||||
<div className="relative">
|
||||
{/* Left scroll button */}
|
||||
<Button
|
||||
onClick={() => scroll('left')}
|
||||
className="absolute left-2 top-1/2 -translate-y-1/2 z-30 bg-black/80 hover:bg-black/95 text-white border-none w-10 h-10 md:w-12 md:h-12 rounded-full opacity-0 group-hover:opacity-100 transition-all duration-300 flex items-center justify-center shadow-xl"
|
||||
size="sm"
|
||||
{/* Left scroll area - covers left half */}
|
||||
<div
|
||||
className="absolute left-0 top-0 w-1/2 h-full z-20 flex items-center justify-start pl-4"
|
||||
onMouseEnter={() => startAutoScroll('left')}
|
||||
onMouseLeave={stopAutoScroll}
|
||||
>
|
||||
<ChevronLeft className="w-4 h-4 md:w-5 md:h-5" />
|
||||
</Button>
|
||||
<div className="bg-black/60 hover:bg-black/80 text-white w-12 h-12 rounded-full opacity-0 group-hover:opacity-100 transition-all duration-300 flex items-center justify-center shadow-xl cursor-pointer">
|
||||
<ChevronLeft className="w-6 h-6" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right scroll button */}
|
||||
<Button
|
||||
onClick={() => scroll('right')}
|
||||
className="absolute right-2 top-1/2 -translate-y-1/2 z-30 bg-black/80 hover:bg-black/95 text-white border-none w-10 h-10 md:w-12 md:h-12 rounded-full opacity-0 group-hover:opacity-100 transition-all duration-300 flex items-center justify-center shadow-xl"
|
||||
size="sm"
|
||||
{/* Right scroll area - covers right half */}
|
||||
<div
|
||||
className="absolute right-0 top-0 w-1/2 h-full z-20 flex items-center justify-end pr-4"
|
||||
onMouseEnter={() => startAutoScroll('right')}
|
||||
onMouseLeave={stopAutoScroll}
|
||||
>
|
||||
<ChevronRight className="w-4 h-4 md:w-5 md:h-5" />
|
||||
</Button>
|
||||
<div className="bg-black/60 hover:bg-black/80 text-white w-12 h-12 rounded-full opacity-0 group-hover:opacity-100 transition-all duration-300 flex items-center justify-center shadow-xl cursor-pointer">
|
||||
<ChevronRight className="w-6 h-6" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Scrollable video row - true edge to edge */}
|
||||
<div
|
||||
|
||||
Loading…
Reference in New Issue
Block a user