tweenJS是一个简单的javascript补间动画库,支持数字,对象属性,CSS样式等的动态效果过渡,允许平滑的修改元素的属性值。告诉它需要改变的元素的开始值和结束值,并设置好过渡时间,补间动画将会自动计算从开始到结束的状态,并产生平滑的动画变换效果。
tweenjs在threejs中经常作为过渡动画使用,所以做了一些学习说明,供以后方便查阅。
- 首先需要引用该库
<script src="js/libs/tween.min.js"></script>
- 设置元素属性
var position={
x:-150,
y:0
};
- 初始化动画变量,设置下一个状态,设置过渡样式,更新回调,然后开始动画
tween=new TWEEN.Tween(position);//初始化动画变量
tween.to({
x:150
},8000);//设置下一个状态量
tween.easing(TWEEN.Easing.Sinusoidal.InOut);//设置过渡效果
tween.onUpdate(callback);//更新回调函数
tween.start();//启动动画
- 每帧渲染更新动画
function animate() {
// [...]
TWEEN.update();
requestAnimationFrame(animate);
}
完整代码示例:
var position={x:-150,y:0};
tween=new TWEEN.Tween(position).to({x:150},8000)
.easing(TWEEN.Easing.Sinusoidal.InOut).onUpdate(function(){
cube.position.x=this.x;
})
.start();
tweenback=new TWEEN.Tween(position).to({x:-150},8000)
.easing(TWEEN.Easing.Sinusoidal.InOut).onUpdate(callback);
tween.chain(tweenback);//动画链接
tweenback.chain(tween);
function callback(){
cube.position.x=this.x;
};
基础方法:
控制单个补间动画。
-
.start()
开始动画。start 方法可以接受一个参数 time(单位ms),否则动画立即执行。如果使用tween.start(2000),补间将在2秒后运行,但当动画停止后,在下次启动时也会立即执行。 -
.stop()
停止动画。对于已经结束和未开始的动画,stop()方法无效。 -
.chain()
链式补间,链接两个动画。例如:一个动画tweenA在另一个动画tweenB结束后开始。可以通过chain方法来使实现。
tweenA.chain(tweenB);//单链接
//循环无限链接
tweenA.chain(tweenB);
tweenB.chain(tweenA);
//将多个补间链接到另一个补间,以使它们(链接的补间)同时开始动画:
tweenA.chain(tweenB,tweenC);
-
.update()
更新动画。一般使用全局方法TWEEN.update()来执行动画的更新,除非是一个疯狂的hacker。 -
.repeat(times)
循环动画。不同的动画采用链式补间,而相同的动画循环一般推荐使用该方法。执行顺序优于chain()方法。
tween.repeat(10); // 重复10次后结束
tween.repeat(Infinity); // 无限循环
-
.yoyo()
实现yoyo效果。即动画会在开始或结束处向反方向反弹,而不是重头开始,只有在repeat方法被使用时生效。 -
.delay(time)
控制动画延时。动画将在time毫秒之后运行。
缓动效果函数:
.easing(TWEEN.Easing.easing函数.easing类型)
-
easing函数:
Linear ==> 线性匀速运动效果
Quadratic ==> 二次方的缓动
Cubic ==> 三次方的缓动
Quartic ==> 四次方的缓动
Quintic ==> 五次方的缓动
Sinusoidal ==> 正弦曲线的缓动
Exponential ==> 指数曲线的缓动
Circular ==> 圆形曲线的缓动
Elastic ==> 指数衰减的正弦曲线缓动
Back ==> 超过范围的三次方的缓动
Bounce ==> 指数衰减的反弹缓动 -
easing类型:
In ==> easeIn,加速,先慢后快
Out ==> easeOut,减速,先快后慢
InOut ==> easeInOut,前半段加速,后半段减速
使用自定义的缓动功能:
自定义缓动函数
- 必须接受一个参数:
K:缓动过程,或补间所处时间有多长,允许的值在[0,1]的范围内; - 必须根据参数返回一个值
不管修改多少个属性,easing函数在每次更新时只调用一次,然后将结果与初始值以及这个值和最终值之间的差值(delta)一起使用
//伪代码,过程表示
easedElapsed = easing(k);
for each property:
newPropertyValue = initialPropertyValue + propertyDelta * easedElapsed;
为了性能,只有在补间上调用start()时自会计算增量值。
//自定义缓动函数
function tenStepEasing(k) {
return Math.floor(k * 10) / 10;
}
//调用
tween.easing(tenStepEasing);
回调函数:
-
.onStart(callback)
tween开始动画前的回调函数。 -
.onStop(callback)
tween结束动画后的回调函数。 -
.onUpdate(callback)
在tween每次被更新后执行。 -
.onComplete(callback)
在tween动画全部结束后执行。
全局方法:
控制所有补间动画。以下方法都定义在全局对象TWEEN中。
-
TWEEN.update(time)
更新所有的补间动画。如果time没有被指定,将使用当前时间。 -
TWEEN.getAll ()
获取tweens数组的引用。 -
TWEEN.removeAll()
从数组中删除所有tweens。 -
TWEEN.add(tween)
在被激活的tweens中添加一个tween -
TWEEN.remove(tween)
在被激活的tweens中移除一个tween。
控制补间组
使用TWEEN单例来管理补间,可能会在包含多组件的大型应用程序中出现问题,所以引入了更小的补间组。每个组件都可以创建自己的TWEEN.Group实例(这是全局对象TWEEN在内部使用)。实例化新的补间时,可以将补间组作为第二个可选参数传入,以便补间单独使用:
//补间组
var groupA = new TWEEN.Group();
var groupB = new TWEEN.Group();
var tweenA = new TWEEN.Tween({ x: 1 }, groupA)
.to({ x: 10 }, 100)
.start();
var tweenB = new TWEEN.Tween({ x: 1 }, groupB)
.to({ x: 10 }, 100)
.start();
var tweenC = new TWEEN.Tween({ x: 1 })
.to({ x: 10 }, 100)
.start();
groupA.update(); // 只更新tweenA
groupB.update(); // 只更新tweenB
TWEEN.update(); // 只更新tweenC
groupA.removeAll(); // 只移除tweenA
groupB.removeAll(); // 只移除tweenB
TWEEN.removeAll(); // 只移除tweenC
通过管理补间组,每个组件都有可以处理创建、更新和销毁自己的一组补间,并且不会与其他补间相互影响。
高级补间
相对值:
在使用to()方法时,也可以使用相对值,当tween启动时,Tweenjs将读取当前属性值并应用相对值来找出新的最终值,但是相对值必须使用引号(“”),否则该值被视为绝对值
// 对象的属性x的值最后将变成100
var absoluteTween = new TWEEN.Tween(absoluteObj).to({ x: 100 });
absoluteTween.start();
//对象的属性x的值最后会+100
var relativeTween = new TWEEN.Tween(relativeObj).to({ x: "+100" });
relativeTween.start();
补间值的数组:
指定一个属性值数组,x的值将从初始值变为0,-100和100.
var tween = new TWEEN.Tween(relativeObj).to({ x: [0, -100, 100] });
值的计算方式:
- 首先,补间进度如常计算
- 进度(从0到1)用作插值函数的输入
- 基于进度和值的数组,生成内插值
比如,当补间刚启动时(进度为0),插值函数将返回数组的第一个值,当补间到一半时,插值函数将返回数组中间的值,当补间结束时,将返回最后一个值。
可以使用差值方法.interpolation()修改插值函数:
可用值:
- TWEEN.Interpolation.Linear
- TWEEN.Interpolation.Bezier
- TWEEN.Interpolation.CatmullRom
tween.interpolation( TWEEN.Interpolation.Bezier );
请注意,插值函数对于同一补间中的数组进行补间的所有属性都是全局的。不能使用数组和线性函数对属性A的更改,也不能使用相同的补间进行数组B的属性B和Bezier函数的更改,而是应该使用运行在同一对象上的两个补间,但修改不同的属性并使用不同的插值函数。