# \[GSAP] Sử dụng toggle menu (ok)

Để tạo **toggle menu (menu ẩn/hiện)** bằng **GSAP** (kèm animation mượt mà), bạn có thể làm theo ví dụ dưới đây.

#### ✅ Ví dụ: Toggle menu với GSAP

**✅ HTML:**

```html
<button id="menu-toggle">Toggle Menu</button>
<nav id="menu" class="menu">
  <ul>
    <li><a href="#">Trang chủ</a></li>
    <li><a href="#">Giới thiệu</a></li>
    <li><a href="#">Dịch vụ</a></li>
    <li><a href="#">Liên hệ</a></li>
  </ul>
</nav>

```

✅ CSS (cơ bản để ẩn menu ban đầu):

```css
.menu {
  overflow: hidden;
  height: 0;
}

```

**✅ JavaScript (GSAP):**

```javascript
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
<script>
  const menu = document.getElementById("menu");
  const toggleBtn = document.getElementById("menu-toggle");

  let isOpen = false;

  toggleBtn.addEventListener("click", () => {
    if (isOpen) {
      // Ẩn menu
      gsap.to(menu, {
        height: 0,
        duration: 0.5,
        ease: "power2.inOut"
      });
    } else {
      // Hiện menu
      const fullHeight = menu.scrollHeight;
      gsap.to(menu, {
        height: fullHeight,
        duration: 0.5,
        ease: "power2.inOut"
      });
    }
    isOpen = !isOpen;
  });
</script>

```

#### 📝 Gợi ý nâng cao:

* Nếu bạn dùng **Tailwind CSS**, bạn có thể dùng `max-h-0` và `overflow-hidden` thay cho `height: 0` và dùng class toggling với GSAP để thay đổi `maxHeight`.
* Với menu phức tạp (như overlay toàn màn hình), bạn có thể thêm các hiệu ứng như `opacity`, `scale`, `translateY`, v.v.

***

Bạn đang dùng **GSAP với React**, **Next.js**, hay là HTML thuần? Mình có thể điều chỉnh ví dụ theo đúng nhu cầu nếu bạn cho biết thêm.

Tuyệt vời! Nếu bạn muốn **toggle menu bằng GSAP nhưng điều khiển thông qua class (ví dụ: `.active`)**, thì bạn có thể:

* Dùng class để xác định trạng thái mở/đóng của menu.
* GSAP chỉ dùng để tạo hiệu ứng chuyển đổi (animation).

***

#### ✅ Ví dụ Toggle menu bằng class + GSAP

**✅ HTML:**

```html
<button id="menu-toggle">Toggle Menu</button>
<nav id="menu" class="menu">
  <ul>
    <li><a href="#">Trang chủ</a></li>
    <li><a href="#">Giới thiệu</a></li>
    <li><a href="#">Dịch vụ</a></li>
    <li><a href="#">Liên hệ</a></li>
  </ul>
</nav>

```

✅ CSS:

```css
.menu {
  overflow: hidden;
  height: 0;
  transition: height 0.3s ease;
}

/* Khi menu được bật */
.menu.active {
  /* Không cần height cố định vì sẽ dùng gsap */
}

```

✅ JavaScript (dùng class `active`):

```javascript
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
<script>
  const menu = document.getElementById("menu");
  const toggleBtn = document.getElementById("menu-toggle");
  toggleBtn.addEventListener("click", () => {
    if (menu.classList.contains("active")) {
      // Đang mở → đóng
      gsap.to(menu, {
        height: 0,
        duration: 0.5,
        ease: "power2.inOut",
        onComplete: () => {
          menu.classList.remove("active");
        }
      });
    } else {
      // Đang đóng → mở
      menu.classList.add("active"); // cần thêm class để hiện nội dung cho đo chiều cao
      const fullHeight = menu.scrollHeight;

      gsap.fromTo(menu,
        { height: 0 },
        {
          height: fullHeight,
          duration: 0.5,
          ease: "power2.inOut"
        }
      );
    }
  });
</script>

```

#### ✅ Mẹo:

* `scrollHeight` là chiều cao thật sự của phần tử cần hiển thị (giúp animation chính xác).
* Thêm `menu.classList.add('active')` trước khi đo `scrollHeight` để đảm bảo nội dung được render ra DOM.
* Bạn có thể dùng Tailwind CSS với `max-h-0` và `max-h-[500px]` kết hợp nếu muốn class-based control nhưng vẫn dùng GSAP cho animation mượt.

Bạn có muốn mình viết lại phiên bản này bằng **Tailwind CSS + React/Next.js + GSAP** không?
