【问题标题】:CSS Animation several div one after anotherCSS Animation 几个 div 一个接一个
【发布时间】:2021-05-03 17:42:39
【问题描述】:

我有 7 个 div 元素(作为 100x100),我希望每个盒子一个接一个地转动 - 所以,当第一个完成旋转时,下一个开始。最好的情况是这将永远持续下去。但我不确定在哪里放置无限。我在问我是否可以仅在一个语句中而不是在这么多行中进行动画延迟。动画本身可以按我的意愿工作,但我对我编写代码的方式不满意。有没有更简单的方法?

这是我的代码:

div {
  margin: 24px;
  width: 50px;
  height: 50px;
  float: left;
  background: #0f9;
  
  animation: spin 4s cubic-bezier(.84, .13, .40, .96);
}

@keyframes spin {
  0% {
    transform: rotateY(0turn);
  }
  100% {
    transform: rotateY(7turn);
  }
}

.two {
  animation-delay: 4s;
}

.three {
  animation-delay: 8s;
}

.four {
  animation-delay: 12s;
}

.five {
  animation-delay: 16s;
}

.six {
  animation-delay: 20s;
}

.seven {
  animation-delay: 24s;
}
<div></div>
<div class="two"></div>
<div class="three"></div>
<div class="four"></div>
<div class="five"></div>
<div class="six"></div>
<div class="seven"></div>

目前,我在每个盒子上都有延迟。不管它是用纯 CSS、JS 还是 React 编写的。我感谢每一个使代码尽可能简单的建议。

【问题讨论】:

  • 你是在问如何让动画循环播放?
  • 我在问我是否可以写 .two {animation-delay}, three.{anim.. 例如只在一个语句中,而不是在这么多行中。动画本身可以按我的意愿工作,但我对我编写代码的方式不满意。
  • div的个数是固定的吗?您是避免使用 sass 还是可以使用它(因为它可能使动态情况更容易定义)?
  • @salia_in_red 除非你使用像sass 这样的预处理器,否则我很确定它会尽可能地紧凑。
  • @MosheJonathanGordonRadian sass 当然完全没问题 :) 是的,对于这个项目,div 的数量是恒定的!

标签: javascript css reactjs css-animations keyframe


【解决方案1】:

最后不需要 sass,因为 JS 是公平的游戏;)。

这是我的建议:

  1. 仅当元素具有附加类(在我的示例中为“run”)时才开始动画。

  2. 将“run”添加到第一个元素。

  3. the animationend event 添加一个监听器。

  4. 如果结束的动画是相关的。

    一个。从元素中移除 'run' 类。

    b.获取下一个兄弟(即通过 nextElementSibling 属性)或第一个元素(如果这是最后一个元素)。

    c。将 'run' 类添加到兄弟元素。

这是这个逻辑的一个实现

function sync(animationName) {
  function animationEnd(event) {
    console.log(event.animationName);
    if (event.animationName === animationName) {
      const el = event.target;
      el.classList.remove("run");
      if (el.nextElementSibling) {
        el.nextElementSibling.classList.add("run");
      } else if (el.parentElement && el.parentElement.children && el.parentElement.children[0]) {
        el.parentElement.children[0].classList.add("run");
      }
    }
  }
  window.addEventListener('animationend', animationEnd, true);

  const firstEl = document.querySelector(".hi");
  if (firstEl) {
    firstEl.classList.add("run");
  }
}

Full fiddle of an implementation example(用我自己的动画,因为我基于一个不同问题的解决方案:P + 它看起来很酷)。

最后,这是fiddle running your example

【讨论】:

    【解决方案2】:

    假设你有这样的 html:

    <div id="divs">
      <div>1</div>
      <div>2</div>
      <div>3</div>
      <div>4</div>
      <div>5</div>
      <div>6</div>
      <div>7</div>
    </div>
    

    我能想到的是:

    1. 对于原版 js:
    function generateDelayDivCss() {
      let cssStrings = [1, 2, 3, 4, 5].map(
        (n, idx) =>
          `#divs div:nth-child(${idx + 1}) {
          animation-delay: ${idx * 4}s;
        }`
      );
      return cssStrings.join("");
    }
    
    // then append the css from the result of the generateDelayDivCss() to the document
    // let css = generateDelayDivCss();
    // create <style> element and append to document
    
    1. 反应:
    export default function App() {
      return (
        <div className="items">
          {[1, 2, 3, 4, 5].map((n, idx) => (
            <div className="item" style={{ animationDelay: `${idx * 4}s` }} />
          ))}
        </div>
      );
    }
    
    1. 对于纯css,或许你可以替换div上的类名(.second,.three ...),只用css来识别:
    #divs div:nth-child(2) {
      animation-delay: 4s;
    }
    
    #divs div:nth-child(3) {
      animation-delay: 8s;
    }
    
    ... // yes, you still need to write the following animation-delay for each div element :(
    

    1.和3.方式的思路基本相同,但是js可以根据需要支持动态的div个数。两者都从元素中删除了类名,这样可能会更干净,避免将来出现一些问题(例如,您想在第二个和第三个div之间插入另一个div,或者切换div元素的顺序) . 2.的想法是你可以只使用内联样式在每个元素上附加不同的css延迟时间。

    此外,还有其他东西,如 css-preprocessor(如评论中所述!)或 css-in-js 库,可以实现这一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-11
      • 2015-10-24
      • 1970-01-01
      • 2013-01-27
      相关资源
      最近更新 更多