如何以编程方式知道哪个是具有动画的最后一个对象
How to know programmatically which is the last object that has the animation
有没有办法让我以编程方式知道 CSS 动画最后应用在哪个对象上
例如,
.r1 {
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;
}
.c1 {
animation-name: blink;
animation-delay: 0.5s;
animation-duration: 1s;
animation-iteration-count: 2;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
/*.text1 {
animation-name: scl;
animation-delay: 5.5s;
animation-duration: 1s;
animation-iteration-count: 2;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}*/
.r2 {
transform-origin: center;
transform-box: fill-box;
animation-name: gr;
animation-delay: 3.5s;
animation-duration: 2s;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
.r3 {
animation-name: move2;
animation-delay: 7.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);
}
}
@keyframes blink {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes gr {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
@keyframes scl {
to {
transform: scale(1.1);
}
}
@keyframes move2 {
to {
transform: translateY(400px);
}
}
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<rect id="r1" class="r1" x="10" y="20" width="100" height="100" fill="red" />
<rect id="r2" class="r2" x="10" y="130" width="100" height="100" fill="green" />
<rect id="r3" class="r3" x="10" y="240" width="100" height="100" fill="blue" />
<circle id="c1" class="c1" cx="50" cy="400" r="40" fill="orange" />
<text class="text1" id="text1" x="80" y="500" font-size="30" fill="red">I love SVG!</text>
</svg>
在此,我有 5 个元素,我正在对其中的 4 个元素应用动画,r3
是应用动画的最后一个元素。有没有一种方法可以检测 r3
的 animation-delay+animation-duration
- 动画应用 javascript.
的最后一个元素
您可以像这样使用 animationend
来实现此目的 :-
const animatedElements = [];
const noOfElementsToAnimate = 4;
const svgLayer = document.querySelector('#Layer_1');
const onAnimationEnd = (e) => {
animatedElements.push(e.target.id);
if (animatedElements.length === noOfElementsToAnimate) {
svgLayer.removeEventListener('animationend', onAnimationEnd);
console.log(animatedElements[animatedElements.length - 1])
}
}
svgLayer.addEventListener('animationend', onAnimationEnd);
.r1 {
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;
}
.c1 {
animation-name: blink;
animation-delay: 0.5s;
animation-duration: 1s;
animation-iteration-count: 2;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
/*.text1 {
animation-name: scl;
animation-delay: 5.5s;
animation-duration: 1s;
animation-iteration-count: 2;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}*/
.r2 {
transform-origin: center;
transform-box: fill-box;
animation-name: gr;
animation-delay: 3.5s;
animation-duration: 2s;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
.r3 {
animation-name: move2;
animation-delay: 7.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);
}
}
@keyframes blink {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes gr {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
@keyframes scl {
to {
transform: scale(1.1);
}
}
@keyframes move2 {
to {
transform: translateY(400px);
}
}
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<rect id="r1" class="r1" x="10" y="20" width="100" height="100" fill="red" />
<rect id="r2" class="r2" x="10" y="130" width="100" height="100" fill="green" />
<rect id="r3" class="r3" x="10" y="240" width="100" height="100" fill="blue" />
<circle id="c1" class="c1" cx="50" cy="400" r="40" fill="orange" />
<text class="text1" id="text1" x="80" y="500" font-size="30" fill="red">I love SVG!</text>
</svg>
说明: - 这里我将 animationend
事件的事件侦听器附加到父元素,即 Layer_1 svg.
每当动画为其子元素结束时,我将该元素的 id
推入一个数组并将其与现有编号进行比较,该编号表示 DOM 中的动画元素编号(可以使用一个独特的 class 也可以动态获取它们)。当 animatedElements
和 noOfElementsToAnimate
相等时,我删除侦听器和 log/use animatedElements
数组的最后一个值。
或者,您也可以放弃数组,只使用一个变量来跟踪最后一个动画元素,例如,lastAnimatedElement
并递减 noOfElementsToAnimate
并记录 lastAnimatedElement
当 noOfElementsToAnimate
是 0.
我想到了这个,它计算每个 svg 元素的 Delay+(Duration*Iteration-Count)
,最后 returns 该表达式的最大值,这将是最后一个元素的总持续时间动画 运行。从逻辑上讲,带有动画的最后一个元素将具有最长的 Delay+(Duration*Iteration-Count)
,我需要将其作为 animation-delay
传递给我的下一个动画元素。
var _layer1 = document.querySelectorAll('svg > *');
var _max = -1;
for (const el of _layer1) {
var __del = getComputedStyle(el).animationDelay;
var __del = __del.split(',');
var __delLast = parseFloat(__del[__del.length - 1]);
var __duration = getComputedStyle(el).animationDuration;
var __duration = __duration.split(',');
var __durationLast = parseFloat(__duration[__del.length - 1]);
var __iterationCount = getComputedStyle(el).animationIterationCount;
var __iterationCount = __iterationCount.split(',');
var __iterationCountLast = parseFloat(__iterationCount[__iterationCount.length - 1]);
function alternate(a, b) {
if (isNaN(a)) {
return b
} else {
return a
}
};
var modified = alternate(__iterationCountLast, __durationLast);
var _expression = __delLast + (__durationLast * modified); //Delay+(Duration*Iteration-Count)
_max = Math.max(_max, _expression);
};
.r1 {
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;
}
.c1 {
animation-name: blink;
animation-delay: 0.5s;
animation-duration: 1s;
animation-iteration-count: 2;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
/*.text1 {
animation-name: scl;
animation-delay: 5.5s;
animation-duration: 1s;
animation-iteration-count: 2;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}*/
.r2 {
transform-origin: center;
transform-box: fill-box;
animation-name: gr;
animation-delay: 3.5s;
animation-duration: 2s;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
.r3 {
animation-name: move2;
animation-delay: 7.5s;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
@keyframes move1 {
to {
transform: translateX(200px);
}
}
@keyframes blink {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes gr {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
@keyframes scl {
to {
transform: scale(1.1);
}
}
@keyframes move2 {
to {
transform: translateY(400px);
}
}
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
</svg>
Web Animations API可以检查动画。
document.getAnimations()
returns 在文档中找到的所有动画。他们每个人都有一个 effect
属性,在你的例子中,他们都是 KeyframeEffect
.
类型
animation.animationName
returns CSS @keyframes
声明中的动画名称。
animation.effect.target
returns 动画所针对的元素。
animation.effect.getComputedTiming().endTime
returns动画结束的时间。
从那里您可以比较和过滤您需要的信息。
document.getAnimations().forEach(animation => {
console.log(
animation.animationName,
animation.effect.target.id,
animation.effect.getComputedTiming().endTime
);
});
.r1 {
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;
}
.c1 {
animation-name: blink;
animation-delay: 0.5s;
animation-duration: 1s;
animation-iteration-count: 2;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
/*.text1 {
animation-name: scl;
animation-delay: 5.5s;
animation-duration: 1s;
animation-iteration-count: 2;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}*/
.r2 {
transform-origin: center;
transform-box: fill-box;
animation-name: gr;
animation-delay: 3.5s;
animation-duration: 2s;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
.r3 {
animation-name: move2;
animation-delay: 7.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);
}
}
@keyframes blink {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes gr {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
@keyframes scl {
to {
transform: scale(1.1);
}
}
@keyframes move2 {
to {
transform: translateY(400px);
}
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<rect id="r1" class="r1" x="10" y="20" width="100" height="100" fill="red" />
<rect id="r2" class="r2" x="10" y="130" width="100" height="100" fill="green" />
<rect id="r3" class="r3" x="10" y="240" width="100" height="100" fill="blue" />
<circle id="c1" class="c1" cx="50" cy="400" r="40" fill="orange" />
<text class="text1" id="text1" x="80" y="500" font-size="30" fill="red">I love SVG!</text>
</svg>
有没有办法让我以编程方式知道 CSS 动画最后应用在哪个对象上
例如,
.r1 {
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;
}
.c1 {
animation-name: blink;
animation-delay: 0.5s;
animation-duration: 1s;
animation-iteration-count: 2;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
/*.text1 {
animation-name: scl;
animation-delay: 5.5s;
animation-duration: 1s;
animation-iteration-count: 2;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}*/
.r2 {
transform-origin: center;
transform-box: fill-box;
animation-name: gr;
animation-delay: 3.5s;
animation-duration: 2s;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
.r3 {
animation-name: move2;
animation-delay: 7.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);
}
}
@keyframes blink {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes gr {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
@keyframes scl {
to {
transform: scale(1.1);
}
}
@keyframes move2 {
to {
transform: translateY(400px);
}
}
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<rect id="r1" class="r1" x="10" y="20" width="100" height="100" fill="red" />
<rect id="r2" class="r2" x="10" y="130" width="100" height="100" fill="green" />
<rect id="r3" class="r3" x="10" y="240" width="100" height="100" fill="blue" />
<circle id="c1" class="c1" cx="50" cy="400" r="40" fill="orange" />
<text class="text1" id="text1" x="80" y="500" font-size="30" fill="red">I love SVG!</text>
</svg>
在此,我有 5 个元素,我正在对其中的 4 个元素应用动画,r3
是应用动画的最后一个元素。有没有一种方法可以检测 r3
的 animation-delay+animation-duration
- 动画应用 javascript.
您可以像这样使用 animationend
来实现此目的 :-
const animatedElements = [];
const noOfElementsToAnimate = 4;
const svgLayer = document.querySelector('#Layer_1');
const onAnimationEnd = (e) => {
animatedElements.push(e.target.id);
if (animatedElements.length === noOfElementsToAnimate) {
svgLayer.removeEventListener('animationend', onAnimationEnd);
console.log(animatedElements[animatedElements.length - 1])
}
}
svgLayer.addEventListener('animationend', onAnimationEnd);
.r1 {
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;
}
.c1 {
animation-name: blink;
animation-delay: 0.5s;
animation-duration: 1s;
animation-iteration-count: 2;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
/*.text1 {
animation-name: scl;
animation-delay: 5.5s;
animation-duration: 1s;
animation-iteration-count: 2;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}*/
.r2 {
transform-origin: center;
transform-box: fill-box;
animation-name: gr;
animation-delay: 3.5s;
animation-duration: 2s;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
.r3 {
animation-name: move2;
animation-delay: 7.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);
}
}
@keyframes blink {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes gr {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
@keyframes scl {
to {
transform: scale(1.1);
}
}
@keyframes move2 {
to {
transform: translateY(400px);
}
}
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<rect id="r1" class="r1" x="10" y="20" width="100" height="100" fill="red" />
<rect id="r2" class="r2" x="10" y="130" width="100" height="100" fill="green" />
<rect id="r3" class="r3" x="10" y="240" width="100" height="100" fill="blue" />
<circle id="c1" class="c1" cx="50" cy="400" r="40" fill="orange" />
<text class="text1" id="text1" x="80" y="500" font-size="30" fill="red">I love SVG!</text>
</svg>
说明: - 这里我将 animationend
事件的事件侦听器附加到父元素,即 Layer_1 svg.
每当动画为其子元素结束时,我将该元素的 id
推入一个数组并将其与现有编号进行比较,该编号表示 DOM 中的动画元素编号(可以使用一个独特的 class 也可以动态获取它们)。当 animatedElements
和 noOfElementsToAnimate
相等时,我删除侦听器和 log/use animatedElements
数组的最后一个值。
或者,您也可以放弃数组,只使用一个变量来跟踪最后一个动画元素,例如,lastAnimatedElement
并递减 noOfElementsToAnimate
并记录 lastAnimatedElement
当 noOfElementsToAnimate
是 0.
我想到了这个,它计算每个 svg 元素的 Delay+(Duration*Iteration-Count)
,最后 returns 该表达式的最大值,这将是最后一个元素的总持续时间动画 运行。从逻辑上讲,带有动画的最后一个元素将具有最长的 Delay+(Duration*Iteration-Count)
,我需要将其作为 animation-delay
传递给我的下一个动画元素。
var _layer1 = document.querySelectorAll('svg > *');
var _max = -1;
for (const el of _layer1) {
var __del = getComputedStyle(el).animationDelay;
var __del = __del.split(',');
var __delLast = parseFloat(__del[__del.length - 1]);
var __duration = getComputedStyle(el).animationDuration;
var __duration = __duration.split(',');
var __durationLast = parseFloat(__duration[__del.length - 1]);
var __iterationCount = getComputedStyle(el).animationIterationCount;
var __iterationCount = __iterationCount.split(',');
var __iterationCountLast = parseFloat(__iterationCount[__iterationCount.length - 1]);
function alternate(a, b) {
if (isNaN(a)) {
return b
} else {
return a
}
};
var modified = alternate(__iterationCountLast, __durationLast);
var _expression = __delLast + (__durationLast * modified); //Delay+(Duration*Iteration-Count)
_max = Math.max(_max, _expression);
};
.r1 {
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;
}
.c1 {
animation-name: blink;
animation-delay: 0.5s;
animation-duration: 1s;
animation-iteration-count: 2;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
/*.text1 {
animation-name: scl;
animation-delay: 5.5s;
animation-duration: 1s;
animation-iteration-count: 2;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}*/
.r2 {
transform-origin: center;
transform-box: fill-box;
animation-name: gr;
animation-delay: 3.5s;
animation-duration: 2s;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
.r3 {
animation-name: move2;
animation-delay: 7.5s;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
@keyframes move1 {
to {
transform: translateX(200px);
}
}
@keyframes blink {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes gr {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
@keyframes scl {
to {
transform: scale(1.1);
}
}
@keyframes move2 {
to {
transform: translateY(400px);
}
}
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
</svg>
Web Animations API可以检查动画。
document.getAnimations()
returns 在文档中找到的所有动画。他们每个人都有一个 effect
属性,在你的例子中,他们都是 KeyframeEffect
.
animation.animationName
returns CSS@keyframes
声明中的动画名称。animation.effect.target
returns 动画所针对的元素。animation.effect.getComputedTiming().endTime
returns动画结束的时间。
从那里您可以比较和过滤您需要的信息。
document.getAnimations().forEach(animation => {
console.log(
animation.animationName,
animation.effect.target.id,
animation.effect.getComputedTiming().endTime
);
});
.r1 {
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;
}
.c1 {
animation-name: blink;
animation-delay: 0.5s;
animation-duration: 1s;
animation-iteration-count: 2;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
/*.text1 {
animation-name: scl;
animation-delay: 5.5s;
animation-duration: 1s;
animation-iteration-count: 2;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}*/
.r2 {
transform-origin: center;
transform-box: fill-box;
animation-name: gr;
animation-delay: 3.5s;
animation-duration: 2s;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-direction: normal;
animation-fill-mode: forwards;
}
.r3 {
animation-name: move2;
animation-delay: 7.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);
}
}
@keyframes blink {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes gr {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
@keyframes scl {
to {
transform: scale(1.1);
}
}
@keyframes move2 {
to {
transform: translateY(400px);
}
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<rect id="r1" class="r1" x="10" y="20" width="100" height="100" fill="red" />
<rect id="r2" class="r2" x="10" y="130" width="100" height="100" fill="green" />
<rect id="r3" class="r3" x="10" y="240" width="100" height="100" fill="blue" />
<circle id="c1" class="c1" cx="50" cy="400" r="40" fill="orange" />
<text class="text1" id="text1" x="80" y="500" font-size="30" fill="red">I love SVG!</text>
</svg>