如何创建一个无限更改不同背景颜色的循环动画

时间:2015-06-02 14:47:15

标签: javascript jquery html css animation

我正在尝试实现以下动画:

我有八个圆圈,四个小圆圈和四个圆圈。第一个(小圆圈)具有绿色背景颜色,其余小圆圈具有灰色背景颜色,大圆圈具有红色背景颜色。每过一步,动画将一次一个地向圆圈添加绿色背景颜色。当所有圆圈的背景颜色为绿色时,在整个动画从头开始之前会有1秒的延迟。动画将无限重复动画。

TLDR:jsFiddle

初始状态: 1个小圆圈绿色,3个小圆圈灰色,4个大圆圈红色。

介于两者之间:一次一个,每1秒为每个圆圈着色,直到所有圆圈都是绿色。

最终状态: 4个小圆圈和4个大圆圈颜色为绿色。重置初始状态并无限重复动画。

- 编辑开始 -

对于那些对我放在一起的集体解决方案感兴趣的人,你可以在这个jsFiddle中找到它,它涉及CSS和jQuery。当你第一次看到它时,它将使用jQuery;要查看纯CSS实现,请删除CSS中的注释,以启用动画标记。一定要评论jQuery。

- 编辑结束 -

注意:我最好想找一个仅限CSS的解决方案,但我对CSS动画非常新手,到目前为止它真的很痛苦,这就是为什么我来到这里请求帮忙。但是,如果单独使用CSS是不可能的,那么请接受jQuery解决方案。鉴于此,这是我在jQuery中尝试过的但是无济于事:

HTML

<div class="smallCircles">
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
</div>
<div class="largeCircles">
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
</div>

CSS

.smallCircles { 
    margin-bottom: 20px;
}
.smallCircles .circle { 
    display: inline-block;
    height: 25px;
    width: 25px;
    border-radius: 25px;    
}
.largeCircles .circle {
    display: inline-block;
    height: 75px;
    width: 75px;
    border-radius: 75px;
}
.smallCircles :first-child {
    background-color: green;
}
.smallCircles :not(:first-child)
    background-color: gray;
}
.largeCircles .circle { 
    background-color: red;
}
.bg--green {
    background-color: green;
}

.bg--gray {
    background-color: gray;
}

的jQuery

jQuery(document).ready(function(){
    var elements = [jQuery(".smallCircles :nth-child(1)"),
                    jQuery(".smallCircles :nth-child(2)"),
                    jQuery(".smallCircles :nth-child(3)"),
                    jQuery(".smallCircles :nth-child(4)"),
                    jQuery(".largeCircles :nth-child(1)"),
                    jQuery(".largeCircles :nth-child(2)"),
                    jQuery(".largeCircles :nth-child(3)"),
                    jQuery(".largeCircles :nth-child(4)")
                   ];
    var count = elements.length;
    var i;
    var infinitely = 9999999999999999999999999999999999999999;

    for(i = 0; i < infinitely; i++){
        try {
            if (i % count === 0) {
                resetColors((i % count), elements);
            }
            else {
                colorEach((i % count), elements);
            }
        } catch(e) {
            console.log(e);
        }
    }

    function resetColors (i, elements) {
        if (i > 0) { // the changes in here will have occurred on the second loop
            var timer;
            setTimeout(elements.each(function(index, element){
                if(index > 0 && index < 4) { // omit the first element in the list    
                    element.removeClass("bg--green");
                    if(index < 4) { // only the small circles
                        element.addClass("bg--gray");
                    }
                    if(index > 3) { // only the large circles
                        element.addClass("bg--red");
                    }
                }
            }), 3000);
        }
    }

    function colorEach (i, elements)  {
        switch (i) {
            // Small Circles, except the first one
            case 1:
                colorBackground(i, elements, 1);
                break;
            case 2:
                colorBackground(i, elements, 1);
            case 3:
                colorBackground(i, elements, 1);
                break;
            // Large Circles
            case 4:
                colorBackground(i, elements, 0);
                break;
            case 5:
                colorBackground(i, elements, 0);
                break;
            case 6:
                colorBackground(i, elements, 0);
                break;
            case 7:
                colorBackground(i, elements, 0);
                break;
        }
    }

    function colorBackground (i, elements, type) {
        if(type) { // type 1: large circle
            var timer;
            setTimeout(function(i, a){
                console.log("timeout function at colorBackground i: " + i);
                a[i].removeClass("bg--red");
                a[i].addClass("bg--green");
            }, 3000);
        }
        else { // type 0: small circle
            var timer;
            setTimeout(function(i, elements){
                console.log("timeout function at colorBackground i: " + i);
                elements[i].removeClass("bg--gray");
                elements[i].addClass("bg--green");
            }, 3000);
        }
    }
}

我在CSS动画中尝试失败,没有jQuery,这是100%:

.smallCircle :nth-child(2) {
    animation: smallCircle-2 1s infinite;
}
.smallCircle :nth-child(3) {
    animation: smallCircle-3 2s infinite;
}
.largeCircle :nth-child(4) {
    animation: smallCircle-1 3s infinite;
}
.largeCircle :nth-child(1) {
    animation: largeCircle-2 4s infinite;
}
.largeCircle :nth-child(2) {
    animation: largeCircle-3 5s infinite;
}
.largeCircle :nth-child(3) {
    animation: largeCircle-4 6s infinite;
}
.smallCircle :nth-child(4) {
    animation: largeCircle-4 7s infinite;
}
@keyframes smallCircle-2 {
    99% { background:gray }
    100% {background:green;}
}
@keyframes smallCircle-3 {
    99% { background:gray }
    100% {background:green;}
}
@keyframes smallCircle-4 {
    99% { background:gray }
    100% {background:green;}
}
@keyframes largeCircle-1 {
    99% { background:gray }
    100% {background:green;}
}
@keyframes largeCircle-2 {
    99% { background:gray }
    100% {background:green;}
}
@keyframes largeCircle-3 {
    99% { background:gray }
    100% {background:green;}
}
@keyframes largeCircle-4 {
    99% { background:gray }
    100% {background:green;}
}

3 个答案:

答案 0 :(得分:4)

这只有CSS才有可能,如果有点单调乏味。您需要为每个圆圈设置一个新的关键帧动画。每个圆圈保持灰色,然后绿色12.5%(100除以8)进一步变为动画,而不是前一个动画。所有动画都设置为持续8秒,并重复广告inifinium。

下面的示例代码使用标准语法。您可能希望添加供应商前缀以确保遗留支持,但所有主要浏览器currently support都是这种语法。

jsFiddle

@keyframes a1 {
    0% { background-color: green; }
}
@keyframes a2 {
    12.5% { background-color: green; }
}
@keyframes a3 {
    25% { background-color: green; }
}
@keyframes a4 {
    37.5% { background-color: green; }
}
@keyframes a5 {
    50% { background-color: green; }
}
@keyframes a6 {
    62.5% { background-color: green; }
}
@keyframes a7 {
    75% { background-color: green; }
}
@keyframes a8 {
    87.5% { background-color: green; }
}

.circle {
    animation-duration: 8s;
    animation-iteration-count: infinite;
    animation-fill-mode: forwards;
    animation-timing-function: steps(1,end)
}

.smallCircles .circle:nth-of-type(1) {
    animation-name: a1;
}

.smallCircles .circle:nth-of-type(2) {
    animation-name: a2;
}

.smallCircles .circle:nth-of-type(3) {
    animation-name: a3;
}

.smallCircles .circle:nth-of-type(4) {
    animation-name: a4;
}

.largeCircles .circle:nth-of-type(1) {
    animation-name: a5;
}

.largeCircles .circle:nth-of-type(2) {
    animation-name: a6;
}

.largeCircles .circle:nth-of-type(3) {
    animation-name: a7;
}

.largeCircles .circle:nth-of-type(4) {
    animation-name: a8;
}

答案 1 :(得分:2)

尝试使用.queue()

(function cycle(elems) {
  elems.queue("bg", $.map(elems, function(el, i) {
      return function(next) {
        setTimeout(function() {
          el.style.backgroundColor = "green";
          next();
        }, 1000)
      }
    })).dequeue("bg").promise("bg")
    .then(function(_elems) {
    console.log(_elems);
      setTimeout(function() {
        elems
        .slice(0, 1).css("backgroundColor", "green")
        .addBack()
        .slice(1, 4)
        .css("backgroundColor", "gray")
        .addBack()
        .slice(4)
        .css("backgroundColor", "red");
        cycle(_elems);
      }, 3000);
    });
}($(".circle")));
.smallCircles {
  margin-bottom: 20px;
}
.smallCircles .circle {
  display: inline-block;
  height: 25px;
  width: 25px;
  border-radius: 25px;
}
.largeCircles .circle {
  display: inline-block;
  height: 75px;
  width: 75px;
  border-radius: 75px;
  background-color: red;
}
.smallCircles .circle:first-child {
  background-color: green;
}
.largeCircles .circle {
  background-color: red;
}
.smallCircles .circle:not(:first-child) {
  background-color: gray;
}
.bg--green {
  background-color: green;
}
.bg--gray {
  background-color: gray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="smallCircles">
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
</div>
<div class="largeCircles">
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
</div>

答案 2 :(得分:2)

<强>解决方案: 使用CSS关键帧和动画可以完全实现此效果。

浏览器支持我已经 Firefox 5 +,IE 10 +,Chrome,Safari 4 +,Opera 12 +

<强> JSFiddle Demo

<强> HTML:

<div class="smallCircles">
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
</div>
<div class="largeCircles">
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
</div>

<强> CSS:

.smallCircles { 
    margin-bottom: 20px;
}
.smallCircles .circle { 
    height: 25px;
    width: 25px;
}
.largeCircles .circle {
    height: 75px;
    width: 75px;
}
.circle {
    display: inline-block;
    border-radius: 50%;
    background-color: gray;
}

.circle {
    -webkit-animation: 8s infinite;
    -moz-animation: 8s infinite;
    -o-animation: 8s infinite;
    animation: 8s infinite;
    -webkit-animation-fill-mode: forwards;
    -moz-animation-fill-mode: forwards;
    -o-animation-fill-mode: forwards;
    animation-fill-mode: forwards;
    -webkit-animation-timing-function: steps(1,end);
    -moz-animation-timing-function: steps(1,end);
    -o-animation-timing-function: steps(1,end);
    animation-timing-function: steps(1,end);
}

.smallCircles > .circle:nth-of-type(1) {
    -webkit-animation-name: state1;
    -moz-animation-name: state1;
    -o-animation-name: state1;
    animation-name: state1;
}
.smallCircles > .circle:nth-of-type(2) {
    -webkit-animation-name: state2;
    -moz-animation-name: state2;
    -o-animation-name: state2;
    animation-name: state2;
}
.smallCircles > .circle:nth-of-type(3) {
    -webkit-animation-name: state3;
    -moz-animation-name: state3;
    -o-animation-name: state3;
    animation-name: state3;
}
.smallCircles > .circle:nth-of-type(4) {
    -webkit-animation-name: state4;
    -moz-animation-name: state4;
    -o-animation-name: state4;
    animation-name: state4;
}
.largeCircles > .circle:nth-of-type(1) {
    -webkit-animation-name: state5;
    -moz-animation-name: state5;
    -o-animation-name: state5;
    animation-name: state5;
}
.largeCircles > .circle:nth-of-type(2) {
    -webkit-animation-name: state6;
    -moz-animation-name: state6;
    -o-animation-name: state6;
    animation-name: state6;
}
.largeCircles > .circle:nth-of-type(3) {
    -webkit-animation-name: state7;
    -moz-animation-name: state7;
    -o-animation-name: state7;
    animation-name: state7;
}
.largeCircles > .circle:nth-of-type(4) {
    -webkit-animation-name: state8;
    -moz-animation-name: state8;
    -o-animation-name: state8;
    animation-name: state8;
}

@-webkit-keyframes state1 {
    0% { background-color: green; }
    100% {background-color: green; }
}
@-moz-keyframes state1 {
    0% { background-color: green; }
    100% { background-color: green; }
}
@-o-keyframes state1 {
    0% { background-color: green; }
    100% { background-color: green; }
}
@keyframes state1 {
    0% { background-color: green; }
    100% { background-color: green; }
}
@-webkit-keyframes state2 {
    12% { background-color: gray; }
    12.5% { background-color: green; }
    100% { background-color: green; }
}
@-moz-keyframes state2 {
    12% { background-color: gray; }
    12.5% { background-color: green; }
    100% { background-color: green; }
}
@-o-keyframes state2 {
    12% { background-color: gray; }
    12.5% { background-color: green; }
    100% { background-color: green; }
}
@keyframes state2 {
    12% { background-color: gray; }
    12.5% { background-color: green; }
    100% { background-color: green; }
}
@-webkit-keyframes state3 {
    24.5% { background-color: gray; }
    25% { background-color: green; }
    100% { background-color: green; }
}
@-moz-keyframes state3 {
    24.5% { background-color: gray; }
    25% { background-color: green; }
    100% { background-color: green; }
}
@-o-keyframes state3 {
    24.5% { background-color: gray; }
    25% { background-color: green; }
    100% { background-color: green; }
}
@keyframes state3 {
    24.5% { background-color: gray; }
    25% { background-color: green; }
    100% { background-color: green; }
}
@-webkit-keyframes state4 {
    37% { background-color: gray; }
    37.5% { background-color: green; }
    100% { background-color: green; }
}
@-moz-keyframes state4 {
    37% { background-color: gray; }
    37.5% { background-color: green; }
    100% { background-color: green; }
}
@-o-keyframes state4 {
    37% { background-color: gray; }
    37.5% { background-color: green; }
    100% { background-color: green; }
}
@keyframes state4 {
    37% { background-color: gray; }
    37.5% { background-color: green; }
    100% { background-color: green; }
}
@-webkit-keyframes state5 {
    49.5% { background-color: gray; }
    50% { background-color: green; }
    100% { background-color: green; }
}
@-moz-keyframes state5 {
    49.5% { background-color: gray; }
    50% { background-color: green; }
    100% { background-color: green; }
}
@-o-keyframes state5 {
    49.5% { background-color: gray; }
    50% { background-color: green; }
    100% { background-color: green; }
}
@keyframes state5 {
    49.5% { background-color: gray; }
    50% { background-color: green; }
    100% { background-color: green; }
}
@-webkit-keyframes state6 {
    62% { background-color: gray; }
    62.5% { background-color: green; }
    100% { background-color: green; }
}
@-moz-keyframes state6 {
    62% { background-color: gray; }
    62.5% { background-color: green; }
    100% { background-color: green; }
}
@-o-keyframes state6 {
    62% { background-color: gray; }
    62.5% { background-color: green; }
    100% { background-color: green; }
}
@keyframes state6 {
    62% { background-color: gray; }
    62.5% { background-color: green; }
    100% { background-color: green; }
}
@-webkit-keyframes state7 {
    74.5% { background-color: gray; }
    75% { background-color: green; }
    100% { background-color: green; }
}
@-moz-keyframes state7 {
    74.5% { background-color: gray; }
    75% { background-color: green; }
    100% { background-color: green; }
}
@-o-keyframes state7 {
    74.5% { background-color: gray; }
    75% { background-color: green; }
    100% { background-color: green; }
}
@keyframes state7 {
    74.5% { background-color: gray; }
    75% { background-color: green; }
    100% { background-color: green; }
}
@-webkit-keyframes state8 {
    87% { background-color: gray; }
    87.5% { background-color: green; }
    100% { background-color: green; }
}
@-moz-keyframes state8 {
    87% { background-color: gray; }
    87.5% { background-color: green; }
    100% { background-color: green; }
}
@-o-keyframes state8 {
    87% { background-color: gray; }
    87.5% { background-color: green; }
    100% { background-color: green; }
}
@keyframes state8 {
    87% { background-color: gray; }
    87.5% { background-color: green; }
    100% { background-color: green; }
}

&#13;
&#13;
.smallCircles { 
    margin-bottom: 20px;
}
.smallCircles .circle { 
    height: 25px;
    width: 25px;
}
.largeCircles .circle {
    height: 75px;
    width: 75px;
}
.circle {
    display: inline-block;
    border-radius: 50%;
    background-color: gray;
}

.circle {
    -webkit-animation: 8s infinite;
    -moz-animation: 8s infinite;
    -o-animation: 8s infinite;
    animation: 8s infinite;
    -webkit-animation-fill-mode: forwards;
    -moz-animation-fill-mode: forwards;
    -o-animation-fill-mode: forwards;
    animation-fill-mode: forwards;
    -webkit-animation-timing-function: steps(1,end);
    -moz-animation-timing-function: steps(1,end);
    -o-animation-timing-function: steps(1,end);
    animation-timing-function: steps(1,end);
}

.smallCircles > .circle:nth-of-type(1) {
    -webkit-animation-name: state1;
    -moz-animation-name: state1;
    -o-animation-name: state1;
    animation-name: state1;
}
.smallCircles > .circle:nth-of-type(2) {
    -webkit-animation-name: state2;
    -moz-animation-name: state2;
    -o-animation-name: state2;
    animation-name: state2;
}
.smallCircles > .circle:nth-of-type(3) {
    -webkit-animation-name: state3;
    -moz-animation-name: state3;
    -o-animation-name: state3;
    animation-name: state3;
}
.smallCircles > .circle:nth-of-type(4) {
    -webkit-animation-name: state4;
    -moz-animation-name: state4;
    -o-animation-name: state4;
    animation-name: state4;
}
.largeCircles > .circle:nth-of-type(1) {
    -webkit-animation-name: state5;
    -moz-animation-name: state5;
    -o-animation-name: state5;
    animation-name: state5;
}
.largeCircles > .circle:nth-of-type(2) {
    -webkit-animation-name: state6;
    -moz-animation-name: state6;
    -o-animation-name: state6;
    animation-name: state6;
}
.largeCircles > .circle:nth-of-type(3) {
    -webkit-animation-name: state7;
    -moz-animation-name: state7;
    -o-animation-name: state7;
    animation-name: state7;
}
.largeCircles > .circle:nth-of-type(4) {
    -webkit-animation-name: state8;
    -moz-animation-name: state8;
    -o-animation-name: state8;
    animation-name: state8;
}

@-webkit-keyframes state1 {
    0% { background-color: green; }
    100% {background-color: green; }
}
@-moz-keyframes state1 {
    0% { background-color: green; }
    100% { background-color: green; }
}
@-o-keyframes state1 {
    0% { background-color: green; }
    100% { background-color: green; }
}
@keyframes state1 {
    0% { background-color: green; }
    100% { background-color: green; }
}
@-webkit-keyframes state2 {
    12% { background-color: gray; }
    12.5% { background-color: green; }
    100% { background-color: green; }
}
@-moz-keyframes state2 {
    12% { background-color: gray; }
    12.5% { background-color: green; }
    100% { background-color: green; }
}
@-o-keyframes state2 {
    12% { background-color: gray; }
    12.5% { background-color: green; }
    100% { background-color: green; }
}
@keyframes state2 {
    12% { background-color: gray; }
    12.5% { background-color: green; }
    100% { background-color: green; }
}
@-webkit-keyframes state3 {
    24.5% { background-color: gray; }
    25% { background-color: green; }
    100% { background-color: green; }
}
@-moz-keyframes state3 {
    24.5% { background-color: gray; }
    25% { background-color: green; }
    100% { background-color: green; }
}
@-o-keyframes state3 {
    24.5% { background-color: gray; }
    25% { background-color: green; }
    100% { background-color: green; }
}
@keyframes state3 {
    24.5% { background-color: gray; }
    25% { background-color: green; }
    100% { background-color: green; }
}
@-webkit-keyframes state4 {
    37% { background-color: gray; }
    37.5% { background-color: green; }
    100% { background-color: green; }
}
@-moz-keyframes state4 {
    37% { background-color: gray; }
    37.5% { background-color: green; }
    100% { background-color: green; }
}
@-o-keyframes state4 {
    37% { background-color: gray; }
    37.5% { background-color: green; }
    100% { background-color: green; }
}
@keyframes state4 {
    37% { background-color: gray; }
    37.5% { background-color: green; }
    100% { background-color: green; }
}
@-webkit-keyframes state5 {
    49.5% { background-color: gray; }
    50% { background-color: green; }
    100% { background-color: green; }
}
@-moz-keyframes state5 {
    49.5% { background-color: gray; }
    50% { background-color: green; }
    100% { background-color: green; }
}
@-o-keyframes state5 {
    49.5% { background-color: gray; }
    50% { background-color: green; }
    100% { background-color: green; }
}
@keyframes state5 {
    49.5% { background-color: gray; }
    50% { background-color: green; }
    100% { background-color: green; }
}
@-webkit-keyframes state6 {
    62% { background-color: gray; }
    62.5% { background-color: green; }
    100% { background-color: green; }
}
@-moz-keyframes state6 {
    62% { background-color: gray; }
    62.5% { background-color: green; }
    100% { background-color: green; }
}
@-o-keyframes state6 {
    62% { background-color: gray; }
    62.5% { background-color: green; }
    100% { background-color: green; }
}
@keyframes state6 {
    62% { background-color: gray; }
    62.5% { background-color: green; }
    100% { background-color: green; }
}
@-webkit-keyframes state7 {
    74.5% { background-color: gray; }
    75% { background-color: green; }
    100% { background-color: green; }
}
@-moz-keyframes state7 {
    74.5% { background-color: gray; }
    75% { background-color: green; }
    100% { background-color: green; }
}
@-o-keyframes state7 {
    74.5% { background-color: gray; }
    75% { background-color: green; }
    100% { background-color: green; }
}
@keyframes state7 {
    74.5% { background-color: gray; }
    75% { background-color: green; }
    100% { background-color: green; }
}
@-webkit-keyframes state8 {
    87% { background-color: gray; }
    87.5% { background-color: green; }
    100% { background-color: green; }
}
@-moz-keyframes state8 {
    87% { background-color: gray; }
    87.5% { background-color: green; }
    100% { background-color: green; }
}
@-o-keyframes state8 {
    87% { background-color: gray; }
    87.5% { background-color: green; }
    100% { background-color: green; }
}
@keyframes state8 {
    87% { background-color: gray; }
    87.5% { background-color: green; }
    100% { background-color: green; }
}
&#13;
<div class="smallCircles">
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
</div>
<div class="largeCircles">
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
</div>
&#13;
&#13;
&#13;

<强>替代: 由于浏览器的兼容性,代码可能会非常重复,因为我们使用相同的声明,但使用不同的供应商前缀。更好的方法是使用CSS预处理器,例如 LESS 。这会大大降低代码,例如下面的内容。

<强> LESS

@-webkit-keyframes some-animation {.state1;}
@-moz-keyframes some-animation {.state1;}
@-o-keyframes some-animation {.state1;}
@keyframes some-animation {.state1;}

.state1 () {
    0% { background-color: green; }
    100% {background-color: green; }
}