javascript简易缓动插件(源码打包)


Posted in Javascript onFebruary 16, 2012

要求如下:
可以开始、暂停(线性、非线性tween都支持)、继续、结束
支持多个样式并行
最好不依赖于某个框架下运行
文件尺寸越小越好
他找了一下现有的一些插件或者库,鲜有能满足或者比较均衡的,我在这个要求下,写了一个比较简陋的动画组件,基本满足了这个需求。先上代码
在线演示:http://demo.3water.com/js/2012/animate/
打包下载:animate_jquery.rar
html部分:

<!DOCTYPE html> 
<html> 
<head> 
<meta charset="utf-8" /> 
<title>animate</title> 
<script type="text/javascript" src="tangram-1.5.0.core.js"></script> 
<script type="text/javascript" src="jquery.min.js"></script> 
<style> 
html,body,ul,li{padding:0;margin:0;} 
#anim{width:50px;height:50px;background:red;position:absolute; top:30px;left:0;} 
</style> 
</head> 
<body> 
<div> 
<input type="button" value="start" onclick="an.start()" /> 
<input type="button" value="pause" onclick="an.pause()" /> 
<input type="button" value="resume" onclick="an.resume()" /> 
<input type="button" value="stop" onclick="an.stop()" /> 
<a target="_self" id="demolink" href="animate.html?demo=1" />auto start,pasue,then resume</a> 
</div> 
<div id="anim"></div> 
</body></html>

animate部分:
function animate(options){ 
this.from = options.from;//如果没有from,就计算出from 
this.to = options.to || {}; 
this.onStart = options.onStart || empty;//以下是一些回调函数,就不采用事件机制了 
this.onStop = options.onStop || empty; 
this.onAnimate = options.onAnimate || empty; 
this.onContinue = options.onContinue || empty; 
this.onPause = options.onPause || empty; 
var element = options.element; 
var duration = options.duration || 300;//变化的总时长,单位是ms 
var pending = false;//是不是已经暂停了,如果还木有开始的话,该值也是true 
var timer = null; 
var mixin = options.mix; 
var defaultState = this.from || getState(element, this.to);//原始的数据 
var thiz = this; 
//获取最初始的样式 
function getState(ele, targetStyles){ 
var obj = {}; 
var i = 0; 
for (var p in targetStyles) 
{ 
i++; 
obj[p] = parseFloat(mixin.getStyle(ele, p)); 
} 
if(i == 0){ 
return null; 
} 
return obj; 
} 
function empty(){} 
function animate(from, to, elapse){ 
var startTime = (new Date).getTime() + (elapse ? - elapse : 0);//如果有第三个参数,证明是从一个暂停开始的,那么就设置startTime为当前时间减去暂定时已经逝去的时间,如果只有两个参数,那么逝去时间就是0 
timer = setInterval(function(){ 
var endTime = (new Date).getTime(); 
if(endTime - startTime < duration){ 
thiz.onAnimate(); 
currentElapse = endTime - startTime; 
for(var p in from){ 
if(from.hasOwnProperty(p)){ 
var currentPropertyStyle = mixin.compute(currentElapse, from[p], to[p]-from[p], duration); 
mixin.setStyle(element, p, currentPropertyStyle); 
} 
} 
} 
else{ 
thiz.stop(thiz.to); 
} 
}, 16); 
} 
this.start = function(){ 
if(pending){ 
this.resume(); 
} 
else{ 
this.onStart(); 
animate(defaultState, this.to); 
} 
} 
this.stop = function(){ 
clearInterval(timer); 
var styles = this.to; 
for(var p in styles){ 
if(styles.hasOwnProperty(p)){ 
mixin.setStyle(element, p, styles[p]); 
} 
} 
this.onStop(); 
} 
this.pause = function(){ 
clearInterval(timer); 
pending = true; 
this.onPause(); 
} 
this.resume = function(){ 
pending = false; 
this.onContinue(); 
animate(defaultState, this.to, currentElapse); 
} 
}

使用部分:
var mixinT = { 
getStyle:baidu.dom.getStyle, 
setStyle:baidu.dom.setStyle, 
compute:function(t, b, c, d){ 
//return t*c/d + b; 
if (t==0) return b; 
if (t==d) return b+c; 
if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; 
return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; 
} 
}; 
var mixinJQ = { 
getStyle:function(ele, styleName){ 
return $(ele).css(styleName); 
}, 
setStyle:function(ele, styleName, styleValue){ 
$(ele).css(styleName, styleValue); 
}, 
compute:function(t, b, c, d){ 
return b+ t*c/d; 
} 
}; 
var an = new animate({ 
element:document.getElementById('anim'), 
//from:{'width':100, 'height':100, left:0, top:30}, 
to:{left:500}, 
mix:mixinT, 
duration:2000 
}); 
if(/demo=1/.test(location.search)){ 
var demolink = baidu.g('demolink'); 
demolink.href= 'animate.html'; 
demolink.innerHTML = 'back'; 
an.start(); 
setTimeout(function(){ 
an.pause(); 
resume(); 
}, 1200); 
function resume(){ 
setTimeout(function(){an.resume()}, 1000); 
} 
}

上面是一个完整demo的代码。做几点说明:
代码尺寸足够小了,一共才100行,gzip后连1k都不到。
满足了可以start、pause、resume、stop的需求,赠送了几个回调函数:D。
可以支持多个样式一起变化。
采用了一个mixin变量,传进来三个函数需要在执行动画时的操作,getStyle、setStyle、compute,我感觉这三个确实和用户的选择有关系,前两个可能和框架有关,第三个和用户采用的变化计算方式有关,之所以传进去四个参数,主要是和主流的tween类能适应起来,可以参考http://www.robertpenner.com/easing/和http://www.actionscript.org/resources/articles/170/1/Flash-MX-2004-Undocumented-TweenEasing-Classes-Documented/Page1.html。我给的例子用了tangram和jquery俩类库,分别对应了两个mixin对象,做一下简单的适配,就能用了。
一些“私有”变量和函数放闭包里了,这样初始化一个animate的时候,对象是干净的,但是缺点就是占用内存多了,每个实例都维护自己的方法。
使用的时候,可以不提供options.from,函数会根据额options.to来计算from中对应样式的值,这很大程度上依赖于mixin提供的方法够不够强大,所以这一块还是有bug 的,不过,80%的功能够用了。麻雀虽小,五脏俱全了。
Javascript 相关文章推荐
IE autocomplete internet explorer's autocomplete
Jun 30 Javascript
JavaScript中instanceof运算符的用法总结
Nov 19 Javascript
深入理解js中this的用法
May 28 Javascript
js获取对象、数组的实际长度,元素实际个数的实现代码
Jun 08 Javascript
详解angular2采用自定义指令(Directive)方式加载jquery插件
Feb 09 Javascript
js replace()去除代码中空格的实例
Feb 14 Javascript
详解angularJs模块ui-router之状态嵌套和视图嵌套
Apr 28 Javascript
JS实现获取汉字首字母拼音、全拼音及混拼音的方法
Nov 14 Javascript
Angular(5.2-&gt;6.1)升级小结
Dec 27 Javascript
Vue记住滚动条和实现下拉加载的完美方法
Jul 31 Javascript
Vue检测屏幕变化来改变不同的charts样式实例
Oct 26 Javascript
一篇文章告诉你如何实现Vue前端分页和后端分页
Feb 18 Vue.js
基于jquery的textarea发布框限制文字字数输入(添加中文识别)
Feb 16 #Javascript
js URL参数的拼接方法比较
Feb 15 #Javascript
javascript题目,重写函数让其无限相加
Feb 15 #Javascript
用JQUERY增删元素的代码
Feb 14 #Javascript
修改jQuery Validation里默认的验证方法
Feb 14 #Javascript
利用jquery的获取JS文件中的字符串内容
Feb 14 #Javascript
js 金额文本框实现代码
Feb 14 #Javascript
You might like
PHP4实际应用经验篇(4)
2006/10/09 PHP
php正则取img标记中任意属性(正则替换去掉或改变图片img标记中的任意属性)
2013/08/13 PHP
PHP生成可点击刷新的验证码简单示例
2016/05/13 PHP
浅谈Laravel模板实体转义带来的坑
2019/10/22 PHP
CL vs ForZe BO5 第一场 2.13
2021/03/10 DOTA
HTML中事件触发列表与解说
2007/07/09 Javascript
js更优雅的兼容
2010/08/12 Javascript
基于jquery的给文章加入关键字链接
2010/10/26 Javascript
js判断元素是否隐藏的方法
2014/06/09 Javascript
node.js中Socket.IO的进阶使用技巧
2014/11/04 Javascript
angular.js分页代码的实例
2016/07/27 Javascript
canvas绘制环形进度条
2017/02/23 Javascript
JS中利用localStorage防止页面动态添加数据刷新后数据丢失
2017/03/10 Javascript
jQuery+PHP+Mysql实现抽奖程序
2020/04/12 jQuery
vue.js项目中实用的小技巧汇总
2017/11/29 Javascript
vue.js编译时给生成的文件增加版本号
2018/09/17 Javascript
JavaScript实现简单计算器
2020/03/19 Javascript
小谈angular ng deploy的实现
2020/04/07 Javascript
微信小程序实现底部弹出框
2020/11/18 Javascript
Python中的上下文管理器和with语句的使用
2018/04/17 Python
python遍历文件夹找出文件夹后缀为py的文件方法
2018/10/21 Python
在unittest中使用 logging 模块记录测试数据的方法
2018/11/30 Python
Reebonz中国官网:新加坡奢侈品购物网站
2017/03/17 全球购物
Trunki英国官网:儿童坐骑式行李箱
2017/05/30 全球购物
世界各地的当地人的食物体验:Eatwith
2019/07/26 全球购物
Cocopanda波兰:购买化妆品、护肤品、护发和香水
2020/05/25 全球购物
大学生村官任职感言
2014/01/09 职场文书
深入开展党的群众路线教育实践活动方案
2014/02/04 职场文书
企业元宵节主持词
2014/03/25 职场文书
加入学生会演讲稿
2014/04/24 职场文书
大班上学期个人总结
2015/02/13 职场文书
公司禁烟通知
2015/04/23 职场文书
讲座通知范文
2015/04/23 职场文书
python必学知识之文件操作(建议收藏)
2021/05/30 Python
java项目构建Gradle的使用教程
2022/03/24 Java/Android
MyBatis核心源码深度剖析SQL语句执行过程
2022/05/20 Java/Android