CSS анимация ключевых кадров не запускается, когда класс элемента применяется JavaScript - PullRequest
0 голосов
/ 13 июня 2018

У меня есть страница, включающая несколько анимаций 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 -->
...