I am trying to build an image carousel with a progress bar showing the remaining time at the bottom of the image. The carousel is able to switch to the next image after the given delay, but I am unable to pause the animation on hover.
https://codesandbox.io/s/unruffled-sun-qz5d89?file=/src/Slider.tsx
import {Fragment, useEffect, useState, useCallback, useRef} from "react";
import './Slider.css';
type Props = {
images: string[];
slideShowDelay?: number;
}
export default function Slider({images, slideShowDelay=5}: Props): JSX.Element {
const [currentSlide, setCurrentSlide] = useState<number>(0);
const [timer, setTimer] = useState<NodeJS.Timer>();
const progressRef = useRef<HTMLDivElement | null>(null);
const [animationState, setAnimationState] = useState('animate');
const prevButtonHandler = () => {
setCurrentSlide(prev => {
const result = prev-1;
if (result < 0) {
return images.length - 1;
}
return result;
});
}
const nextButtonHandler = useCallback(() => {
setCurrentSlide(prev => {
const result = prev+1;
if (result >= images.length) {
return 0;
}
return result;
});
}, [images.length]);
useEffect(() => {
if (progressRef.current) {
progressRef.current.style.transition = "none";
progressRef.current.style.width = "100%";
setTimeout(() => {
if (progressRef.current) {
progressRef.current.style.width = "0%";
progressRef.current.style.transition = `width ${slideShowDelay}s`;
}
}, 50);
}
}, [currentSlide, slideShowDelay]);
const slides = images.map((image, i) => {
const styles = {
transform: `translateX(${(i - currentSlide) * 100}%)`
}
return (<Fragment key={i}>
<div className="slide" style={styles}>
<img src={image} alt="random"/>
</div>
</Fragment>)
});
const mouseHandler = () => {
setAnimationState('paused');
}
const mouseHandlerLeave = () => {
setAnimationState('animate');
}
const transitionEndHandler = nextButtonHandler;
const classes = `progress-bar ${animationState}`;
const containerClasses = `slider-container ${animationState}`;
return (
<>
<div className="container">
<div className={containerClasses} onMouseEnter={mouseHandler} onMouseLeave={mouseHandlerLeave}>
{slides}
<button className="btn btn-prev" onClick={prevButtonHandler}> {"<"} </button>
<button className="btn btn-next" onClick={nextButtonHandler}> {">"} </button>
<div onTransitionEnd={transitionEndHandler} ref={progressRef} role={"progressbar"} className={classes} />
</div>
</div>
</>
)
}
What am I doing wrong here? Any help is appreciated.
from How can I make Animation Play State paused to work in React on hover
No comments:
Post a Comment