FE 개발자 이창우 포트폴리오 사이트
팀 : 1인개발
프론트엔드 : Next, TypeScript
개발기간 : 9월10일 ~ 진행중
깃허브 : https://github.com/changchangwoo/changwoo_portfolio
배포주소 : https://www.changwoo.site/ <도메인 만료, 배포 중단>
- 모바일/태블릿/PC 등 디바이스별 호환 가능한 반응형 컴포넌트 설계
- 사용자 경험을 고려한 UI/UX 디자인 ( 애니메이션 라이브러리 적용 )
- 배포 및 커스텀 도메인 적용
- 3주 이내의 최대한 빠른 개발 시간
프레임워크는 Next.JS를 선택하였다. SSR을 통해 SEO 이점을 얻을 수 있으며, 현재는 미구현이지만 이후 방명록과 같은 데이터를 처리하는 부분에 있어 백엔드 접근이 간편하고, Vercel 생태계를 활용해 쉽게 배포할 수 있기 때문이었다.
const FlipUp = ({ children, initialY, delay, className, height, leading } : FlipUpProps) => {
return (
<div className={`overflow-hidden ${height} ${leading}`}>
<motion.h1
className={className}
initial={{ y: initialY }}
animate={{ y: 0 }}
transition={{ duration: 0.5, ease: "easeOut", delay }}
>
{children}
</motion.h1>
</div> )
}
라이브러리로 Framer Motion을 선택한 이유
- Framer Motion 진입 장벽이 낮아 단순 애니메이션 구현을 요구하는 현재 상황에 적합하다
- 또한 컴포넌트 구조이기에 React 기반 프레임워크와의 호환이 좋고 가상 DOM 최적화를 제공한다.
- 보통 해상도에 따라 사이즈나 배치를 변경함으로 전환이 가능하였지만 컴포넌트 형태가 변경되는 경우 기능은 동일하기에 단일 컴포넌트로 설계하여 반응형에따라 속성을 변경할지, 아니면 디바이스별 독립된 컴포넌트를 조건에 따라 출력할지가 고민이 되었다.
- 이후 개선 작업이 예정되어있고, 각 컴포넌트 별로 분리되어있는 것이 컴포넌트 복잡성을 줄이는 방법이라고 생각하여 후자의 방법을 선택하였다.
return (
<AnimatePresence>
{isNav && (
<>
<div className="lg:block hidden">
// 데스크탑 NavBar 컴포넌트
</div>
{/* 데스크탑 */}
<div className="lg:hidden block">
// 모바일, 태블릿 NavBar 컴포넌트
</div>
{/* 모바일, 태블릿 */}
</>
)}
</AnimatePresence>
);
};
export default NavBar;
PC | 모바일 |
---|---|
![]() | ![]() |
https://www.changwoo.site/ 확실히 내 이름이 있는 사이트라 마음에 든다!
import Script from 'next/script';
export default function GoogleAnalytics({ gaId }: { gaId: string }) {
return (
<>
<Script
async
src={`https://www.googletagmanager.com/gtag/js
?id=${gaId}`}
/>
<Script
id="google-analytics"
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${gaId}');
`,
}}
/>
</>
);
}
안녕하세요!! 혹시 포트폴리오 템플릿이 마음에 들어서 그런데, 사용해도 괜찮을까요???