[英]How to get the position of an element after css animation (vanilla js)
我正在从事一个涉及多个动画的项目,尽管大多数动画都可以轻松地通过css关键帧动画完成,但其他动画需要使用javascript,我对如何执行这些动画颇有兴趣。 我将尽我所能描述无法在小提琴中显示的内容(我正在编码视频中的演示内容)。
页面中有几个部分,每个部分具有淡入和淡出,旋转等各种元素。当每个部分滚动到视图中时,将向其中添加一个“动画”类以触发css动画,其中一个是svg元素从视口的北部下降到停放的视口的底部。 但是,当用户继续向下滚动时,我需要对此svg元素进行动画处理,使其离开视口以南的视图,然后在下一部分滚动到视图中时重新进入。 所以我试图在停放时在findSection函数中获取元素的位置(请用香草js),即, 完成其关键帧动画后,但到目前为止我尝试过的方法是获取动画前的位置。 通过css设置动画后 ,如何获取绝对定位元素的当前位置? 而且,如果有比目前为止更好的整体方法,我将不胜感激,尤其是如果我可以使用单个svg元素而不是在每个部分中将其重复的话。
非常感谢您的帮助/建议。
威士忌T.
标记(每个部分):
<div class="section" id="section-1">
<svg version="1.1" class="thing-svg" [ etc. ] >
<g class="thing-path-group">
<path class="thing-path" d=" ... " />
</g>
</svg>
<!-- content -->
</div><!-- #section-1 -->
CSS:
.thing-svg {
position: absolute;
width: 60px;
height: 60px;
left: calc(50% - 30px);
top: -60px;
opacity: 0;
z-index: 9;
}
.animate .thing-svg {
animation: dropIt 1.8s ease-in-out forwards .3s;
}
@keyframes dropIt {
0% {
top: -60px;
opacity: 0;
}
3% {
opacity: 1;
}
100% {
top: calc(100vh - 60px);
opacity: 1;
}
}
javascript:
const sections = document.querySelectorAll('.section');
const svgEl = document.querySelector('#svg-el');
window.addEventListener('scroll', debounce(findSection)); // yes, there's a debounce fn
function findSection(e) {
let svgElPosition = svgEl.getBoundingClientRect();
sections.forEach(section => {
const sectionInAt = (window.scrollY + window.innerHeight) - section.offsetHeight / 2;
// these both get the pre-css keyframe animation value of 'top', but I need the post-keyframe animation 'top' value
console.log("svgElPosition.top", svgElPosition.top);
console.log(window.getComputedStyle(svgEl, null).getPropertyValue("top"));
// bottom of the section:
const sectionBottom = section.offsetTop + section.offsetHeight;
// isHalfShown is true while sectionInAt/triggerCoord > section.offsetTop (i.e., section is half viz)
const isHalfShown = sectionInAt > section.offsetTop;
// isNotScrolledPast is true while window.scrollY < imageBottom (i.e., image is still viz)
const isNotScrolledPast = window.scrollY < sectionBottom;
if (isHalfShown && isNotScrolledPast) {
section.classList.add('animate');
} else {
section.classList.remove('animate');
}
});
}
您应该在元素上注册animationend事件监听器:
svgEl.addEventListener('animationend', function (event) {
const svgRect = this.getBoundingClientRect();
});
每当CSS动画在您的元素上完成时,此方法就会触发,这是知道它已完成的可靠方法。 还要注意,您可以使用animationstart , animationiteration和animationcancel事件。
在这种情况下,我认为您最好的选择是使用setTimeout()等待动画完成的适当时间,然后在关闭函数中获取位置。 这是一个示例片段:
if (isHalfShown && isNotScrolledPast) {
section.classList.add('animate');
let timer = setTimeout(function() {
let rect = element.getBoundingClientRect();
console.log(rect.top, rect.right, rect.bottom, rect.left);
},300); //.3 seconds, if I read that correctly from the CSS (maybe an extra .01 seconds or something as well for good measure)
}
在此示例中未明确使用“ timer”变量,但是如果您还需要取消动画来取消计时器,则它可能很有用(尽管您需要将作用域置于此条件语句之外)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.