Javascript div匀速滚动

时间:2019-03-06 10:36:33

标签: javascript angular requestanimationframe

我有固定数量的div,需要水平无限滚动。

因此,当您滚动时,将在末尾创建一个新的子级,并在另一侧删除一个子级。像这样的东西: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 btw。

0 个答案:

没有答案