Surveyor 실전 적용기
Figma MCP를 실제 프로덕션 환경에 적용한 사례다. 바닐라 JS 기반 지도 측량 웹 UI를 Figma 디자인 그대로 구현한 전 과정을 기록한다. 업데이트: 2026-03-10
핵심 요약
| 구분 | 내용 |
|---|---|
| 📖 프로젝트 | Surveyor — 드론 측량 지도 웹 UI |
| 🛠️ 스택 | 바닐라 JS / HTML5 / CSS3 |
| 🎯 Figma 파일키 | 3N8raa5fKRNy5Lec4XGS5b |
| 📦 결과물 | 팝업 9종, SVG 아이콘 38개, CSS ~1430줄, JS ~239줄 |
| 💡 핵심 도구 | get_design_context — 모든 작업의 기준점 |
목차
1. 프로젝트 개요
Surveyor는 측량 현장용 지도 뷰어 웹 UI다. Figma 디자인 파일을 기준으로 삼아 픽셀 단위 피델리티를 목표로 구현했다.
| 항목 | 내용 |
|---|---|
| 주요 화면 | 헤더 툴바 / 푸터 상태바 / 나침반·줌 컨트롤 |
| 팝업 | 좌표변환 / 프로젝트목록 / 프로젝트상세 / 프로젝트편집 / 배경지도 / 측량정보 / 측량모듈 |
| Figma 기준 | 1920px 프레임, 좌우 margin 12px |
| 작업 기간 | 세션 3회 |
2. Figma MCP 활용 흐름
flowchart TD A[Figma URL + 노드 ID 전달] --> B[get_design_context 호출] B --> C[레이아웃·크기·색·아이콘 UUID 추출] C --> D[HTML 구조 작성] C --> E[아이콘 SVG 로컬 저장\nviews/img/] D --> F[CSS 스타일링\n수치 1:1 반영] E --> F F --> G[JS 동작 로직 구현] G --> H[Figma 재조회로 오류 검증]
Figma URL을 전달하면 get_design_context가 레이아웃 수치, 색상 토큰, 아이콘 에셋 UUID를 한 번에 반환한다. 이를 기반으로 HTML → CSS → JS 순서로 구현하고, 이상이 발견되면 같은 도구로 재조회해 검증한다.
실제 사용 흐름: 팝업 하나를 구현할 때마다 해당 노드 ID를 지정해
get_design_context를 호출했다. 전체 프레임을 한 번에 처리하지 않고, 컴포넌트 단위로 쪼개서 요청한 것이 정확도를 높이는 핵심이었다.
3. 구현 결과물
팝업 9종
| 팝업 | 트리거 | 위치 |
|---|---|---|
convertCoord_popup | 푸터 좌표변환 버튼 | fixed; left: 0.75rem; bottom: 4.25rem |
projectList_popup | 헤더 측량 버튼 | fixed; left: 0.75rem; top: 4.25rem |
projectDetail_popup | 프로젝트 케밥 버튼 | projectList 오른쪽, top 동적 계산 |
projectEdit_popup | 프로젝트상세 편집 버튼 | fixed; left: 50%; top: 50%; transform: translate(-50%, -50%) |
basemapLayer_popup | 헤더 배경지도 버튼 | fixed; right: 0.75rem; top: 4.25rem |
surveyInfo_popup | 헤더 측정 버튼 | fixed; left: 50%; transform: translateX(-50%); top: 7.75rem |
surveyModule_popup | 헤더 측정 버튼 | fixed; left: 50%; transform: translateX(-50%); top: 4.25rem |
파일 구조
views/
css/
reset.css 기존 리셋
system.css 색상 변수, 폰트, 타이포그래피
style.css ~1430줄 (레이아웃 + 팝업 전체)
img/ SVG 아이콘 38개
jsm/
main.js ~239줄 (팝업 토글 + 라디오 동작)
index.html 헤더/푸터/컨트롤/팝업 전체
4. 핵심 컨벤션
컬러 변수
| 변수 | 값 | 용도 |
|---|---|---|
--color-accent | #1b6fdd | 선택 상태, 강조 파랑 |
--color-dahong | #FF3D00 | 편집 가능한 input 텍스트 |
--color-bg-panel | rgba(255,255,255,0.7) | 패널 배경 |
--color-border-panel | rgba(221,221,221,0.7) | 패널 테두리 |
--color-text-primary | #111 | 기본 텍스트 |
--color-text-sub | #555 | 서브 텍스트 |
--color-text-caption | #777 | 캡션 텍스트 |
--color-text-muted | #aaa | 흐린 텍스트 |
편집 가능 요소 컨벤션
/* 편집 가능한 입력 요소는 반드시 빨간색 텍스트를 사용한다 */
.--editable { color: var(--color-dahong); }projectEdit_popup에서 확립된 규칙으로, 빨간색 텍스트 = 사용자가 수정 가능한 필드를 의미한다. input, textarea 모두 동일하게 적용된다.
팝업 show/hide 패턴
popup.classList.toggle('--show'); // 토글
popup.classList.add('--show'); // 열기
popup.classList.remove('--show'); // 닫기헤더/푸터 내부 위치 공식
left % = (피그마 left px - 12) / 1896 × 100%
1920px 기준 프레임에서 좌우 margin 12px를 제외한 유효 폭 1896px를 기준으로 퍼센트를 계산한다.
5. 주요 학습 포인트
실제 적용 과정에서 마주친 문제와 해결 방법을 정리한다.
빈 SVG 파일 문제
get_design_context가 반환하는 에셋 UUID 중 일부는 base frame(컨테이너)의 UUID다. 이 UUID로 다운로드한 SVG는 <g id="Vector"></g>처럼 경로 데이터가 없는 빈 파일이다.
해결: 노드를 한 레벨 더 내려가 실제 path 데이터가 있는 inner 레이어의 UUID를 사용한다.
예시: icon__mode-edit--gray.svg
❌ base frame UUID → <g id="Vector"></g> (빈 파일)
✅ inner body UUID → <path d="M0,0 L..."> (실제 아이콘)
overflow: hidden + border-radius 충돌
3D/2D 모드 토글 버튼처럼 서로 영역을 살짝 침범하는 디자인에서 overflow: hidden을 사용하면 각 버튼의 둥근 모서리가 잘린다.
해결: 부모 컨테이너에서 overflow: hidden을 제거하고, 각 버튼에 독립적으로 border-radius를 적용한다.
/* 수정 전 */
.--mode-toggle { overflow: hidden; border-radius: 0.75rem; }
/* 수정 후 */
.--mode-toggle { border-radius: 0.75rem; } /* overflow 제거 */
.--mode-toggle > .--mode-btn { border-radius: 0.75rem; } /* 각 버튼에 독립 적용 */아이콘 width/height 반전 오류
Figma에서 width: 14.4px, height: 13px인 아이콘을 HTML에 반영할 때 실수로 width↔height를 뒤바꿔 적용하는 경우가 발생한다. 아이콘 비율이 비슷할수록 육안으로 발견하기 어렵다.
해결: get_design_context 재조회로 원본 수치를 재확인 후 수정한다. 특히 가로/세로 비율이 비슷한 아이콘은 주의가 필요하다.
Figma 에셋 URL 직접 사용 금지
초기 구현 시 Figma CDN URL을 HTML에 직접 참조했다. 이는 Figma 정책상 언제든 무효화될 수 있다.
규칙: 아이콘은 반드시 views/img/ 폴더에 SVG로 저장한 뒤 상대경로(./img/파일명.svg)로 참조한다.