chore: show each slide based on video time

This commit is contained in:
Ephraim Atta-Duncan
2024-06-10 13:43:50 +00:00
parent 1b849d1fb8
commit 1fda9ed2a6

View File

@ -57,9 +57,10 @@ export const Carousel = () => {
const [progress, setProgress] = useState(0); const [progress, setProgress] = useState(0);
const videoRefs = useRef<(HTMLVideoElement | null)[]>([]); const videoRefs = useRef<(HTMLVideoElement | null)[]>([]);
const { theme } = useTheme(); const { theme } = useTheme();
const [autoplayDelay, setAutoplayDelay] = useState<number[]>([]);
const [emblaRef, emblaApi] = useEmblaCarousel({ loop: true }, [ const [emblaRef, emblaApi] = useEmblaCarousel({ loop: true }, [
Autoplay({ playOnInit: true, delay: 5000 }), Autoplay({ playOnInit: true, delay: autoplayDelay[selectedIndex] || 5000 }),
]); ]);
const [emblaThumbsRef, emblaThumbsApi] = useEmblaCarousel( const [emblaThumbsRef, emblaThumbsApi] = useEmblaCarousel(
{ {
@ -67,7 +68,7 @@ export const Carousel = () => {
containScroll: 'keepSnaps', containScroll: 'keepSnaps',
dragFree: true, dragFree: true,
}, },
[Autoplay({ playOnInit: true, delay: 5000 })], [Autoplay({ playOnInit: true, delay: autoplayDelay[selectedIndex] || 5000 })],
); );
const onThumbClick = useCallback( const onThumbClick = useCallback(
@ -95,6 +96,27 @@ export const Carousel = () => {
setProgress(0); setProgress(0);
}, []); }, []);
useEffect(() => {
const setVideoDurations = async () => {
const durations = await Promise.all(
videoRefs.current.map(
async (video) =>
new Promise<number>((resolve) => {
if (video) {
video.onloadedmetadata = () => resolve(video.duration * 1000);
} else {
resolve(5000);
}
}),
),
);
setAutoplayDelay(durations);
};
void setVideoDurations();
}, [slides, theme]);
useEffect(() => { useEffect(() => {
const observer = new IntersectionObserver( const observer = new IntersectionObserver(
(entries) => { (entries) => {
@ -144,22 +166,54 @@ export const Carousel = () => {
.on('reInit', () => setIsPlaying(autoplay.isPlaying())); .on('reInit', () => setIsPlaying(autoplay.isPlaying()));
}, [emblaApi]); }, [emblaApi]);
// useEffect(() => {
// const updateInterval = 50;
// const increment = 100 / (autoplayDelay[selectedIndex] / updateInterval);
// const timer = setInterval(() => {
// setProgress((prevProgress) => {
// if (prevProgress >= 100) {
// clearInterval(timer);
// return 100;
// }
// return prevProgress + increment;
// });
// }, updateInterval);
// return () => clearInterval(timer);
// }, [selectedIndex, autoplayDelay]);
useEffect(() => { useEffect(() => {
if (autoplayDelay[selectedIndex] === undefined) return;
const updateInterval = 50; const updateInterval = 50;
const increment = 100 / (5000 / updateInterval); const increment = 100 / (autoplayDelay[selectedIndex] / updateInterval);
let progressValue = 0;
const timer = setInterval(() => { const timer = setInterval(() => {
setProgress((prevProgress) => { setProgress((prevProgress) => {
if (prevProgress >= 100) { progressValue = prevProgress + increment;
if (progressValue >= 100) {
clearInterval(timer); clearInterval(timer);
if (emblaApi) {
emblaApi.scrollNext();
}
return 100; return 100;
} }
return prevProgress + increment; return progressValue;
}); });
}, updateInterval); }, updateInterval);
return () => clearInterval(timer); return () => clearInterval(timer);
}, [selectedIndex]); }, [selectedIndex, autoplayDelay, emblaApi]);
useEffect(() => {
videoRefs.current.forEach((video) => {
if (video) {
video.load();
}
});
}, [theme]);
useEffect(() => { useEffect(() => {
if (!emblaApi) return; if (!emblaApi) return;
@ -170,7 +224,7 @@ export const Carousel = () => {
}; };
resetCarousel(); resetCarousel();
}, [theme, emblaApi]); }, [theme, emblaApi, autoplayDelay]);
return ( return (
<> <>
@ -188,7 +242,7 @@ export const Carousel = () => {
className="h-auto w-full rounded-xl" className="h-auto w-full rounded-xl"
> >
<source <source
src={theme === 'light' ? slide.srcLight : slide.srcDark} src={theme === 'dark' ? slide.srcDark : slide.srcLight}
type="video/webm" type="video/webm"
/> />
Your browser does not support the video tag. Your browser does not support the video tag.