1. 程式人生 > >12 使用 Tween.js 建立補間動畫

12 使用 Tween.js 建立補間動畫

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 方法去做。因此,為了使 tweenBtewwnA 啟動:

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停止的補間將不會觸發此回撥。