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 相关文章推荐
用javascript实现改变TEXTAREA滚动条和按钮的颜色,以及怎样让滚动条变得扁平
Apr 20 Javascript
JavaScript中操作字符串小结
May 04 Javascript
利用Javascript实现BMI计算器
Aug 16 Javascript
微信公众号-获取用户信息(网页授权获取)实现步骤
Oct 21 Javascript
Vuex之理解Store的用法
Apr 19 Javascript
AngulaJS路由 ui-router 传参实例
Apr 28 Javascript
Vue中建立全局引用或者全局命令的方法
Aug 21 Javascript
JS实现分页浏览横向图片(类轮播)实例代码
Nov 06 Javascript
Fundebug支持监控微信小程序HTTP请求错误的方法
Feb 21 Javascript
小程序多图列表实现性能优化的方法步骤
May 28 Javascript
Vue组件实现触底判断
Jun 26 Javascript
使用 Angular RouteReuseStrategy 缓存(路由)组件的实例代码
Nov 01 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
PHP中在数据库中保存Checkbox数据(2)
2006/10/09 PHP
php学习之 认清变量的作用范围
2010/01/26 PHP
ThinkPHP模板之变量输出、自定义函数与判断语句用法
2014/11/01 PHP
深入浅出php socket编程
2015/05/13 PHP
php使用curl实现简单模拟提交表单功能
2017/05/15 PHP
JavaScript使用过程中需要注意的地方和一些基本语法
2010/08/26 Javascript
javascript使用百度地图api和html5特性获取浏览器位置
2014/01/10 Javascript
封装好的javascript前端分页插件pagination
2016/01/04 Javascript
浏览器检测JS代码(兼容目前各大主流浏览器)
2016/02/21 Javascript
AngularJS 路由和模板实例及路由地址简化方法(必看)
2016/06/24 Javascript
HTML5 JS压缩图片并获取图片BASE64编码上传
2020/11/16 Javascript
jQuery实现jQuery-form.js实现异步上传文件
2017/04/28 jQuery
基于vue2.0实现的级联选择器
2017/06/09 Javascript
浅谈基于Vue.js的移动组件库cube-ui
2017/12/20 Javascript
javascript少儿编程关于返回值的函数内容
2018/05/27 Javascript
解决vue this.$forceUpdate() 处理页面刷新问题(v-for循环值刷新等)
2018/07/26 Javascript
如何利用node.js开发一个生成逐帧动画的小工具
2019/12/01 Javascript
[03:23]我的刀塔你不可能这么可爱 第一期金萌萌的故事
2014/06/20 DOTA
python通过floor函数舍弃小数位的方法
2015/03/17 Python
python爬虫入门教程--HTML文本的解析库BeautifulSoup(四)
2017/05/25 Python
python2.6.6如何升级到python2.7.14
2018/04/08 Python
python实现定时提取实时日志程序
2018/06/22 Python
利用pandas进行大文件计数处理的方法
2018/07/25 Python
解决python cv2.imread 读取中文路径的图片返回为None的问题
2020/06/02 Python
Python Spyder 调出缩进对齐线的操作
2021/02/26 Python
美国最古老的精致书写工具制造商:A.T. Cross(高仕)
2018/01/30 全球购物
乌克兰时尚鞋子和衣服购物网站:Born2be
2018/05/24 全球购物
请用用Java代码写一个堆栈
2012/01/26 面试题
信息技术专业大学生个人的自我评价
2013/10/05 职场文书
学院领导推荐信
2013/10/30 职场文书
护理专业毕业生自荐信范文
2014/01/05 职场文书
乡镇干部十八大感言
2014/02/17 职场文书
教师自我剖析材料(四风问题)
2014/09/30 职场文书
2015年公共机构节能宣传周活动总结
2015/03/26 职场文书
特此通知格式
2015/04/27 职场文书
六年级作文之关于梦
2019/10/22 职场文书