使用tween.js来制作three.js相机转场动画

使用tween.js来制作three.js相机转场动画

关于tween.js在之前的文章中有介绍, three.js补间动画Tween.js和选择物体
@tweenjs/tween.js-tween.js-TweenJS-TweenMax

tween.js在three.js中有很多使用场景,比如粒子动画,相机转场动画,物体运动。
这里我们使用tween.js的 chain来制作相机转场动画。

tween.chain

当你顺序排列不同的补间时,事情会变得有趣,例如在上一个补间结束的时候立即启动另外一个补间。我们称这为链式补间,这使用 chain 方法去做。因此,为了使 tweenB 在 tewwnA 启动:
tweenA.chain(tweenB);
或者,对于一个无限的链式,设置tweenA一旦tweenB完成就开始:
tweenA.chain(tweenB);
tweenB.chain(tweenA);
转场动画原理很简单,通过tween.js不断的去更新相机的位置和视点即可。直接上代码实验,写4个tween,组成一个无限循环。

var tweena = cameraCon({x:0,y:10,z:20},{x:20,y:0,z:0},4000);
var tweenb = cameraCon({x:20,y:0,z:0},{x:0,y:10,z:-20},4000);
var tweenc = cameraCon({x:0,y:10,z:-20},{x:-20,y:0,z:0},4000);
var tweend = cameraCon({x:-20,y:0,z:0},{x:20,y:0,z:0},4000);
tweena.chain(tweenb);
tweenb.chain(tweenc);
tweenc.chain(tweend);
tweend.chain(tweena);
tweena.start();

function cameraCon(p1={x:0,y:0,z:0},p2={x:30,y:30,z:30},time=6000) {
    var tween1 = new TWEEN.Tween(p1).to(p2,time||200000).easing(TWEEN.Easing.Quadratic.InOut);
    var update = function () {
        camera.position.set(p1.x,p1.y,p1.z);
    };
    tween1.onUpdate(update);
    return tween1;
}

跑一遍代码,发现只有在第一次的时候是正确的,后面循环相机就是跳动。仔细分析了之后找到了问题所在,于是把p1提到全局变量中。

var p1 = {x:0,y:10,z:20};
var tweena = cameraCon({x:20,y:2,z:0},9000);
var tweenb = cameraCon({x:0,y:10,z:-20},9000);
var tweenc = cameraCon({x:-20,y:2,z:0},4000);
var tweend = cameraCon({x:0,y:10,z:20},4000);
tweena.chain(tweenb);
tweenb.chain(tweenc);
tweenc.chain(tweend);
tweend.chain(tweena);
tweena.start();

function cameraCon(p2={x:10,y:30,z:10},time=6000) {
    var tween1 = new TWEEN.Tween(p1).to(p2,time).easing(TWEEN.Easing.Quadratic.InOut);
    var update = function () {
        camera.position.set(p1.x,p1.y,p1.z);
    };
    tween1.onUpdate(update);
    return tween1;
}

效果如下:

基本思路搞定了,剩下的就是自由发挥时间了。sin,cos,tan三角函数走起,转场效果就会更加圆滑了。
一些常用的补间函数:tween.easing(TWEEN.Easing.Sinusoidal.InOut);
使用tween.js来制作three.js相机转场动画_第1张图片


关于tween.js 的参数有一个问题

var coords = { x: 0, y: 0 }; // 起始点 (0, 0)
var tween = new TWEEN.Tween(coords) // 创建一个新的tween用来改变 'coords'
    .to({ x: 300, y: 200 }, 1000) // 在1s内移动至 (300, 200)

比如上面代码:coords可以是一个对象(不带嵌套的对象),或者一个数组[1,2]。但是不能是一个变量 coords=x,也不能是对象中嵌套对象既:{x:{x1:0}}。
想去看下源码,也没看懂具体的原因。估计是因为变量属于值类型,tween需要的是一个引用类型的。而数组和对象就是,但是他用的是浅拷贝,所以嵌套的对象就不行了。

你可能感兴趣的:(JavaScript,three.js)