Browse Source

fix : 비행상황관리 시스템 적용분야 이미지 용량 최적화

remotes/origin/main
이시연 2 weeks ago
parent
commit
ecd0c3a9d4
  1. BIN
      public/images/domain_img1.jpg
  2. BIN
      public/images/domain_img2.jpg
  3. BIN
      public/images/domain_img3.jpg
  4. BIN
      public/images/domain_img3.png
  5. BIN
      public/images/domain_img4.jpg
  6. BIN
      public/images/domain_img5.jpg
  7. BIN
      public/images/domain_img5.png
  8. 232
      src/pages/solution/FlightControlPage.jsx

BIN
public/images/domain_img1.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 MiB

After

Width:  |  Height:  |  Size: 464 KiB

BIN
public/images/domain_img2.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

BIN
public/images/domain_img3.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 MiB

After

Width:  |  Height:  |  Size: 908 KiB

BIN
public/images/domain_img3.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 MiB

BIN
public/images/domain_img4.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

BIN
public/images/domain_img5.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

BIN
public/images/domain_img5.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

232
src/pages/solution/FlightControlPage.jsx

@ -1,6 +1,18 @@
import { useRef, useState } from "react"; import { useRef, useState } from "react";
import { motion, useInView, AnimatePresence } from "framer-motion"; import { motion, useInView, AnimatePresence } from "framer-motion";
import { Radio, Puzzle, Network, Expand, Shield, ArrowUpRight, Package, Wind, AlertTriangle, Ship, Plane } from "lucide-react"; import {
Radio,
Puzzle,
Network,
Expand,
Shield,
ArrowUpRight,
Package,
Wind,
AlertTriangle,
Ship,
Plane,
} from "lucide-react";
import SubHero from "../../components/SubHero"; import SubHero from "../../components/SubHero";
import useFadeIn from "../../hooks/useFadeIn"; import useFadeIn from "../../hooks/useFadeIn";
@ -33,7 +45,7 @@ const DOMAINS = [
desc: "도심 및 광역 드론 배송 경로 최적화 및 실시간 위치 관제", desc: "도심 및 광역 드론 배송 경로 최적화 및 실시간 위치 관제",
}, },
{ {
img: "domain_img2.png", img: "domain_img2.jpg",
label: "UAM 도심항공 모빌리티", label: "UAM 도심항공 모빌리티",
desc: "미래형 도심 항공 교통 인프라 연계 관제 시스템", desc: "미래형 도심 항공 교통 인프라 연계 관제 시스템",
}, },
@ -43,7 +55,7 @@ const DOMAINS = [
desc: "대기질·기상 데이터 수집 드론 운용 및 모니터링", desc: "대기질·기상 데이터 수집 드론 운용 및 모니터링",
}, },
{ {
img: "domain_img4.png", img: "domain_img4.jpg",
label: "안티드론 보안관제", label: "안티드론 보안관제",
desc: "비인가 드론 탐지·추적 및 무력화 대응 지원", desc: "비인가 드론 탐지·추적 및 무력화 대응 지원",
}, },
@ -88,7 +100,12 @@ const ease = [0.22, 1, 0.36, 1];
function RevealText({ children, delay = 0, className }) { function RevealText({ children, delay = 0, className }) {
return ( return (
<div style={{ overflow: "hidden" }}> <div style={{ overflow: "hidden" }}>
<motion.div className={className} initial={{ y: "105%", opacity: 0 }} animate={{ y: "0%", opacity: 1 }} transition={{ duration: 0.75, ease: [0.22, 1, 0.36, 1], delay }}> <motion.div
className={className}
initial={{ y: "105%", opacity: 0 }}
animate={{ y: "0%", opacity: 1 }}
transition={{ duration: 0.75, ease: [0.22, 1, 0.36, 1], delay }}
>
{children} {children}
</motion.div> </motion.div>
</div> </div>
@ -98,7 +115,10 @@ function RevealText({ children, delay = 0, className }) {
function StaggerWords({ text, delay = 0, className }) { function StaggerWords({ text, delay = 0, className }) {
const words = text.split(" "); const words = text.split(" ");
return ( return (
<span className={className} style={{ display: "flex", flexWrap: "wrap", gap: "0 .3em" }}> <span
className={className}
style={{ display: "flex", flexWrap: "wrap", gap: "0 .3em" }}
>
{words.map((word, i) => ( {words.map((word, i) => (
<span key={i} style={{ overflow: "hidden", display: "inline-block" }}> <span key={i} style={{ overflow: "hidden", display: "inline-block" }}>
<motion.span <motion.span
@ -148,7 +168,11 @@ function FlightControlPage() {
return ( return (
<article ref={ref}> <article ref={ref}>
<SubHero label="SOLUTION" title={<em>Flight Management</em>} navItems={SOLUTION_NAV} /> <SubHero
label="SOLUTION"
title={<em>Flight Management</em>}
navItems={SOLUTION_NAV}
/>
<div className="sub-content"> <div className="sub-content">
<div className="inner-wrap"> <div className="inner-wrap">
@ -221,19 +245,40 @@ function FlightControlPage() {
{/* 개요 인트로 */} {/* 개요 인트로 */}
<section className="fc-intro" ref={introRef}> <section className="fc-intro" ref={introRef}>
<div className="fc-intro__left"> <div className="fc-intro__left">
<motion.span className="fc-eyebrow" initial={{ opacity: 0, y: 16 }} animate={introInView ? { opacity: 1, y: 0 } : {}} transition={{ duration: 0.6, ease }}> <motion.span
className="fc-eyebrow"
initial={{ opacity: 0, y: 16 }}
animate={introInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.6, ease }}
>
Overview Overview
</motion.span> </motion.span>
<motion.h2 className="fc-intro__title" initial={{ opacity: 0, y: 24 }} animate={introInView ? { opacity: 1, y: 0 } : {}} transition={{ duration: 0.7, ease, delay: 0.1 }}> <motion.h2
className="fc-intro__title"
initial={{ opacity: 0, y: 24 }}
animate={introInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.7, ease, delay: 0.1 }}
>
모든 이동체 정보를 모든 이동체 정보를
<br /> <br />
하나의 플랫폼에서 하나의 플랫폼에서
</motion.h2> </motion.h2>
<motion.p className="fc-intro__desc" initial={{ opacity: 0, y: 16 }} animate={introInView ? { opacity: 1, y: 0 } : {}} transition={{ duration: 0.6, ease, delay: 0.2 }}> <motion.p
항공기, 무인기, 선박, 지상 이동체의 실시간 정보를 통합 모니터링하고 <br /> className="fc-intro__desc"
initial={{ opacity: 0, y: 16 }}
animate={introInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.6, ease, delay: 0.2 }}
>
항공기, 무인기, 선박, 지상 이동체의 실시간 정보를 통합
모니터링하고 <br />
상황을 인식하여 신속하고 안전한 운영 의사결정을 지원합니다. 상황을 인식하여 신속하고 안전한 운영 의사결정을 지원합니다.
</motion.p> </motion.p>
<motion.div className="fc-intro__icons" initial={{ opacity: 0, y: 16 }} animate={introInView ? { opacity: 1, y: 0 } : {}} transition={{ duration: 0.6, ease, delay: 0.3 }}> <motion.div
className="fc-intro__icons"
initial={{ opacity: 0, y: 16 }}
animate={introInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.6, ease, delay: 0.3 }}
>
{[ {[
{ img: "fc_aircraft.png", label: "항공기" }, { img: "fc_aircraft.png", label: "항공기" },
{ img: "fc_drone.png", label: "무인기" }, { img: "fc_drone.png", label: "무인기" },
@ -241,15 +286,27 @@ function FlightControlPage() {
{ img: "fc_car.png", label: "차량 등" }, { img: "fc_car.png", label: "차량 등" },
].map((item, i) => ( ].map((item, i) => (
<div key={i} className="fc-intro__icon-item"> <div key={i} className="fc-intro__icon-item">
<img src={`${basePath}images/${item.img}`} alt={item.label} /> <img
src={`${basePath}images/${item.img}`}
alt={item.label}
/>
<span>{item.label}</span> <span>{item.label}</span>
</div> </div>
))} ))}
</motion.div> </motion.div>
</div> </div>
<motion.div className="fc-intro__right" initial={{ opacity: 0, x: 40 }} animate={introInView ? { opacity: 1, x: 0 } : {}} transition={{ duration: 0.9, ease, delay: 0.15 }}> <motion.div
<img src={`${basePath}images/fc_computer.png`} alt="비행상황관리 시스템" className="fc-intro__monitor" /> className="fc-intro__right"
initial={{ opacity: 0, x: 40 }}
animate={introInView ? { opacity: 1, x: 0 } : {}}
transition={{ duration: 0.9, ease, delay: 0.15 }}
>
<img
src={`${basePath}images/fc_computer.png`}
alt="비행상황관리 시스템"
className="fc-intro__monitor"
/>
</motion.div> </motion.div>
</section> </section>
@ -302,7 +359,13 @@ function FlightControlPage() {
icons: null, icons: null,
}, },
].map((item, i) => ( ].map((item, i) => (
<motion.div key={i} className="fc-highlight__item" initial={{ opacity: 0, y: 40 }} animate={highlightInView ? { opacity: 1, y: 0 } : {}} transition={{ duration: 0.7, ease, delay: i * 0.15 }}> <motion.div
key={i}
className="fc-highlight__item"
initial={{ opacity: 0, y: 40 }}
animate={highlightInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.7, ease, delay: i * 0.15 }}
>
<div className="fc-highlight__text"> <div className="fc-highlight__text">
<span className="fc-eyebrow">{item.tag}</span> <span className="fc-eyebrow">{item.tag}</span>
<h3 className="fc-highlight__title"> <h3 className="fc-highlight__title">
@ -317,7 +380,11 @@ function FlightControlPage() {
</div> </div>
<div className="fc-highlight__img-wrap"> <div className="fc-highlight__img-wrap">
<div className="fc-highlight__img-scene"> <div className="fc-highlight__img-scene">
<img src={`${basePath}images/${item.img}`} alt={item.tag} className="fc-highlight__tablet" /> <img
src={`${basePath}images/${item.img}`}
alt={item.tag}
className="fc-highlight__tablet"
/>
{item.icons && {item.icons &&
item.icons.map((icon, j) => ( item.icons.map((icon, j) => (
<motion.img <motion.img
@ -327,7 +394,11 @@ function FlightControlPage() {
className="fc-highlight__float-icon" className="fc-highlight__float-icon"
style={{ left: icon.x, top: icon.y }} style={{ left: icon.x, top: icon.y }}
initial={{ x: 0, y: 0 }} initial={{ x: 0, y: 0 }}
animate={highlightInView ? { x: icon.move.x[1], y: icon.move.y[1] } : { x: 0, y: 0 }} animate={
highlightInView
? { x: icon.move.x[1], y: icon.move.y[1] }
: { x: 0, y: 0 }
}
transition={{ transition={{
duration: 2.5, duration: 2.5,
repeat: 0, repeat: 0,
@ -339,9 +410,30 @@ function FlightControlPage() {
{i === 1 && ( {i === 1 && (
<> <>
<motion.img src={`${basePath}images/fc_left_tab.png`} alt="" className="fc-situation__left" initial={{ opacity: 0, x: -30 }} animate={highlightInView ? { opacity: 1, x: 0 } : {}} transition={{ duration: 0.8, ease, delay: 0.3 }} /> <motion.img
<motion.img src={`${basePath}images/fc_right_tab.png`} alt="" className="fc-situation__right" initial={{ opacity: 0, x: 30 }} animate={highlightInView ? { opacity: 1, x: 0 } : {}} transition={{ duration: 0.8, ease, delay: 0.5 }} /> src={`${basePath}images/fc_left_tab.png`}
<motion.img src={`${basePath}images/fc_bottom_tab.png`} alt="" className="fc-situation__bottom" initial={{ opacity: 0, y: 30 }} animate={highlightInView ? { opacity: 1, y: 0 } : {}} transition={{ duration: 0.8, ease, delay: 0.7 }} /> alt=""
className="fc-situation__left"
initial={{ opacity: 0, x: -30 }}
animate={highlightInView ? { opacity: 1, x: 0 } : {}}
transition={{ duration: 0.8, ease, delay: 0.3 }}
/>
<motion.img
src={`${basePath}images/fc_right_tab.png`}
alt=""
className="fc-situation__right"
initial={{ opacity: 0, x: 30 }}
animate={highlightInView ? { opacity: 1, x: 0 } : {}}
transition={{ duration: 0.8, ease, delay: 0.5 }}
/>
<motion.img
src={`${basePath}images/fc_bottom_tab.png`}
alt=""
className="fc-situation__bottom"
initial={{ opacity: 0, y: 30 }}
animate={highlightInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.8, ease, delay: 0.7 }}
/>
</> </>
)} )}
</div> </div>
@ -367,13 +459,28 @@ function FlightControlPage() {
{/* 3. 적용 분야 */} {/* 3. 적용 분야 */}
<section className="fc-domains" ref={domainsRef}> <section className="fc-domains" ref={domainsRef}>
<motion.span className="fc-section-title" initial={{ opacity: 0, y: 20 }} animate={domainsInView ? { opacity: 1, y: 0 } : {}} transition={{ duration: 0.6, ease }}> <motion.span
className="fc-section-title"
initial={{ opacity: 0, y: 20 }}
animate={domainsInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.6, ease }}
>
적용 분야 적용 분야
</motion.span> </motion.span>
<div className="fc-domains__grid"> <div className="fc-domains__grid">
{DOMAINS.map(({ icon: Icon, img, label, desc }, i) => ( {DOMAINS.map(({ icon: Icon, img, label, desc }, i) => (
<motion.div key={label} className="fc-domain-card" initial={{ opacity: 0, y: 24 }} animate={domainsInView ? { opacity: 1, y: 0 } : {}} transition={{ duration: 0.55, ease, delay: 0.07 * i }}> <motion.div
<img className="fc-domain-card__img" src={`${basePath}images/${img}`} alt={label} /> key={label}
className="fc-domain-card"
initial={{ opacity: 0, y: 24 }}
animate={domainsInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.55, ease, delay: 0.07 * i }}
>
<img
className="fc-domain-card__img"
src={`${basePath}images/${img}`}
alt={label}
/>
<div className="fc-domain-card__overlay"> <div className="fc-domain-card__overlay">
<span className="fc-domain-card__label">{label}</span> <span className="fc-domain-card__label">{label}</span>
<p className="fc-domain-card__desc">{desc}</p> <p className="fc-domain-card__desc">{desc}</p>
@ -385,31 +492,79 @@ function FlightControlPage() {
{/* 4. 주요기능 */} {/* 4. 주요기능 */}
<section className="fc-functions" ref={funcRef}> <section className="fc-functions" ref={funcRef}>
<motion.span className="fc-section-title" initial={{ opacity: 0, y: 20 }} animate={funcInView ? { opacity: 1, y: 0 } : {}} transition={{ duration: 0.6, ease }}> <motion.span
className="fc-section-title"
initial={{ opacity: 0, y: 20 }}
animate={funcInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.6, ease }}
>
주요기능 주요기능
</motion.span> </motion.span>
<div className="fc-functions__body"> <div className="fc-functions__body">
<ul className="fc-func-list"> <ul className="fc-func-list">
{FUNCTIONS.map(({ num, label }, i) => ( {FUNCTIONS.map(({ num, label }, i) => (
<motion.li key={num} className={`fc-func-item${activeIdx === i ? " is-active" : ""}`} onMouseEnter={() => setActiveIdx(i)} initial={{ opacity: 0, y: 16 }} animate={funcInView ? { opacity: 1, y: 0 } : {}} transition={{ duration: 0.5, ease, delay: 0.05 * i }}> <motion.li
key={num}
className={`fc-func-item${activeIdx === i ? " is-active" : ""}`}
onMouseEnter={() => setActiveIdx(i)}
initial={{ opacity: 0, y: 16 }}
animate={funcInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.5, ease, delay: 0.05 * i }}
>
<span className="fc-func-item__num">{num}</span> <span className="fc-func-item__num">{num}</span>
<span className="fc-func-item__label">{label}</span> <span className="fc-func-item__label">{label}</span>
<motion.span className="fc-func-item__arrow" initial={{ opacity: 0, x: -6 }} animate={activeIdx === i ? { opacity: 1, x: 0 } : { opacity: 0, x: -6 }} transition={{ duration: 0.2 }}> <motion.span
className="fc-func-item__arrow"
initial={{ opacity: 0, x: -6 }}
animate={
activeIdx === i
? { opacity: 1, x: 0 }
: { opacity: 0, x: -6 }
}
transition={{ duration: 0.2 }}
>
<ArrowUpRight size={16} strokeWidth={1.5} /> <ArrowUpRight size={16} strokeWidth={1.5} />
</motion.span> </motion.span>
<motion.div className="fc-func-item__line" animate={{ scaleX: activeIdx === i ? 1 : 0 }} transition={{ duration: 0.35, ease }} /> <motion.div
className="fc-func-item__line"
animate={{ scaleX: activeIdx === i ? 1 : 0 }}
transition={{ duration: 0.35, ease }}
/>
</motion.li> </motion.li>
))} ))}
</ul> </ul>
<div className="fc-func-display"> <div className="fc-func-display">
<AnimatePresence mode="wait"> <AnimatePresence mode="wait">
<motion.div key={activeIdx} className="fc-func-display__inner" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} transition={{ duration: 0.35, ease: "easeInOut" }}> <motion.div
<img src={FUNCTIONS[activeIdx].img} alt={FUNCTIONS[activeIdx].label} className="fc-func-display__img" /> key={activeIdx}
className="fc-func-display__inner"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.35, ease: "easeInOut" }}
>
<img
src={FUNCTIONS[activeIdx].img}
alt={FUNCTIONS[activeIdx].label}
className="fc-func-display__img"
/>
<div className="fc-func-display__caption"> <div className="fc-func-display__caption">
<motion.span key={`num-${activeIdx}`} className="fc-func-display__num" initial={{ opacity: 0, y: 6 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.25 }}> <motion.span
key={`num-${activeIdx}`}
className="fc-func-display__num"
initial={{ opacity: 0, y: 6 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.25 }}
>
{FUNCTIONS[activeIdx].num} {FUNCTIONS[activeIdx].num}
</motion.span> </motion.span>
<motion.span key={`label-${activeIdx}`} className="fc-func-display__label" initial={{ opacity: 0, y: 6 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.25, delay: 0.05 }}> <motion.span
key={`label-${activeIdx}`}
className="fc-func-display__label"
initial={{ opacity: 0, y: 6 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.25, delay: 0.05 }}
>
{FUNCTIONS[activeIdx].label} {FUNCTIONS[activeIdx].label}
</motion.span> </motion.span>
</div> </div>
@ -421,12 +576,23 @@ function FlightControlPage() {
{/* 5. 시스템 구성 흐름 */} {/* 5. 시스템 구성 흐름 */}
<section className="fc-flow" ref={flowRef}> <section className="fc-flow" ref={flowRef}>
<motion.span className="fc-section-title" initial={{ opacity: 0, y: 20 }} animate={flowInView ? { opacity: 1, y: 0 } : {}} transition={{ duration: 0.6, ease }}> <motion.span
className="fc-section-title"
initial={{ opacity: 0, y: 20 }}
animate={flowInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.6, ease }}
>
시스템 구성 시스템 구성
</motion.span> </motion.span>
<div className="fc-flow__row"> <div className="fc-flow__row">
{FLOW.map(({ step, label, desc }, i) => ( {FLOW.map(({ step, label, desc }, i) => (
<motion.div key={step} className="fc-flow__item" initial={{ opacity: 0, y: 20 }} animate={flowInView ? { opacity: 1, y: 0 } : {}} transition={{ duration: 0.5, ease, delay: 0.08 * i }}> <motion.div
key={step}
className="fc-flow__item"
initial={{ opacity: 0, y: 20 }}
animate={flowInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.5, ease, delay: 0.08 * i }}
>
<span className="fc-flow__step">{step}</span> <span className="fc-flow__step">{step}</span>
<span className="fc-flow__label">{label}</span> <span className="fc-flow__label">{label}</span>
<p className="fc-flow__desc">{desc}</p> <p className="fc-flow__desc">{desc}</p>

Loading…
Cancel
Save