Browse Source

test

remotes/origin/main
김지은 2 months ago
parent
commit
839aa12728
  1. 142
      src/components/main/MainUtm.jsx
  2. 87
      src/css/common.css

142
src/components/main/MainUtm.jsx

@ -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-sticky" ref={stickyRef}>
<div className="main-utm-inner"> <div className="main-utm-inner">
<div className="main-utm-head"> <div className="main-utm-copy">
<h2>UTM SYSTEM</h2> <p className="main-utm-kicker">UTM SYSTEM</p>
<p>드론 교통을 안전하게 관리하는 통합 관제 시스템</p>
<div className="main-utm-title-track" ref={trackRef}>
<h2 className="main-utm-line line-1" ref={line1Ref}>
<span className="main-utm-strong">Monitor</span>
<span className="main-utm-muted"> the airspace</span>
</h2>
<h2 className="main-utm-line line-2" ref={line2Ref}>
<span className="main-utm-strong">Approve</span>
<span className="main-utm-muted"> every mission</span>
</h2>
<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>
<p className="main-utm-desc" ref={descRef}>
실시간 모니터링, 자동 비행 승인, 운항 시뮬레이션과 영상 연계를 하나의 경험으로 구성한 통합 UTM 플랫폼
</p>
</div>
<div className="main-utm-showcase">
<div className="main-utm-glow" ref={glowRef}></div>
<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>
<div className="main-utm-flow"> <div className="main-utm-radar"></div>
<div className="utm-item">
<span className="num">01</span> <div className="main-utm-floating-card card-a" ref={card1Ref}>
<h3>비행 요청</h3> <strong>Monitoring</strong>
<p>운영자는 비행 계획을 등록합니다</p> <p>실시간 비행 상황 공역 상태 가시화</p>
</div> </div>
<div className="utm-item"> <div className="main-utm-floating-card card-b" ref={card2Ref}>
<span className="num">02</span> <strong>Approval</strong>
<h3>자동 승인</h3> <p>비행 가능 여부 검토와 자동 승인 프로세스</p>
<p>공역과 규제 기준을 기반으로 승인됩니다</p>
</div> </div>
<div className="utm-item"> <div className="main-utm-floating-card card-c" ref={card3Ref}>
<span className="num">03</span> <strong>Simulation</strong>
<h3>경로 관리</h3> <p>운항 시뮬레이션과 상황 대응 연계</p>
<p>비행 경로를 실시간으로 추적합니다</p>
</div> </div>
<div className="utm-item"> <div className="main-utm-grid-lines"></div>
<span className="num">04</span> </div>
<h3>실시간 관제</h3> </div>
<p>이상 상황을 즉시 감지하고 대응합니다</p>
</div> </div>
</div> </div>
</div> </div>

87
src/css/common.css

@ -134,3 +134,90 @@ body{overflow-x:hidden;}
.main-scroll-line{height:22px;} .main-scroll-line{height:22px;}
.main-scroll-text{font-size:10px;letter-spacing:.22em;} .main-scroll-text{font-size:10px;letter-spacing:.22em;}
} }
.main-utm-section{position:relative;height:320vh;background:linear-gradient(180deg,#f6f8fc 0%,#eef3fb 100%);}
.main-utm-sticky{position:sticky;top:0;height:100vh;overflow:hidden;}
.main-utm-inner{display:grid;grid-template-columns:minmax(0,1.02fr) minmax(0,.98fr);align-items:center;gap:40px;max-width:1440px;height:100%;margin:0 auto;padding:0 40px;}
.main-utm-copy{position:relative;z-index:2;}
.main-utm-kicker{margin:0 0 28px;font-size:13px;line-height:1;font-weight:800;letter-spacing:.22em;color:#3A4081;}
.main-utm-title-track{position:relative;height:260px;overflow:hidden;}
.main-utm-line{display:block;margin:0;font-size:clamp(52px,7vw,104px);line-height:.96;font-weight:800;letter-spacing:-.06em;transform-origin:left center;will-change:transform,opacity;}
.main-utm-line+.main-utm-line{margin-top:34px;}
.main-utm-strong{color:#111827;}
.main-utm-muted{color:#c3cad8;}
.main-utm-desc{max-width:620px;margin:34px 0 0;font-size:18px;line-height:1.8;font-weight:500;color:#5b6474;word-break:keep-all;}
.main-utm-showcase{position:relative;height:100%;display:flex;align-items:center;justify-content:center;}
.main-utm-glow{position:absolute;top:50%;left:50%;width:760px;height:760px;border-radius:50%;background:radial-gradient(circle,rgba(58,64,129,.18) 0%,rgba(58,64,129,.08) 34%,rgba(58,64,129,0) 72%);transform:translate(-50%,-50%);filter:blur(18px);pointer-events:none;}
.main-utm-panel-frame{position:relative;width:min(100%,640px);aspect-ratio:1/1.05;perspective:1200px;}
.main-utm-panel{position:relative;width:100%;height:100%;border:1px solid rgba(255,255,255,.42);border-radius:34px;background:linear-gradient(180deg,rgba(12,18,33,.94) 0%,rgba(17,27,52,.98) 100%);box-shadow:0 40px 120px rgba(14,22,44,.28);overflow:hidden;transform-style:preserve-3d;}
.main-utm-panel::before{content:"";position:absolute;inset:0;background:linear-gradient(135deg,rgba(255,255,255,.12) 0%,rgba(255,255,255,0) 38%);pointer-events:none;}
.main-utm-panel-top{position:absolute;top:24px;left:24px;right:24px;display:flex;align-items:center;justify-content:space-between;z-index:3;}
.main-utm-chip{display:inline-flex;align-items:center;height:38px;padding:0 14px;border:1px solid rgba(255,255,255,.14);border-radius:999px;background:rgba(255,255,255,.08);font-size:13px;font-weight:700;color:#f8fafc;}
.main-utm-status{display:inline-flex;align-items:center;gap:8px;font-size:13px;font-weight:700;color:#d9e1f1;}
.main-utm-status i{display:block;width:8px;height:8px;border-radius:50%;background:#4ade80;box-shadow:0 0 0 8px rgba(74,222,128,.12);}
.main-utm-radar{position:absolute;inset:50% auto auto 50%;width:72%;aspect-ratio:1/1;border-radius:50%;transform:translate(-50%,-44%);background:radial-gradient(circle,rgba(58,64,129,.24) 0%,rgba(58,64,129,.12) 26%,rgba(58,64,129,.04) 46%,rgba(58,64,129,0) 66%);}
.main-utm-radar::before{content:"";position:absolute;inset:10%;border:1px solid rgba(255,255,255,.12);border-radius:50%;}
.main-utm-radar::after{content:"";position:absolute;inset:24%;border:1px solid rgba(255,255,255,.1);border-radius:50%;}
.main-utm-grid-lines{position:absolute;inset:0;background-image:linear-gradient(rgba(255,255,255,.05) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.05) 1px,transparent 1px);background-size:56px 56px;mask-image:linear-gradient(180deg,rgba(0,0,0,.12) 0%,rgba(0,0,0,.82) 36%,rgba(0,0,0,.82) 100%);pointer-events:none;}
.main-utm-floating-card{position:absolute;z-index:3;width:220px;padding:20px 20px 18px;border:1px solid rgba(255,255,255,.12);border-radius:22px;background:linear-gradient(180deg,rgba(255,255,255,.14) 0%,rgba(255,255,255,.08) 100%);backdrop-filter:blur(16px);box-shadow:0 24px 48px rgba(0,0,0,.2);}
.main-utm-floating-card strong{display:block;margin:0 0 8px;font-size:22px;line-height:1.1;font-weight:800;color:#fff;letter-spacing:-.03em;}
.main-utm-floating-card p{margin:0;font-size:14px;line-height:1.6;font-weight:500;color:rgba(255,255,255,.72);word-break:keep-all;}
.card-a{top:112px;right:-16px;}
.card-b{left:42px;bottom:110px;width:250px;}
.card-c{right:26px;bottom:38px;}
@media (max-width:1100px){
.main-utm-section{height:280vh;}
.main-utm-inner{grid-template-columns:1fr;gap:30px;padding:100px 24px 40px;}
.main-utm-copy{align-self:end;}
.main-utm-title-track{height:210px;}
.main-utm-showcase{align-items:flex-start;}
.main-utm-panel-frame{width:min(100%,620px);}
}
@media (max-width:767px){
.main-utm-section{height:260vh;}
.main-utm-inner{padding:88px 20px 30px;}
.main-utm-title-track{height:168px;}
.main-utm-line{font-size:clamp(38px,12vw,64px);}
.main-utm-line+.main-utm-line{margin-top:22px;}
.main-utm-desc{margin-top:24px;font-size:16px;line-height:1.7;}
.main-utm-panel-frame{aspect-ratio:1/1.12;}
.main-utm-panel{border-radius:26px;}
.main-utm-panel-top{top:18px;left:18px;right:18px;flex-direction:column;align-items:flex-start;gap:10px;}
.main-utm-floating-card{width:180px;padding:16px;border-radius:18px;}
.main-utm-floating-card strong{font-size:18px;}
.main-utm-floating-card p{font-size:13px;line-height:1.5;}
.card-a{top:96px;right:6px;}
.card-b{left:12px;bottom:96px;width:200px;}
.card-c{right:12px;bottom:20px;}
}
Loading…
Cancel
Save