포트폴리오 사이트 전 섹션에 WebGL 비주얼과 한글 폰트 적용
목차
포트폴리오 사이트 전 섹션에 WebGL 비주얼을 붙이고, S-Core Dream 폰트를 적용한 작업이었다.
왜 이 타이밍에 WebGL이었나
솔직히 말하면, 포트폴리오 사이트는 오래된 숙제였다. 텍스트와 레이아웃만 있는 정적인 페이지로 몇 달을 방치해뒀는데, 그 상태로 외부에 공유하는 게 점점 불편해졌다. 개발자 소개 페이지인데 "비주얼이 너무 심심하다"는 피드백도 있었고, 무엇보다 내가 직접 봤을 때 뭔가 설레지 않았다.
이번에 아예 전 섹션에 WebGL 기반 배경 비주얼을 넣기로 결정했다. Three.js를 선택한 건 거의 자연스러운 수순이었다 — 브라우저에서 WebGL을 다루는 데 있어 진입장벽이 낮으면서도 표현의 폭이 넓고, three.min.js를 직접 번들에 포함시키는 방식으로 외부 CDN 의존을 없앴다. 빌드 파이프라인 없는 순수 HTML/JS 구조에서는 이게 제일 안정적이다.
작업 구조
변경된 파일을 보면 관심사가 꽤 명확하게 분리돼 있다.
| 파일 | 역할 |
|---|---|
index.html |
섹션 구조 마크업, 폰트 선언, canvas 마운트 포인트 |
effects.css |
WebGL canvas 위치 고정, z-index 레이어링, 섹션별 오버레이 처리 |
effects.js |
Three.js scene 초기화, 각 섹션 비주얼 로직, scroll 연동 |
three.min.js |
Three.js 번들 (로컬 포함) |
robots.txt |
크롤러 설정 |
3be4a8be474a3fef87f06b2474fc59e7.txt |
에셋 또는 캐시 키 관련 파일 |
가장 손이 많이 간 건 역시 effects.js였다. 전 섹션에 WebGL을 입힌다는 게 단순히 배경 하나 그리는 게 아니라, 스크롤 위치에 따라 scene이 전환되거나 인터랙션이 달라지는 흐름을 짜야 했기 때문이다. IntersectionObserver와 scroll 이벤트를 조합해서 섹션 진입 시점에 Three.js 애니메이션 파라미터를 바꾸는 방식으로 처리했다.
// 섹션 진입 시 WebGL 파라미터 전환 패턴 (일반 예시)
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const sectionId = entry.target.dataset.section;
transitionScene(sectionId); // Three.js uniform/mesh 교체
}
});
}, { threshold: 0.3 });
document.querySelectorAll('[data-section]').forEach(el => observer.observe(el));
이런 구조에서 주의할 점은 scene 전환 시 이전 geometry와 material을 dispose 처리하는 것이다. 포트폴리오 사이트 특성상 롱런 세션보다는 짧은 방문이 많지만, GPU 메모리 누수를 그냥 두면 모바일에서 눈에 띄게 느려진다.
effects.css에서 신경 쓴 부분은 canvas의 레이어 처리였다. WebGL canvas를 position: fixed로 전체 화면에 깔고, 섹션 콘텐츠는 그 위에 올라가는 구조인데, pointer-events: none을 canvas에 걸어서 텍스트나 버튼 클릭을 방해하지 않도록 했다. 이걸 빠뜨리면 인터랙션 전체가 막혀버리는 꽤 황당한 버그가 생긴다.
S-Core Dream 폰트 선택
폰트는 S-Core Dream으로 결정했다. 무료 한글 폰트 중에서 기하학적이고 현대적인 느낌을 주는 게 이 폰트 말고는 선택지가 좁았다. WebGL 비주얼이 주는 기계적/추상적인 분위기와 잘 맞는다고 판단했고, 실제로 올려보니 예상보다 잘 어울렸다.
다만 폰트 파일 용량이 꽤 크기 때문에, 실제로 사용하는 굵기 weight만 subset으로 로드하는 게 이상적이다. 현재는 전체 weight를 로드하고 있는데, 이 부분은 다음 작업에서 손봐야 할 포인트로 남겨뒀다.
회고
포트폴리오 사이트 작업은 팀 업무와 달리 "누군가 리뷰해주는 사람이 없다"는 특수한 상황이다. 그래서 오히려 내가 평소에 코드리뷰에서 지적하는 것들 — dispose 누락, z-index 마법 숫자, 이벤트 리스너 중복 등록 — 을 내 코드에서 발견하게 된다. 민망하지만 유익한 경험이다.
robots.txt를 이번에 함께 정리한 건, WebGL 캔버스 자체가 크롤러한테 의미 없는 리소스라 중요 콘텐츠 인덱싱에 집중시키려는 의도였다. 작은 파일이지만 배포 전 체크리스트에서 자주 빠지는 항목 중 하나라 같이 처리했다.
3be4a8be474a3fef87f06b2474fc59e7.txt 파일은 해시 기반 파일명으로 보아 에셋 버전 관리 또는 캐시 무효화용 마커 파일로 추정된다. 빌드 없는 정적 사이트에서 브라우저 캐시를 수동으로 제어할 때 종종 쓰는 패턴이다.
결과적으로 배포 후 처음으로 사이트를 열었을 때 "이제 공유해도 되겠다"는 느낌이 들었다. 그 감각을 되찾는 데 생각보다 오래 걸렸다.
끝.
🛒 이 글과 어울리는 추천 상품
*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.
댓글 0
첫 댓글 달아줘.