You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

153 lines
4.1 KiB

import { useEffect, useRef } from "react";
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);
function MainUTM() {
const sectionRef = useRef(null);
const overlayRef = useRef(null);
const titleRef = useRef(null);
const vehicleRef = useRef(null);
const panelsRef = useRef([]);
const items = [
{
label: "UTM NETWORK",
title: "Urban Air Mobility",
desc: "도심 내 버티포트, 운항 경로, 항공 교통 데이터를 연결해 미래형 도심 항공 이동 환경을 구축합니다.",
},
{
label: "VERTIPORT",
title: "Vertiport Connection",
desc: "도심 곳곳의 이착륙 거점을 연결해 사람과 도시의 이동 흐름을 확장합니다.",
},
{
label: "AIR CORRIDOR",
title: "Smart Air Corridor",
desc: "복잡한 도심 상공에서도 안전한 항로를 구성하고 실시간 운항 흐름을 관리합니다.",
},
];
useEffect(() => {
const ctx = gsap.context(() => {
gsap.set(overlayRef.current, { yPercent: 0 });
gsap.set(titleRef.current, { y: 80, opacity: 0 });
gsap.set(vehicleRef.current, {
xPercent: -120,
yPercent: 80,
opacity: 0,
});
gsap.set(panelsRef.current, { y: 40, opacity: 0 });
const tl = gsap.timeline({
scrollTrigger: {
trigger: sectionRef.current,
start: "top bottom",
end: "+=1400",
scrub: 1,
},
});
tl.to(overlayRef.current, {
yPercent: -100,
duration: 1,
ease: "none",
});
tl.to(
titleRef.current,
{
y: 0,
opacity: 1,
duration: 0.8,
ease: "none",
},
"<0.25",
);
tl.to(
vehicleRef.current,
{
xPercent: 0,
yPercent: 0,
opacity: 1,
duration: 1,
ease: "none",
},
"<0.2",
);
tl.to(
panelsRef.current,
{
y: 0,
opacity: 1,
stagger: 0.16,
duration: 0.8,
ease: "none",
},
"<0.35",
);
}, sectionRef);
return () => ctx.revert();
}, []);
return (
<section className="main-UTM-section" ref={sectionRef}>
<div className="main-UTM-screen-wipe" ref={overlayRef}>
<span>FROM UTM</span>
<strong>TO UTM</strong>
</div>
<div className="main-UTM-bg-grid" />
<div className="main-UTM-light main-UTM-light--a" />
<div className="main-UTM-light main-UTM-light--b" />
<div className="main-UTM-inner">
<div className="main-UTM-visual">
<div className="main-UTM-route main-UTM-route--a" />
<div className="main-UTM-route main-UTM-route--b" />
<div className="main-UTM-route main-UTM-route--c" />
<div className="main-UTM-node main-UTM-node--a">V</div>
<div className="main-UTM-node main-UTM-node--b">P</div>
<div className="main-UTM-node main-UTM-node--c">C</div>
<div className="main-UTM-vehicle" ref={vehicleRef}>
<span />
</div>
</div>
<div className="main-UTM-content" ref={titleRef}>
<p className="main-UTM-eyebrow">UTM SYSTEM</p>
<h2>
도심항공교통
<br />
UTM
</h2>
<p>드론 관제에서 확장된 하늘길은 이제 도시의 이동 네트워크로 이어집니다. UTM은 버티포트, 항로, 운항 데이터를 하나의 흐름으로 연결합니다.</p>
</div>
<div className="main-UTM-panels">
{items.map((item, index) => (
<article
className="main-UTM-panel"
key={item.label}
ref={(el) => {
panelsRef.current[index] = el;
}}
>
<span>{item.label}</span>
<h3>{item.title}</h3>
<p>{item.desc}</p>
</article>
))}
</div>
</div>
</section>
);
}
export default MainUTM;