1

I'm trying to make an animation loading screen but I can't loop the multiple keyframes. I learned that I can only do it with JavaScript and I'm not good with scripting how can I do it?
Also, I can't make it one keyframe (slide in arrow 1 then 2 then 3 will slide in and slideout arrow 3 will slide out first then 2 then 3)

let index = 1;

function repeatAnimation() {
  const arrow = document.querySelector('.arrow');

  if (index === 1) {
    arrow.style.animationName = 'slideIn';
    index = 0;
  } else {
    arrow.style.animationName = 'slideOut';
    index = 1;
  }

}

setInterval(repeatAnimation, 2000);
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #f4f4f4;
  color: #EE4036;
  font-family: Arial, sans-serif;
  font-weight: bolder;
  font-size: xx-large;
}

.arrows {
  display: flex;
  justify-content: start;
  align-items: start;
  padding-left: 6px;
  gap: 3px;
}


/* Common styles for arrows */

.arrow {
  position: relative;
  width: 10px;
  height: 10px;
  background: #EE4036;
  border-top-right-radius: 30%;
  transform: rotate(-60deg) skewX(-30deg) scale(1, .866);
  rotate: 90deg;
  opacity: 0;
  animation: slideInOut 6s infinite;
}

.arrow::before,
.arrow::after {
  content: "";
  position: absolute;
  width: inherit;
  height: inherit;
  background: inherit;
  border-top-right-radius: inherit;
}

.arrow::before {
  background: #EE4036;
  transform: rotate(-135deg) skewX(-45deg) scale( 1.414, .707) translateY(-50%);
}

.arrow::after {
  background: #EE4036;
  transform: rotate(135deg) skewY(-45deg) scale( .707, 1.414) translateX(50%);
}

@keyframes slideIn {
  from {
    transform: translateY(100%) rotate(-60deg) skewX(-30deg) scale(1, .866);
    opacity: 0;
  }
  to {
    transform: translateY(0) rotate(-60deg) skewX(-30deg) scale(1, .866);
    opacity: 1;
  }
}

@keyframes slideOut {
  from {
    transform: translateY(100%) rotate(-60deg) skewX(-30deg) scale(1, .866);
    opacity: 1;
    left: 10px;
  }
  to {
    transform: translateY(0) rotate(-60deg) skewX(-30deg) scale(1, .866);
    opacity: 0;
    left: 10px;
  }
}

.arrow {
  opacity: 0;
  animation: slideIn 0.5s forwards, slideOut 0.5s forwards, repeatSequence 2s infinite;
}

.arrow_1 {
  animation-delay: 0s, 2.5s;
}

.arrow_2 {
  animation-delay: 0.5s, 2s;
}

.arrow_3 {
  animation-delay: 1s, 1.5s;
}
<section>
  <div class="loading">Loading</div>
  <section class="arrows">
    <div class="arrow arrow_1"></div>
    <div class="arrow arrow_2"></div>
    <div class="arrow arrow_3"></div>
  </section>
</section>

im really bad with script but i think this how i should do it but its working only on the first arroe

5 Answers 5

1

You really don't need JS but I would recommend making an own animation for ever single arrow:

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #f4f4f4;
  color: #EE4036;
  font-family: Arial, sans-serif;
  font-weight: bolder;
  font-size: xx-large;
}

.arrows {
  display: flex;
  justify-content: start;
  align-items: start;
  padding-left: 6px;
  gap: 3px;
}


/* Common styles for arrows */
.arrow {
  position: relative;
  width: 10px;
  height: 10px;
  background: #EE4036;
  border-top-right-radius: 30%;
  transform: rotate(-60deg) skewX(-30deg) scale(1, .866);
  rotate: 90deg;
  opacity: 0;
  animation: slideInOut 6s infinite;
  &::before, &::after {
    content: "";
    position: absolute;
    width: inherit;
    height: inherit;
    background: inherit;
    border-top-right-radius: inherit;
    background: #EE4036;
  }
  &::before {
    transform: rotate(-135deg) skewX(-45deg) scale( 1.414, .707) translateY(-50%);
  }
  &::after {
    transform: rotate(135deg) skewY(-45deg) scale( .707, 1.414) translateX(50%);
  }
}

@keyframes arrow1 {
  from {
    opacity: 0;
    left: -10px
  }
  12.5%,
  75% {
    opacity: 1;
    left: 0
  }
  87.5%,
  100% {
    opacity: 0;
    left: 10px;
  }
}

@keyframes arrow2 {
  0%,
  12.5% {
    opacity: 0;
    left: -10px
  }
  25%,
  62.5% {
    opacity: 1;
    left: 0
  }
  75%,
  100% {
    opacity: 0;
    left: 10px;
  }
}

@keyframes arrow3 {
  0%,
  25% {
    opacity: 0;
    left: -10px
  }
  37.5%,
  50% {
    opacity: 1;
    left: 0
  }
  62.5%,
  100% {
    opacity: 0;
    left: 10px;
  }
}


.arrows {
  .arrow { 
    &:nth-child(1) {
      animation: arrow1 3.5s infinite;
    }
    &:nth-child(2) {
      animation: arrow2 3.5s infinite;
    }
    &:nth-child(3) {
      animation: arrow3 3.5s infinite;
    }
  }
}
<section>
  <div class="loading">Loading</div>
  <section class="arrows">
    <div class="arrow"></div>
    <div class="arrow"></div>
    <div class="arrow"></div>
  </section>
</section>

0

If the start from the third arrow is not critical, then only one animation with appropriate animation-delay will be needed:

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #f4f4f4;
  color: #EE4036;
  font-family: Arial, sans-serif;
  font-weight: bolder;
  font-size: xx-large;
}

.arrows {
  display: flex;
  justify-content: start;
  align-items: start;
  padding-left: 6px;
  gap: 4px;
}


/* Common styles for arrows */

.arrow {
  position: relative;
  width: 10px;
  height: 10px;
  background: #EE4036;
  border-top-right-radius: 30%;
  transform: rotate(-60deg) skewX(-30deg) scale(1, .866);
  rotate: 90deg;
  opacity: 0;
  animation: slideInOut 6s infinite;
}

.arrow::before,
.arrow::after {
  content: "";
  position: absolute;
  width: inherit;
  height: inherit;
  background: inherit;
  border-top-right-radius: inherit;
}

.arrow::before {
  background: #EE4036;
  transform: rotate(-135deg) skewX(-45deg) scale( 1.414, .707) translateY(-50%);
}

.arrow::after {
  background: #EE4036;
  transform: rotate(135deg) skewY(-45deg) scale( .707, 1.414) translateX(50%);
}

@keyframes arrow {
  0% {
    opacity: 0;
    translate: -100% 0;
  }
  12.5%,
  50% {
    opacity: 1;
    translate: 0;
  }
  62.5%,
  100%  {
    opacity: 0;
    translate: 100% 0;
  }
}

.arrow { 
  animation: arrow 2s infinite;
  &:nth-child(2) {
      animation-delay: .25s;
  }
  &:nth-child(1) {
      animation-delay: .5s;
  }
}
<section>
  <div class="loading">Loading</div>
  <section class="arrows">
    <div class="arrow"></div>
    <div class="arrow"></div>
    <div class="arrow"></div>
  </section>
</section>

0

I have created the same animation on loop with JS.

So, what I have done is dynamically added display: none after animation is completed & added display: flex after few seconds. What this do is it hides element and unhides element which helps to restart the animation. Also added setInterval which will run above process on loop.

If you have query with code feel free to ask. Also your animation looks good.Thanks.

let allArrows = document.querySelector(".arrows");
let delayOne = 0;
let delayTwo = 2.5;

function addAnimation() {
  allArrows.style.display = "flex";
  setTimeout(() => {
    allArrows.style.display = "none";
    delayOne = 0;
    delayTwo = 2.5;
  }, 2700);
}

addAnimation();

setInterval(() => {
  addAnimation();
}, 3000);
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #f4f4f4;
  color: #ee4036;
  font-family: Arial, sans-serif;
  font-weight: bolder;
  font-size: xx-large;
}

.arrows {
  display: flex;
  justify-content: start;
  align-items: start;
  padding-left: 6px;
  gap: 3px;
}

/* Common styles for arrows */

.arrow {
  position: relative;
  width: 10px;
  height: 10px;
  background: #ee4036;
  border-top-right-radius: 30%;
  transform: rotate(-60deg) skewX(-30deg) scale(1, 0.866);
  rotate: 90deg;
  opacity: 0;
  animation: slideInOut 6s infinite;
}

.arrow::before,
.arrow::after {
  content: "";
  position: absolute;
  width: inherit;
  height: inherit;
  background: inherit;
  border-top-right-radius: inherit;
}

.arrow::before {
  background: #ee4036;
  transform: rotate(-135deg) skewX(-45deg) scale(1.414, 0.707) translateY(-50%);
}

.arrow::after {
  background: #ee4036;
  transform: rotate(135deg) skewY(-45deg) scale(0.707, 1.414) translateX(50%);
}

@keyframes slideIn {
  from {
    transform: translateY(100%) rotate(-60deg) skewX(-30deg) scale(1, 0.866);
    opacity: 0;
  }
  to {
    transform: translateY(0) rotate(-60deg) skewX(-30deg) scale(1, 0.866);
    opacity: 1;
  }
}

@keyframes slideOut {
  from {
    transform: translateY(100%) rotate(-60deg) skewX(-30deg) scale(1, 0.866);
    opacity: 1;
    left: 10px;
  }
  to {
    transform: translateY(0) rotate(-60deg) skewX(-30deg) scale(1, 0.866);
    opacity: 0;
    left: 10px;
  }
}

.arrow {
  opacity: 0;
  animation: slideIn 0.5s forwards, slideOut 0.5s forwards,
    repeatSequence 2s infinite;
}

.arrow_1 {
  animation-delay: 0s, 2.5s;
}

.arrow_2 {
  animation-delay: 0.5s, 2s;
}

.arrow_3 {
  animation-delay: 1s, 1.5s;
}
/* NEWLY ADDED */

section {
  position: relative;
}

.arrows {
  position: absolute;
}
<section>
  <div class="loading">Loading</div>
  <section class="arrows">
    <div class="arrow arrow_1"></div>
    <div class="arrow arrow_2"></div>
    <div class="arrow arrow_3"></div>
  </section>
</section>

0

I have used the setTimeout function in the javascript to repeat the animation infinitely. Initially, the CSS class applied and ran the animation. once the animation was complete I removed the animation class for each of the arrows and add again to run the animation again.

const arrow1 = document.querySelector('.arrow_1');
const arrow2 = document.querySelector('.arrow_2');
const arrow3 = document.querySelector('.arrow_3');

//Run every 6s second
setInterval(function () {
  arrow1.classList.remove('animationClass1');
  arrow1.offsetHeight;
  arrow1.classList.add('animationClass1');
  
  arrow2.classList.remove('animationClass2');
  arrow2.offsetHeight;
  arrow2.classList.add('animationClass2');
  
  arrow3.classList.remove('animationClass3');
  arrow3.offsetHeight;
  arrow3.classList.add('animationClass3');  
}, 6000);
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #f4f4f4;
  color: #EE4036;
  font-family: Arial, sans-serif;
  font-weight: bolder;
  font-size: xx-large;
}

.arrows {
  display: flex;
  justify-content: start;
  align-items: start;
  padding-left: 6px;
  gap: 3px;
}


/* Common styles for arrows */

.arrow {
  position: relative;
  width: 10px;
  height: 10px;
  background: #EE4036;
  border-top-right-radius: 30%;
  transform: rotate(-60deg) skewX(-30deg) scale(1, .866);
  rotate: 90deg;
  opacity: 0;
  
}

.arrow::before,
.arrow::after {
  content: "";
  position: absolute;
  width: inherit;
  height: inherit;
  background: inherit;
  border-top-right-radius: inherit;
}

.arrow::before {
  background: #EE4036;
  transform: rotate(-135deg) skewX(-45deg) scale( 1.414, .707) translateY(-50%);
}

.arrow::after {
  background: #EE4036;
  transform: rotate(135deg) skewY(-45deg) scale( .707, 1.414) translateX(50%);
}
@keyframes slideIn {
  from {
    transform: translateY(100%) rotate(-60deg) skewX(-30deg) scale(1, 0.866);
    opacity: 0;
  }
  to {
    transform: translateY(0) rotate(-60deg) skewX(-30deg) scale(1, 0.866);
    opacity: 1;
  }
}

@keyframes slideOut {
  from {
    transform: translateY(100%) rotate(-60deg) skewX(-30deg) scale(1, 0.866);
    opacity: 1;
    left: 10px;
  }
  to {
    transform: translateY(0) rotate(-60deg) skewX(-30deg) scale(1, 0.866);
    opacity: 0;
    left: 10px;
  }
}

.animationClass1 {
  animation: slideIn 0.5s forwards 0s, slideOut 0.5s forwards 5s;
}

.animationClass2 {
  animation: slideIn 0.5s forwards 1s, slideOut 0.5s forwards 4s;
}

.animationClass3 {
  animation: slideIn 0.5s forwards 2s, slideOut 0.5s forwards 3s;
}
<section>
  <div class="loading">Loading</div>
  <section class="arrows">
    <div class="arrow arrow_1 animationClass1"></div>
    <div class="arrow arrow_2 animationClass2"></div>
    <div class="arrow arrow_3 animationClass3"></div>
  </section>
</section>

-1

You can achieve this without using the JS and but have to be very careful for animation

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #f4f4f4;
  color: #EE4036;
  font-family: Arial, sans-serif;
  font-weight: bolder;
  font-size: xx-large;
}

.loading {
  margin-bottom: 20px;
}

.arrows {
  display: flex;
  justify-content: start;
  align-items: start;
  padding-left: 6px;
  gap: 3px;
}

.arrow {
  position: relative;
  width: 10px;
  height: 10px;
  background: #EE4036;
  border-top-right-radius: 30%;
  transform: rotate(-60deg) skewX(-30deg) scale(1, .866);
  rotate: 90deg;
  opacity: 0;
  animation: slideSequence 6s infinite;
}

.arrow::before,
.arrow::after {
  content: "";
  position: absolute;
  width: inherit;
  height: inherit;
  background: inherit;
  border-top-right-radius: inherit;
}

.arrow::before {
  background: #EE4036;
  transform: rotate(-135deg) skewX(-45deg) scale(1.414, .707) translateY(-50%);
}

.arrow::after {
  background: #EE4036;
  transform: rotate(135deg) skewY(-45deg) scale(.707, 1.414) translateX(50%);
}

@keyframes slideSequence {
  0%, 20%, 40%, 60%, 80%, 100% {
    opacity: 0;
    transform: translateY(100%) rotate(-60deg) skewX(-30deg) scale(1, .866);
  }
  10%, 30%, 50%, 70%, 90% {
    opacity: 1;
    transform: translateY(0) rotate(-60deg) skewX(-30deg) scale(1, .866);
  }
  25%, 45%, 65%, 85% {
    opacity: 0;
    transform: translateY(100%) rotate(-60deg) skewX(-30deg) scale(1, .866);
  }
}

.arrow_1 {
  animation-delay: 0s;
}

.arrow_2 {
  animation-delay: 0.5s;
}

.arrow_3 {
  animation-delay: 1s;
}
<section>
  <div class="loading">Loading</div>
  <section class="arrows">
    <div class="arrow arrow_1"></div>
    <div class="arrow arrow_2"></div>
    <div class="arrow arrow_3"></div>
  </section>
</section>

Please note that:

slideSequence animation keyframes manage the entire animation and sequence. The arrow elements each have different animation-delay values to stagger their animations

1
  • 3
    that animation looks completely messed up to me
    – tacoshy
    Commented Jul 10 at 9:02

Not the answer you're looking for? Browse other questions tagged or ask your own question.