原理如下:

假设要从数值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,点击下面的按钮感受效果:

点击我执行backToTop(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;
    });
  })

});

JS实现缓动动画效果的更多相关文章

  1. js off 缓动动画

    动画也有很多种,一起来学习,缓动动画吧 缓动动画 1.缓动动画原理=盒子位置+(目标盒子位置-现在盒子位置)/10 2.步长越来越小 3.让步长越来越小的公式      步长=(目标位置-本身位置)/ ...

  2. js简单动画:匀速动画、缓动动画、多物体动画以及透明度动画

    主要实现以下几种简单的动画效果(其实原理基本相同): 1.匀速动画:物体的速度固定 2.缓动动画:物体速度逐渐变慢 3.多物体动画 4.透明度动画 效果实现: 1.匀速动画(以物体左右匀速运动为例) ...

  3. JS基础知识——缓动动画

    基于距离的缓动动画 原理:设定起始位置  start 和终止位置 end,变化会越来越慢. 公式:start=start+(end-start)/10;     这个10不是固定的,想分成多少份就分成 ...

  4. jQuery-1.9.1源码分析系列(十五) 动画处理——缓动动画核心Tween

    在jQuery内部函数Animation中调用到了createTweens()来创建缓动动画组,创建完成后的结果为: 可以看到上面的缓动动画组有四个原子动画组成.每一个原子动画的信息都包含在里面了. ...

  5. 背水一战 Windows 10 (15) - 动画: 缓动动画

    [源码下载] 背水一战 Windows 10 (15) - 动画: 缓动动画 作者:webabcd 介绍背水一战 Windows 10 之 动画 缓动动画 - easing 示例演示缓动(easing ...

  6. WPF界面设计技巧(7)—模拟电梯升降的缓动动画

    原文:WPF界面设计技巧(7)-模拟电梯升降的缓动动画 如同Flash一样,WPF的亮点之一也在于其擅于表现平滑的动画效果,但以移动动画来说,仅凭简单的起始位置.目标位置,所产生的动画仍会非常生硬,这 ...

  7. Windows Phone开发(42):缓动动画

    原文:Windows Phone开发(42):缓动动画 前面在讨论关键帧动画的时候,我有意把几个带缓动动画的关键帧动画忽略掉,如EasingColorKeyFrame.EasingDoubleKeyF ...

  8. 重新想象 Windows 8 Store Apps (19) - 动画: 线性动画, 关键帧动画, 缓动动画

    原文:重新想象 Windows 8 Store Apps (19) - 动画: 线性动画, 关键帧动画, 缓动动画 [源码下载] 重新想象 Windows 8 Store Apps (19) - 动画 ...

  9. JS-特效 ~ 04. client对象、网页可视区域的宽高、client / offset / scroll 三大家族的区别、冒泡事件、事件委托、获取内嵌式和外链式属性getStyle(ele,attr) ;、缓动动画封装

    知识点: 模拟滚动条的解除事件问题 : event内置对象,包含 了大量事件: page兼容性: pageX || clientX + scool().top  : if (true === a)tr ...

随机推荐

  1. tail -f -n 0 /var/log/messages

    <pre><font color="#CC0000"><b>root@kali</b></font>:<font ...

  2. git教程笔记(二)

    1.首先进入自己的项目文件 在GitHub上申请一个自己的账户信息.创建一个Repository.然后复制仓库的地址在gitbush中进行clone gitbush中进行远程clone 2.gitbu ...

  3. poj1185 状态压缩经典题

    状态压缩的好题,直接求会爆内存,先把所有可能的状态求出来存在stk里,然后f[i][k][t]表示i行状态为t,i-1状态为k,由i-1状态来推出i状态即可 注意要打好边际条件的状态,并且某个可行状态 ...

  4. centos--git搭建之Gogs安装

    1.下载git yum intall -y git 2. 创建git用户(必须新创建git用户, 用root用户会导致无法下载) #创建git用户 sudo adduser git #给git用户设置 ...

  5. SCSS 使用@each 方法循环遍历数组颜色并给li赋值

    $list-bg:red,orange,blue,skyblue; ul{ >li{ height: 30px; @each $c in $list-bg{ $i:index($list-bg, ...

  6. js FileReader 笔记

    以上传图片为例 通过input type='file' 上传完成图片后,获取图片 $('#input').files[0] var reader = new FileReader();    read ...

  7. azkaban安装使用

    本文记录azkaban的安装和 一些报错处理(文章末尾). AzKaban组成 MySQL数据库,azkaban-server (web端),azkaban-executor (执行job) 1.下载 ...

  8. logging模板日志格式

    logging模板日志格式 创建loginfo.py模块,然后导入定义的logging配置,即可使用 cat loginfo.py """ logging配置 " ...

  9. Linux环境安装Eclipse工具开发

    1.官网下载maven:https://maven.apache.org/download.cgi 2.上传到虚拟机进行解压缩操作: [hadoop@slaver1 package]$ tar -zx ...

  10. Atcoder ARC101 Ribbons on Tree

    题解: 前面牛客网的那个比赛也有一道容斥+dp 两道感觉都挺不错的 比较容易想到的是 f[i][j]表示枚举到了i点,子树中有j个未匹配 这样的话我们需要枚举儿子中匹配状态 这样是n^2的(这是个经典 ...