javascripthtmlcssanimationslide

The slide animation is not working when scrolls down


I want that when user scrolls to that part of website animation triggers, means when that part comes in user's view the animation happens, here I am talking about the div class part 2, the part 1 working good but the part2 is not working, means animation works when website loads but at that time user is viewing part1 and when it scrolls to part 2, nothing happens as the animation has already happened when website was loaded. so please help me why it's not working.

Code Snippet

// Function to handle animation when elements are in view
const handleAnimation = () => {
  const elements = document.querySelectorAll('.animate-slide-left-bg, .animate-slide-left, .animate-slide-right, .animate-slide-up');

  elements.forEach(element => {
    // Check if the element is in view
    const rect = element.getBoundingClientRect();
    const windowHeight = window.innerHeight || document.documentElement.clientHeight;

    if (rect.top >= 0 && rect.bottom <= windowHeight) {
      // If the element is in view, add the animation class
      element.classList.add('animate-visible');
    }
  });
};

// Add event listener for scroll event
window.addEventListener('scroll', handleAnimation);

// Trigger animation on page load
handleAnimation();
.part2 {
  position: relative;
  width: 100%;
  height: 100%;
  background-color: #fff6f2;
  display: flex;
  flex-direction: column;
  font-family: 'Baskerville Old Face', serif;
  overflow: hidden;
  /* Hide content overflow */
}

.part2b {
  display: flex;
  flex-direction: row;
  position: relative;
}

.part2a {
  display: flex;
  flex-direction: column;
}

.qq {
  font-size: 35px;
  margin-top: 50px;
  margin-left: 60px;
  opacity: 0;
  transition: opacity 1s ease;
}

.q2 {
  font-size: 25px;
  margin-left: 60px;
  margin-top: 100px;
  height: fit-content;
  width: fit-content;
  opacity: 0;
  transition: opacity 1s ease;
}

.q3 {
  font-size: 80px;
  margin-left: 70px;
  margin-top: 20px;
  opacity: 0;
  transition: opacity 1s ease;
}

.bg3 {
  width: 50%;
  height: auto;
  margin-left: auto;
  /* Align the image to the right edge of the screen */
  opacity: 0;
  transition: opacity 1s ease;
}

.circle-image {
  position: absolute;
  top: 40%;
  /* Adjust to your desired position */
  left: 65%;
  /* Adjust to your desired position */
  transform: translate(-50%, -50%);
  width: 300px;
  height: 300px;
  border-radius: 50%;
  object-fit: cover;
  border: 17px solid #fff6f2;
  z-index: 2;
  opacity: 0;
  transition: opacity 1s ease;
}

.animate-slide-right {
  animation: slideRight 1s forwards;
  opacity: 0;
  /* Initially hide the elements */
}

.animate-slide-left {
  animation: slideLeft 1s forwards;
  opacity: 0;
  /* Initially hide the elements */
}

.animate-slide-up {
  animation: slideUp 1s forwards;
  opacity: 0;
  /* Initially hide the elements */
}

.animate-slide-right-circle {
  animation: slideRight 1s forwards;
  opacity: 0;
  /* Initially hide the elements */
}

.animate-slide-left-bg {
  animation: slideLeft 1s forwards;
  opacity: 0;
  /* Initially hide the elements */
}

@keyframes slideRight {
  from {
    transform: translateX(100%);
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

@keyframes slideLeft {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

@keyframes slideUp {
  from {
    transform: translateY(100%);
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}
<body>
  <div class="part1">
    <div class="A1">
      <div class="tt">
        <p class="txt2">Creative Portfolio</p>
      </div>
      <div class="pv">
        <p class="txt">PREMIUM<br> VIRTUAL ASSIST</p>
        <p class="txt1">Elevating Your Efficiency</p>
      </div>
    </div>
    <div class="A1">
      <img src="{% static 'virtualAssist/bg1.jpg' %}" alt="Background Image" class="image">
    </div>
    <div class="logo-container">
      <img src="{% static 'virtualAssist/logo.jpeg' %}" alt="Logo" class="logo">
    </div>
  </div>
  <div class="part2">
    <img src="{% static 'virtualAssist/bg4.jpg' %}" alt="Circle Image" class="circle-image animate-slide-up">
    <div class="part2b">
      <div class="part2a">
        <div class="qq animate-slide-left-bg ">Introducing</div>
        <div class="q2 animate-slide-left-bg">Premium Virtual Assist stands out for its<br>professional, sophisticated, and efficient <br>approach, making it the go-to choice for clients in<br>need of exceptional virtual assistant services</div>
      </div>
      <div class="bg3 animate-slide-right">
        <img src="{% static 'virtualAssist/bg3.jpg' %}" alt="Background Image" class="image">
      </div>
    </div>
    <div class="q3 animate-slide-up">
      WELCOME TO MY </br>
      PORTFOLIO
    </div>
  </div>
  <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>


Solution

  • Full code:

    // Function to handle animation when elements are in view
    const handleAnimation = () => {
      const elements = document.querySelectorAll('.animate-slide-left-bg, .animate-slide-left, .animate-slide-right, .animate-slide-up');
    
      elements.forEach(element => {
        // Check if the element is in view
        const rect = element.getBoundingClientRect();
        const windowHeight = window.innerHeight || document.documentElement.clientHeight;
    
        if ((rect.top >= 0 || rect.height >= windowHeight) && rect.bottom <= windowHeight) {
          // If the element is in view, add the animation class
          element.classList.add('animate-visible');
        }
      });
    };
    
    // Add event listener for scroll event
    window.addEventListener('scroll', handleAnimation);
    
    // Add event listener for resize event
    window.addEventListener('resize', handleAnimation);
    
    // Trigger animation on page load
    window.addEventListener('load', handleAnimation);
    .part2 {
      position: relative;
      width: 100%;
      height: 100%;
      background-color: #fff6f2;
      display: flex;
      flex-direction: column;
      font-family: 'Baskerville Old Face', serif;
      overflow: hidden;
      /* Hide content overflow */
    }
    
    .part2b {
      display: flex;
      flex-direction: row;
      position: relative;
    }
    
    .part2a {
      display: flex;
      flex-direction: column;
    }
    
    .qq {
      font-size: 35px;
      margin-top: 50px;
      margin-left: 60px;
      opacity: 0;
      transition: opacity 1s ease;
    }
    
    .q2 {
      font-size: 25px;
      margin-left: 60px;
      margin-top: 100px;
      height: fit-content;
      width: fit-content;
      opacity: 0;
      transition: opacity 1s ease;
    }
    
    .q3 {
      font-size: 80px;
      margin-left: 70px;
      margin-top: 20px;
      opacity: 0;
      transition: opacity 1s ease;
    }
    
    .bg3 {
      width: 50%;
      height: auto;
      margin-left: auto;
      /* Align the image to the right edge of the screen */
      opacity: 0;
      transition: opacity 1s ease;
    }
    
    .circle-image {
      position: absolute;
      top: 40%;
      /* Adjust to your desired position */
      left: 65%;
      /* Adjust to your desired position */
      transform: translate(-50%, -50%);
      width: 300px;
      height: 300px;
      border-radius: 50%;
      object-fit: cover;
      border: 17px solid #fff6f2;
      z-index: 2;
      opacity: 0;
      transition: opacity 1s ease;
    }
    
    .animate-slide-right {
      animation: 1s forwards;
      opacity: 0;
      /* Initially hide the elements */
    }
    
    .animate-visible.animate-slide-right {
      animation-name: slideRight;
    }
    
    .animate-slide-left {
      animation: 1s forwards;
      opacity: 0;
      /* Initially hide the elements */
    }
    
    .animate-visible.animate-slide-left {
      animation-name: slideLeft;
    }
    
    .animate-slide-up {
      animation: 1s forwards;
      opacity: 0;
      /* Initially hide the elements */
    }
    
    .animate-visible.animate-slide-up {
      animation-name: slideUp;
    }
    
    .animate-slide-right-circle {
      animation: 1s forwards;
      opacity: 0;
      /* Initially hide the elements */
    }
    
    .animate-visible.animate-slide-right-circle {
      animation-name: slideRight;
    }
    
    .animate-slide-left-bg {
      animation: 1s forwards;
      opacity: 0;
      /* Initially hide the elements */
    }
    
    .animate-visible.animate-slide-left-bg {
      animation-name: slideLeft;
    }
    
    @keyframes slideRight {
      from {
        transform: translateX(100%);
      }
      to {
        transform: translateX(0);
        opacity: 1;
      }
    }
    
    @keyframes slideLeft {
      from {
        transform: translateX(-100%);
      }
      to {
        transform: translateX(0);
        opacity: 1;
      }
    }
    
    @keyframes slideUp {
      from {
        transform: translateY(100%);
      }
      to {
        transform: translateY(0);
        opacity: 1;
      }
    }
    <div class="part1">
      <div class="A1">
        <div class="tt">
          <p class="txt2">Creative Portfolio</p>
        </div>
        <div class="pv">
          <p class="txt">PREMIUM<br> VIRTUAL ASSIST</p>
          <p class="txt1">Elevating Your Efficiency</p>
        </div>
      </div>
      <div class="A1">
        <img src="{% static 'virtualAssist/bg1.jpg' %}" alt="Background Image" class="image">
      </div>
      <div class="logo-container">
        <img src="{% static 'virtualAssist/logo.jpeg' %}" alt="Logo" class="logo">
      </div>
    </div>
    <div class="part2">
      <img src="{% static 'virtualAssist/bg4.jpg' %}" alt="Circle Image" class="circle-image animate-slide-up">
      <div class="part2b">
        <div class="part2a">
          <div class="qq animate-slide-left-bg ">Introducing</div>
          <div class="q2 animate-slide-left-bg">Premium Virtual Assist stands out for its<br>professional, sophisticated, and efficient <br>approach, making it the go-to choice for clients in<br>need of exceptional virtual assistant services</div>
        </div>
        <div class="bg3 animate-slide-right">
          <img src="{% static 'virtualAssist/bg3.jpg' %}" alt="Background Image" class="image">
        </div>
      </div>
      <div class="q3 animate-slide-up">
        WELCOME TO MY </br>
        PORTFOLIO
      </div>
    </div>

    All animations play immediately because their state is running when defined like this:

    .animate-slide-right {
      animation: slideRight 1s forwards;
    }
    

    If changed to:

    .animate-slide-right {
      animation: 1s forwards;
    }
    .animate-visible.animate-slide-right {
      animation-name: slideRight;
    }
    

    animation will start only when the element has animate-visible class.

    A view checking condition

    rect.top >= 0 && rect.bottom <= windowHeight
    

    should be extended

    (rect.top >= 0 || rect.height >= windowHeight) && rect.bottom <= windowHeight
    

    to make sure that elements with excessive height get activated too.

    It might be better to change the initial invocation of handleAnimation() to window.addEventListener('load', handleAnimation) so the first animations don't start too soon. Adding window.addEventListener('resize', handleAnimation) will improve the responsiveness.