【问题标题】:How to perform a series of animations using promises如何使用 Promise 执行一系列动画
【发布时间】:2019-08-07 20:54:29
【问题描述】:

我正在使用three.js 制作魔方动画。我目前正在尝试制作一个随机播放立方体的函数。

我已经制作了动画单个移动的功能(例如将右脸顺时针旋转 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 在移动之间添加延迟。但我觉得这不是正确的做法。所以请提出其他建议。

【问题讨论】:

  • 请分享cubeAnimator.rotate 的实现。这对于回答您的问题至关重要
  • @ymz 这是我提供的旋转功能。
  • cubeAnimator.rotate 从这一行开始 cubeAnimator.rotate(cubies,axis,angle,total) 应该有一个回调/承诺处理程序完成后...我需要 api 参考或 cubeAnimator 的完整代码以了解发生了什么
  • @ymz cubeAnimator 只是一个具有 r1 和旋转的对象。为了简单起见,我复制了 r1 并在此处轮换。我已将问题从 MOVES[6*turns+side][1].call(cubeAnimator) 编辑为 MOVES[6*turns+side][1]()。还有其他功能,例如l1,f1等。但它们只是 r1 的副本,具有不同的参数来 getCubiesByVID 和旋转。所以我没有在这里列出所有这些。

标签: javascript three.js


【解决方案1】:

要一个一个地做动作,你需要在解决之前的 Promise 后创建新的 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。

【讨论】:

    猜你喜欢
    • 2014-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-22
    • 1970-01-01
    • 1970-01-01
    • 2013-10-19
    • 2017-06-09
    相关资源
    最近更新 更多