jQuery的animate函数学习记录


Posted in Javascript onAugust 08, 2014

很久之前就对jQuery animate的实现非常感兴趣,不过前段时间很忙,直到前几天端午假期才有时间去研究。

jQuery.animate的每种动画过渡效果都是通过easing函数实现的。jQuery1.4.2中就预置了两个这样的函数:

easing: {
linear: function( p, n, firstNum, diff ) {
return firstNum + diff * p;
},
swing: function( p, n, firstNum, diff ) {
return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
}
}

从参数名隐约可以推测出firstNum是初始值。要是你的数学学得比较好,你可以发现linear函数是直线方程;要是你的物理学得比较好,你可以发现它是匀速运动的位移方程(我数学和物理都没学好,是别人提醒我的……)。那么diff和p就是速度和时间了。

再看看jQuery.animate的原型:

animate: function( prop, speed, easing, callback )

各参数的说明如下:

prop:一组包含作为动画属性和终值的样式属性和及其值的集合。
speed:动画时长。
easing:要使用的擦除效果的名称。
callback:动画完成时执行的函数。

元素的当前样式值(firstNum)可以获取,动画时长(p)就是duration,最终样式值是prop。理论上说,动画速度(diff)是可以算出来的。但是这又必然需要另一个函数进行运算。这样做明显是不明智的。再看看调用easing函数的相关代码(位于jQuery.fx.prototype.step中):

var t = now();
...
var n = t - this.startTime;
this.state = n / this.options.duration;
...
this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);

可以发现,p参数的值也就是this.state的值,从上下文得知它实际上是动画的时间进度。而firstNum和diff的参数值都是写死的,分别是0和1。这下easing函数的秘密完全被解开,p、firstNum、diff都是百分率而非实际数值,easing函数的返回值也就是位移的进度。diff的值是1,也就是以1倍的速度运行动画。算出位移进度后,通过“初始值+(最终值-初始值)×进度”就可以算出当前位移值:

this.now = this.start + ((this.end - this.start) * this.pos);

通过setInterval每隔一定时间(jQuery中是13ms)进行一次位移运算,直到当前时间与初始时间的差值大于动画时长,这就是jQuery.animate的执行过程。

按照常规思路,动画的实现方式是这样的:通过setInterval每隔一定时间给某个值增加特定数值,直到这个值达到限制值。这样做的主要问题是,不同浏览器的运行速度不同,从而导致动画速度有差异,一般是IE下比较慢,Firefox下比较快。而jQuery.animate是以当前时间来决定位移值,某个时刻的位移值总是固定的,因而动画速度不会有差异。

Javascript 相关文章推荐
最简单的js图片切换效果实现代码
Sep 24 Javascript
js倒计时小程序
Nov 05 Javascript
JavaScript中的变量作用域介绍
Dec 31 Javascript
JS实现点击按钮自动增加一个单元格的方法
Mar 09 Javascript
jQuery实现的向下图文信息滚动效果
May 03 Javascript
JS区分浏览器页面是刷新还是关闭
Apr 17 Javascript
第二篇Bootstrap起步
Jun 21 Javascript
详解AngularJS中ng-src指令的使用
Sep 07 Javascript
如何使用CSS3和JQuery easing 插件制作绚丽菜单
Jun 18 jQuery
vue集成chart.js的实现方法
Aug 20 Javascript
详细分析Node.js 多进程
Jun 22 Javascript
JavaScript 闭包的使用场景
Sep 17 Javascript
jQuery中get和post方法传值测试及注意事项
Aug 08 #Javascript
JSON.stringify转换JSON时日期时间不准确的解决方法
Aug 08 #Javascript
js事件监听机制(事件捕获)总结
Aug 08 #Javascript
使用jquery.qrcode生成彩色二维码实例
Aug 08 #Javascript
兼容最新firefox、chrome和IE的javascript图片预览实现代码
Aug 08 #Javascript
js调试工具console.log()方法查看js代码的执行情况
Aug 08 #Javascript
JS创建类和对象的两种不同方式
Aug 08 #Javascript
You might like
如何开发一个虚拟域名系统
2006/10/09 PHP
基于php缓存的详解
2013/05/15 PHP
解决更换PHP5.4以上版本后Dedecms后台登录空白问题的方法
2015/10/23 PHP
PHP命名空间namespace的定义方法详解
2017/03/29 PHP
PHP读取并输出XML文件数据的简单实现方法
2017/12/22 PHP
基于 Swoole 的微信扫码登录功能实现代码
2018/01/15 PHP
js实现多选项切换导航菜单的方法
2015/02/06 Javascript
JavaScript中的函数模式详解
2015/02/11 Javascript
js实现透明度渐变效果的方法
2015/04/10 Javascript
ES6(ECMAScript 6)新特性之模板字符串用法分析
2017/04/01 Javascript
vue生成token保存在客户端localStorage中的方法
2017/10/25 Javascript
Node使用Sequlize连接Mysql报错:Access denied for user ‘xxx’@‘localhost’
2018/01/03 Javascript
使用typescript构建Vue应用的实现
2019/08/26 Javascript
layui在form表单页面通过Validform加入简单验证的方法
2019/09/06 Javascript
jQuery 动态粒子效果示例代码
2020/07/07 jQuery
Element InfiniteScroll无限滚动的具体使用方法
2020/07/27 Javascript
解决antd日期选择组件,添加value就无法点击下一年和下一月问题
2020/10/29 Javascript
微信小程序实现滚动Tab选项卡
2020/11/16 Javascript
Python中pygal绘制雷达图代码分享
2017/12/07 Python
python编程测试电脑开启最大线程数实例代码
2018/02/09 Python
python 编写简单网页服务器的实例
2018/06/01 Python
Python连接Redis的基本配置方法
2018/09/13 Python
Python及Pycharm安装方法图文教程
2019/08/05 Python
tesserocr与pytesseract模块的使用方法解析
2019/08/30 Python
基于python调用psutil模块过程解析
2019/12/20 Python
TensorFlow实现从txt文件读取数据
2020/02/05 Python
Scrapy 配置动态代理IP的实现
2020/09/28 Python
python利用tkinter实现图片格式转换的示例
2020/09/28 Python
搞笑车尾标语
2014/06/23 职场文书
助学感谢信范文
2015/01/21 职场文书
2014年度个人工作总结范文
2015/03/09 职场文书
看上去很美观后感
2015/06/10 职场文书
2016年度优秀辅导员事迹材料
2016/02/26 职场文书
分析JVM源码之Thread.interrupt系统级别线程打断
2021/06/29 Java/Android
如何利用React实现图片识别App
2022/02/18 Javascript
java开发双人五子棋游戏
2022/05/06 Java/Android