|
|
|
|
@ -1,108 +1,109 @@
|
|
|
|
|
import { useEffect, useRef } from "react"; |
|
|
|
|
import { gsap } from "gsap"; |
|
|
|
|
import { ScrollTrigger } from "gsap/ScrollTrigger"; |
|
|
|
|
import { SplitText } from "gsap/SplitText"; |
|
|
|
|
|
|
|
|
|
gsap.registerPlugin(ScrollTrigger, SplitText); |
|
|
|
|
gsap.registerPlugin(ScrollTrigger); |
|
|
|
|
|
|
|
|
|
function MainPage() { |
|
|
|
|
const sectionRef = useRef(null); |
|
|
|
|
const bgRef = useRef(null); |
|
|
|
|
const hero2Ref = useRef(null); |
|
|
|
|
const hero3Ref = useRef(null); |
|
|
|
|
const text1Ref = useRef(null); |
|
|
|
|
const text2Ref = useRef(null); |
|
|
|
|
const splitRef = useRef(null); |
|
|
|
|
const text3Ref = useRef(null); |
|
|
|
|
const progressBarRef = useRef(null); |
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
const setupText = () => { |
|
|
|
|
if (splitRef.current) splitRef.current.revert(); |
|
|
|
|
const ctx = gsap.context(() => { |
|
|
|
|
gsap.set(hero2Ref.current, { opacity: 0, scale: 1.14, filter: "blur(10px)" }); |
|
|
|
|
gsap.set(hero3Ref.current, { opacity: 0, scale: 1.14, filter: "blur(10px)" }); |
|
|
|
|
gsap.set(text2Ref.current, { opacity: 0, y: 40, filter: "blur(8px)" }); |
|
|
|
|
gsap.set(text3Ref.current, { opacity: 0, y: 40, filter: "blur(8px)" }); |
|
|
|
|
gsap.set(progressBarRef.current, { width: "0%" }); |
|
|
|
|
gsap.set(".fill-line", { backgroundPosition: "100% 0%" }); |
|
|
|
|
|
|
|
|
|
splitRef.current = SplitText.create(text1Ref.current, { type: "chars" }); |
|
|
|
|
|
|
|
|
|
gsap.from(splitRef.current.chars, { |
|
|
|
|
x: 150, |
|
|
|
|
opacity: 0, |
|
|
|
|
duration: 0.7, |
|
|
|
|
ease: "power4", |
|
|
|
|
stagger: 0.04, |
|
|
|
|
const tl = gsap.timeline({ |
|
|
|
|
scrollTrigger: { |
|
|
|
|
trigger: sectionRef.current, |
|
|
|
|
start: "top top", |
|
|
|
|
end: "+=2600", |
|
|
|
|
scrub: 1.2, |
|
|
|
|
pin: true, |
|
|
|
|
anticipatePin: 1, |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
setupText(); |
|
|
|
|
tl.to(bgRef.current, { width: "100vw", height: "100vh", borderRadius: 0, ease: "none" }, 0) |
|
|
|
|
.to(bgRef.current, { scale: 1.08, ease: "none" }, 0) |
|
|
|
|
.to(progressBarRef.current, { width: "100%", ease: "none" }, 0) |
|
|
|
|
.to(".fill-line", { backgroundPosition: "0% 0%", ease: "none", stagger: 0.12, duration: 1.2 }, 0.08) |
|
|
|
|
|
|
|
|
|
.to(text1Ref.current, { opacity: 0, y: -40, filter: "blur(8px)", ease: "none" }, 1.35) |
|
|
|
|
|
|
|
|
|
gsap.set(hero2Ref.current, { opacity: 0 }); |
|
|
|
|
gsap.set(text2Ref.current, { opacity: 0, y: 30 }); |
|
|
|
|
.to(hero2Ref.current, { opacity: 1, scale: 1.03, filter: "blur(0px)", ease: "none" }, 1.15) |
|
|
|
|
.fromTo(text2Ref.current, { opacity: 0, y: 40, filter: "blur(8px)" }, { opacity: 1, y: 0, filter: "blur(0px)", ease: "none" }, 1.22) |
|
|
|
|
|
|
|
|
|
const tl = gsap.timeline({ |
|
|
|
|
scrollTrigger: { |
|
|
|
|
.to(hero2Ref.current, { scale: 1.1, ease: "none" }, 1.72) |
|
|
|
|
.to(text2Ref.current, { opacity: 0, y: -40, filter: "blur(8px)", ease: "none" }, 2.02) |
|
|
|
|
|
|
|
|
|
.to(hero3Ref.current, { opacity: 1, scale: 1.03, filter: "blur(0px)", ease: "none" }, 2.14) |
|
|
|
|
.fromTo(text3Ref.current, { opacity: 0, y: 40, filter: "blur(8px)" }, { opacity: 1, y: 0, filter: "blur(0px)", ease: "none" }, 2.28) |
|
|
|
|
.to(hero3Ref.current, { scale: 1.08, ease: "none" }, 2.82); |
|
|
|
|
|
|
|
|
|
ScrollTrigger.create({ |
|
|
|
|
trigger: sectionRef.current, |
|
|
|
|
start: "top top", |
|
|
|
|
end: "+=100%", |
|
|
|
|
scrub: 1, |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
tl.to( |
|
|
|
|
bgRef.current, |
|
|
|
|
{ |
|
|
|
|
scale: 1.18, |
|
|
|
|
borderRadius: 0, |
|
|
|
|
ease: "none", |
|
|
|
|
}, |
|
|
|
|
0, |
|
|
|
|
) |
|
|
|
|
.to( |
|
|
|
|
text1Ref.current, |
|
|
|
|
{ |
|
|
|
|
opacity: 0, |
|
|
|
|
y: -30, |
|
|
|
|
ease: "none", |
|
|
|
|
}, |
|
|
|
|
0.2, |
|
|
|
|
) |
|
|
|
|
.to( |
|
|
|
|
hero2Ref.current, |
|
|
|
|
{ |
|
|
|
|
opacity: 1, |
|
|
|
|
ease: "none", |
|
|
|
|
}, |
|
|
|
|
0.35, |
|
|
|
|
) |
|
|
|
|
.to( |
|
|
|
|
text2Ref.current, |
|
|
|
|
{ |
|
|
|
|
opacity: 1, |
|
|
|
|
y: 0, |
|
|
|
|
ease: "none", |
|
|
|
|
}, |
|
|
|
|
0.45, |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
window.addEventListener("resize", setupText); |
|
|
|
|
end: "+=2600", |
|
|
|
|
onEnter: () => document.body.classList.add("is-dark-hero"), |
|
|
|
|
onEnterBack: () => document.body.classList.add("is-dark-hero"), |
|
|
|
|
onLeave: () => document.body.classList.remove("is-dark-hero"), |
|
|
|
|
onLeaveBack: () => document.body.classList.remove("is-dark-hero"), |
|
|
|
|
}); |
|
|
|
|
}, sectionRef); |
|
|
|
|
|
|
|
|
|
return () => { |
|
|
|
|
window.removeEventListener("resize", setupText); |
|
|
|
|
tl.kill(); |
|
|
|
|
ScrollTrigger.getAll().forEach((trigger) => trigger.kill()); |
|
|
|
|
if (splitRef.current) splitRef.current.revert(); |
|
|
|
|
document.body.classList.remove("is-dark-hero"); |
|
|
|
|
ctx.revert(); |
|
|
|
|
}; |
|
|
|
|
}, []); |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<main className="main-page"> |
|
|
|
|
<section className="main-section" ref={sectionRef}> |
|
|
|
|
<div className="main-bg" ref={bgRef}> |
|
|
|
|
<div className="main-bg-hero2" ref={hero2Ref}></div> |
|
|
|
|
<div className="main-bg-wrap"> |
|
|
|
|
<div className="main-bg" ref={bgRef}> |
|
|
|
|
<div className="main-bg-hero1"></div> |
|
|
|
|
<div className="main-bg-hero2" ref={hero2Ref}></div> |
|
|
|
|
<div className="main-bg-hero3" ref={hero3Ref}></div> |
|
|
|
|
|
|
|
|
|
<div className="main-text"> |
|
|
|
|
<div className="text text-fill" ref={text1Ref}> |
|
|
|
|
<span className="fill-line">Technology Partner for</span> |
|
|
|
|
<br /> |
|
|
|
|
<span className="fill-line">Advanced Air Mobility</span> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div className="text text-change" ref={text2Ref}> |
|
|
|
|
항공 데이터와 통합 관제 기술로 |
|
|
|
|
<br /> |
|
|
|
|
안전한 하늘길을 설계합니다 |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div className="text text-change" ref={text3Ref}> |
|
|
|
|
공역관리와 드론 교통관리(UTM)를 기반으로 |
|
|
|
|
<br /> |
|
|
|
|
실제 운영 가능한 항공 시스템을 구축합니다 |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div className="main-text"> |
|
|
|
|
<div className="text" ref={text1Ref}> |
|
|
|
|
미래 항공 모빌리티를 구현하는 기술 파트너 |
|
|
|
|
<div className="main-progress"> |
|
|
|
|
<span className="main-progress-bar" ref={progressBarRef}></span> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div className="text text-change" ref={text2Ref}> |
|
|
|
|
공역관리와 드론 교통관리(UTM)를 기반으로 |
|
|
|
|
<br /> |
|
|
|
|
실제 운영 가능한 항공 시스템을 구축합니다 |
|
|
|
|
<div className="main-scroll-indicator"> |
|
|
|
|
<span className="main-scroll-line"></span> |
|
|
|
|
<span className="main-scroll-text">SCROLL</span> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
|