Reputation: 3792
I am trying to achieve the following animation:
I have eight circles, four small and four large. The first one (small circle) has green background color, the rest of the small circles have gray background color, the large circles have red background color. The animation will, with each second that goes by, add green background color to the circles one at a time. When all the circles have background color green, then there will be a 1 second delay before the whole animation starts from scratch. The animation will repeat the animation infinitely.
TLDR: jsFiddle
Initial state: 1 small circle colored green, 3 small circles gray, 4 large circles red.
In between: one at a time, color each circle green every 1 second, until all the circles are green.
Final state: 4 small and 4 large circles colored green. Reset the initial state and repeat the animation infinitely.
-- EDIT START --
To those interested in the collective solution I put together, you may find it in this jsFiddle, it involves both CSS and jQuery. When you first see it, it will be using jQuery; to see pure CSS implementation, delete the comment in the CSS which will enable the animation markup. Make sure to comment jQuery out.
-- EDIT END --
Note: I would preferably like to find a CSS only solution but I am very novice regarding CSS animations and it's been a real pain so far, that is why I came here to ask for help. However if it is not possible using CSS alone, then please entertain a jQuery solution. In light of that, here is what I have tried in jQuery but to no avail:
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);
}
}
}
My failed attempts in CSS animations, this is 100% without jQuery:
.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;}
}
Upvotes: 3
Views: 435
Reputation: 1121
Solution: This effect can be achieved entirely with CSS keyframes and animation.
Browser support I've included: Firefox 5+, IE 10+, Chrome, Safari 4+, Opera 12+
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; }
}
.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; }
}
<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>
Alternative: Due to browser compatabilty the code can get very repetitive, since we're using the same declarations, but with different vendor prefixes. A nicer way of doing this would be using a CSS preprocessor, such as LESS. This would cut the code down dramatically, example below.
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; }
}
Upvotes: 2
Reputation: 9057
This is possible with CSS only, if a little tedious. You'll need to set up a new keyframes animation for each and every circle. Each circle stays gray and then turns green 12.5% (100 divided by 8) further into the animation than the previous animation. All animations are set to last 8 seconds and repeat ad inifinium.
The example code below uses the standard syntax. You may wish to add vendor prefixes to ensure legacy support, but all major browsers currently support this syntax.
@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;
}
Upvotes: 4
Reputation: 1
Try utilizing .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>
Upvotes: 2