Tween是什么
补间(动画)(来自 in-between)是一个概念,允许你以平滑的方式更改对象的属性。你只需告诉它哪些属性要更改,当补间结束运行时它们应该具有哪些最终值,以及这需要多长时间,补间引擎将负责计算从起始点到结束点的值。
在Three.js
中,我们也有一些修改模型的位置,旋转和缩放的需求,我们无法直接在webgl
中使用css3
动画,所以,Tween
给我们提供了一个很好的解决方案。
接下来,我们首先查看一下如何实现Tween
的简单应用。
简单应用
闲话少说,我们先实现一个Three.js
应用Tween
的案例:
- 首先,创建一个
position
对象,里面存储当前立方体的位置数据:
var position = {x:-40, y:0, z:-30};
- 然后,通过当前的对象创建一个补间
Tween
:
tween = new TWEEN.Tween(position);
- 设置每一个属性的目标位置,并告诉
Tween
在2000毫秒内移动到目标位置:
tween.to({x:40, y:30, z:30}, 2000);
- 我们设置
Tween
对象的每次更新的回调,在每次数据更新以后,将立方体的位置更新掉:
tween.onUpdate(function (pos) {
cube.position.set(pos.x, pos.y, pos.z);
});
Tween
对象不会直接执行,需要我们去调用start()
方法激活:
tween.start();
- 想要完成整个过程,我们还需要在每帧里面调用
TWEEN.update
,来触发Tween
对象更新位置:
function render() {
//更新Tween
TWEEN.update();
control.update();
renderer.render(scene, camera);
}
链式调用
Tween
插件也支持链式调用的方法,并且还会修改实例化时传入的对象,所以我们可以将:
//设置tween
var position = {x:-40, y:0, z:-30};
tween = new TWEEN.Tween(position);
//设置移动的目标和移动时间
tween.to({x:40, y:30, z:30}, 2000);
//设置每次更新的回调,然后修改几何体的位置
tween.onUpdate(function (pos) {
cube.position.set(pos.x, pos.y, pos.z);
});
简化为链式:
//直接链式实现tween
tween = new TWEEN.Tween(cube.position).to({x:40, y:30, z:30}, 2000);
Tween对象方法
.start()
这个方法是我们最早了解的Tween
的方法,如果你想激活一个补间,请使用这个方法
tween.start();
start
方法还接受一个参数。如果你使用他,那么补间不会立即开始,会从第一次调用TWEEN.update
后开始计时,如果设置的时间已经小于计时的总时间,那计算出来的位置数据将是参数设置时间开始后,运行到的所在位置。
.stop()
这个方法刚好和start
方法对应,如果你想取消一个补间,直接调用这个方法即可:
tween.stop();
.update()
每一个补间其实都有一个更新的方法,只不过我们通过使用TWEEN.update
去调用。我们一般不会单独去调用。
.chain()
当你顺序排列不同的补间时,事情会变得有趣,例如在上一个补间结束的时候立即启动另外一个补间。我们称这为链式补间,这使用 chain
方法去做。因此,为了使 tweenB
在 tewwnA
启动:
tweenA.chain(tweenB);
或者,对于一个无限的链式,设置tweenA一旦tweenB完成就开始:
tweenA.chain(tweenB);
tweenB.chain(tweenA);
在其他情况下,您可能需要将多个补间链接到另一个补间,以使它们(链接的补间)同时开始动画:
tweenA.chain(tweenB,tweenC);
警告:调用 tweenA.chain(tweenB) 实际上修改了tweenA,所以tweenA总是在tweenA完成时启动。 chain 的返回值只是tweenA,不是一个新的tween。
接下来我们查看一下链式补间的案例:
案例查看地址:点击这里
案例代码查看地址:点击这里
.repeat()
如果你想让一个补间永远重复,你可以链接到自己,但更好的方法是使用 repeat
方法。 它接受一个参数,描述第一个补间完成后需要多少次重复:
tween.repeat(10); // 循环10次
tween.repeat(Infinity); // 无限循环
我们可以将simple.html
里面的调用改成无限循环:
tween = new TWEEN.Tween(cube.position).to({x:40, y:30, z:30}, 2000).repeat(Infinity);
.yoyo()
这个功能只有在补间使用repeat
方法时才有效果。我们设置yoyo
以后,位置的切换效果就会变为从头到尾,从尾到头这样的循环。
单个补间的无限从头到尾循环可以写成这样:
tween = new TWEEN.Tween(cube.position).to({x:40, y:30, z:30}, 2000).repeat(Infinity).yoyo(true);
.delay()
这个方法用于控制激活前的延时,即触发start
事件后,需要延时到设置的delay
时间,才会真正激活:
tween.delay(1000);
tween.start();
回调函数
在之前的simple.html
中,我们是在每次更新回调中获取更新后的位置信息:
//设置每次更新的回调,然后修改几何体的位置
tween.onUpdate(function (pos) {
cube.position.set(pos.x, pos.y, pos.z);
});
下面列一下补间支持的所有的回调函数:
onStart
在补间计算开始前的回调,每个补间只能触发一下,即使使用repeat
方法循环,这个回调也只被触发一次。
onStop
通过调用补间的stop
方法停止的补间会触发当前回调,如果是正常完成的补间将不会触发此回调。
onUpdate
每次补间更新后,我们可以在此回调中获取更新后的值。
onComplete
当补间正常完成时,将会触发此回调。通过使用stop
停止的补间将不会触发此回调。