|
|
|
|
@ -9,39 +9,46 @@ const UTM_NAV = [
|
|
|
|
|
|
|
|
|
|
const CASES = [ |
|
|
|
|
{ |
|
|
|
|
id: 1, |
|
|
|
|
id: "01", |
|
|
|
|
eyebrow: "한국공항공사", |
|
|
|
|
title: "KAC 드론교통관리\nUTM 시스템 구축", |
|
|
|
|
desc: "한국공항공사의 공공용 UTM 시스템 정보공유체계 개발 및 드론교통관리 시스템 구축 사업을 수행했습니다. 실시간 비행 승인, 충돌 회피, 관제 데이터 통합 관리 기능을 제공하며 안전한 드론 운항 환경을 구현했습니다.", |
|
|
|
|
title: "KAC 드론교통관리 UTM 시스템 구축", |
|
|
|
|
desc: "공공용 UTM 시스템 정보공유체계 개발 및 드론교통관리 시스템 구축 사업을 수행했습니다. 실시간 비행 승인, 충돌 회피, 관제 데이터 통합 관리 기능을 제공합니다.", |
|
|
|
|
tags: ["UTM", "드론관제", "한국공항공사"], |
|
|
|
|
img: "/images/case/case01.jpg", |
|
|
|
|
year: "2024", |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
id: 2, |
|
|
|
|
id: "02", |
|
|
|
|
eyebrow: "국토교통부", |
|
|
|
|
title: "UAM 팀코리아\n워킹그룹 참여", |
|
|
|
|
title: "UAM 팀코리아 워킹그룹 참여", |
|
|
|
|
desc: "국토교통부 주관 UAM 팀코리아(UTK) 워킹그룹에 참여하여 도심항공교통 운항 공역 비행체 감시 기술 개발 및 UAM 비행상황관리 시스템 구축에 기여했습니다.", |
|
|
|
|
tags: ["UAM", "UATM", "국토교통부"], |
|
|
|
|
img: "/images/case/case02.jpg", |
|
|
|
|
year: "2024", |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
id: 3, |
|
|
|
|
id: "03", |
|
|
|
|
eyebrow: "남원시 · 항공안전기술원", |
|
|
|
|
title: "드론 실증도시\n구축 및 관제시스템", |
|
|
|
|
title: "드론 실증도시 구축 및 관제시스템", |
|
|
|
|
desc: "남원시 드론 실증도시 구축사업 협약 체결 및 드론 규제 샌드박스 사업을 통해 드론 관리 체계에 따른 식별장치 및 비행 관제시스템을 구축했습니다.", |
|
|
|
|
tags: ["드론", "실증도시", "관제시스템"], |
|
|
|
|
img: "/images/case/case03.jpg", |
|
|
|
|
year: "2023", |
|
|
|
|
}, |
|
|
|
|
]; |
|
|
|
|
|
|
|
|
|
function CaseItem({ item }) { |
|
|
|
|
function CaseItem({ item, index }) { |
|
|
|
|
const ref = useRef(null); |
|
|
|
|
const inView = useInView(ref, { once: true, margin: "-15%" }); |
|
|
|
|
const inView = useInView(ref, { once: true, margin: "-10%" }); |
|
|
|
|
const isEven = index % 2 === 0; |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<div ref={ref} className="cs-item"> |
|
|
|
|
{/* 이미지 — clipPath로 왼쪽에서 펼쳐짐 */} |
|
|
|
|
<Motion.div className="cs-img-wrap" initial={{ clipPath: "inset(0 100% 0 0)" }} animate={inView ? { clipPath: "inset(0 0% 0 0)" } : {}} transition={{ duration: 0.9, ease: [0.76, 0, 0.24, 1] }}> |
|
|
|
|
<div ref={ref} className={`cs-item${isEven ? "" : " cs-item--flip"}`}> |
|
|
|
|
{/* 큰 번호 배경 */} |
|
|
|
|
<div className="cs-bg-num">{item.id}</div> |
|
|
|
|
|
|
|
|
|
{/* 이미지 */} |
|
|
|
|
<Motion.div className="cs-img-wrap" initial={{ clipPath: isEven ? "inset(0 100% 0 0)" : "inset(0 0 0 100%)" }} animate={inView ? { clipPath: "inset(0 0% 0 0)" } : {}} transition={{ duration: 1, ease: [0.76, 0, 0.24, 1] }}> |
|
|
|
|
<img |
|
|
|
|
src={item.img} |
|
|
|
|
alt={item.title} |
|
|
|
|
@ -53,18 +60,13 @@ function CaseItem({ item }) {
|
|
|
|
|
<div className="cs-img-fallback" /> |
|
|
|
|
</Motion.div> |
|
|
|
|
|
|
|
|
|
{/* 텍스트 — 페이드인 */} |
|
|
|
|
<Motion.div className="cs-body" initial={{ opacity: 0, y: 24 }} animate={inView ? { opacity: 1, y: 0 } : {}} transition={{ duration: 0.7, delay: 0.4, ease: [0.4, 0, 0.2, 1] }}> |
|
|
|
|
<span className="cs-num">0{item.id}</span> |
|
|
|
|
{/* 텍스트 */} |
|
|
|
|
<Motion.div className="cs-body" initial={{ opacity: 0, y: 32 }} animate={inView ? { opacity: 1, y: 0 } : {}} transition={{ duration: 0.7, delay: 0.5, ease: [0.4, 0, 0.2, 1] }}> |
|
|
|
|
<div className="cs-meta"> |
|
|
|
|
<span className="cs-year">{item.year}</span> |
|
|
|
|
<span className="cs-eyebrow">{item.eyebrow}</span> |
|
|
|
|
<h3 className="cs-item-title"> |
|
|
|
|
{item.title.split("\n").map((line, j) => ( |
|
|
|
|
<span key={j}> |
|
|
|
|
{line} |
|
|
|
|
<br /> |
|
|
|
|
</span> |
|
|
|
|
))} |
|
|
|
|
</h3> |
|
|
|
|
</div> |
|
|
|
|
<h3 className="cs-item-title">{item.title}</h3> |
|
|
|
|
<p className="cs-item-desc">{item.desc}</p> |
|
|
|
|
<div className="cs-tags"> |
|
|
|
|
{item.tags.map((tag) => ( |
|
|
|
|
@ -102,8 +104,8 @@ export default function CasePage() {
|
|
|
|
|
</Motion.div> |
|
|
|
|
|
|
|
|
|
<div className="cs-list"> |
|
|
|
|
{CASES.map((item) => ( |
|
|
|
|
<CaseItem key={item.id} item={item} /> |
|
|
|
|
{CASES.map((item, i) => ( |
|
|
|
|
<CaseItem key={item.id} item={item} index={i} /> |
|
|
|
|
))} |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
|