diff --git a/index.html b/index.html index e4d6dd3..8894b83 100644 --- a/index.html +++ b/index.html @@ -3,23 +3,14 @@
- + - + - + @@ -43,10 +34,7 @@ - + diff --git a/public/images/uam.png b/public/images/uam.png new file mode 100644 index 0000000..458281d Binary files /dev/null and b/public/images/uam.png differ diff --git a/src/components/main/MainUam.jsx b/src/components/main/MainUam.jsx new file mode 100644 index 0000000..c1c3ef6 --- /dev/null +++ b/src/components/main/MainUam.jsx @@ -0,0 +1,330 @@ +import { useEffect, useRef } from "react"; +import { gsap } from "gsap"; +import { ScrollTrigger } from "gsap/ScrollTrigger"; + +gsap.registerPlugin(ScrollTrigger); + +const UAM_SPECS = [ + { + id: "01", + anchor: "navigation", + label: "자율 항법 시스템", + title: "AI 기반\n정밀 항법", + desc: "다중 센서 융합과 실시간 AI 연산으로 도심 상공에서도 센티미터 단위의 정밀 경로 제어를 실현합니다.", + stat: "±0.03m", + statLabel: "위치 정확도", + cx: "28%", + cy: "38%", + cardSide: "left", + }, + { + id: "02", + anchor: "comm", + label: "통합 통신 모듈", + title: "5G·위성\n이중 통신", + desc: "5G와 위성 통신을 동시에 운용하는 이중 링크 구조로 어떤 환경에서도 끊김 없는 데이터 채널을 보장합니다.", + stat: "<8ms", + statLabel: "지연 시간", + cx: "72%", + cy: "30%", + cardSide: "right", + }, + { + id: "03", + anchor: "power", + label: "하이브리드 추진", + title: "전기·수소\n하이브리드", + desc: "전기 모터와 수소 셀을 결합한 하이브리드 추진 시스템으로 항속 거리를 극대화하고 탄소 배출을 최소화합니다.", + stat: "320km", + statLabel: "최대 항속", + cx: "50%", + cy: "72%", + cardSide: "left", + }, + { + id: "04", + anchor: "sensor", + label: "능동 안전 센서", + title: "360° 장애물\n회피", + desc: "LiDAR·레이더·광학 카메라 트리플 센서가 360도 전방위를 실시간 스캔해 돌발 장애물에 즉각 대응합니다.", + stat: "0.12s", + statLabel: "반응 속도", + cx: "78%", + cy: "65%", + cardSide: "right", + }, +]; + +function MainUam() { + const sectionRef = useRef(null); + const eyebrowRef = useRef(null); + const titleRef = useRef(null); + const subRef = useRef(null); + const aircraftRef = useRef(null); + const dotRefs = useRef([]); + const lineRefs = useRef([]); + const cardRefs = useRef([]); + + useEffect(() => { + const ctx = gsap.context(() => { + dotRefs.current = dotRefs.current.slice(0, UAM_SPECS.length); + lineRefs.current = lineRefs.current.slice(0, UAM_SPECS.length); + cardRefs.current = cardRefs.current.slice(0, UAM_SPECS.length); + + gsap.set(aircraftRef.current, { + opacity: 0, + scale: 0.72, + x: "-18vw", + y: "12vh", + }); + + gsap.set(eyebrowRef.current, { + opacity: 0, + y: 28, + filter: "blur(8px)", + }); + + gsap.set(titleRef.current, { + opacity: 0, + y: 36, + filter: "blur(8px)", + }); + + gsap.set(subRef.current, { + opacity: 0, + y: 24, + }); + + cardRefs.current.forEach((el) => { + if (el) gsap.set(el, { opacity: 0, y: 28, scale: 0.96, filter: "blur(6px)" }); + }); + + dotRefs.current.forEach((el) => { + if (el) gsap.set(el, { scale: 0, opacity: 0 }); + }); + + lineRefs.current.forEach((el) => { + if (el) gsap.set(el, { scaleX: 0, opacity: 0 }); + }); + + ScrollTrigger.matchMedia({ + "(min-width: 992px)": () => { + const tl = gsap.timeline({ + scrollTrigger: { + trigger: sectionRef.current, + start: "top top", + end: "+=3200", + scrub: 1.05, + pin: true, + anticipatePin: 1, + invalidateOnRefresh: true, + }, + }); + + tl.to(eyebrowRef.current, { opacity: 1, y: 0, filter: "blur(0px)", ease: "none", duration: 0.5 }, 0).to(titleRef.current, { opacity: 1, y: 0, filter: "blur(0px)", ease: "none", duration: 0.65 }, 0.08).to(subRef.current, { opacity: 1, y: 0, ease: "none", duration: 0.45 }, 0.22).to( + aircraftRef.current, + { + opacity: 1, + scale: 1, + x: 0, + y: 0, + ease: "none", + duration: 1.8, + }, + 0.12, + ); + + UAM_SPECS.forEach((spec, i) => { + const baseTime = 0.5 + i * 0.52; + const origin = spec.cardSide === "left" ? "right center" : "left center"; + + tl.to( + dotRefs.current[i], + { + scale: 1, + opacity: 1, + ease: "none", + duration: 0.18, + }, + baseTime, + ) + .to( + lineRefs.current[i], + { + scaleX: 1, + opacity: 1, + transformOrigin: origin, + ease: "none", + duration: 0.24, + }, + baseTime + 0.08, + ) + .to( + cardRefs.current[i], + { + opacity: 1, + y: 0, + scale: 1, + filter: "blur(0px)", + ease: "none", + duration: 0.32, + }, + baseTime + 0.18, + ); + }); + + tl.to( + aircraftRef.current, + { + scale: 1.05, + ease: "none", + duration: 0.45, + }, + 2.7, + ); + }, + + "(max-width: 991px)": () => { + const tl = gsap.timeline({ + scrollTrigger: { + trigger: sectionRef.current, + start: "top 80%", + end: "bottom 30%", + scrub: 0.8, + invalidateOnRefresh: true, + }, + }); + + tl.to(eyebrowRef.current, { opacity: 1, y: 0, filter: "blur(0px)", ease: "none", duration: 0.22 }, 0) + .to(titleRef.current, { opacity: 1, y: 0, filter: "blur(0px)", ease: "none", duration: 0.24 }, 0.05) + .to(subRef.current, { opacity: 1, y: 0, ease: "none", duration: 0.2 }, 0.1) + .to( + aircraftRef.current, + { + opacity: 1, + scale: 1, + x: 0, + y: 0, + ease: "none", + duration: 0.28, + }, + 0.16, + ) + .to( + dotRefs.current, + { + scale: 1, + opacity: 1, + stagger: 0.05, + ease: "none", + duration: 0.18, + }, + 0.24, + ) + .to( + lineRefs.current, + { + scaleX: 1, + opacity: 1, + stagger: 0.05, + ease: "none", + duration: 0.18, + }, + 0.3, + ) + .to( + cardRefs.current, + { + opacity: 1, + y: 0, + scale: 1, + filter: "blur(0px)", + stagger: 0.06, + ease: "none", + duration: 0.2, + }, + 0.36, + ); + }, + }); + + gsap.to(aircraftRef.current, { + y: -8, + duration: 2.8, + ease: "sine.inOut", + repeat: -1, + yoyo: true, + }); + }, sectionRef); + + return () => ctx.revert(); + }, []); + + return ( ++ PAL NETWORKS의 4대 핵심 기술이 안전한 하늘길을 만듭니다 +
+
+
+ {spec.desc}
+ +