Pause the animation of all html cards when the video popup is opened or when the play button on the video is clicked

37 Views Asked by At

I have two cards a small card which contain the video and another is bigger card which contain the title and description. Small card is nested inside the bigger cards. What i want is when ever i play the video of any card (in popup box or without popup box) the animation(movement) of all cards should be stop. And also why the last card not fully appear its half part is missing. Please review my code and help me to achieve the result.

Code Snippet

document.addEventListener("DOMContentLoaded", function() {
  const container = document.querySelector(".container");
  const cards = document.querySelectorAll(".card");
  const videoPopup = document.querySelector(".video-popup");
  const closePopup = document.querySelector(".close-popup");
  const popupVideo = document.querySelector(".video-popup video");
  const overlay = document.querySelector('.overlay');

  let totalWidth = 0;
  cards.forEach(card => {
    totalWidth += card.offsetWidth;
  });

  container.style.width = totalWidth + "px";

  container.addEventListener("mouseenter", function() {
    container.style.animationPlayState = "paused";
  });

  container.addEventListener("mouseleave", function() {
    container.style.animationPlayState = "running";
  });

  const reviewCards = document.querySelectorAll(".video-card");

  reviewCards.forEach(card => {
    card.addEventListener("click", function() {
      const videoSrc = card.querySelector("video source").getAttribute("src");
      popupVideo.setAttribute("src", videoSrc);
      videoPopup.style.display = "block";
      overlay.style.display = "block";
    });
  });

  closePopup.addEventListener("click", function() {
    popupVideo.pause();
    videoPopup.style.display = "none";
    overlay.style.display = "none";
  });
});
body, html {
  overflow-x: hidden;
}

.container {
  display: flex;
  flex-wrap: nowrap;
  overflow-x: hidden;
  overflow-y: hidden;
  width: calc(100% + 380px);
  margin-left: -20px;
  animation: slide 20s linear infinite;
}

.card {
  flex: 0 0 auto;
  width: 360px;
  background-color: #f0f0f0;
  border-radius: 15px;
  margin-right: 20px;
  padding: 20px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  transition: border 0.3s;
}

.review {
  margin-top: 10px;
}

.video-card {
  border-radius: 10px;
  overflow: hidden;
}

.video-card video {
  width: 100%;
  border-radius: 10px;
}

.company-info {
  text-align: center;
  margin-top: 20px;
}

.arrow-down {
  width: 0;
  height: 0;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  border-top: 15px solid #e0e0e0;
  position: absolute;
  bottom: -20px;
  left: calc(50% - 10px);
}

.card:hover {
  border: 2px solid #007bff;
  cursor: pointer;
}

.card:hover ~ .card {
  animation-play-state: paused;
}

@keyframes slide {
  0% {
    transform: translateX(100%);
  }
  100% {
    transform: translateX(-100%);
  }
}

.video-popup {
  display: none;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 9999;
  background-color: rgba(0, 0, 0, 0.7); /* Semi-transparent black color */
  width: 60%;
  ma
<div class="container">
  <!-- Cards will be dynamically generated here -->
  <!-- Example card -->
  <div class="card">
    <div class="video-card">
      <video controls>
        <source src="https://cdn.pixabay.com/vimeo/912684284/bird-200427.mp4?width=1280&hash=67fef5d5bd129d65e1bb235d5af18c429fd99732" type="video/mp4">
        Your browser does not support the video tag.
      </video>
    </div>
    <div class="review">
      <h2>Title 1</h2>
      <p>Description 1</p>
    </div>
    <div class="company-info">
      <h3>Company Name 1</h3>
    </div>
    <div class="arrow-down"></div>
  </div>
  <!-- End of example card -->

      <!-- Example card -->
  <div class="card">
    <div class="video-card">
      <video controls>
        <source src="https://cdn.pixabay.com/vimeo/912684284/bird-200427.mp4?width=1280&hash=67fef5d5bd129d65e1bb235d5af18c429fd99732" type="video/mp4">
        Your browser does not support the video tag.
      </video>
    </div>
    <div class="review">
      <h2>Title 1</h2>
      <p>Description 1</p>
    </div>
    <div class="company-info">
      <h3>Company Name 1</h3>
    </div>
    <div class="arrow-down"></div>
  </div>
  <!-- End of example card -->


      <!-- Example card -->
  <div class="card">
    <div class="video-card">
      <video controls>
        <source src="https://cdn.pixabay.com/vimeo/912684284/bird-200427.mp4?width=1280&hash=67fef5d5bd129d65e1bb235d5af18c429fd99732" type="video/mp4">
        Your browser does not support the video tag.
      </video>
    </div>
    <div class="review">
      <h2>Title 1</h2>
      <p>Description 1</p>
    </div>
    <div class="company-info">
      <h3>Company Name 1</h3>
    </div>
    <div class="arrow-down"></div>
  </div>
  <!-- End of example card -->


      <!-- Example card -->
  <div class="card">
    <div class="video-card">
      <video controls>
        <source src="https://cdn.pixabay.com/vimeo/912684284/bird-200427.mp4?width=1280&hash=67fef5d5bd129d65e1bb235d5af18c429fd99732" type="video/mp4">
        Your browser does not support the video tag.
      </video>
    </div>
    <div class="review">
      <h2>Title 1</h2>
      <p>Description 1</p>
    </div>
    <div class="company-info">
      <h3>Company Name 1</h3>
    </div>
    <div class="arrow-down"></div>
  </div>
  <!-- End of example card -->


      <!-- Example card -->
  <div class="card">
    <div class="video-card">
      <video controls>
        <source src="https://cdn.pixabay.com/vimeo/912684284/bird-200427.mp4?width=1280&hash=67fef5d5bd129d65e1bb235d5af18c429fd99732" type="video/mp4">
        Your browser does not support the video tag.
      </video>
    </div>
    <div class="review">
      <h2>Title 1</h2>
      <p>Description 1</p>
    </div>
    <div class="company-info">
      <h3>Company Name 1</h3>
    </div>
    <div class="arrow-down"></div>
  </div>
  <!-- End of example card -->

      <!-- Example card -->
  <div class="card">
    <div class="video-card">
      <video controls>
        <source src="https://cdn.pixabay.com/vimeo/912684284/bird-200427.mp4?width=1280&hash=67fef5d5bd129d65e1bb235d5af18c429fd99732" type="video/mp4">
        Your browser does not support the video tag.
      </video>
    </div>
    <div class="review">
      <h2>Title 1</h2>
      <p>Description 1</p>
    </div>
    <div class="company-info">
      <h3>Company Name 1</h3>
    </div>
    <div class="arrow-down"></div>
  </div>
  <!-- End of example card -->
</div>

<div class="video-popup">
  <div class="video-popup-content">
    <video controls></video>
    <button class="close-popup">Close</button>
  </div>
</div>

<div class="overlay"></div>

1

There are 1 best solutions below

3
jme11 On
  1. You can fix the issue with the last video getting cut off by removing the width. You also don't need an overflow (you have one on the body and html) or flex-wrap: nowrap; as this is the default behavior.
  2. You were on the right track with setting the animation-play-state: paused; in a hover class. Since the animation is on the container so animation-play-state can only work on the container. That means you'll need to use the :has() pseudo class to set the animation-play-state to paused only if there is a child card of the container that is being hovered or if there is a child video element that has a custom "data-playing" property that we can set in JavaScript to true.

const video = document.querySelector("video");

/*

If the video is paused or ends the "pause" event is triggered.
If the video is played the "play" event is triggered.

In both cases, we set a custom property (data-playing)
on the video element to true if playing or false if paused.

*/

const handleVideo = (event) => {
  video.dataset.playing = !video.paused;
};

video.addEventListener("play", handleVideo);
video.addEventListener("pause", handleVideo);
body,
html {
  overflow-x: hidden;
  font-family: system-ui;
}

.container {
  /* 
    remove width to fix the issue with
    the last element being cut off 
  */
  display: flex;
  animation: slide 20s linear infinite;
}

/* 
  The animation is on the container so 
  animation-play-state can only work on
  the container. Use :has() to check if
  any card in the container is hovered OR
  if the data-playing property has been 
  set via JavaScript.
*/
.container:has(.card:hover),
.container:has([data-playing="true"]) {
  animation-play-state: paused;
}

.card {
  flex: 0 0 auto;
  width: 360px;
  background-color: #f0f0f0;
  border-radius: 15px;
  margin-right: 20px;
  padding: 20px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  transition: border 0.3s;
}

.card:hover {
  border: 2px solid #007bff;
  cursor: pointer;
}

.video-card {
  border-radius: 10px;
  overflow: hidden;
}

.video-card video {
  width: 100%;
  border-radius: 10px;
}

.company-info {
  text-align: center;
  margin-top: 20px;
}

.arrow-down {
  width: 0;
  height: 0;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  border-top: 15px solid #e0e0e0;
  position: absolute;
  bottom: -20px;
  left: calc(50% - 10px);
}

@keyframes slide {
  0% {
    transform: translateX(100%);
  }
  100% {
    transform: translateX(-100%);
  }
}
<div class="container">
  <div class="card">
    <div class="video-card">
      <video controls>
        <source src="https://v3.cdnpk.net/videvo_files/video/free/2012-07/small_preview/hd0994.mp4" type="video/mp4">
        Your browser does not support the video tag.
      </video>
    </div>
    <div class="review">
      <h2>Title 1</h2>
      <p>Description 1</p>
    </div>
    <div class="company-info">
      <h3>Company Name 1</h3>
    </div>
    <div class="arrow-down"></div>
  </div>
    <div class="card">
    <div class="video-card">
      <video controls>
        <source src="https://v3.cdnpk.net/videvo_files/video/free/2012-08/small_preview/hd0243.mp4" type="video/mp4">
        Your browser does not support the video tag.
      </video>
    </div>
    <div class="review">
      <h2>Title 1</h2>
      <p>Description 1</p>
    </div>
    <div class="company-info">
      <h3>Company Name 1</h3>
    </div>
    <div class="arrow-down"></div>
  </div>
    <div class="card">
    <div class="video-card">
      <video controls>
        <source src="https://cdn.pixabay.com/vimeo/910609536/glitter-199558.mp4?width=1280&hash=143a731648f4e3cad793cea006a0ceec77bafb2f" type="video/mp4">
        Your browser does not support the video tag.
      </video>
    </div>
    <div class="review">
      <h2>Title 1</h2>
      <p>Description 1</p>
    </div>
    <div class="company-info">
      <h3>Company Name 1</h3>
    </div>
    <div class="arrow-down"></div>
  </div>
    <div class="card">
    <div class="video-card">
      <video controls>
        <source src="https://cdn.pixabay.com/vimeo/893427276/fire-192687.mp4?width=640&hash=82a403f33f3588eedde6e64732cc742664d23430" type="video/mp4">
        Your browser does not support the video tag.
      </video>
    </div>
    <div class="review">
      <h2>Title 1</h2>
      <p>Description 1</p>
    </div>
    <div class="company-info">
      <h3>Company Name 1</h3>
    </div>
    <div class="arrow-down"></div>
  </div>
</div>