How to build a full-page menu (off-canvas) with GSAP

SHARE

SIGN UP FOR THE NEWSLETTER

Your subscription could not be saved. Please try again.
Your subscription has been successful.

The template uses a custom font called Morganite-Medium. You can find it here: https://www.behance.net/rajputrajesh


Code:

Javascript/GSAP (Icon list widget)

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.4/gsap.min.js"></script>
<script src="https://unpkg.com/gsap@3/dist/CSSRulePlugin.min.js"></script>

<script>
    
      document.addEventListener("DOMContentLoaded", function () {
         let activeItemIndicator = CSSRulePlugin.getRule(".elementor-icon-list-text#active::after");
         const toggleButton = document.querySelector(".burger");
         let isOpen = false;

        gsap.set(".elementor-icon-list-text, .test", {y: 400})
        gsap.set(".image-test", {y: 1000})
          
        const timeline = gsap.timeline({ paused: true });

          timeline.to(".overlay", {
            duration: 1.5,
            clipPath: "polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%)",
            ease: "power4.inOut"
          });
              timeline.to(".elementor-icon-list-text, .test, .image-test", {
            duration: 1.3,
            y: 0,
            stagger: 0.2,
            ease: "power4.out"
          }, "-=1");
          timeline.to(activeItemIndicator, {
            width: "100%",
            duration: 1,
            ease: "power4.out",
            delay: 0.5
          }, "<");
       
          toggleButton.addEventListener("click", function () {
            if (isOpen) {
              timeline.reverse();
            } else {
              timeline.play();
            }
            isOpen = !isOpen;
          });
        });
</script>  

Javascript/GSAP (WP Menu widget)

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.4/gsap.min.js"></script>
<script src="https://unpkg.com/gsap@3/dist/CSSRulePlugin.min.js"></script>

<script>
      document.addEventListener("DOMContentLoaded", function () {
         let activeItemIndicator = CSSRulePlugin.getRule(".test#active::after");
         const toggleButton = document.querySelector(".burger");
         let isOpen = false;

         gsap.set(".test", {y: 400})

         const timeline = gsap.timeline({ paused: true });

          timeline.to(".overlay", {
            duration: 1.5,
            clipPath: "polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%)",
            ease: "power4.inOut"
          });
              timeline.to(".test", {
            duration: 1.3,
            y: 0,
            stagger: 0.2,
            ease: "power4.out"
          }, "-=1");
          timeline.to(activeItemIndicator, {
            width: "100%",
            duration: 1,
            ease: "power4.out",
            delay: 0.5
          }, "<");
       
          toggleButton.addEventListener("click", function () {
            if (isOpen) {
              timeline.reverse();
            } else {
              timeline.play();
            }
            isOpen = !isOpen;
          });
        });
</script>

CSS

.burger:focus {
    border: none !important;
    outline: none !important;
}

.overlay {
  position: fixed;
  top: 0;
  left: 0;
  clip-path: polygon(0 0, 100% 0, 100% 0, 0 0);
  will-change: transform;
}

.burger {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 1.75em 2em 1.5em 2em;
  background: rgba(255, 255, 255, 0);
  border-radius: 0.25em;
  outline: none;
  height: 20px;
  width: 28px;
  border: none;
  transition: all 250ms ease-out;
  cursor: pointer;
}

.burger:before,
.burger:after
{
  content: "";
  width: 40px;
  height: 2px;
  position: absolute;
/*change the color of the burger menu lines here*/
  background: #fff;
  transition: all 250ms ease-out;
  will-change: transform;
}

.burger:before {
  transform: translateY(-3px);
}

.burger:after {
  transform: translateY(3px);
}


.active.burger:before {
  transform: translateY(0) rotate(45deg);
}

.active.burger:after {
  transform: translateY(0) rotate(-45deg);
}

/*optional - delete if not needed*/
.elementor-icon-list-item:hover  {
    letter-spacing: 8px;
    transition:all 0.5s ease;
}



Video:

SIGN UP FOR THE NEWSLETTER

Your subscription could not be saved. Please try again.
Your subscription has been successful.