gshow8 shac
gshow8 shac

Reputation: 421

How can I flip cards in a sequence at intervals?

I am building some flip cards using HTML and CSS. I got the part that if I hover over, the cards will flip themselves. Right now, I am trying to achieve that the card would automatically flip one after the other at a certain delay interval without hovering. Each of flip card codes look like this, I have 4 of these cards in total:

setTimeout(function() {
  document.getElementsByClassName("flip-card").style = " transform: rotateY(180deg); -webkit-transform: rotateY(180deg); -ms-transform: rotateY(180deg); ";
}, 2000)
.flip-card {
  background-color: transparent;
  width: 100%;
  height: 250px;
  perspective: 1000px;
}

.flip-card-inner {
  position: relative;
  width: 100%;
  height: 100%;
  text-align: center;
  transition: transform 0.6s;
  transform-style: preserve-3d;
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
}

.flip-card:hover .flip-card-inner {
  transform: rotateY(180deg);
  -webkit-transform: rotateY(180deg);
  -ms-transform: rotateY(180deg);
}

.flip-card-front, .flip-card-back {
  position: absolute;
  height: 100%;
  backface-visibility: hidden;
}

.flip-card-front {
  background-color: rgba(249, 207, 0, 0.1);
  color: black;
  z-index: 100;
  width: 100%;
}
<div class="flip-card" style="cursor:pointer">
  <div class="flip-card-inner">
    <div class="flip-card-front">
      <img
        src="xxx"
        class="images" alt=" " style="width:150px;height:150px;">
      <br>
      <h3>Realtime</h3>
    </div>
    <div class="flip-card-back">
      <p><br>Instant matching, voice <br> &amp; text live chat<br></p>
    </div>
  </div>
</div>

How do I achieve automatic card flipping with a delay? In another word, after 2s, card one will flip without any action, then after another 2s, card one will flip back, and card two will flip, and so on.

I tried the following JS codes, and it does not work:

    setTimeout(function() {
      document.getElementsByClassName("flip-card").style = " transform: rotateY(180deg); -webkit-transform: rotateY(180deg); -ms-transform: rotateY(180deg); ";
    }, 2000)

Upvotes: 0

Views: 942

Answers (1)

secan
secan

Reputation: 2669

const cards = document.querySelectorAll('.flip-card');

/*
 * 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;
}, 2000);
.flip-card {
  background-color: transparent;
  width: 100%;
  height: 250px;
  perspective: 1000px;
}

.flip-card-inner {
  position: relative;
  width: 100%;
  height: 100%;
  text-align: center;
  transition: transform 0.6s;
  transform-style: preserve-3d;
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
}

.flip-card .rotated {
  transform: rotateY(180deg);
  -webkit-transform: rotateY(180deg);
  -ms-transform: rotateY(180deg);
}

.flip-card-front,
.flip-card-back {
  position: absolute;
  height: 100%;
  backface-visibility: hidden;
}

.flip-card-front {
  background-color: rgba(249, 207, 0, 0.1);
  color: black;
  z-index: 100;
  width: 100%;
}
<div class="flip-card" style="cursor:pointer">
  <div class="flip-card-inner">
    <div class="flip-card-front">
      <img src="xxx" class="images" alt=" " style="width:150px;height:150px;">
      <br>
      <h3>Realtime 1</h3>
    </div>
    <div class="flip-card-back">
      <p><br>Instant matching, voice <br> &amp; text live chat<br></p>
    </div>
  </div>
</div>

<div class="flip-card" style="cursor:pointer">
  <div class="flip-card-inner">
    <div class="flip-card-front">
      <img src="xxx" class="images" alt=" " style="width:150px;height:150px;">
      <br>
      <h3>Realtime 2</h3>
    </div>
    <div class="flip-card-back">
      <p><br>Instant matching, voice <br> &amp; text live chat<br></p>
    </div>
  </div>
</div>

<div class="flip-card" style="cursor:pointer">
  <div class="flip-card-inner">
    <div class="flip-card-front">
      <img src="xxx" class="images" alt=" " style="width:150px;height:150px;">
      <br>
      <h3>Realtime 3</h3>
    </div>
    <div class="flip-card-back">
      <p><br>Instant matching, voice <br> &amp; text live chat<br></p>
    </div>
  </div>
</div>

<div class="flip-card" style="cursor:pointer">
  <div class="flip-card-inner">
    <div class="flip-card-front">
      <img src="xxx" class="images" alt=" " style="width:150px;height:150px;">
      <br>
      <h3>Realtime 4</h3>
    </div>
    <div class="flip-card-back">
      <p><br>Instant matching, voice <br> &amp; text live chat<br></p>
    </div>
  </div>
</div>

Upvotes: 3

Related Questions