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>
我能想到的是:
- 对于香草 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
- 反应:
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>
);
}
- 对于纯 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 是公平的游戏 ;)。
这是我的建议:
仅当元素具有额外的 class(在我的示例中为“运行”)时才启动动画。
将“运行”添加到第一个元素。
为 the animationend event 添加侦听器。
如果结束的动画是相关的。
一个。从元素中删除 '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。
我有 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>
我能想到的是:
- 对于香草 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
- 反应:
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>
);
}
- 对于纯 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 是公平的游戏 ;)。
这是我的建议:
仅当元素具有额外的 class(在我的示例中为“运行”)时才启动动画。
将“运行”添加到第一个元素。
为 the animationend event 添加侦听器。
如果结束的动画是相关的。
一个。从元素中删除 '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。