Как изменить слайды в слайдере на Swiper.js?

Здравствуйте! У меня есть слайдер с 10 слайдами, и я хочу прокрутить его полностью 3 раза для создания небольшой анимации. <br/> Что я уже пробовал? Я добавил для Swiper свойство loop и использовал setTimeout внутри useEffect для вызова slideTo(30) при загрузке страницы. Слайдер прокрутился, но только до 10-го слайда. Как мне решить эту проблему? <br/> <br/> Код на React: <br/> <pre><code class="javascript">const Roulette = () =&gt; {
	const swiperRef = useRef&lt;any&gt;(null)
	const [currentSlide, setCurrentSlide] = useState&lt;number | null&gt;(null)
    const times = 3

	useEffect(() =&gt; {
		if (swiperRef.current)
			setTimeout(() =&gt; {
				swiperRef.current.slideTo(30)
			}, 300)
	}, [swiperRef])

	const spinWheel = () =&gt; {
		if (swiperRef.current) {
			const totalSlides = swiperRef.current.slides.length
			const randomIndex = Math.floor(Math.random() * totalSlides)
			const spinTimes = times * totalSlides + randomIndex
			console.log(spinTimes, swiperRef.current.slideTo)

			// Вращаем колесо
			swiperRef.current.slideTo(spinTimes, 2000, 'ease-out')

			// Выводим индекс в console после вращения
			setTimeout(() =&gt; {
				setCurrentSlide(randomIndex)
				console.log('Выпавший слайд: ', randomIndex)
			}, 2000) // 2 секунды - это длина времени вращения
		}
	}

	return (
		&lt;div className='bg-red-200 relative'&gt;
			&lt;Swiper
				onSwiper={swiper =&gt; {
					swiperRef.current = swiper
				}}
				slidesPerView={1}
				loop={true}
				className='mySwiper'
			&gt;
				{[...Array(10)].map((_, index) =&gt; (
					&lt;SwiperSlide className='swiper-slide' key={index}&gt;
						Слайд {index + 1}
					&lt;/SwiperSlide&gt;
				))}
			&lt;/Swiper&gt;

			&lt;di
  • 28 ноября 2024 г. 18:33
Ответы на вопрос 2
Чтобы реализовать эффект вращения слайдера на Swiper.js, прокручивая его три полного оборота, вам необходимо скорректировать способ, которым вы вызываете `slideTo`. Чтобы слайдер прокрутился на три оборота, учтите, что вы должны передать число, которое является кратным количеству слайдов, умноженным на 3, плюс случайный индекс.

Вот исправленный вариант вашего кода:

```javascript
import React, { useEffect, useRef, useState } from 'react';
import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/swiper-bundle.css';

const Roulette = () => {
    const swiperRef = useRef(null);
    const [currentSlide, setCurrentSlide] = useState(null);
    const times = 3; // количество полных прокруток

    // Функция, которая будет выполняться по загрузке компонента
    useEffect(() => {
        if (swiperRef.current) {
            const totalSlides = swiperRef.current.slides.length;
            const randomIndex = Math.floor(Math.random() * totalSlides);
            const spinTimes = times * totalSlides + randomIndex;

            // Вращаем колесо
            swiperRef.current.slideTo(spinTimes, 2000, true); // используем "true" для анимации
            
            // Выводим индекс в console после вращения
            setTimeout(() => {
                setCurrentSlide(randomIndex);
                console.log('Выпавший слайд: ', randomIndex);
            }, 2000); // 2 секунды - это длина времени вращения
        }
    }, [swiperRef]);

    return (
        <div className='bg-red-200 relative'>
            <Swiper
                onSwiper={swiper => {
                    swiperRef.current = swiper;
                }}
                slidesPerView={1}
                loop={true}
                className='mySwiper'
            >
                {[...Array(10)].map((_, index) => (
                    <SwiperSlide className='swiper-slide' key={index}>
                        Слайд {index + 1}
                    </SwiperSlide>
                ))}
            </Swiper>
        </div>
    );
};

export default Roulette;
```

### Объяснение изменений:

1. **spinTimes**: Этот расчет теперь учитывает количество слайдов, и вы добавляете случайный индекс для обеспечения полного прокручивания слайдов.
   
2. **slideTo**: Вы вызываете его с проекцией на `spinTimes`, что позволяет слайдеру прокрутиться на нужное количество раз.

3. **Анимация**: Убедитесь, что параметр анимации установлен на `true` (или оставьте по умолчанию), чтобы анимация работала корректно.

При таком подходе слайдер будет вертеться на три полных круга и остановится на случайном слайде. Не забудьте удостовериться, что ваш Swiper настроен на работу с нужными стилями и компонентами.
Проблема в том, что Swiper с включённым loop воспринимает только фактические индексы слайдов, соответствующие количеству слайдов (в вашем случае — от 0 до 9). 
Даже если ты передаёшь индекс больше количества слайдов, Swiper всё равно будет ограничивать значение.

Чтобы реализовать вращение на 3 полных круга + случайный индекс, нужно учитывать поведение с loop, а также использовать slideToLoop, который корректно обрабатывает циклическую прокрутку

swiperRef.current.slideToLoop(randomIndex, 2000, 'ease-out');
setTimeout(() => {
    setCurrentSlide(randomIndex);
    console.log('Выпавший слайд: ', randomIndex);
}, 2000);


И useEffect лишний
потому что он пытался сразу перейти на индекс 30, который не существует

https://jsfiddle.net/fdot6gpe/
Похожие вопросы