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 相关文章推荐
基于Jquery的温度计动画效果
Jun 18 Javascript
JavaScript制作的可折叠弹出式菜单示例
Apr 04 Javascript
三种带箭头提示框总结实例
Jun 14 Javascript
客户端验证用户名和密码的方法详解
Jun 16 Javascript
BootStrap学习系列之布局组件(下拉,按钮组[toolbar],上拉)
Jan 03 Javascript
js实现手机拍照上传功能
Jan 17 Javascript
Angularjs修改密码的实例代码
May 26 Javascript
JavaScript刷新页面的几种方法总结
Mar 28 Javascript
vue项目中mock.js的使用及基本用法
May 22 Javascript
vue拖拽组件 vuedraggable API options实现盒子之间相互拖拽排序
Jul 08 Javascript
解决vue加scoped后就无法修改vant的UI组件的样式问题
Sep 07 Javascript
Vue axios获取token临时令牌封装案例
Sep 11 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
一个oracle+PHP的查询的例子
2006/10/09 PHP
PHP Document 代码注释规范
2009/04/13 PHP
PHP中的常见魔术方法功能作用及用法实例
2015/07/01 PHP
让你的PHP7更快之Hugepage用法分析
2016/05/31 PHP
PHP使用finfo_file()函数检测上传图片类型的实现方法
2017/04/18 PHP
PHP文件上传小程序 适合初学者学习!
2019/05/23 PHP
WordPress免插件实现面包屑导航的示例代码
2020/08/20 PHP
jQuery.extend()的实现方式详解及实例
2013/06/29 Javascript
JS正则验证邮箱的格式详细介绍
2013/11/19 Javascript
深入剖析JavaScript中的函数currying柯里化
2016/04/29 Javascript
如何使用AngularJs打造权限管理系统【简易型】
2016/05/09 Javascript
Three.js学习之几何形状
2016/08/01 Javascript
Javascript6中字符串的四个新用法分享
2016/09/11 Javascript
基于slideout.js实现移动端侧边栏滑动特效
2016/11/28 Javascript
关于微信上网页图片点击全屏放大效果
2016/12/19 Javascript
vue-resource 拦截器使用详解
2017/02/21 Javascript
浅谈AngularJS中使用$resource(已更新)
2017/09/14 Javascript
ES6学习教程之对象字面量详解
2017/10/09 Javascript
nodejs中实现修改用户路由功能
2019/05/24 NodeJs
Javascript 关于基本类型和引用类型的个人理解
2019/11/01 Javascript
[05:17]DOTA2睡衣妹卖萌求签名 CJ第二天全明星影像
2013/07/28 DOTA
[01:34]DAC2018主赛事第四日五佳镜头 Gh巨牙海民助Miracle-死里逃生
2018/04/07 DOTA
Python的time模块中的常用方法整理
2015/06/18 Python
python实现Floyd算法
2018/01/03 Python
Python如何定义有默认参数的函数
2020/08/10 Python
Python包资源下载路径报404解决方案
2020/11/05 Python
Qoo10台湾站:亚洲领先的在线市场
2018/05/15 全球购物
Tahari ASL官方网站:高级设计师女装
2021/03/15 全球购物
优秀大学生的自我评价
2014/01/16 职场文书
土木工程专业推荐信
2014/02/19 职场文书
2014年公司迎新年活动方案
2014/02/24 职场文书
学校教师安全责任书
2014/07/23 职场文书
公司文体活动总结
2015/05/07 职场文书
2015年城管执法工作总结
2015/07/23 职场文书
Go 通过结构struct实现接口interface的问题
2021/10/05 Golang
Ubuntu安装Mysql+启用远程连接的完整过程
2022/06/21 Servers