JavaScript Tween算法及缓动效果

Flash做动画时会用到Tween类,利用它可以做很多动画效果,例如缓动、弹簧等等。
我这里要教大家的是怎么利用flash的Tween类的算法,来做js的Tween算法,并利用它做一些简单的缓动效果。

实例效果


Tween类型:

ease类型:


效果说明

首先大家到这里下载flash的as脚本(建议看看这里的demo),1.0和2.0都可以(里面的算法都一样)。
例如打开2.0的可以看到几个as文件,每个文件对应一个Tween效果,分别有(参考里面的说明):
Linear:无缓动效果;
Quadratic:二次方的缓动(t^2);
Cubic:三次方的缓动(t^3);
Quartic:四次方的缓动(t^4);
Quintic:五次方的缓动(t^5);
Sinusoidal:正弦曲线的缓动(sin(t));
Exponential:指数曲线的缓动(2^t);
Circular:圆形曲线的缓动(sqrt(1-t^2));
Elastic:指数衰减的正弦曲线缓动;
Back:超过范围的三次方缓动((s+1)*t^3 - s*t^2);
Bounce:指数衰减的反弹缓动。
ps:以上都是自己的烂翻译,希望各位修正。

每个效果都分三个缓动方式(方法),分别是:
easeIn:从0开始加速的缓动;
easeOut:减速到0的缓动;
easeInOut:前半段从0开始加速,后半段减速到0的缓动。
其中Linear是无缓动效果,没有以上效果。

然后看看里面的算法,以Quad.as的easeOut为例:

Code

 
这是as代码,四个参数分别是:
t: current time(当前时间);
b: beginning value(初始值);
c: change in value(变化量);
d: duration(持续时间)。
ps:Elastic和Back有其他可选参数,里面都有说明。

那如何在js中利用这些算法呢?可以看到,虽然是as代码,但里面的程序是可以直接放在js里使用的。
我们可以定义一个类,把它这部分放在里面:

Code


这样,就可以用Tween.Quad.easeOut取得这个算法了,其他算法也一样处理就行了。

接下来就可以利用这个js的Tween来做一些缓动效果了。
先通过上面的坐标实例说一下算法原理:
x轴是时间,y轴是当前值,b是y轴的初始值,x轴的初始值是0,t是当前时间。当t(x轴)逐渐增加到达d时,当前值(y轴)会到达目标值(b+c)。
想详细理解的话可以找资料看看吧(貌似跟数学关系比较大)。

下面就介绍如何使用这个Tween了,首先b、c、d三个参数(即初始值,变化量,持续时间)在缓动开始前,是需要先确定好的。
举一个简单的例子,一个div要向右缓动,left初始值是50,那么b就是50,要向右移动100,那c就是100,如果知道的是目标值,例如要向右移动到150,那就把目标值150减初始值b就是变化量c了。
至于d的设置就比较灵活,只要符合t是从0向d递增(或递减)就可以了。
d跟步长配合使用来设置持续时间,例如d设置为100,如果设置步长是1,那么从0到100就有100步,即分100次来完成这个过程,步数越多那么持续时间就越长。
至于t的变化相当于时间的变化,一般是均匀变化的,每次变化都增加一个步长,当t从0递增(或递减)到d时,缓动就结束了。
要注意的是t是从0开始的,设置步长时必须确定t确实能到达d,如果上面的步长是3,那么t就永远都到不了d了。更好的处理是当t等于或超过d之后,就停止定时器并设置当前值为目标值。

了解了Tween的使用后就可以实现动画效果了。继续上面的例子,已经确定b是50,c是100,d是100,步长是1,使用Tween.Quad.easeOut算法。那么可以用以下程序实现缓动:

Code


一个简单的缓动效果就实现了,要实现不同的缓动,只需要使用对应的Tween算法就行了,以前看来遥不可及的效果,现在这么容易就实现了(当然那些算法才是最难的地方)。

这样关于缓动的效果就介绍完了,但其实远远不止这些,我们还可以自己定义一些算法,发挥想象力,做一些好玩的效果。

Code

 

完整Tween

Code

 

完整实例下载

应用实例:
JavaScript 图片滑动切换效果

转载请注明出处:http://www.cnblogs.com/cloudgamer/

如有任何建议或疑问,欢迎留言讨论。

如果觉得文章不错的话,欢迎点一下右下角的推荐。

程序中包含的js工具库CJL.0.1.min.js,原文在这里

对广告有兴趣的也欢迎点一下^_^。

cloudgamer
关注 - 7
粉丝 - 130
5
0
(请您对文章做出评价)
« 上一篇:Slider 滑动条效果
» 下一篇:JavaScript 颜色梯度和渐变效果
posted @ 2009-01-06 09:17 cloudgamer 阅读(26214) 评论(55) 编辑 收藏 所属分类: Javascript

 回复 引用 查看   
#1楼2009-01-06 09:27 | Leepy      
很不错
 回复 引用 查看   
#2楼2009-01-06 09:41 | 痴情客      
很不错了
 回复 引用 查看   
#3楼2009-01-06 09:42 | 狼Robot      
向楼主学习.
 回复 引用 查看   
#4楼2009-01-06 10:23 | MythYsJh      
神仙...
 回复 引用 查看   
#5楼2009-01-06 10:38 | yww      
很有趣,呵呵,说的对,难的是那些数学公式!研究这些公式出来得到这个效果的是大牛。
 回复 引用 查看   
#6楼2009-01-06 10:43 | xzf158      
从中学习了很多JS不一样的写法,感觉自己的JS水平一下提高了很多,谢谢了!
 回复 引用 查看   
#7楼[楼主]2009-01-06 10:52 | cloudgamer      
@Leepy
@痴情客
@狼Robot
@MythYsJh
@yww
@xzf158
谢谢支持

 回复 引用 查看   
#8楼2009-01-06 11:26 | 坷垃和克拉      
楼主JS错误太多呀,
Quadratic Cubic Quartic Quintic Sinusoidal
Exponential Circular Elastic Back Bounce

ease类型:
easeIn easeOut easeInOut


这些都不能点

 回复 引用 查看   
#9楼2009-01-06 12:44 | 账号难注册      
不错
 回复 引用 查看   
#10楼[楼主]2009-01-06 14:04 | cloudgamer      
@坷垃和克拉
@账号难注册
谢谢支持
不能点?什么意思

 回复 引用   
#11楼2009-01-07 02:23 | diryboy is me[未注册用户]
谢谢楼主,讲解得很明白~
 回复 引用 查看   
#12楼2009-01-07 09:28 | DotNet菜园      
学习
 回复 引用   
#13楼2009-01-07 16:33 | 四五爱人[未注册用户]
哈哈 大家多点点那个click试下
 回复 引用 查看   
#14楼[楼主]2009-01-07 16:56 | cloudgamer      
@diryboy is me
@DotNet菜园
谢谢支持

@四五爱人
呵呵
忘记clear掉
不过也挺好

 回复 引用   
#15楼2009-01-08 08:59 | tiger2009[未注册用户]
51js看了你的东西过来的。
强得一塌糊涂啊!

 回复 引用   
#16楼2009-01-08 14:47 | smile_bug[未注册用户]
很是强悍
申请交换链接www.fomly.cn

 回复 引用 查看   
#17楼[楼主]2009-01-09 08:55 | cloudgamer      
@tiger2009
谢谢支持

@smile_bug
呵呵 可以的

 回复 引用   
#18楼2009-01-13 16:06 | chxwei[未注册用户]
强悍!
学习

 回复 引用   
#19楼2009-01-14 15:50 | xuyi[未注册用户]
对的,算法非常重要.
一般的增删查改用不到.

特别在JS方面,算法体验了一好的程序.

 回复 引用 查看   
#20楼2009-01-15 10:28 | 彭仁夔      

在分析Ext的特效时,不知道如何解决这些名词
同时也想把这些算法采用图表示出来
楼主已经做了,厉害!!

 回复 引用   
#21楼2009-01-20 22:30 | Kim Wang[未注册用户]
强!
 回复 引用 查看   
#22楼2009-02-05 18:48 | SilverNet      
很强!
 回复 引用   
#23楼2009-02-17 14:06 | passing[未注册用户]
只能说一句,谢谢了。
 回复 引用 查看   
#24楼2009-02-22 17:46 | Rmania      
- - 越来越强大了!
谢谢分享! 我也正在学js
想问下楼主:
function addEvent( node, type, listener )
{
if(!isCompatible()) { return false }
if(!(node = $(node))) return false;
if (node.addEventListener)
{
node.addEventListener( type, listener, false );
return true;
}
else if(node.attachEvent)
{
node['e'+type+listener] = listener;
node[type+listener] = function(){node['e'+type+listener]( window.event );}
node.attachEvent( 'on'+type, node[type+listener] );
return true;
}
return false;
};
window['Rmania']['addEvent'] = addEvent;
这是我从书上拿到自己类库上的一个方法,但是对这里node['e'+type+listener] = listener;我自己都不明白了node是取得的一个对象id,如你常用的方法$(node),type是注册好的事件,如click,load.listener是一方法. 这样用'+'语法连接起来后listener他是一个东西了? 先谢谢了

 回复 引用 查看   
#25楼[楼主]2009-02-23 09:01 | cloudgamer      
@Rmania
感觉是想把attachEvent模拟成addEventListener
不过我不清楚这样写的用意
建议看 精通javascript 的addEvent

 回复 引用 查看   
#26楼[楼主]2009-02-23 09:02 | cloudgamer      
@chxwei
@xuyi
@彭仁夔
@Kim Wang
@SilverNet
@passing
谢谢支持

 回复 引用 查看   
#27楼2009-03-08 23:00 | 杨云涛      
楼主,你太有才了!用JavaScript实现这样的算法,让我这个新手眼前一亮。多谢!学习中……
 回复 引用   
#28楼2009-03-27 16:45 | wx525[未注册用户]
太强了,无语形容
 回复 引用   
#29楼2009-05-19 13:13 | 雪!~[未注册用户]
牛人!
很强大……JS也可以这么玩了,会不会有一天!网页代替Windows系统所有的功能?

 回复 引用 查看   
#30楼[楼主]2009-05-19 19:36 | cloudgamer      
@杨云涛
@wx525
谢谢支持

@雪!~
呵呵
那至少现在是没这个可能

 回复 引用   
#31楼2009-05-22 16:24 | 1k-studio[未注册用户]
太酷了!!我赶紧给收藏了
晚上研究研究~~

感谢博主!

 回复 引用 查看   
#32楼2009-05-26 00:01 | Biny      
博主的每篇文章都是精华!
 回复 引用   
#33楼2009-06-21 01:43 | yihaijian1[未注册用户]
楼主真的太牛X了
 回复 引用 查看   
#34楼[楼主]2009-06-22 08:44 | cloudgamer      
@1k-studio
@Biny
@yihaijian1
谢谢支持

 回复 引用 查看   
#35楼2009-07-14 10:00 | 选择多灵活多      
牛人
 回复 引用   
#36楼2009-07-28 10:38 | 抱抱[未注册用户]
感觉一个怪怪的地方,2次方的图形和3次方的图形前两个都那么像,第三个差别太大了吧。
不过已在博主这学到很大,我很高兴,真的很感谢博主。

 回复 引用   
#37楼2009-07-28 10:50 | 抱抱[未注册用户]
对了,是不是:
所有easeInOut都可以换成下面的形式啊?
easeInOut: function(t,b,c,d){
if (t<=d/2 ) return easeIn(t,b,c/2,d/2);
return easeOut(t-d/2,b+c/2,c/2,d/2);
}

对博主介绍的封装功能很佩服,真的非常喜欢。

 回复 引用 查看   
#38楼[楼主]2009-07-28 13:58 | cloudgamer      
@抱抱
easeInOut就是一半的easeIn一半的easeOut

@选择多灵活多
谢谢支持

 回复 引用   
#39楼2009-08-14 17:30 | applezqp[未注册用户]
转载了,很强大。
 回复 引用 查看   
#40楼2009-08-29 19:04 | 石头儿      
@cloudgamer
x轴是时间,y轴是当前值,b是y轴的初始值,x轴的初始值是0,t是当前时间。当t(x轴)逐渐增加到达d时,当前值(y轴)会到达目标值(b+c)。
想详细理解的话可以找资料看看吧(貌似跟数学关系比较大)。

看到这句话时我笑歪了,b(begin)是y轴初始值,c(change)是y轴在0~d时的变化量,那b的值不是(b+c)么?还貌似跟数学有关系( ⊙ o ⊙ )~~
不过很佩服博主啊,看来只是融会贯通起来,都真成神仙了~

 回复 引用 查看   
#41楼2009-08-29 19:05 | 石头儿      
@cloudgamer
只是->知识

 回复 引用 查看   
#42楼[楼主]2009-08-29 21:51 | cloudgamer      
@石头儿
y轴的初始值不是0哦,是b
那时应该弄个图比较好理解

@applezqp
谢谢支持


 回复 引用   
#43楼2009-09-16 14:11 | Csdn--ooMinder[未注册用户]
cloudgamer大侠 偶然看到了你的博客 真是受益匪浅... 自己也想跟着你的教程好好学下JS最近硬着头皮写了个效果..但 最后的缓动效果怎么也用不好..希望你有时间能帮我看看.写了两天了..再写不出来 不知道怎么坚持了.
http://topic.csdn.net/u/20090916/13/68c45885-b43c-4013-87bd-2d1fbe77e140.html?seed=1017804559&r=59838101#r_59838101

 回复 引用 查看   
#44楼[楼主]2009-09-16 14:24 | cloudgamer      
@Csdn--ooMinder
已经回复了

 回复 引用 查看   
#45楼2009-10-22 22:17 | NONE7      
http://www.cnblogs.com/NONE/archive/2009/10/22/JavaScriptSpringEmluator.html
这是我刚申请的博客:里面有我刚放上去的弹簧振子,教教我怎么把代码放上去能隐藏,还能变色,想你的一样,带个加号,我自己先查查!

 回复 引用 查看   
#46楼[楼主]2009-10-22 23:00 | cloudgamer      
@NONE7
博客的使用你可以问管理员

 回复 引用 查看   
#47楼2009-10-25 02:10 | NONE.      
@cloudgamer
O了 谢谢!

 回复 引用   
#48楼2009-11-02 14:40 | DNS地址[未注册用户]
很强大……JS也可以这么玩了,会不会有一天!网页代替Windows系统所有的功能?
 回复 引用 查看   
#49楼[楼主]2009-11-02 15:11 | cloudgamer      
@DNS地址
估计不会
有的话估计也不叫js了

 回复 引用 查看   
#50楼2009-11-05 14:46 | 小zz      
很喜欢你最后的小程序,在鼠标晃悠的那个。学习JS,
 回复 引用 查看   
#51楼2009-12-22 15:28 | authen      
步长越大持续性时间越
 回复 引用 查看   
#52楼2010-01-27 09:59 | 易明之光      
在楼主这里能学到东西,谢谢楼主
 回复 引用 查看   
#53楼[楼主]2010-03-03 17:06 | cloudgamer      
@小zz
@authen
@易明之光
谢谢支持

 回复 引用 查看   
#54楼2010-07-27 17:00 | carlos      
js 在ie下运行总感觉不流畅,有没有那个动画类对ie专门做过优化的?
 回复 引用 查看   
#55楼[楼主]2010-07-27 17:06 | cloudgamer      
@carlos
这个我也没研究

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1369979 ZltHKRdfaJg=