은하계 인맥 커뮤니티를 만든 이야기 · 5편 — three.js와 모바일
이미지 불러오는 중…
지금까지가 무엇을 만들까였다면, 이번엔 어떻게 보이게 할까다. 관심사와 연결을 진짜 은하처럼 움직이게 하는 일. 이 서비스에서 화면은 장식이 아니라 제품 그 자체다.
데모는 원래 PC 기준이었다. 큰 캔버스 위에 작은 패널들이 떠 있는 형태. 그런데 실제 사용은 모바일로 흐르고 있었고, 무엇보다 밤하늘은 침대에 누워 폰으로 보는 것이다. 그래서 모든 화면을 모바일 뷰포트 기준으로 다시 설계했다. three.js 은하계도 터치와 성능을 먼저 고려했다.
PC는 버리지 않고 확장으로 뒀다. 화면 너비가 넓으면(≥1024px) 12개 별자리를 한눈에 보는 조망 뷰로, 좁으면 별자리를 하나씩 몰입해서 보는 순회 뷰로. 기기를 UA로 감지하지 않고 너비로 분기했다 — 위조나 신기기 문제 없이, 반응형의 정석대로.
한 캔버스에 다 욱여넣지 않았다.
여기서 기술적으로 가장 까다로웠던 부분. 글 상세는 공유·딥링크·뒤로가기가 돼야 하니 주소(라우트)로 분리해야 한다. 그런데 은하계 캔버스는 화면을 옮겨도 재마운트되면 안 된다 — three.js 씬을 매번 다시 초기화하면 무겁고 깜빡인다.
그래서 캔버스는 항상 살아있는 배경으로 두고, 그 위에 화면들을 시트·스택으로 얹는 구조로 갔다. 주소는 바뀌지만 은하는 계속 그 자리에 떠 있다.
글 상세에서의 이동은 제스처 대신 명시적인 화살표 버튼으로 정했다(제스처는 3D 조작과 충돌한다).
그리고 작은 배려 하나 — 어디까지 봤는지 기억한다. 잘못 옆 별로 갔다 돌아와도 보던 글이 그대로다. 이걸 세 겹으로 저장했다: 주소(가장 견고) → 세션 메모리(빠른 복귀) → localStorage(앱을 껐다 켜도 기억, 보너스). 하나가 없어도 다음 것으로 폴백해서 안 깨진다.
작지만 애정이 담긴 디테일. 은하 첫 렌더는 별 수천 개에 후처리(블룸)까지 얹혀 무겁다. 그 순간 흰 화면이 뜨면 "고장났나?" 싶어 이탈한다. 그래서 "별자리를 구성하고 있어요…" 로딩 오버레이를 넣었다. 은하 톤의 가벼운 링이 돌고 별이 반짝이다가, 준비되면 은하로 부드럽게 페이드인된다.
여기에도 함정이 있었다. 회전 애니메이션이 무거운 초기화 중에 멈춰 보이길래, GPU 레이어로 올려 안 얼게 했다. 실제 개선(첫 렌더 비용 자체)과 체감 개선(안 멈춰 보이게)은 다른 문제라는 걸 다시 배웠다.
이제 은하가 손안에서 움직인다. 그런데 한 번 온 사람을 다시 오게 하려면?
밤하늘은 매일 봐도 질리지 않는다. 그 감각을 서비스에 넣는 이야기 — 주간 리포트와 재방문 장치. 다음 글에서.
6편 예고: 「다시 오게 만들기 — 매주 열어보고 싶은 우주」