Browse Source

TEST

remotes/origin/main
김지은 2 months ago
parent
commit
16696a8b3d
  1. 29
      src/components/ScrollToTop.jsx
  2. 10
      src/components/main/MainVisual.jsx
  3. 125
      src/pages/company/AboutPage.jsx

29
src/components/ScrollToTop.jsx

@ -1,21 +1,38 @@
import { useEffect } from "react";
import { useLocation } from "react-router-dom";
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
export default function ScrollToTop() {
const { pathname } = useLocation();
useEffect(() => {
// ScrollTrigger ( )
// ScrollTrigger
ScrollTrigger.getAll().forEach((t) => t.kill());
ScrollTrigger.clearScrollMemory();
window.history.scrollRestoration = "manual";
gsap.killTweensOf("*");
// pin body
document.body.style.removeProperty("overflow");
document.body.style.removeProperty("padding-bottom");
document.body.style.removeProperty("height");
document.documentElement.style.removeProperty("overflow");
document.documentElement.style.removeProperty("height");
// is-dark-hero
document.body.classList.remove("is-dark-hero");
//
//
window.scrollTo({ top: 0, behavior: "instant" });
document.documentElement.scrollTop = 0;
document.body.scrollTop = 0;
// ScrollTrigger
ScrollTrigger.clearScrollMemory();
window.history.scrollRestoration = "manual";
// DOM refresh
requestAnimationFrame(() => ScrollTrigger.refresh());
requestAnimationFrame(() => {
ScrollTrigger.refresh(true);
});
}, [pathname]);
return null;

10
src/components/main/MainVisual.jsx

@ -88,7 +88,15 @@ function MainVisual() {
};
}, sectionRef);
return () => ctx.revert();
return () => {
ctx.revert();
// pin
ScrollTrigger.getAll().forEach((t) => t.kill());
document.body.style.removeProperty("overflow");
document.body.style.removeProperty("padding-bottom");
document.documentElement.style.removeProperty("overflow");
document.body.classList.remove("is-dark-hero");
};
}, []);
return (
<section className="main-section" ref={sectionRef}>

125
src/pages/company/AboutPage.jsx

@ -7,37 +7,37 @@ import SubHero from "../../components/SubHero";
gsap.registerPlugin(ScrollTrigger);
const COMPANY_NAV = [
{ label: "회사소개", to: "/company/about" },
{ label: "연혁", to: "/company/history" },
{ label: "회사소개", to: "/company/about" },
{ label: "연혁", to: "/company/history" },
{ label: "고객 및 협력사", to: "/company/partners" },
{ label: "찾아오시는 길", to: "/company/location" },
];
const STATS = [
{ num: 2010, suffix: "", label: "설립연도" },
{ num: 50, suffix: "+", label: "완료 프로젝트" },
{ num: 15, suffix: "+", label: "주요 고객사" },
{ num: 10, suffix: "+", label: "R&D 전문인력" },
{ num: 50, suffix: "+", label: "완료 프로젝트" },
{ num: 15, suffix: "+", label: "주요 고객사" },
{ num: 10, suffix: "+", label: "R&D 전문인력" },
];
const VALUES = [
{ num: "01", title: "기술 혁신", desc: "항공 데이터와 UTM 기술의 경계를 지속적으로 확장하며 미래 모빌리티 시대를 선도합니다.", img: "/images/img1.jpg" },
{ num: "01", title: "기술 혁신", desc: "항공 데이터와 UTM 기술의 경계를 지속적으로 확장하며 미래 모빌리티 시대를 선도합니다.", img: "/images/img1.jpg" },
{ num: "02", title: "신뢰와 책임", desc: "공공·항공 분야의 핵심 인프라를 다루는 만큼 모든 서비스에 안전과 신뢰를 최우선으로 합니다.", img: "/images/img2.jpg" },
{ num: "03", title: "파트너십", desc: "고객사와 장기 파트너로서 구축부터 운영·유지보수까지 전 과정을 함께합니다.", img: "/images/img3.jpg" },
{ num: "04", title: "전문성", desc: "항공 IT 분야 10년 이상의 전문 인력이 SI, R&D, 솔루션 개발을 일관되게 수행합니다.", img: "/images/img4.jpg" },
{ num: "03", title: "파트너십", desc: "고객사와 장기 파트너로서 구축부터 운영·유지보수까지 전 과정을 함께합니다.", img: "/images/img3.jpg" },
{ num: "04", title: "전문성", desc: "항공 IT 분야 10년 이상의 전문 인력이 SI, R&D, 솔루션 개발을 일관되게 수행합니다.", img: "/images/img4.jpg" },
];
const AWARDS = [
{ year: "2022", title: "인천 항공산업 선도기업 유망기업 선정", org: "인천시 · 인천테크노파크" },
{ year: "2021", title: "소프트웨어 품질인증 GS 인증 획득", org: "한국정보통신기술협회(TTA)" },
{ year: "2021", title: "기업부설연구소 인정", org: "한국산업기술진흥협회" },
{ year: "2020", title: "조달청 우수제품 지정", org: "비행상황관제 시스템" },
{ year: "2021", title: "소프트웨어 품질인증 GS 인증 획득", org: "한국정보통신기술협회(TTA)" },
{ year: "2021", title: "기업부설연구소 인정", org: "한국산업기술진흥협회" },
{ year: "2020", title: "조달청 우수제품 지정", org: "비행상황관제 시스템" },
];
function animateCount(el, target, suffix, duration = 1600) {
const from = target > 100 ? target - 4 : 0;
let start = null;
const step = ts => {
const step = (ts) => {
if (!start) start = ts;
const p = Math.min((ts - start) / duration, 1);
const ease = 1 - Math.pow(1 - p, 3);
@ -48,10 +48,10 @@ function animateCount(el, target, suffix, duration = 1600) {
}
export default function AboutPage() {
const videoRef = useRef(null);
const videoRef = useRef(null);
const videoSecRef = useRef(null);
const statRefs = useRef([]);
const statDone = useRef(false);
const statRefs = useRef([]);
const statDone = useRef(false);
useEffect(() => {
const ctx = gsap.context(() => {
@ -61,53 +61,36 @@ export default function AboutPage() {
scrollTrigger: { trigger: videoSecRef.current, start: "top top", end: "bottom top", scrub: 2 },
});
gsap.to(".ab-vid-txt", {
y: -80, opacity: 0,
y: -80,
opacity: 0,
scrollTrigger: { trigger: videoSecRef.current, start: "top top", end: "55% top", scrub: 1 },
});
//
gsap.fromTo(".ab-phil-line",
{ opacity: 0, x: -40 },
{ opacity: 1, x: 0, stagger: 0.18, duration: 1, ease: "power3.out",
scrollTrigger: { trigger: ".ab-phil", start: "top 68%" } }
);
gsap.fromTo(".ab-phil-line", { opacity: 0, x: -40 }, { opacity: 1, x: 0, stagger: 0.18, duration: 1, ease: "power3.out", scrollTrigger: { trigger: ".ab-phil", start: "top 68%" } });
//
gsap.fromTo(".ab-phil-right",
{ opacity: 0, x: 50 },
{ opacity: 1, x: 0, duration: 1.1, ease: "power3.out",
scrollTrigger: { trigger: ".ab-phil", start: "top 68%" } }
);
gsap.fromTo(".ab-phil-body",
{ opacity: 0, y: 24 },
{ opacity: 1, y: 0, duration: 0.8, ease: "power2.out",
scrollTrigger: { trigger: ".ab-phil", start: "top 55%" } }
);
gsap.fromTo(".ab-phil-right", { opacity: 0, x: 50 }, { opacity: 1, x: 0, duration: 1.1, ease: "power3.out", scrollTrigger: { trigger: ".ab-phil", start: "top 68%" } });
gsap.fromTo(".ab-phil-body", { opacity: 0, y: 24 }, { opacity: 1, y: 0, duration: 0.8, ease: "power2.out", scrollTrigger: { trigger: ".ab-phil", start: "top 55%" } });
//
gsap.fromTo(".ab-val-item",
{ opacity: 0, y: 40 },
{ opacity: 1, y: 0, stagger: 0.1, duration: 0.7, ease: "power3.out",
scrollTrigger: { trigger: ".ab-vals", start: "top 72%" } }
);
gsap.fromTo(".ab-val-item", { opacity: 0, y: 40 }, { opacity: 1, y: 0, stagger: 0.1, duration: 0.7, ease: "power3.out", scrollTrigger: { trigger: ".ab-vals", start: "top 72%" } });
//
gsap.fromTo(".ab-awd-row",
{ opacity: 0, y: 22 },
{ opacity: 1, y: 0, stagger: 0.1, duration: 0.6, ease: "power2.out",
scrollTrigger: { trigger: ".ab-awds", start: "top 76%" } }
);
gsap.fromTo(".ab-awd-row", { opacity: 0, y: 22 }, { opacity: 1, y: 0, stagger: 0.1, duration: 0.6, ease: "power2.out", scrollTrigger: { trigger: ".ab-awds", start: "top 76%" } });
// CTA
gsap.fromTo(".ab-cta-inner > *",
{ opacity: 0, y: 28 },
{ opacity: 1, y: 0, stagger: 0.14, duration: 0.8, ease: "power2.out",
scrollTrigger: { trigger: ".ab-cta", start: "top 75%" } }
);
gsap.fromTo(".ab-cta-inner > *", { opacity: 0, y: 28 }, { opacity: 1, y: 0, stagger: 0.14, duration: 0.8, ease: "power2.out", scrollTrigger: { trigger: ".ab-cta", start: "top 75%" } });
// stats fade
gsap.fromTo(".ab-si",
gsap.fromTo(
".ab-si",
{ opacity: 0, y: 32 },
{ opacity: 1, y: 0, stagger: 0.1, duration: 0.7, ease: "power3.out",
{
opacity: 1,
y: 0,
stagger: 0.1,
duration: 0.7,
ease: "power3.out",
scrollTrigger: {
trigger: ".ab-stats",
start: "top 78%",
@ -118,9 +101,9 @@ export default function AboutPage() {
if (!el) return;
setTimeout(() => animateCount(el, STATS[i].num, STATS[i].suffix), i * 80);
});
}
}
}
},
},
},
);
});
@ -129,12 +112,7 @@ export default function AboutPage() {
return (
<article>
<SubHero
title={"가치를 실천하는\n항공 IT 전문기업"}
desc="팔네트웍스는 항공 데이터와 통합 관제 기술을 기반으로 안전한 하늘길을 만들어갑니다."
navItems={COMPANY_NAV}
bgImage="/images/hero1.png"
/>
<SubHero title={"가치를 실천하는\n항공 IT 전문기업"} desc="팔네트웍스는 항공 데이터와 통합 관제 기술을 기반으로 안전한 하늘길을 만들어갑니다." navItems={COMPANY_NAV} bgImage="/images/hero1.png" />
{/* 수치 */}
<section className="ab-stats">
@ -143,7 +121,10 @@ export default function AboutPage() {
<div className="ab-stats-grid">
{STATS.map((s, i) => (
<div className="ab-si" key={s.label}>
<strong className="ab-si-num" ref={el => statRefs.current[i] = el}>{s.num}{s.suffix}</strong>
<strong className="ab-si-num" ref={(el) => (statRefs.current[i] = el)}>
{s.num}
{s.suffix}
</strong>
<span className="ab-si-lbl">{s.label}</span>
<span className="ab-si-bar" />
</div>
@ -158,8 +139,16 @@ export default function AboutPage() {
<div className="ab-vid-overlay" />
<div className="ab-vid-txt">
<span className="ab-vid-kicker">PAL Networks × UAM</span>
<h2 className="ab-vid-title">미래의 하늘을<br />설계합니다</h2>
<p className="ab-vid-desc">도심항공교통(UAM) 안전한 운항을 위한<br />통합 관제 기술을 연구·개발합니다</p>
<h2 className="ab-vid-title">
미래의 하늘을
<br />
설계합니다
</h2>
<p className="ab-vid-desc">
도심항공교통(UAM) 안전한 운항을 위한
<br />
통합 관제 기술을 연구·개발합니다
</p>
</div>
</section>
@ -191,7 +180,7 @@ export default function AboutPage() {
<span className="ab-vals-ew">Core Values</span>
<h2 className="ab-vals-title">우리가 지키는 가치</h2>
<div className="ab-vals-list">
{VALUES.map(v => (
{VALUES.map((v) => (
<div className="ab-val-item" key={v.num}>
<span className="ab-val-num">{v.num}</span>
<div className="ab-val-body">
@ -233,11 +222,19 @@ export default function AboutPage() {
<div className="ab-cta-glow" />
<div className="ab-cta-inner">
<span className="ab-cta-chip">Contact Us</span>
<h2 className="ab-cta-title">팔네트웍스와<br />함께하세요</h2>
<h2 className="ab-cta-title">
팔네트웍스와
<br />
함께하세요
</h2>
<p className="ab-cta-desc">파트너십 문의, 채용, 사업 협력 무엇이든 편하게 연락주세요.</p>
<div className="ab-cta-btns">
<Link to="/contact/inquiry" className="ab-cta-btn ab-cta-btn--w">문의하기</Link>
<Link to="/contact/recruit" className="ab-cta-btn ab-cta-btn--g">채용 안내</Link>
<Link to="/contact/inquiry" className="ab-cta-btn ab-cta-btn--w">
문의하기
</Link>
<Link to="/contact/recruit" className="ab-cta-btn ab-cta-btn--g">
채용 안내
</Link>
</div>
</div>
</section>

Loading…
Cancel
Save