【问题标题】:Reverse Multiple CSS Keyframe Animations On Toggle在切换时反转多个 CSS 关键帧动画
【发布时间】:2021-08-03 13:32:11
【问题描述】:

我正在制作一个小动画,用于在明暗模式之间切换我的网站。这是一个相当复杂的动画,所以我猜解决方案也会很复杂。

我基本上在类之间切换,但这会阻止我在切换按钮时反转动画。一直在网上寻找简单的解决方案,但没有找到任何解释如何使用多个 CSS 关键帧反转动画。

这是代码的CSS部分,基本上重复了8次:

.line {
width: 1rem;
height: 2rem;
background-color: black;
position: absolute;
display: block;
transform: translateY(5rem);
border-radius: 0.5em;
}
.is-dark {
animation: is-dark 2s forwards;
}
@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);
    }
}

JS

let line = document.querySelector(".line");

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

btn.addEventListener("click", toggleDarkMode);

function toggleDarkMode() {
  line.classList.toggle("is-dark");
}

这是此按钮的完整版本:https://jsfiddle.net/a6euokxy/4/

提前致谢, 陆拉蒙

【问题讨论】:

    标签: javascript html css


    【解决方案1】:

    我有一些解决你的问题。我改进了 js 文件,确实添加了带有动画alternate infinite paused; 属性的类。在 html 中添加了动画类。

    working exampleLocalStorage

    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>

    【讨论】:

    • 感谢@ЖнецЪ 抽出宝贵时间,虽然有一点小问题。向按钮发送垃圾邮件时,将在 2 秒后执行操作,这会导致奇怪的结果。和我的一个朋友一起进一步研究。
    猜你喜欢
    • 2019-09-28
    • 1970-01-01
    • 1970-01-01
    • 2011-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多