Hero Bento Animated

hidden 👍 Gathering votes

I used this template as a section on my page: https://fancybricks.co/templates-2-0/18-hero-bento-animated/

As it was in the middle of the page, by the time I reached that section, the animation had already played.

In order run the animation in viewport, I adjusted the CSS to this:


%root%{
  --gaps: 1.5rem;
  --animation-time: 2s;
  --height: 70vh;
}

%root% %root%__col-1 %root%__image,
%root% %root%__col-2 %root%__image,
%root%__container,
%root%__inner {
  opacity: 0; /* Initially invisible */
  transition: opacity 0.5s ease-in-out; /* Smooth opacity transition */
}

/* Add 'animate' class once elements come into viewport */
%root% %root%__col-1 %root%__image:first-child.animate {
  opacity: 1;
  animation: fbEnterFromTop var(--animation-time) ease-in-out forwards;
}

%root% %root%__col-2 %root%__image:last-child.animate {
  opacity: 1;
  animation: fbEnterFromBottom var(--animation-time) ease-in-out forwards;
}

%root% %root%__col-1 %root%__image:last-child.animate, %root% %root%__col-2 %root%__image:first-child.animate {
  opacity: 1;
  animation: fbResize calc(var(--animation-time) / 2) ease-in-out forwards;
  animation-delay: calc(var(--animation-time) / 2);
}

%root%__container.animate {
  opacity: 1;
  animation: fbGrid60 calc(var(--animation-time) / 2) ease-in-out forwards;
  animation-delay: calc(var(--animation-time) / 1);
}

%root%__inner.animate {
  opacity: 1;
  animation: fbContent calc(var(--animation-time) / 2) ease-in-out forwards;
  /*animation-delay: calc(var(--animation-time) * 1.4);*/
}

/* Keyframe animations */
@keyframes fbEnterFromTop {
  0% {
    transform: translateY(-100%);
    opacity: 0;
    height: 100%;
  }
  50% {
    transform: translateY(0);
    opacity: 1;
    height: 100%;
  }
  100% {
    height: calc(70% - var(--gaps) / 2);
  }
}

@keyframes fbEnterFromBottom {
  0% {
    transform: translateY(100%);
    opacity: 0;
    height: 100%;
  }
  50% {
    transform: translateY(0);
    opacity: 1;
    height: 100%;
  }
  100% {
    height: calc(70% - var(--gaps) / 2);
  }
}

@keyframes fbResize {
  0% {
    height: 0;
  }
  100% {
    height: calc(30% - var(--gaps) / 2);;
  }
}

@keyframes fbGrid60{
  0% {
    grid-template-columns: 100% 0%;
  }
  100% {
    grid-template-columns: calc(60% - var(--gaps)) 40%;
  }
}

@keyframes fbContent{
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}```

Added this JS code:

document.addEventListener("DOMContentLoaded", () => {
  // Select all the elements you want to animate
  const elementsToAnimate = document.querySelectorAll('.fb-hero-anim__image, .fb-hero-anim__container, .fb-hero-anim__inner');

  const options = {
    root: null,  // Use the viewport as the root
    threshold: 0.5,  // Trigger when 50% of the element is visible
  };

  const observer = new IntersectionObserver((entries, observer) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        // Add the 'animate' class to trigger the animation
        entry.target.classList.add('animate');
      }
    });
  }, options);

  // Observe each element for visibility
  elementsToAnimate.forEach(element => {
    observer.observe(element);
  });
});

Let me know if there is a better way to achieve it.

Aashishbisht

2 months ago

One vote
Categories
Template