简单易用的缓动算法

返回顶部按钮执行的函数

    var backToTop = function (rate){
        var doc = document.body.scrollTop? document.body : document.documentElement;
        var scrollTop = doc.scrollTop;
        if(!window.requestAnimationFrame){
            requestAnimationFrame = function (fn){
                setTimeout(fn, 17);
            }
        }
        var step = function (){
            scrollTop = scrollTop + ( 0 - scrollTop ) / ( rate || 2 );
            if(scrollTop < 1) {
                doc.scrollTop = 0;
                return
            }
            doc.scrollTop = scrollTop;
            requestAnimationFrame(step);
        };
        step();
    };

进度条函数(使用封装后的缓动算法)

    /*
    {
        A: 初始值,
        B: 最终值,
        rate: 缓动速率,
        callback: 回调函数,用来对每一帧动画的进行监控(对目标元素的属性进行操作),执行动画。
    }
    */
    Math.easeout = function (A, B, rate, callback){
        let args = arguments;
        B = B || 0;
        rate = rate || 2;
        if( A == B || typeof A != 'number' ) {
            console.error(args[0] + ' and ' + args[1] + ' must be number');
        }

        //兼容性处理
        if(!window.requestAnimationFrame){
            requestAnimationFrame = function (fn){

                //1000 / 60 约等于 17,每秒60帧保证动画的顺畅。
                setTimeout(fn, 17);
            }
        }

        //每帧动画跑起来之前执行的函数
        const step = function (){
            A = A + ( B - A ) / rate;
            
            //结束条件, 在A > B的情况下,A小于1时结束;在 A < B的情况下,B - A 小于1时结束。
            if(Math.abs(A) < 1 || Math.abs(B - A) < 1) {
                callback(B, true);
                return;
            }
            callback(A, false);
            requestAnimationFrame(step);
        };
        step();
    };

    const _$ = function (query){
        return document.querySelector(query);
    };
    let leftDiv = _$('#moveLeft');
    const WIDTH = leftDiv.parentElement.clientWidth;
    _$('#width-all').addEventListener('click', function (){
        let me = this;

        //避免重复触发
        me.disabled = true;
        Math.easeout(0, WIDTH, 60, function (val, isEnding){
            leftDiv.style.width = val + 'px';
            leftDiv.textContent = parseInt(val / WIDTH * 100) + '%';
            if(isEnding) {
                alert('加载完成');
                me.disabled = false;
            }
        });
    });
<body> <a href="http://www.zhangxinxu.com/wordpress/2017/01/share-a-animation-algorithm-js/" class="source">参考:张鑫旭——即插即用缓动js算法</a> <div class="padding" style="line-height: 1;color: red;padding: 1rem 0;"> 点击下面的按钮查看效果 <p>ps: 在PC端下使用,貌似博客园在移动端下不支持button节点的点击事件</p> </div> <button class="backToTop" id="default-rate" onclick="backToTop(2);">点击我返回顶部</button> <button class="backToTop" onclick="backToTop(4);">backToTop(4)</button> <button class="backToTop" onclick="backToTop(10);">backToTop(10)</button> <button class="backToTop" onclick="backToTop(20);">backToTop(20)</button> <button id="width-all" >点我加载缓动进度条</button> <div id="moveLeft" style="width: 0px;height: 20px;background: lightblue;text-align:right;">0%</div> <script> var backToTop = function (rate){ var doc = document.body.scrollTop? document.body : document.documentElement; var scrollTop = doc.scrollTop; if(!window.requestAnimationFrame){ requestAnimationFrame = function (fn){ setTimeout(fn, 17); } } var step = function (){ scrollTop = scrollTop + ( 0 - scrollTop ) / ( rate || 2 ); if(scrollTop < 1) { doc.scrollTop = 0; return } doc.scrollTop = scrollTop; requestAnimationFrame(step); }; step(); }; /* { A: 初始值, B: 最终值, rate: 缓动速率, callback: 回调函数,用来对每一帧动画的进行监控(对目标元素的属性进行操作),执行动画。 } */ Math.easeout = function (A, B, rate, callback){ let args = arguments; B = B || 0; rate = rate || 2; if( A == B || typeof A != 'number' ) { console.error(args[0] + ' and ' + args[1] + ' must be string'); } if(!window.requestAnimationFrame){ requestAnimationFrame = function (fn){ setTimeout(fn, 17); } } const step = function (){ A = A + ( B - A ) / rate; if(Math.abs(A) < 1 || Math.abs(B - A) < 1) { callback(B, true); return; } callback(A, false); requestAnimationFrame(step); }; step(); };
const _$ = function (query){
    return document.querySelector(query);
};
let leftDiv = _$('#moveLeft');
const WIDTH = leftDiv.parentElement.clientWidth;
_$('#width-all').addEventListener('click', function (){
    var me = this;
    me.disabled = true;
    Math.easeout(0, WIDTH, 60, function (val, isEnding){
        leftDiv.style.width = val + 'px';
        leftDiv.textContent = (val / WIDTH * 100).toFixed(1) + '%';
        if(isEnding) {
            alert('加载完成');
            me.disabled = false;
        }
    });
});
</script>
</body>
posted @ 2017-02-10 14:25  君寻不惑  阅读(288)  评论(0编辑  收藏  举报