• JS实现缓动动画效果


    原理如下:

    假设要从数值A变化到数值B,如果是线性运动,则每次移动距离是一样;如果是缓动,每次移动距离不一样。那如何才能不一样呢?很简单,按比例移动就可以。

    例如:每次移动剩余距离的一半。

    对吧,超容易理解的。

    比方说:你和初恋之间距离是64,每秒移动一半,则,你们之间的距离下一秒就是32, 再下一秒就是16,然后8,然后4,然后2,然后1,然后……你们就在一起了。你们在一起的这个过程就是一个典型的先快后慢的缓动运动过程,如下示意图:

    位置移动标注示意图

    用一个简单的公式表示就是:

    A = A + (B - A) / 2

    点击按钮执行的是下面的backToTop()方法:

    // 滚动到顶部缓动实现
    // rate表示缓动速率,默认是2
    var backToTop = function (rate) {
        var doc = document.body.scrollTop? document.body : document.documentElement;
        var scrollTop = doc.scrollTop;
        
        var top = function () {
            scrollTop = scrollTop + (0 - scrollTop) / (rate || 2);
            
            // 临界判断,终止动画
            if (scrollTop < 1) {
                doc.scrollTop = 0;
                return;
            }
            doc.scrollTop = scrollTop;
            // 动画gogogo!
            requestAnimationFrame(top);    
        };
        top();
    };

    其中,代码的核心是:

    scrollTop = scrollTop + (0 - scrollTop) / (rate || 2);

    scrollTop表示公式的A, 滚动到顶部滚动高度是0,因此,上面的0,实际上就是公式的B, 而公式中的2表示缓动速率,实际开发的时候是可以灵活调整的,缓动速率范围是1到无穷大,速率值越小,运动越快。比如说上面的返回顶部效果,我们把缓动速率改成4,点击下面的按钮感受效果:

    等比例靠近理论上最终只会无穷靠近,并不会真正的相等,也就是动画永远没有结束的时候,所以说需要做一个临界判断,也就是距离小到一定数目的时候,直接等于目标值,并终止动画。例如,上面的返回顶部,就是当距离顶部滚动高度小于1的时候,直接返回顶部,并终止动画。

    if (scrollTop < 1) {
        doc.scrollTop = 0;
        return;
    }


    如果项目很多地方使用该算法,每次都写一遍requestAnimationFrame和边界判断是很啰嗦的,于是,我们可以把算法变个身,例如下面这样:

    var _easeout = function(start, end, rate, callback) {
    var _end = end;
    if (start == end || typeof start != 'number') {
      return;
    }
      end = end || 0;
      rate = rate || 2;

    var step = function() {
      start = start + (end - start) / rate;
    if (Math.abs(start - _end) < 1) {


      console.log('end');
      callback(end, true);
      return;
    }
      callback(start, false);
      requestAnimationFrame(step);
    };
      step();
    };

    其中:

    • A是起始位置;
    • B是目标位置;
    • rate是缓动速率;
    • callback是变化的位置回调,支持两个参数,valueisEnding,表示当前的位置值(数值)以及是否动画结束了(布尔值);

    于是,我们的返回顶部效果可以这么使用:

    var doc = document.body.scrollTop !== undefined ? document.body : document.documentElement;
      console.log('start', doc.scrollTop);

    $("#back").click(function(){
      console.log('start', doc.scrollTop);
      _easeout(doc.scrollTop, 500, 2, function(value) {
        doc.scrollTop = value;
        });
      })

    });

  • 相关阅读:
    bzoj2045: 双亲数&bzoj1101: [POI2007]Zap
    spoj GCDEX
    jQuery Ajax
    jQuery 动画效果
    jQuery 事件处理API
    jQuery 常用getter&setter
    jQuery 文档操作
    jQuery 基础
    Vue2.2.0+新特性整理
    JavaScript中的HTTP
  • 原文地址:https://www.cnblogs.com/yzhihao/p/6479002.html
Copyright © 2020-2023  润新知