簡體   English   中英

如何使用諾言執行一系列動畫

[英]How to perform a series of animations using promises

我正在使用three.js制作Rubik的立方體動畫。 我目前正在嘗試制作一個可以隨機播放多維數據集的函數。

我已經制作了使單個動作動起來的函數(例如,將右面順時針旋轉90度)。 現在,要隨機播放多維數據集,我隨機選擇5個動作並調用與該動作相對應的函數。 我要一個接一個地執行這些動作(動畫)。 為此,我使用了諾言鏈。 但是,它們是同時發生的。

function shuffle(){
    let promise = Promise.resolve();
    for(let i = 0; i < 5; i++){
        promise = promise.then(randomMove);
    }
}
function randomMove(){
    //this function randomly selects a move and calls the corrosponding function
    //MOVES is an array of functions that animate a move
    //cubeAnimator is a class that stores these functions
    let side = Math.floor(Math.random()*6);
    let turns = Math.floor(Math.random()*3);
    MOVES[6*turns+side][1]();
}
//this is sample of a functions that rotate a side of cube
function r1(){
        let cubiesToRotate = cube.getCubiesByVID([].concat(cube.RIGHT_CENTRAL_CUBIES).concat(cube.RIGHT_CORNER_CUBIES).concat(cube.RIGHT_EDGE_CUBIES)); // this is list of cubies to rotate
        let group = new THREE.Object3D();
        for(let cubie of cubiesToRotate){
            group.add(cubie);
        }
        scene.add(group);
        this.rotate(group,new THREE.Vector3(-1,0,0),90*Math.PI/180,0);
    }
function rotate(cubies,axis,angle,total){
        console.log(axis);
        if(total <= angle){
            total+=0.05;
            cubies.rotateOnAxis(axis,0.05);
            renderer.render(scene,camera);
            requestAnimationFrame(function(){
                cubeAnimator.rotate(cubies,axis,angle,total);
            });
        }
    }

每個功能使用以下邏輯。

更改立方的位置

調用renderer.render

如果旋轉未完成,請使用與回調相同的函數調用requestAnimation

我想我可以使用setTimeout在移動之間添加延遲。 但是我覺得這不是正確的方法。 因此,請提出其他建議。

要一步一步地移動,您需要在解決前一個問題后創建新的Promise。 您的承諾會立即得到解決,因此它會同時發生。 您可以通過以下方法解決此問題:

function shuffle(){
    let promise = Promise.resolve();
    for(let i = 0; i < 5; i++){
        promise = promise.then(_ => new Promise(resolve =>
        randomMove();
        resolve();
      ));
    }
}

處理運動流的一種更糟糕的方法是使用rxjs。 您可以這樣:

function shuffle(){
    const movements = []
    for(let i = 0; i < 5; i++){
      movements.push[randomMove]
    }
    from(movements).pipe(concatMap((callback) => callback()) 
}

concatMap將在前一個完成后執行下一個randomMove。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM