Есть такая простая реализация карусели - в примере на реакте, но смысл не в этом.
В общем по кнопкам или по навигации переход сделать несложно, но я хочу добавить еще и autoplay.
Если я его просто добавляю как функцию следующего слайда с таймаутом, то автоплей работает, но если я при этом нажму на кнопку или навигацию, то у меня начинают работать новые экземпляры этой функции, и чем больше я нажимаю на кнопку тем больше таких экземпляров. Т.е. начинает скакать, мелькать, моргать.
Я так понимаю, что нажимая на кнопку надо сначала остановить автоплей, но как?
Код
import React, { useState } from 'react'
import { BsChevronCompactLeft, BsChevronCompactRight, BsDot } from 'react-icons/bs'
import Slide_1 from '../assets/slide1.jpg'
import Slide_2 from '../assets/slide2.jpg'
import Slide_3 from '../assets/slide3.jpg'
const slides = [
{
url: Slide_1
},
{
url: Slide_2
},
{
url: Slide_3
},
];
function Hero() {
const [currentIndex, setCurrentIndex] = useState(0);
const prevSlide = () => {
const isFirstSlide = currentIndex === 0;
const newIndex = isFirstSlide ? slides.length - 1 : currentIndex - 1;
setCurrentIndex(newIndex);
}
const nextSlide = () => {
const isLastSlide = currentIndex === slides.length - 1;
const newIndex = isLastSlide ? 0 : currentIndex + 1;
setCurrentIndex(newIndex);
}
const goToSlide = (slideIndex) => {
setCurrentIndex(slideIndex);
}
const autoPlay = () => {
setTimeout(function () {
nextSlide();
}, 3000);
}
autoPlay();
return (
<div className='w-full h-auto mx-auto my-8'>
{/* <div style={{backgroundImage: `url(${slides[currentIndex].url})`}} className='w-full h-full bg-center bg-cover border-gray-100 border-[10px] duration-500'></div>*/}
<div className='w-full max-w-[1280px] h-auto mx-auto duration-500 relative group'>
<img className='mx-auto border-gray-100 border-[10px]' src={slides[currentIndex].url} alt="" />
{/* left arrow */}
<div className='opacity-30 group-hover:opacity-100 absolute top-[50%] -translate-x-0 translaty-[-50%] left-5 text-2xl rounded-full p-2 bg-black/20 text-white cursor-pointer'>
<BsChevronCompactLeft onClick={prevSlide} size={30} />
</div>
{/* right arrow */}
<div className='opacity-30 group-hover:opacity-100 absolute top-[50%] -translate-x-0 translaty-[-50%] right-5 text-2xl rounded-full p-2 bg-black/20 text-white cursor-pointer'>
<BsChevronCompactRight onClick={nextSlide} size={30} />
</div>
</div>
<div className="flex top-4 justify-center py-2">
{slides.map((slide, slideIndex) => (
<div key={slideIndex} onClick={() => goToSlide(slideIndex)} className='text-2xl cursor-pointer'>
<BsDot />
</div>
))}
</div >
</div>
)
}
export default Hero