при достижении последнего слайда изменять translateX в положительную сторону

Создаю слайдер, с автоплеем, который при достижении определенного условия будет идти в обратную сторону.

Проблема заключается в том что когда он доходит до определенной границы, он начинает дергаться на этой границе, прибавлять один пиксель и сразу же убавлять.

  // ---------------sliider----------------------

    const prev = document.querySelector('.slider__btn_prev'),
        next = document.querySelector('.slider__btn_next'),
        slider = document.querySelector('.slider_top'),
        slidesWrapper = document.querySelector('.slider__wrapper'),
        slidesField = document.querySelector('.slider__field');
    let width = 0;
        




    // slidesField.style.width = 100 * slides.length + '%';



    slidesWrapper.style.overflow = 'hidden';


    slider.style.position = 'relative';




    function moveSliderRight() {

        if (width > -100 ) {
            width -= 1;
            slidesField.style.transform = `translateX(${width}px)`;

        } else {
            width += 1;
            slidesField.style.transform = `translateX(${width}px)`;
        }
        //console.log(width);
            

    }





    let sliderInterval = setInterval(moveSliderRight, 40);


    slider.addEventListener('mouseenter', () => {
        clearInterval(sliderInterval);
        slidesField.style.transition = 'all 0.5s ease 0s';
    });
    slider.addEventListener('mouseleave', () => {
        sliderInterval = setInterval(moveSliderRight, 40);
        slidesField.style.transition = 'all 0.1s ease 0s';
    });


    next.addEventListener('click', () => {

        width -= 400;
        slidesField.style.transform = `translateX(${width}px)`;
        

    });

    prev.addEventListener('click', () => {

        width += 400;
        slidesField.style.transform = `translateX(${width + 400}px)`;
        
    });
.slider_top {
            position: relative;
        }

        .slider__wrapper {
            width: 100%;
         overflow: hidden;

        }

        .slider__field {
          display: flex;
            list-style-type: none;
            transition: all 0.1s ease 0s;
            gap: 20px;
        }

        .slider__slide {
            height: 400px;
            
            
        }
    
    img {
                height: 100%;
                
            }
<section class="sliders">
        <div class="slider_top">
            <div class="slider__wrapper">
                <ul class="slider__field">
                    <li class="slider__slide">
                        <a data-fslightbox="gallery" href="https://i.imgur.com/fsyrScY.jpg">
                            <img src="https://i.imgur.com/fsyrScY.jpg" alt="">
                        </a>
                    </li>
                    <li class="slider__slide">
                        <a data-fslightbox="gallery" href="https://i.imgur.com/fsyrScY.jpg">
                            <img src="https://i.imgur.com/fsyrScY.jpg" alt="">
                        </a>
                    </li>
                    <li class="slider__slide">
                        <a data-fslightbox="gallery" href="https://i.imgur.com/fsyrScY.jpg">
                            <img src="https://i.imgur.com/fsyrScY.jpg" alt="">
                        </a>
                    </li>
                    <li class="slider__slide">
                        <a data-fslightbox="gallery" href="https://i.imgur.com/fsyrScY.jpg">
                            <img src="https://i.imgur.com/fsyrScY.jpg" alt="">
                        </a>
                    </li>
                    <li class="slider__slide">
                        <a data-fslightbox="gallery" href="https://i.imgur.com/fsyrScY.jpg">
                            <img src="https://i.imgur.com/fsyrScY.jpg" alt="">
                        </a>
                    </li>
                </ul>
            </div>
            <div class="slider__btns">
                <button class="slider__btn slider__btn_prev">left</button>
                <button class="slider__btn slider__btn_next">right</button>
            </div>
        </div>
    </section>


Ответы (1 шт):

Автор решения: Павел Рыбакин

SetTimeout - плохое решение. Анимация из-за него становится рваной и это влияет на производительность.

Я переписал код и заменил SetTimeout на requestAnimationFrame:

window.addEventListener('DOMContentLoaded', () => {

    // ---------------sliider----------------------

    const prev = document.querySelector('.slider__btn_prev'),
        next = document.querySelector('.slider__btn_next'),
        slider = document.querySelector('.slider_top'),
        slidesWrapper = document.querySelector('.slider__wrapper'),
        slidesField = document.querySelector('.slider__field'),
        slides = document.querySelectorAll('.slider__slide');

    let width = 0,
        widthRace = 0;


    //получаем ширину дорожки слайдера  
    function getWidthRace() {
        slides.forEach(slide => {
            const widthItem = slide.clientWidth;
            widthRace -= widthItem;
        });

        widthRace += slidesWrapper.clientWidth;
    }

    getWidthRace();




    slidesWrapper.style.overflow = 'hidden';


    slider.style.position = 'relative';

    //запускаем движение слайдера влево
    function moveLeft() {
        width += 1;
        slidesField.style.transform = `translateX(${width}px)`;

        if (width < 0) {
            requestAnimationFrame(moveLeft);
        } else {
            moveSlider();
        }
    }
    //запускаем движение слайдера вправо
    function moveRight() {

        width -= 1;
        slidesField.style.transform = `translateX(${width}px)`;

        if (width > widthRace) {
            requestAnimationFrame(moveRight);
        } else {
            moveSlider();
        }
    }

    function moveSlider() {
        if (width > widthRace) {

            moveRight();

        } else if (width < 0) {

            moveLeft();
        }
    }

    moveSlider();


    next.addEventListener('click', () => {

        width += widthRace / 2;
        slidesField.style.transform = `translateX(${width}px)`;


    });

    prev.addEventListener('click', () => {
        width += -widthRace / 2;
        slidesField.style.transform = `translateX(${width}px)`;

    });
    
});
.slider_top {
    position: relative;
}

.slider__wrapper {
    width: 100%;
 overflow: hidden;

}

.slider__field {
  display: flex;
    list-style-type: none;
    transition: all 0.5s ease 0s;
    padding: 0;
    
}

.slider__slide {
    height: 400px;
    padding-right: 20px;
    
}

.slider__slide:last-child {
    padding-right: 0;
}

img {
        height: 100%;
        
    }
<section class="sliders">
        <div class="slider_top">
            <div class="slider__wrapper">
                <ul class="slider__field">
                    <li class="slider__slide">
                        <img src="https://mirpozitiva.ru/wp-content/uploads/2019/11/1472042492_01.jpg" alt="">
                    </li>
                    <li class="slider__slide">
                        <img src="https://mirpozitiva.ru/wp-content/uploads/2019/11/1472042585_06.jpg" alt="">
                    </li>
                    <li class="slider__slide">
                        <img src="https://mirpozitiva.ru/wp-content/uploads/2019/11/1472042485_04.jpg" alt="">
                    </li>
                    <li class="slider__slide">
                        <img src="https://mirpozitiva.ru/wp-content/uploads/2019/11/1472042660_10.jpg" alt="">
                    </li>
                    
                </ul>
            </div>
            <div class="slider__btns">
                <button class="slider__btn slider__btn_prev">left</button>
                <button class="slider__btn slider__btn_next">right</button>
            </div>
        </div>
    </section>

→ Ссылка