CSS动画数个div一个接一个

CSS Animation several div one after another

我有 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 编写都没有关系。我感谢每一个使代码尽可能简单的建议。

考虑到您 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 上的 class 名称(.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的动态数。它们都从元素中删除了 class 名称,因此它可能更干净并避免将来出现一些问题(例如,您想在第二个和第三个 [=42] 之间插入另一个 div =],或切换 div 元素的顺序)。 2. 的想法是,您可以只使用内联样式在每个元素上附加不同的 css 延迟持续时间。

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

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

这是我的建议:

  1. 仅当元素具有额外的 class(在我的示例中为“运行”)时才启动动画。

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

  3. the animationend event 添加侦听器。

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

    一个。从元素中删除 'run' class。

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

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

下面是这个逻辑的实现

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