Skip to content Skip to sidebar Skip to footer

Reverse Multiple CSS Keyframe Animations On Toggle

I'm working on a little animation for toggling my website between dark- and light mode. It's a pretty complicated animation, so I'm guessing the solution will be complicated as wel

Solution 1:

I have some the solution for you issue. I improved js file, did add into classes with animation alternate infinite paused; properties. In html added classes with animation.

working example with LocalStorage

let theme = 'light';
// Get all container elements
const lines = document.querySelector('.container').querySelectorAll('div');

let btn = document.querySelector('.btn');

btn.addEventListener('click', toggleDarkMode);

function toggleDarkMode() {
  if (theme === 'light') {
    lines.forEach(line => {
      // Remove unnecessary DOM elements
      if (!line.hasAttribute('class')) return;
      // Set pause after play 2s animation
      setTimeout(() => {
        line.removeAttribute('style');
      }, 2000);
      // Start play
      line.setAttribute('style', 'animation-play-state: running');
    });
    theme = 'dark';
    return;
  }

  if (theme === 'dark') {
    lines.forEach(line => {
      if (!line.hasAttribute('class')) return;

      setTimeout(() => {
        line.removeAttribute('style');
      }, 2000);

      line.setAttribute('style', 'animation-play-state: running');
    });
    theme = 'light';
    return;
  }
}
* {
  padding: 0;
  margin: 0;
}

.button {
  display: flex;
  justify-content: center;
  margin-top: 3rem;
}

.button .btn {
  background: none;
  border: 0.2rem solid black;
  font-size: 1rem;
  padding: 1rem;
  border-radius: 2rem;
  font-weight: bold;
}

.container {
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

#circle {
  width: 4rem;
  height: 4rem;
  border: 1rem solid black;
  border-radius: 50%;
  position: absolute;
}

#lines {
  display: flex;
  justify-content: center;
  align-items: center;
}

#lines1 {
  transform: rotate(45deg);
  transform-origin: center;
  position: absolute;
  display: flex;
  justify-content: center;
  align-items: center;
}

.line,
.line1,
.line2,
.line3,
.line4,
.line5,
.line6,
.line7 {
  width: 1rem;
  height: 2rem;
  background-color: black;
  position: absolute;
  display: block;
  border-radius: 0.5em;
}

.line {
  transform: translateY(5rem);
}

.is-dark {
  animation: is-dark 2s alternate infinite paused;
}

@keyframes is-dark {
  0% {
    height: 2rem;
    width: 1rem;
    border-radius: 0.5em;
    transform: translateX(0) translateY(5rem);
  }
  33.33% {
    height: 1rem;
    width: 1rem;
    border-radius: 50%;
    transform: translateX(0) translateY(5rem);
  }
  66.66% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateX(0) translateY(0);
  }
  100% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateX(1rem) translateY(-1rem);
  }
}

.line1 {
  transform: translateY(-5rem);
}

.is-dark1 {
  animation: is-dark1 2s alternate infinite paused;
}

@keyframes is-dark1 {
  0% {
    height: 2rem;
    width: 1rem;
    border-radius: 0.5em;
    transform: translateY(-5rem);
    opacity: 100%;
  }
  33.33% {
    height: 1rem;
    width: 1rem;
    border-radius: 50%;
    transform: translateY(-5rem);
    opacity: 100%;
  }
  66.66% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateY(0);
    opacity: 100%;
  }
  66.67% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateY(0);
    opacity: 0;
  }
  100% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateY(0);
    opacity: 0;
  }
}

.line2 {
  transform: translateX(5rem) rotate(90deg);
}

.is-dark2 {
  animation: is-dark2 2s alternate infinite paused;
}

@keyframes is-dark2 {
  0% {
    height: 2rem;
    width: 1rem;
    border-radius: 0.5em;
    transform: translateX(5rem) rotate(90deg);
    opacity: 100%;
  }
  33.33% {
    height: 1rem;
    width: 1rem;
    border-radius: 50%;
    transform: translateX(5rem) rotate(90deg);
    opacity: 100%;
  }
  66.66% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateX(0) rotate(90deg);
    opacity: 100%;
  }
  66.67% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateX(0) rotate(90deg);
    opacity: 0;
  }
  100% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateX(0) rotate(90deg);
    opacity: 0;
  }
}

.line3 {
  transform: translateX(-5rem) rotate(90deg);
}

.is-dark3 {
  animation: is-dark3 2s alternate infinite paused;
}

@keyframes is-dark3 {
  0% {
    height: 2rem;
    width: 1rem;
    border-radius: 0.5em;
    transform: translateX(-5rem) rotate(90deg);
    opacity: 100%;
  }
  33.33% {
    height: 1rem;
    width: 1rem;
    border-radius: 50%;
    transform: translateX(-5rem) rotate(90deg);
    opacity: 100%;
  }
  66.66% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateX(0) rotate(90deg);
    opacity: 100%;
  }
  66.67% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateX(0) rotate(90deg);
    opacity: 0;
  }
  100% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateX(0) rotate(90deg);
    opacity: 0;
  }
}

.line4 {
  transform: translateY(5rem);
}

.is-dark4 {
  animation: is-dark4 2s alternate infinite paused;
}

@keyframes is-dark4 {
  0% {
    height: 2rem;
    width: 1rem;
    border-radius: 0.5em;
    transform: translateX(0) translateY(5rem);
    opacity: 100%;
  }
  33.33% {
    height: 1rem;
    width: 1rem;
    border-radius: 50%;
    transform: translateX(0) translateY(5rem);
    opacity: 100%;
  }
  66.66% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateX(0) translateY(0);
    opacity: 100%;
  }
  66.67% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateX(1rem) translateY(1rem);
    opacity: 0;
  }
  100% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateX(1rem) translateY(1rem);
    opacity: 0;
  }
}

.line5 {
  transform: translateY(-5rem);
}

.is-dark5 {
  animation: is-dark5 2s alternate infinite paused;
}

@keyframes is-dark5 {
  0% {
    height: 2rem;
    width: 1rem;
    border-radius: 0.5em;
    transform: translateY(-5rem);
    opacity: 100%;
  }
  33.33% {
    height: 1rem;
    width: 1rem;
    border-radius: 50%;
    transform: translateY(-5rem);
    opacity: 100%;
  }
  66.66% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateY(0);
    opacity: 100%;
  }
  66.67% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateY(0);
    opacity: 0;
  }
  100% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateY(0);
    opacity: 0;
  }
}

.line6 {
  transform: translateX(5rem) rotate(90deg);
}

.is-dark6 {
  animation: is-dark6 2s alternate infinite paused;
}

@keyframes is-dark6 {
  0% {
    height: 2rem;
    width: 1rem;
    border-radius: 0.5em;
    transform: translateX(5rem) rotate(90deg);
    opacity: 100%;
  }
  33.33% {
    height: 1rem;
    width: 1rem;
    border-radius: 50%;
    transform: translateX(5rem) rotate(90deg);
    opacity: 100%;
  }
  66.66% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateX(0) rotate(90deg);
    opacity: 100%;
  }
  66.67% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateX(0) rotate(90deg);
    opacity: 0;
  }
  100% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateX(0) rotate(90deg);
    opacity: 0;
  }
}

.line7 {
  transform: translateX(-5rem) rotate(90deg);
}

.is-dark7 {
  animation: is-dark7 2s alternate infinite paused;
}

@keyframes is-dark7 {
  0% {
    height: 2rem;
    width: 1rem;
    border-radius: 0.5em;
    transform: translateX(-5rem) rotate(90deg);
    opacity: 100%;
  }
  33.33% {
    height: 1rem;
    width: 1rem;
    border-radius: 50%;
    transform: translateX(-5rem) rotate(90deg);
    opacity: 100%;
  }
  66.66% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateX(0) rotate(90deg);
    opacity: 100%;
  }
  66.67% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateX(0) rotate(90deg);
    opacity: 0;
  }
  100% {
    height: 3rem;
    width: 3rem;
    border-radius: 50%;
    transform: translateX(0) rotate(90deg);
    opacity: 0;
  }
}
<div class="button">
  <button class="btn">Dark Mode</button>
</div>
<div class="container">
  <div id="circle"></div>
  <div id="lines">
    <div class="line is-dark"></div>
    <div class="line1 is-dark1"></div>
    <div class="line2 is-dark2"></div>
    <div class="line3 is-dark3"></div>
  </div>
  <div id="lines1">
    <div class="line4 is-dark4"></div>
    <div class="line5 is-dark5"></div>
    <div class="line6 is-dark6"></div>
    <div class="line7 is-dark7"></div>
  </div>
</div>

Post a Comment for "Reverse Multiple CSS Keyframe Animations On Toggle"