Javascript прокрутки div с постоянной скоростью - PullRequest
0 голосов
/ 06 марта 2019

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

Итак, когда вы прокручиваете, в конце создается новый дочерний элемент, а дочерний элемент удаляется с другой стороны. Как то так: http://jsfiddle.net/3neoap96/

Я нашел эту функцию анимации из другого ответа здесь, в SO, но проблема в том, что мне не нужно анимировать из точки A в точку BI, нужно анимировать с постоянной скоростью, и эта анимация никогда не заканчивается, она просто продолжается и продолжается .

Вот моя текущая функция. Все начинается нормально, но потом идет очень быстро.

document.addEventListener("DOMContentLoaded", function (event) {
    let lastPos = 0;

    document.getElementById('scroll').addEventListener('scroll', evt => {
        if (lastPos && lastPos - evt.target.scrollLeft > 0) {
            document.querySelectorAll('.element').reverse().forEach(elem => {
                if (isRightOfContainer(elem)) {
                    const width = elem.getBoundingClientRect().width;
                    elem.parentNode.prepend(elem)
                    elem.parentNode.parentNode.scrollLeft += width;
                }
            });
        } else if (lastPos && lastPos - evt.target.scrollLeft < 0) {
            document.querySelectorAll('.element').forEach(elem => {
                if (isLeftOfContainer(elem)) {
                    const width = elem.getBoundingClientRect().width;
                    elem.parentNode.append(elem)
                    elem.parentNode.parentNode.scrollLeft -= width;
                }
            });
        }

        lastPos = evt.target.scrollLeft;
    });

    const isLeftOfContainer = element => {
        const bounds = element.getBoundingClientRect();
        return (-bounds.left + element.parentNode.offsetLeft) >= bounds.width;
    };

    const isRightOfContainer = element => {
        const bounds = element.getBoundingClientRect();
        const box = element.parentNode.parentNode.getBoundingClientRect();
        return bounds.left - element.parentNode.offsetLeft > box.width;
    };

    function scrollToX(scrollTargetX, speed, easing) {
        // scrollTargetY: the target scrollY property of the window
        // speed: time in pixels per second
        // easing: easing equation to use

        const scroll = document.getElementById('scroll');

        const scrollX = scroll.scrollX || scroll.scrollLeft
        scrollTargetX = scrollTargetX || 0,
            speed = speed || 2000,
            easing = easing || 'easeOutSine';
        let currentTime = 0;

        // min time .1, max time .8 seconds
        const time = Math.max(.1, Math.min(Math.abs(scrollX - scrollTargetX) / speed, .8));

        // easing equations from https://github.com/danro/easing-js/blob/master/easing.js
        const easingEquations = {
            easeOutSine: (pos) => {
                return Math.sin(pos * (Math.PI / 2));
            },
            easeInOutSine: (pos) => {
                return (-0.5 * (Math.cos(Math.PI * pos) - 1));
            },
            easeInOutQuint: (pos) => {
                if ((pos /= 0.5) < 1) {
                    return 0.5 * Math.pow(pos, 5);
                }
                return 0.5 * (Math.pow((pos - 2), 5) + 2);
            }
        };

        // add animation loop
        function tick() {
            currentTime += 1 / 60;

            const p = currentTime / time;
            const t = easingEquations[easing](p);

            if (p < 1) {
                requestAnimationFrame(tick);

                scroll.scrollTo(scrollX + ((scrollTargetX - scrollX) * t), 0);
            } else {
                console.log('scroll done');
                scroll.scrollTo(scrollTargetX, 0);
            }
        }

        // call it once to get started
        tick();
    }

    scrollToX(1500, 0, 'easeInOutQuint');
})

Я использую Angular 6, кстати.

...