У меня есть страница, включающая несколько анимаций CSS.Моя цель: когда страница прокручивается через серию секций, функция применяет серию классов к абсолютно позиционированному элементу («вещь», которая приходит и уходит повсюду), которая запускает анимацию ключевого кадра в соответствии с классом css.
Классы устанавливаются при загрузке в первый раздел и элемент abs pos, и первая анимация CSS выполняется нормально.Проблема в том, что, хотя я вижу, что при прокрутке страницы получаются правильные классы, соответствующие анимации не запускаются.
html:
<svg version="1.1" id="thing-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="60px" height="60px" viewBox="0 0 60 60" style="enable-background:new 0 0 60 60;" xml:space="preserve">
<g id="thing-path-group">
<path id="thing-path" d="M25.313,0.103c-1.789,1.724-2.727,4.989-3.638,7.156c-3.326,7.915-6.434,15.931-9.448,23.964 c-1.847,4.923-3.105,9.807-4.238,14.902c-0.181,0.82-0.404,1.511-0.752,2.264c-1.012,2.188-2.523,4.126-3.851,6.137 c-1.192,1.803-2.034,3.912-3.414,5.571c4.71-0.283,9.534-2.292,14.253-2.933c10.085-1.371,20.049-0.629,30.118,0.077 c5.03,0.35,10.369,0.483,15.201-0.976c-2.641-4.111-5.831-7.679-8.15-12.042c-2.742-5.157-5.317-10.727-8.843-15.439 c-1.816-2.43-3.04-5.247-5.1-7.486c-1.252-1.36-2.596-2.599-3.517-4.211c-0.51-0.896-0.559-1.765-0.904-2.656 c-0.339-0.874-0.646-1.31-1.25-2.176c-1.419-2.038-2.822-4.347-3.851-6.602c-0.776-1.701-1.001-4.141-2.758-5.142" />
</g>
</svg>
<div class="sections">
<div class="section" id="section-1"></div>
<div class="section" id="section-2"></div>
<div class="section" id="section-3"></div>
</div> <!-- .sections -->
css:
#thing-svg {
position: absolute;
width: 60px;
height: 60px;
left: calc(50% - 30px);
top: -60px;
opacity: 1;
z-index: 999;
}
#thing-svg.section-1 { animation: section-1 1.8s ease-in-out forwards .3s; }
@keyframes section-1 {
0% {
top: -60px;
opacity: 0;
}
3% {
opacity: 1;
}
100% {
top: 66%;
opacity: 1;
}
}
#thing-svg.section-2 { animation: section-2 .9s ease-in-out forwards .3s; }
@keyframes section-2 {
0% {
top: -60px;
opacity: 0;
}
3% {
opacity: 1;
border: 9px solid red;
}
100% {
top: 36%;
opacity: 1;
border: 9px solid red;
}
}
JavaScript:
function debounce(func, wait = 33, immediate = true) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
const viewportHeight = function() {
return Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
}
const sectionsWrapper = document.querySelector('.sections');
const sections = document.querySelectorAll('.section');
const thing = document.querySelector('#thing-svg');
var prevPos = window.scrollY || document.documentElement.scrollTop;
var scrollingDown = false;
window.addEventListener('scroll', debounce(updateSection));
thing.addEventListener('animationend', findthing);
function findthing(e) {
return thingPosition = thing.getBoundingClientRect().top;
}
function updateSection(e) {
const vpHeight = viewportHeight();
var currPos = window.scrollY || document.documentElement.scrollTop;
if (prevPos > currPos) {
scrollingDown = false;
} else {
scrollingDown = true;
}
if (scrollingDown) {
const thingPosition = findthing();
sections.forEach((section, ix) => {
var sectionId = section.getAttribute("id");
var distanceFromTop = section.getBoundingClientRect().top;
if (distanceFromTop < (vpHeight / 3) && distanceFromTop > -(2 * vpHeight / 3)) {
section.classList.add('animate');
}
else {
section.classList.remove('animate');
}
}); // forEach
var activeSection = document.querySelector('.animate');
var activeSectionId = activeSection.getAttribute("id");
console.log("activeSectionId", activeSectionId);
thing.classList = activeSectionId;
} // if scrollingDown
prevPos = currPos;
} // updateSection
window.onload = function() {
var newScrollPos;
var scrollPos = 0;
window.scrollTo({
top: 0,
behavior: "smooth"
});
setTimeout(initFirstSection, 1500);
function initFirstSection() {
sections[0].classList.add("animate");
}
thing.classList.add("animation-1");
sections.forEach(section => {
section.style.height = viewportHeight();
})
} // onload
function debounce(func, wait = 33, immediate = true) {
var timeout;
return function() {
var context = this,
args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
const viewportHeight = function() {
return Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
}
const sectionsWrapper = document.querySelector('.sections');
const sections = document.querySelectorAll('.section');
const thing = document.querySelector('#thing-svg');
var prevPos = window.scrollY || document.documentElement.scrollTop;
var scrollingDown = false;
window.addEventListener('scroll', debounce(updateSection));
thing.addEventListener('animationend', findthing);
function findthing(e) {
return thingPosition = thing.getBoundingClientRect().top;
}
function updateSection(e) {
const vpHeight = viewportHeight();
var currPos = window.scrollY || document.documentElement.scrollTop;
if (prevPos > currPos) {
scrollingDown = false;
} else {
scrollingDown = true;
}
if (scrollingDown) {
const thingPosition = findthing();
sections.forEach((section, ix) => {
var sectionId = section.getAttribute("id");
var distanceFromTop = section.getBoundingClientRect().top;
if (distanceFromTop < (vpHeight / 3) && distanceFromTop > -(2 * vpHeight / 3)) {
section.classList.add('animate');
} else {
section.classList.remove('animate');
}
}); // forEach
var activeSection = document.querySelector('.animate');
var activeSectionId = activeSection.getAttribute("id");
console.log("activeSectionId", activeSectionId);
thing.classList = activeSectionId;
} // if scrollingDown
prevPos = currPos;
} // updateSection
window.onload = function() {
var newScrollPos;
var scrollPos = 0;
window.scrollTo({
top: 0,
behavior: "smooth"
});
setTimeout(initFirstSection, 1500);
function initFirstSection() {
sections[0].classList.add("animate");
}
thing.classList.add("animation-1");
sections.forEach(section => {
section.style.height = viewportHeight();
})
} // onload
section { height: 100vh; }
.section#section-1 { background: red; }
.section#section-2 { background: lime; }
.section#section-3 { background: blue; }
#thing-svg {
position: absolute;
width: 60px;
height: 60px;
left: calc(50% - 30px);
top: -60px;
opacity: 1;
z-index: 999;
}
#thing-svg.section-1 {
animation: section-1 1.8s ease-in-out forwards .3s;
}
@keyframes section-1 {
0% {
top: -60px;
opacity: 0;
}
3% {
opacity: 1;
}
100% {
top: 66%;
opacity: 1;
}
}
#thing-svg.section-2 {
animation: section-2 .9s ease-in-out forwards .3s;
}
@keyframes section-2 {
0% {
top: -60px;
opacity: 0;
}
3% {
opacity: 1;
border: 9px solid red;
}
100% {
top: 36%;
opacity: 1;
border: 9px solid red;
}
}
<svg version="1.1" id="thing-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="60px" height="60px" viewBox="0 0 60 60" style="enable-background:new 0 0 60 60;" xml:space="preserve">
<g id="thing-path-group">
<path id="thing-path" d="M25.313,0.103c-1.789,1.724-2.727,4.989-3.638,7.156c-3.326,7.915-6.434,15.931-9.448,23.964 c-1.847,4.923-3.105,9.807-4.238,14.902c-0.181,0.82-0.404,1.511-0.752,2.264c-1.012,2.188-2.523,4.126-3.851,6.137 c-1.192,1.803-2.034,3.912-3.414,5.571c4.71-0.283,9.534-2.292,14.253-2.933c10.085-1.371,20.049-0.629,30.118,0.077 c5.03,0.35,10.369,0.483,15.201-0.976c-2.641-4.111-5.831-7.679-8.15-12.042c-2.742-5.157-5.317-10.727-8.843-15.439 c-1.816-2.43-3.04-5.247-5.1-7.486c-1.252-1.36-2.596-2.599-3.517-4.211c-0.51-0.896-0.559-1.765-0.904-2.656 c-0.339-0.874-0.646-1.31-1.25-2.176c-1.419-2.038-2.822-4.347-3.851-6.602c-0.776-1.701-1.001-4.141-2.758-5.142" />
</g>
</svg>
<div class="sections">
<div class="section" id="section-1"></div>
<div class="section" id="section-2"></div>
<div class="section" id="section-3"></div>
</div>
<!-- .sections -->