防止在循环中同时发生多个动画

时间:2016-05-10 01:46:09

标签: javascript jquery loops animation

我正在制作一个简单的Simon Says风格游戏并使用for循环来浏览已添加的颜色数组。目前,每次单击该按钮时,它都会添加一种颜色并运行for循环。我的问题是,当满足两个条件时,不是动画一种颜​​色然后是下一种颜色,而是同时激活两种颜色。我尝试使用setInterval,它只是一个无限循环,而setTimeout只是让第一个动画在它发生之前等待。有谁知道如何让每种颜色一次动画一个?

在我的演示中,请滚动到js的底部。顶部是color.js,它允许颜色动画。单击该按钮几次以查看动画的行为方式。

DEMO

var colors = [];
var red, yellow, blue, green;

//random number
mathF = function() {
    return Math.random();
};

//determine what color is added
function newColorF() {
    var math = mathF();
    if(math <= .25) {
        newColor = 'red';
    }
    else if(math <= .5) {
        newColor = 'green';
    }
    else if(math <= .75) {
        newColor = 'yellow';
    }
    else {
        newColor = 'blue';
    }
    return newColor;
}

function computerTurn() {
    newColor = newColorF();
    colors.push(newColor);
    var colorlength = colors.length;
    setTimeout(function() {
    for(i=0; i<colorlength; i++) {
        x = colors[i];
        console.log(x);
        if(x === 'red') {
            $('#red').animate({
                backgroundColor: '#ff9e9e'
            }, 750)
            .delay(250)
            .animate({
                backgroundColor: 'red'
            }, 750);
        }
        else if(x === 'green') {
            $('#green').animate({
                backgroundColor: '#bdffbd'
            }, 750)
            .delay(250)
            .animate({
                backgroundColor: 'green'
            }, 750);
        }
        else if(x === 'yellow') {
            $('#yellow').animate({
                backgroundColor: '#ffffc2'
            }, 750)
            .delay(250)
            .animate({
                backgroundColor: 'yellow'
            }, 750);
        }
        else {
            $('#blue').animate({
                backgroundColor: '#a3a3ff'
            }, 750)
            .delay(250)
            .animate({
                backgroundColor: 'blue'
            }, 750);
        }
    }
}, 500);
}
//when begin button is pushed
function beginGame() {
    computerTurn();
}

$('#startGame').click(function() {
    beginGame();
});

2 个答案:

答案 0 :(得分:4)

我能想到的一个可能的解决方案是使用animate函数的complete回调参数。

function computerTurn() {
    newColor = newColorF();
    colors.push(newColor);
    var colorlength = colors.length;

    var i = 0; // Our iteration variable

    var check = function() { // the function to increment i and go to next step of animation, or exit
        i++;
        if (i < colorlength) {
            step();
        }
    };

    var step = function() {
        x = colors[i];
        console.log(x);
        if (x === 'red') {
            $('#red').animate({
                    backgroundColor: '#ff9e9e'
                }, 750)
                .delay(250)
                .animate({
                    backgroundColor: 'red'
                }, 750, check); // <--- attached check function here
        } else if (x === 'green') {
            $('#green').animate({
                    backgroundColor: '#bdffbd'
                }, 750)
                .delay(250)
                .animate({
                    backgroundColor: 'green'
                }, 750, check); // <--- attached check function here
        } else if (x === 'yellow') {
            $('#yellow').animate({
                    backgroundColor: '#ffffc2'
                }, 750)
                .delay(250)
                .animate({
                    backgroundColor: 'yellow'
                }, 750, check); // <--- attached check function here
        } else {
            $('#blue').animate({
                    backgroundColor: '#a3a3ff'
                }, 750)
                .delay(250)
                .animate({
                    backgroundColor: 'blue'
                }, 750, check); // <--- attached check function here
        }
    };

    step(); // For the initial step in the animation
}

在这里,我所做的不是使用for循环来遍历colors数组,而是通过complete回调使用递归方法{{1接受作为其最后一个参数。

来自animate的文档:

  

完整

     

类型:功能()

     

元素上的动画完成后调用的函数。

我已将代码分解为两个函数:completestep

check执行动画的下一步。

step用于检查数组是否完全迭代。如果是,则退出。否则,请致电check

最后,我手动调用step来开始动画序列。

注意:可能有更好的解决方案,我不确定。

答案 1 :(得分:1)

听起来像你的意思是排队动画? animate()实际上允许使用queue属性:

    if(x === 'red') {
        $('#red').animate({backgroundColor: '#ff9e9e'}, {
        queue: true,
        duration: 750,
        delay: 250
    });