向上滚动跑马灯效果 jquery插件
2022/08/08    
        (function ($) {
        $.fn.extend({
            animateScroll: function (speed) {
                let linear = function (t, b, c, d) { return Math.floor(c * t / d + b); }
                typeof (speed) == 'undefined' && (speed = 26);
                let that = this;
                let AnimateId = '';
                if (typeof ($(this).attr('animationId')) == 'undefined') {
                    AnimateId = 'ANIMATION' + '_' + Math.random().toString().substr(2);
                    $(this).attr('animationId', AnimateId);
                    $(this).children().wrapAll('<div></div>');
                    $(this).append($(this).children().clone(true));
                    $(this).children().wrapAll('<div style="-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);"></div>');
                } else {
                    AnimateId = $(this).attr('animationId');
                }
                if (typeof (window[AnimateId]) == 'undefined') {
                    window[AnimateId] = '';
                }
                clearTimeout(window[AnimateId]);
                let begin = new Date();
                let translateY = $(this).children().children().eq(0).height();
                let duration = 1000 * (translateY / speed);
                let $AnimationDom = $(that).children();
                $AnimationDom.off('mouseenter.animation');
                $AnimationDom.off('mouseleave.animation');
                $AnimationDom.on('mouseenter.animation', function () {
                    clearTimeout(window[AnimateId]);
                });
                $AnimationDom.on('mouseleave.animation', function () {
                    begin = new Date() - (-parseInt($AnimationDom.css('transform').match(/([-]\d+)|(\d+)/g)[5])) / translateY * duration;
                    let animationFun = function () {
                        let newDate = new Date();
                        if (newDate - begin > duration) {
                            begin = newDate.getTime();
                            $AnimationDom.css('transform', 'translate3d(0 0 0)');
                        }
                        //console.log('translate3d(0, ' + (-linear(new Date() - begin, 0, translateY, duration)) + 'px, 0)');
                        $AnimationDom.css('transform', 'translate3d(0, ' + (-linear(newDate - begin, 0, translateY, duration)) + 'px, 0)');
                        window[AnimateId] = setTimeout(function () { animationFun() },1);
                    }
                    animationFun();
                })
                $AnimationDom.trigger('mouseenter');
                $AnimationDom.trigger('mouseleave');
            }
        })
    })(jQuery)

使用

$("body").animateScroll(26);

不用 requestAnimationFrame,因为requestAnimationFrame大概16ms执行一次,但不稳定,而且还有程序运行的时间。setTimeout和setInterval在新版的chrome已经优化的很好了。执行时间间隔6ms以内