1

I have my code here that shows animation for a check-mark.

It works but the problem is that, it doesn't loop. It only animates for 1 time. What I want is to animate it every 2 seconds.

Codepen link: http://codepen.io/haniotis/pen/KwvYLO

CSS looks like this:

@import "bourbon";

$color--green: #7ac142;
$curve: cubic-bezier(0.650, 0.000, 0.450, 1.000);

.checkmark__circle {
  stroke-dasharray: 166;
  stroke-dashoffset: 166;
  stroke-width: 2;
  stroke-miterlimit: 10;
  stroke: $color--green;
  fill: none;
  animation: stroke .6s $curve forwards;
}

.checkmark {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  display: block;
  stroke-width: 2;
  stroke: #fff;
  stroke-miterlimit: 10;
  margin: 10% auto;
  box-shadow: inset 0px 0px 0px $color--green;
  animation: fill .4s ease-in-out .4s forwards, scale .3s ease-in-out .9s both;
}

.checkmark__check {
  transform-origin: 50% 50%;
  stroke-dasharray: 48;
  stroke-dashoffset: 48;
  animation: stroke .3s $curve .8s forwards;
}

@keyframes stroke {
  100% {
    stroke-dashoffset: 0;
  }
}

@keyframes scale {
  0%, 100% {
    transform: none;
  }
  50% {
    transform: scale3d(1.1, 1.1, 1);
  }
}

@keyframes fill {
  100% {
    box-shadow: inset 0px 0px 0px 30px $color--green;
  }
}

HTML looks like this:

<svg class="checkmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">
  <circle class="checkmark__circle" cx="26" cy="26" r="25" fill="none" />
  <path class="checkmark__check" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8" />
</svg>
Harry
  • 87,580
  • 25
  • 202
  • 214
tokis
  • 125
  • 1
  • 4
  • 14
  • 1
    Making the animation infinite is pretty easy, you just need to set iteration count as infinite. Repeating it every 2 seconds need some alterations to keyframes like mentioned [here](http://stackoverflow.com/questions/32223835/repeat-animation-every-3-seconds/32223950?s=1|3.5463#32223950). – Harry Feb 08 '16 at 08:17
  • 1
    For your case, it is a bit more complex than that because you are having 3 animations and each have to be tuned such that they let the others complete before starting their next loop. – Harry Feb 08 '16 at 08:25
  • Does this answer your question? [SVG animation delay on each repetition](https://stackoverflow.com/questions/31690880/svg-animation-delay-on-each-repetition) – Mahozad May 08 '22 at 15:52

1 Answers1

6

Note: Though this question is partly similar to the one I had linked in comments, it is a bit complex due to the presence of multiple animations that need to be chained together and hence I am adding a separate answer to explain it.

Making any CSS3 animation run infinite number of times is very simple. That can be achieved by just setting animation-iteration-count to infinite. But making an animation repeat every [x] seconds is a lot more complex because as explained in my answer here, the animation-delay property adds a delay only before the first iteration of the animation and not before each and every single iteration.

That answer explains how to add a delay between each iteration and so I wouldn't go into more details about that. But your case is a bit more complex because there are four animations which are chained together to produce the effect and so all of them need to be modified to make it work.

The following are the things that you need to do to make it repeat every 2 seconds infinitely:

  • Add animation-iteration-count: infinite to all 4 animations (or) just add infinite keyword to all animation shorthand properties.
  • Firstly calculate the total amount of time for which the entire animation (all 4 put together) runs. In your original snippet it was running for 1.2s and you needed a delay of 2s, so the total duration for the animation is 3.2s. This 3.2s should be made the duration for all the 4 animations.
  • The animation on .checkmark__circle was supposed to run for .6s and had no delay. .6s is roughly 18.75% of 3.2s and so the animation's keyframes should be changed so that the entire animation is completed at the 18.75% mark and it stays that way till 100% mark.
  • The animation on .checkmark__check was supposed to have a delay of .8s which is 25% of the 3.2s duration. So it should start at the 25% mark and duration was .3s which is roughly 9.37% of 3.2s. So, this animation should start at 25% mark and be complete by the time it reaches the 34.37% mark. From there on till 100% mark, it must hold that state. Since, the keyframes are now different with the circle animation, we need to add two different @keyframes rules.
  • The fill animation on .checkmark has .4s duration and same delay. So, it should start at 12.5% mark, complete at 25% mark and stay that way till the 100% mark.
  • The scale animation on .checkmark has a .3s duration and a .9s delay. So, this must start at 28.125% mark and complete by the 37.5% mark. This means the mid point (by which it should be transform: scale3d(1.1, 1.1, 1); would be at 32.8125% mark.

Once all these changes are done, the animation would run infinitely with a delay of 2 seconds between each loop. Below is a demo using the compiled CSS. The SCSS version is available here.

.checkmark__circle {
  stroke-dasharray: 166;
  stroke-dashoffset: 166;
  stroke-width: 2;
  stroke-miterlimit: 10;
  stroke: #7ac142;
  fill: none;
  animation: stroke 3.2s cubic-bezier(0.65, 0, 0.45, 1) forwards infinite;
}
.checkmark {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  display: block;
  stroke-width: 2;
  stroke: #fff;
  stroke-miterlimit: 10;
  margin: 10% auto;
  box-shadow: inset 0px 0px 0px #7ac142;
  animation: fill 3.2s ease-in-out forwards infinite, scale 3.2s ease-in-out both infinite;
}
.checkmark__check {
  transform-origin: 50% 50%;
  stroke-dasharray: 48;
  stroke-dashoffset: 48;
  animation: stroke-check 3.2s cubic-bezier(0.65, 0, 0.45, 1) forwards infinite;
}
@keyframes stroke {
  18.75%, 100% {
    stroke-dashoffset: 0;
  }
}
@keyframes stroke-check {
  25% {
    stroke-dashoffset: 48;
  }
  34.37%,
  100% {
    stroke-dashoffset: 0;
  }
}
@keyframes scale {
  0%, 28.125%, 37.5%, 100% {
    transform: none;
  }
  32.8125% {
    transform: scale3d(1.1, 1.1, 1);
  }
}
@keyframes fill {
  12.5% {
    box-shadow: inset 0px 0px 0px #7ac142;
  }
  25%,
  100% {
    box-shadow: inset 0px 0px 0px 30px #7ac142;
  }
}
<svg class="checkmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">
  <circle class="checkmark__circle" cx="26" cy="26" r="25" fill="none" />
  <path class="checkmark__check" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8" />
</svg>
Community
  • 1
  • 1
Harry
  • 87,580
  • 25
  • 202
  • 214