|
|
|
@ -1,35 +1,135 @@ |
|
|
|
|
|
|
|
import { useEffect, useRef } from "react"; |
|
|
|
|
|
|
|
import { gsap } from "gsap"; |
|
|
|
|
|
|
|
import { ScrollTrigger } from "gsap/ScrollTrigger"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gsap.registerPlugin(ScrollTrigger); |
|
|
|
|
|
|
|
|
|
|
|
function MainUtm() { |
|
|
|
function MainUtm() { |
|
|
|
|
|
|
|
const sectionRef = useRef(null); |
|
|
|
|
|
|
|
const stickyRef = useRef(null); |
|
|
|
|
|
|
|
const trackRef = useRef(null); |
|
|
|
|
|
|
|
const line1Ref = useRef(null); |
|
|
|
|
|
|
|
const line2Ref = useRef(null); |
|
|
|
|
|
|
|
const line3Ref = useRef(null); |
|
|
|
|
|
|
|
const descRef = useRef(null); |
|
|
|
|
|
|
|
const panelRef = useRef(null); |
|
|
|
|
|
|
|
const frameRef = useRef(null); |
|
|
|
|
|
|
|
const card1Ref = useRef(null); |
|
|
|
|
|
|
|
const card2Ref = useRef(null); |
|
|
|
|
|
|
|
const card3Ref = useRef(null); |
|
|
|
|
|
|
|
const glowRef = useRef(null); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
|
|
|
const ctx = gsap.context(() => { |
|
|
|
|
|
|
|
gsap.set([line1Ref.current, line2Ref.current, line3Ref.current], { yPercent: 0 }); |
|
|
|
|
|
|
|
gsap.set(line2Ref.current, { opacity: 0.18 }); |
|
|
|
|
|
|
|
gsap.set(line3Ref.current, { opacity: 0.12 }); |
|
|
|
|
|
|
|
gsap.set(descRef.current, { opacity: 0.35, y: 20 }); |
|
|
|
|
|
|
|
gsap.set(panelRef.current, { scale: 0.92, y: 40, rotateX: 8 }); |
|
|
|
|
|
|
|
gsap.set(card1Ref.current, { x: 40, y: 0, rotate: -6 }); |
|
|
|
|
|
|
|
gsap.set(card2Ref.current, { x: 0, y: 0, rotate: 0 }); |
|
|
|
|
|
|
|
gsap.set(card3Ref.current, { x: -40, y: 0, rotate: 6 }); |
|
|
|
|
|
|
|
gsap.set(glowRef.current, { scale: 0.8, opacity: 0.3 }); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const tl = gsap.timeline({ |
|
|
|
|
|
|
|
scrollTrigger: { |
|
|
|
|
|
|
|
trigger: sectionRef.current, |
|
|
|
|
|
|
|
start: "top top", |
|
|
|
|
|
|
|
end: "+=2200", |
|
|
|
|
|
|
|
scrub: 1.1, |
|
|
|
|
|
|
|
pin: stickyRef.current, |
|
|
|
|
|
|
|
anticipatePin: 1, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tl.to(line1Ref.current, { yPercent: -110, opacity: 0.08, ease: "none" }, 0) |
|
|
|
|
|
|
|
.to(line2Ref.current, { yPercent: -102, opacity: 1, ease: "none" }, 0) |
|
|
|
|
|
|
|
.to(descRef.current, { opacity: 0.7, y: 0, ease: "none" }, 0.08) |
|
|
|
|
|
|
|
.to(panelRef.current, { scale: 1, y: 0, rotateX: 0, ease: "none" }, 0.02) |
|
|
|
|
|
|
|
.to(card1Ref.current, { x: 0, y: -18, rotate: 0, ease: "none" }, 0.06) |
|
|
|
|
|
|
|
.to(card2Ref.current, { y: -8, ease: "none" }, 0.08) |
|
|
|
|
|
|
|
.to(card3Ref.current, { x: 0, y: 16, rotate: 0, ease: "none" }, 0.1) |
|
|
|
|
|
|
|
.to(glowRef.current, { scale: 1.2, opacity: 0.55, ease: "none" }, 0.08) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.to(line2Ref.current, { yPercent: -210, opacity: 0.08, ease: "none" }, 0.42) |
|
|
|
|
|
|
|
.to(line3Ref.current, { yPercent: -196, opacity: 1, ease: "none" }, 0.42) |
|
|
|
|
|
|
|
.to(descRef.current, { opacity: 1, ease: "none" }, 0.48) |
|
|
|
|
|
|
|
.to(panelRef.current, { y: -12, scale: 1.03, ease: "none" }, 0.46) |
|
|
|
|
|
|
|
.to(card1Ref.current, { x: -26, y: -28, scale: 0.96, opacity: 0.7, ease: "none" }, 0.46) |
|
|
|
|
|
|
|
.to(card2Ref.current, { y: -18, scale: 1.04, ease: "none" }, 0.48) |
|
|
|
|
|
|
|
.to(card3Ref.current, { x: 26, y: 24, scale: 0.96, opacity: 0.7, ease: "none" }, 0.46) |
|
|
|
|
|
|
|
.to(glowRef.current, { scale: 1.45, opacity: 0.72, ease: "none" }, 0.48) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.to(trackRef.current, { yPercent: -8, ease: "none" }, 0.68) |
|
|
|
|
|
|
|
.to(panelRef.current, { scale: 1.08, y: -26, ease: "none" }, 0.68) |
|
|
|
|
|
|
|
.to(descRef.current, { y: -8, ease: "none" }, 0.68); |
|
|
|
|
|
|
|
}, sectionRef); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return () => ctx.revert(); |
|
|
|
|
|
|
|
}, []); |
|
|
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
return ( |
|
|
|
<section className="main-utm-section"> |
|
|
|
<section className="main-utm-section" ref={sectionRef}> |
|
|
|
<div className="main-utm-inner"> |
|
|
|
<div className="main-utm-sticky" ref={stickyRef}> |
|
|
|
<div className="main-utm-head"> |
|
|
|
<div className="main-utm-inner"> |
|
|
|
<h2>UTM SYSTEM</h2> |
|
|
|
<div className="main-utm-copy"> |
|
|
|
<p>드론 교통을 안전하게 관리하는 통합 관제 시스템</p> |
|
|
|
<p className="main-utm-kicker">UTM SYSTEM</p> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div className="main-utm-flow"> |
|
|
|
<div className="main-utm-title-track" ref={trackRef}> |
|
|
|
<div className="utm-item"> |
|
|
|
<h2 className="main-utm-line line-1" ref={line1Ref}> |
|
|
|
<span className="num">01</span> |
|
|
|
<span className="main-utm-strong">Monitor</span> |
|
|
|
<h3>비행 요청</h3> |
|
|
|
<span className="main-utm-muted"> the airspace</span> |
|
|
|
<p>운영자는 비행 계획을 등록합니다</p> |
|
|
|
</h2> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div className="utm-item"> |
|
|
|
<h2 className="main-utm-line line-2" ref={line2Ref}> |
|
|
|
<span className="num">02</span> |
|
|
|
<span className="main-utm-strong">Approve</span> |
|
|
|
<h3>자동 승인</h3> |
|
|
|
<span className="main-utm-muted"> every mission</span> |
|
|
|
<p>공역과 규제 기준을 기반으로 승인됩니다</p> |
|
|
|
</h2> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<h2 className="main-utm-line line-3" ref={line3Ref}> |
|
|
|
|
|
|
|
<span className="main-utm-strong">Control</span> |
|
|
|
|
|
|
|
<span className="main-utm-muted"> in real time</span> |
|
|
|
|
|
|
|
</h2> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<div className="utm-item"> |
|
|
|
<p className="main-utm-desc" ref={descRef}> |
|
|
|
<span className="num">03</span> |
|
|
|
실시간 모니터링, 자동 비행 승인, 운항 시뮬레이션과 영상 연계를 하나의 경험으로 구성한 통합 UTM 플랫폼 |
|
|
|
<h3>경로 관리</h3> |
|
|
|
</p> |
|
|
|
<p>비행 경로를 실시간으로 추적합니다</p> |
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<div className="utm-item"> |
|
|
|
<div className="main-utm-showcase"> |
|
|
|
<span className="num">04</span> |
|
|
|
<div className="main-utm-glow" ref={glowRef}></div> |
|
|
|
<h3>실시간 관제</h3> |
|
|
|
|
|
|
|
<p>이상 상황을 즉시 감지하고 대응합니다</p> |
|
|
|
<div className="main-utm-panel-frame" ref={frameRef}> |
|
|
|
|
|
|
|
<div className="main-utm-panel" ref={panelRef}> |
|
|
|
|
|
|
|
<div className="main-utm-panel-top"> |
|
|
|
|
|
|
|
<span className="main-utm-chip">Live Operations</span> |
|
|
|
|
|
|
|
<span className="main-utm-status"> |
|
|
|
|
|
|
|
<i></i> |
|
|
|
|
|
|
|
System Active |
|
|
|
|
|
|
|
</span> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div className="main-utm-radar"></div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div className="main-utm-floating-card card-a" ref={card1Ref}> |
|
|
|
|
|
|
|
<strong>Monitoring</strong> |
|
|
|
|
|
|
|
<p>실시간 비행 상황 및 공역 상태 가시화</p> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div className="main-utm-floating-card card-b" ref={card2Ref}> |
|
|
|
|
|
|
|
<strong>Approval</strong> |
|
|
|
|
|
|
|
<p>비행 가능 여부 검토와 자동 승인 프로세스</p> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div className="main-utm-floating-card card-c" ref={card3Ref}> |
|
|
|
|
|
|
|
<strong>Simulation</strong> |
|
|
|
|
|
|
|
<p>운항 전 시뮬레이션과 상황 대응 연계</p> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div className="main-utm-grid-lines"></div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|