fix: gsap 추가

This commit is contained in:
이희원 2026-06-20 02:14:00 +09:00
parent 1cdb048e36
commit 67c0bfe5b9
6 changed files with 70 additions and 40 deletions

View File

@ -19,6 +19,7 @@
"vite-plugin-imagemin": "^0.6.1" "vite-plugin-imagemin": "^0.6.1"
}, },
"dependencies": { "dependencies": {
"gsap": "^3.15.0",
"jquery": "^4.0.0", "jquery": "^4.0.0",
"sharp": "^0.35.1" "sharp": "^0.35.1"
} }

View File

@ -18,7 +18,7 @@
</a> </a>
<nav class="gnb__nav"> <nav class="gnb__nav">
<ul class="gnb__navList"> <ul class="gnb__navList">
<li class="gnb__navItem is-active"><a class="gnb__navLink" href="#intro">HOME</a></li> <li class="gnb__navItem"><a class="gnb__navLink" href="#intro">HOME</a></li>
<li class="gnb__navItem"><a class="gnb__navLink" href="#about">ABOUT</a></li> <li class="gnb__navItem"><a class="gnb__navLink" href="#about">ABOUT</a></li>
<li class="gnb__navItem"><a class="gnb__navLink" href="#project">PROJECTS</a></li> <li class="gnb__navItem"><a class="gnb__navLink" href="#project">PROJECTS</a></li>
<li class="gnb__navItem"><a class="gnb__navLink" href="#contact">CONTACT</a></li> <li class="gnb__navItem"><a class="gnb__navLink" href="#contact">CONTACT</a></li>
@ -638,7 +638,7 @@
</div> </div>
<!-- 프로젝트 문의 --> <!-- 프로젝트 문의 -->
<div class="contactAccordion"> <div class="contactAccordion">
<div class="contactAccordion__item is-open" id="acc-project"> <div class="contactAccordion__item isOpen" id="acc-project">
<button class="contactAccordion__header" aria-expanded="true" aria-controls="acc-project-body"> <button class="contactAccordion__header" aria-expanded="true" aria-controls="acc-project-body">
<span>프로젝트 문의</span> <span>프로젝트 문의</span>
<img class="contactAccordion__icon" src="images/icon-chevron.svg" alt="" /> <img class="contactAccordion__icon" src="images/icon-chevron.svg" alt="" />

View File

@ -1,55 +1,86 @@
import $ from "jquery"; import $ from "jquery";
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);
$(function () { $(function () {
const $gnb = $("#gnb"); const $gnb = $("#gnb");
const $hamburger = $(".gnb__hamburger"); const $hamburger = $(".gnb__hamburger");
const $mobileNav = $(".gnb__mobileNav"); const $mobileNav = $(".gnb__mobileNav");
const $sections = $("section[id]");
const $navLinks = $(".gnb__navItem"); // 섹션 → nav 귀속 맵
const sectionToNav = {
intro: "intro",
about: "about",
history: "about",
"boda-intro": "about",
vision: "about",
project: "project",
expertise: "project",
contact: "contact",
};
// GNB 스크롤 배경 // GNB 스크롤 배경
$(window).on("scroll.gnb", { passive: true }, function () { ScrollTrigger.create({
$gnb.toggleClass("is-scrolled", $(this).scrollTop() > 40); start: "40px top",
updateActiveNav(); onEnter: () => $gnb.addClass("isScrolled"),
onLeaveBack: () => $gnb.removeClass("isScrolled"),
}); });
// 현재 섹션에 따라 GNB 활성화
const $navLinks = $(".gnb__navLink");
const sections = $("section[id]").toArray();
function setActiveNav(navId) {
$navLinks.each(function () {
const href = $(this).attr("href").replace("#", "");
$(this).toggleClass("isActive", href === navId);
});
}
function updateActiveNav() {
const scrollY = window.scrollY + window.innerHeight / 3;
let current = "";
sections.forEach((el) => {
if (el.offsetTop <= scrollY) {
current = sectionToNav[el.id] || current;
}
});
setActiveNav(current);
}
ScrollTrigger.create({
trigger: document.body,
start: "top top",
end: "max",
onUpdate: updateActiveNav,
});
updateActiveNav();
// 햄버거 메뉴 // 햄버거 메뉴
$hamburger.on("click", function () { $hamburger.on("click", function () {
const isOpen = $hamburger.toggleClass("is-open").hasClass("is-open"); const isOpen = $hamburger.toggleClass("isOpen").hasClass("isOpen");
$hamburger.attr("aria-expanded", isOpen); $hamburger.attr("aria-expanded", isOpen);
$mobileNav.toggleClass("is-open", isOpen); $mobileNav.toggleClass("isOpen", isOpen);
}); });
// 모바일 메뉴 링크 클릭 시 닫기 // 모바일 메뉴 링크 클릭 시 닫기
$(".gnb__mobileNavLink").on("click", function () { $(".gnb__mobileNavLink").on("click", function () {
$hamburger.removeClass("is-open").attr("aria-expanded", false); $hamburger.removeClass("isOpen").attr("aria-expanded", false);
$mobileNav.removeClass("is-open"); $mobileNav.removeClass("isOpen");
}); });
// 현재 섹션에 따라 GNB 활성화
function updateActiveNav() {
let current = "";
const scrollY = $(window).scrollTop() + $(window).height() / 3;
$sections.each(function () {
if ($(this).offset().top <= scrollY) {
current = $(this).attr("id");
}
});
$navLinks.each(function () {
const href = $(this).find("a").attr("href").replace("#", "");
$(this).toggleClass("is-active", href === current);
});
}
// Contact 아코디언 // Contact 아코디언
$(".contactAccordion__header").on("click", function () { $(".contactAccordion__header").on("click", function () {
const $item = $(this).closest(".contactAccordion__item"); const $item = $(this).closest(".contactAccordion__item");
const $body = $("#" + $(this).attr("aria-controls")); const $body = $("#" + $(this).attr("aria-controls"));
const isOpen = $item.hasClass("is-open"); const isOpen = $item.hasClass("isOpen");
$item.toggleClass("is-open", !isOpen); $item.toggleClass("isOpen", !isOpen);
$(this).attr("aria-expanded", !isOpen); $(this).attr("aria-expanded", !isOpen);
if (isOpen) { if (isOpen) {
@ -58,7 +89,4 @@ $(function () {
$body.removeAttr("hidden"); $body.removeAttr("hidden");
} }
}); });
// 초기 실행
updateActiveNav();
}); });

View File

@ -205,7 +205,7 @@
object-fit: unset; object-fit: unset;
} }
.contactAccordion__item.is-open .contactAccordion__icon { .contactAccordion__item.isOpen .contactAccordion__icon {
transform: rotate(180deg); transform: rotate(180deg);
} }

View File

@ -11,7 +11,7 @@
z-index: 100; z-index: 100;
transition: background 0.4s; transition: background 0.4s;
&.is-scrolled { &.isScrolled {
background: rgba($color-bg, 0.92); background: rgba($color-bg, 0.92);
backdrop-filter: blur(12px); backdrop-filter: blur(12px);
} }
@ -63,7 +63,7 @@
} }
} }
.gnb__navItem.is-active .gnb__navLink { .gnb__navLink.isActive {
color: $color-cyan; color: $color-cyan;
} }
@ -90,13 +90,13 @@
opacity 0.3s; opacity 0.3s;
} }
.gnb__hamburger.is-open .gnb__hamburgerLine:nth-child(1) { .gnb__hamburger.isOpen .gnb__hamburgerLine:nth-child(1) {
transform: translateY(6px) rotate(45deg); transform: translateY(6px) rotate(45deg);
} }
.gnb__hamburger.is-open .gnb__hamburgerLine:nth-child(2) { .gnb__hamburger.isOpen .gnb__hamburgerLine:nth-child(2) {
opacity: 0; opacity: 0;
} }
.gnb__hamburger.is-open .gnb__hamburgerLine:nth-child(3) { .gnb__hamburger.isOpen .gnb__hamburgerLine:nth-child(3) {
transform: translateY(-6px) rotate(-45deg); transform: translateY(-6px) rotate(-45deg);
} }
@ -116,7 +116,7 @@
opacity 0.35s ease; opacity 0.35s ease;
pointer-events: none; pointer-events: none;
&.is-open { &.isOpen {
transform: translateY(0); transform: translateY(0);
opacity: 1; opacity: 1;
pointer-events: auto; pointer-events: auto;

View File

@ -29,6 +29,7 @@ export default defineConfig({
plugins: [ plugins: [
{ {
name: 'remove-module-attrs', name: 'remove-module-attrs',
apply: 'build',
transformIndexHtml(html) { transformIndexHtml(html) {
return html return html
.replace(/ type="module"/g, '') .replace(/ type="module"/g, '')