如何以编程方式在 CSS 动画中堆叠关键帧
How to stack keyframes in CSS animation programmatically
我正在尝试在下面堆叠 CSS 个关键帧(动画延迟),但我不确定如何以编程方式执行此操作?
.r1 {
animation-name: move1;
animation-delay: 0.5s;
animation-duration: 1s;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
.r2 {
animation-name: move1;
animation-delay: 1.5s;
animation-duration: 1s;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
.r3 {
animation-name: move1;
animation-delay: 2.5s;
animation-duration: 1s;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
@keyframes move1 {
to {
transform: translateX(200px);
}
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<rect class="r1" x="10" y="20" width="100" height="100" fill="red"/>
<rect class="r2" x="10" y="130" width="100" height="100" fill="green"/>
<rect class="r3" x="10" y="240" width="100" height="100" fill="blue"/>
</svg>
animation-duration
为每个 class 硬编码,animation-delay
为第一个 class 硬编码,即 r1
.
如何传递r2和r3的延迟,例如
r2 delay= r1 delay + r1 duration->0.5+1=1.5s
和
r3 delay= r2 delay + r2 duration ->1.5+1=2.5s
javascript 中有什么东西可以通过 class 给出 animation-duration
吗?
我尝试通过 Element.getAnimations() 执行此操作,但我不确定是否有任何东西可以通过 class 提供动画持续时间。
我不想手动执行此操作,因为 svg 中有很多 class。
提前致谢。
为您的直肠设置 r class,我认为这可以帮助您:
const blocks = document.querySelectorAll('svg rect');
for (let i = 1; i<blocks.length; i++) {
const element = blocks[i];
const prevElementStyles = getComputedStyle(blocks[i-1]);
element.style.animationDelay = `${parseFloat(prevElementStyles.animationDelay) + parseFloat(prevElementStyles.animationDuration)}s`;
}
r class:
.r {
animation-name: move1;
animation-delay: 0.5s;
animation-duration: 1s;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<rect class="r" x="10" y="20" width="100" height="100" fill="red"/>
<rect class="r" x="10" y="130" width="100" height="100" fill="green"/>
<rect class="r" x="10" y="240" width="100" height="100" fill="blue"/>
</svg>
动画链接:使用事件animationend
您可以通过对此事件使用侦听器来链接 CSS 动画。当元素上的动画完成时(包括动画延迟),它将被触发。或者,如果您使用 transitions
,则需要使用 transitionend 事件。
基本工作流程
将动画属性提取到单独的 class,例如.animation
.
#firstEl.animation {
// your animation properties
}
#secondEl.animation {
// your animation properties
}
// etc
const firstEl = document.getElementById('#firstEl');
const secondEl = document.getElementById('#secondEl');
const thirdEl = document.getElementById('#thirdEl');
firstEl.classList.add('animation');
firstEl.addEventListener('animationend', () => {
// start the 2nd animation
secondEl.classList.add('animation');
});
secondEl.addEventListener('animationend', () => {
// start the 3rd animation
thirdEl.classList.add('animation');
});
// etc
例子
这是一个带有链式动画的示例(来自 docs):
const animation = document.querySelector('p.animation');
const animationEventLog = document.querySelector('.animation-example>.event-log');
const applyAnimation = document.querySelector('.animation-example>button.activate');
let iterationCount = 0;
animation.addEventListener('animationstart', () => {
animationEventLog.textContent = `${animationEventLog.textContent}'animation started' `;
});
animation.addEventListener('animationiteration', () => {
iterationCount++;
animationEventLog.textContent = `${animationEventLog.textContent}'animation iterations: ${iterationCount}' `;
});
animation.addEventListener('animationend', () => {
animationEventLog.textContent = `${animationEventLog.textContent}'animation ended'`;
animation.classList.remove('active');
applyAnimation.textContent = "Activate animation";
});
animation.addEventListener('animationcancel', () => {
animationEventLog.textContent = `${animationEventLog.textContent}'animation canceled'`;
});
applyAnimation.addEventListener('click', () => {
animation.classList.toggle('active');
animationEventLog.textContent = '';
iterationCount = 0;
let active = animation.classList.contains('active');
if (active) {
applyAnimation.textContent = "Cancel animation";
} else {
applyAnimation.textContent = "Activate animation";
}
});
.container {
height: 3rem;
}
.event-log {
width: 25rem;
height: 2rem;
border: 1px solid black;
margin: .2rem;
padding: .2rem;
}
.animation.active {
animation-duration: 2s;
animation-name: slidein;
animation-iteration-count: 2;
}
@keyframes slidein {
from {
margin-left: 100%;
width: 300%;
}
to {
margin-left: 0%;
width: 100%;
}
}
<div class="animation-example">
<div class="container">
<p class="animation">You chose a cold night to visit our planet.</p>
</div>
<button class="activate" type="button">Activate animation</button>
<div class="event-log"></div>
</div>
我正在尝试在下面堆叠 CSS 个关键帧(动画延迟),但我不确定如何以编程方式执行此操作?
.r1 {
animation-name: move1;
animation-delay: 0.5s;
animation-duration: 1s;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
.r2 {
animation-name: move1;
animation-delay: 1.5s;
animation-duration: 1s;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
.r3 {
animation-name: move1;
animation-delay: 2.5s;
animation-duration: 1s;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
@keyframes move1 {
to {
transform: translateX(200px);
}
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<rect class="r1" x="10" y="20" width="100" height="100" fill="red"/>
<rect class="r2" x="10" y="130" width="100" height="100" fill="green"/>
<rect class="r3" x="10" y="240" width="100" height="100" fill="blue"/>
</svg>
animation-duration
为每个 class 硬编码,animation-delay
为第一个 class 硬编码,即 r1
.
如何传递r2和r3的延迟,例如
r2 delay= r1 delay + r1 duration->0.5+1=1.5s
和
r3 delay= r2 delay + r2 duration ->1.5+1=2.5s
javascript 中有什么东西可以通过 class 给出 animation-duration
吗?
我尝试通过 Element.getAnimations() 执行此操作,但我不确定是否有任何东西可以通过 class 提供动画持续时间。
我不想手动执行此操作,因为 svg 中有很多 class。
提前致谢。
为您的直肠设置 r class,我认为这可以帮助您:
const blocks = document.querySelectorAll('svg rect');
for (let i = 1; i<blocks.length; i++) {
const element = blocks[i];
const prevElementStyles = getComputedStyle(blocks[i-1]);
element.style.animationDelay = `${parseFloat(prevElementStyles.animationDelay) + parseFloat(prevElementStyles.animationDuration)}s`;
}
r class:
.r {
animation-name: move1;
animation-delay: 0.5s;
animation-duration: 1s;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<rect class="r" x="10" y="20" width="100" height="100" fill="red"/>
<rect class="r" x="10" y="130" width="100" height="100" fill="green"/>
<rect class="r" x="10" y="240" width="100" height="100" fill="blue"/>
</svg>
动画链接:使用事件animationend
您可以通过对此事件使用侦听器来链接 CSS 动画。当元素上的动画完成时(包括动画延迟),它将被触发。或者,如果您使用 transitions
,则需要使用 transitionend 事件。
基本工作流程
将动画属性提取到单独的 class,例如.animation
.
#firstEl.animation {
// your animation properties
}
#secondEl.animation {
// your animation properties
}
// etc
const firstEl = document.getElementById('#firstEl');
const secondEl = document.getElementById('#secondEl');
const thirdEl = document.getElementById('#thirdEl');
firstEl.classList.add('animation');
firstEl.addEventListener('animationend', () => {
// start the 2nd animation
secondEl.classList.add('animation');
});
secondEl.addEventListener('animationend', () => {
// start the 3rd animation
thirdEl.classList.add('animation');
});
// etc
例子
这是一个带有链式动画的示例(来自 docs):
const animation = document.querySelector('p.animation');
const animationEventLog = document.querySelector('.animation-example>.event-log');
const applyAnimation = document.querySelector('.animation-example>button.activate');
let iterationCount = 0;
animation.addEventListener('animationstart', () => {
animationEventLog.textContent = `${animationEventLog.textContent}'animation started' `;
});
animation.addEventListener('animationiteration', () => {
iterationCount++;
animationEventLog.textContent = `${animationEventLog.textContent}'animation iterations: ${iterationCount}' `;
});
animation.addEventListener('animationend', () => {
animationEventLog.textContent = `${animationEventLog.textContent}'animation ended'`;
animation.classList.remove('active');
applyAnimation.textContent = "Activate animation";
});
animation.addEventListener('animationcancel', () => {
animationEventLog.textContent = `${animationEventLog.textContent}'animation canceled'`;
});
applyAnimation.addEventListener('click', () => {
animation.classList.toggle('active');
animationEventLog.textContent = '';
iterationCount = 0;
let active = animation.classList.contains('active');
if (active) {
applyAnimation.textContent = "Cancel animation";
} else {
applyAnimation.textContent = "Activate animation";
}
});
.container {
height: 3rem;
}
.event-log {
width: 25rem;
height: 2rem;
border: 1px solid black;
margin: .2rem;
padding: .2rem;
}
.animation.active {
animation-duration: 2s;
animation-name: slidein;
animation-iteration-count: 2;
}
@keyframes slidein {
from {
margin-left: 100%;
width: 300%;
}
to {
margin-left: 0%;
width: 100%;
}
}
<div class="animation-example">
<div class="container">
<p class="animation">You chose a cold night to visit our planet.</p>
</div>
<button class="activate" type="button">Activate animation</button>
<div class="event-log"></div>
</div>