0

I have some HTML flipping cards with automatic flipping animations. I am trying to implement a feature such that when the user scrolls to the part where they see the flipping cards, start the flipping animation. If the user scrolls more such that the flipping cards are not visible anymore, stop the flipping animation. Below is the JavaScript codes:

    function isScrolledIntoView(elem) {
      var docViewTop = $(window).scrollTop();
      var docViewBottom = docViewTop + $(window).height();

      var elemTop = $(elem).offset().top;
      var elemBottom = elemTop + $(elem).height();

      return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
    }

    // $(window).scroll(function() {
      if (isScrolledIntoView(".flip-card")) {
        console.log(true);
        const cards = document.querySelectorAll('.flip-card');
        const flip_delay = 2000;
        /*
         * function to flip the card forward (rotateY 180deg) or back (no rotation)
         */
        const flipCard = (card, direction) => {
          switch (direction) {
            case 'forward':
              card.children[0].classList.add("rotated");
              break;
            case 'back':
              card.children[0].classList.remove("rotated");
              break;
            default:
              card.children[0].classList.toggle("rotated");
          }
        };

        /*
         * function to check whether the automatic flip should skip the card
         */
        const skipFlip = (cardIndex) => {
          return cards[cardIndex].getAttribute('data-isHovered') || false;
        }

        cards.forEach((card, index) => {
          card.addEventListener('mouseenter', (event) => {
            /*
             * onMouseEnter:
             *   1. flip the card forward (comment the function call if you do not want a "flip on mouse over" behaviour)
             *   2. add an attribute to prevent automatic flip
             */
            flipCard(card, 'forward');
            card.setAttribute('data-isHovered', true);
          });
          card.addEventListener('mouseleave', (event) => {
            /*
             * onMouseLeave
             *   1. flip the card back (comment the function call if you do not want a "flip on mouse over" behaviour)
             *   2. remove the attribute preventing the automatic flip
             */
            flipCard(card, 'back');
            card.removeAttribute('data-isHovered', false);
          });
        });

        /*
         * Automatically flip forward/back the cards one after the other, every 2 seconds
         * unless a card is hovered by the mouse (in which case the card will
         * stay in the same flipping position until the mouse moves out of it)
         */
        let currCardIndex = 0;
        window.setInterval(() => {
          const prevCardIndex = (currCardIndex === 0 && cards.length - 1) || currCardIndex - 1;

          if (!skipFlip(prevCardIndex)) {
            flipCard(cards[prevCardIndex], 'back');
          }
          if (!skipFlip(currCardIndex)) {
            flipCard(cards[currCardIndex], 'forward');
          }

          currCardIndex = currCardIndex === cards.length - 1 ? 0 : currCardIndex + 1;
        }, flip_delay);
      }

I tried to use the solution provided here: How to check if element is visible after scrolling? But it only detect if the element is in the viewport on page reload, I am trying to implement it on scrolling. I tried to use $(window).scroll(function() {, but it just piles up the flipping animation at every scroll.

gshow8 shac
  • 191
  • 8